diff --git a/.gitignore b/.gitignore index 04d768c88..441680cc4 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,13 @@ Desktop.ini .claude/*.local.* .stripe/ +# Wizard-run droppings inside fixture apps — installed skills, the run cache, +# and the setup report a run leaves behind must never be committed as fixture +# state (they bias later runs into skipping install/report steps). +apps/**/.claude/skills/ +apps/**/.posthog-wizard-cache/ +apps/**/posthog-*-report.md + # Temporary tmp/ temp/ diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/.gitignore b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/.gitignore new file mode 100644 index 000000000..d19729d8d --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/.gitignore @@ -0,0 +1,27 @@ +# Dependencies +node_modules/ + +# Build output +dist/ + +# Environment variables +.env +.env.local +.env.*.local + +# Logs +*.log +npm-debug.log* + +# Editor +.vscode/ +.idea/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# TypeScript cache +*.tsbuildinfo diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/CLAUDE.md b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/CLAUDE.md new file mode 100644 index 000000000..ac0822404 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/CLAUDE.md @@ -0,0 +1,81 @@ +# Simple Chat App + +A minimal chat application demonstrating the Claude Agent SDK. + +## Architecture + +- **Frontend**: React + Vite + Tailwind CSS +- **Backend**: Node.js + Express + WebSocket (ws) +- **Agent**: Claude Agent SDK integrated directly on the server + +## Running the App + +```bash +cd simple-chatapp +npm install +npm run dev +``` + +This starts both: +- Backend server on http://localhost:3001 +- Vite dev server on http://localhost:5173 + +Visit http://localhost:5173 + +## Project Structure + +``` +simple-chatapp/ +├── client/ # React frontend +│ ├── App.tsx # Main app component +│ ├── index.tsx # Entry point +│ ├── index.html # HTML template +│ ├── globals.css # Tailwind CSS +│ ├── components/ +│ │ ├── ChatList.tsx # Left sidebar with chat list +│ │ └── ChatWindow.tsx # Main chat interface +│ └── hooks/ +│ └── useWebSocket.ts # WebSocket hook +├── server/ +│ ├── server.ts # Express server (REST + WebSocket) +│ ├── ai-client.ts # Claude Agent SDK wrapper +│ ├── session.ts # Chat session management +│ ├── chat-store.ts # In-memory chat storage +│ └── types.ts # TypeScript types +├── package.json +├── tsconfig.json +├── vite.config.ts +├── tailwind.config.js +└── postcss.config.js +``` + +## API Endpoints + +### REST API + +- `GET /api/chats` - List all chats +- `POST /api/chats` - Create new chat +- `GET /api/chats/:id` - Get chat details +- `DELETE /api/chats/:id` - Delete chat +- `GET /api/chats/:id/messages` - Get chat messages + +### WebSocket (`ws://localhost:3001/ws`) + +**Client -> Server:** +- `{ type: "subscribe", chatId: string }` - Subscribe to a chat +- `{ type: "chat", chatId: string, content: string }` - Send message + +**Server -> Client:** +- `{ type: "connected" }` - Connection established +- `{ type: "history", messages: [...] }` - Chat history +- `{ type: "assistant_message", content: string }` - AI response +- `{ type: "tool_use", toolName: string, toolInput: {...} }` - Tool being used +- `{ type: "result", success: boolean }` - Query complete +- `{ type: "error", error: string }` - Error occurred + +## Notes + +- In-memory storage (data lost on restart) +- Agent has access to: Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch +- Uses Vite for frontend development with hot reload +- Uses tsx for TypeScript execution on the backend diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/README.md b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/README.md new file mode 100644 index 000000000..291ea9cb3 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/README.md @@ -0,0 +1,46 @@ +# Simple Chat App + +A demo chat application using the Claude Agent SDK with a React frontend and Express backend. + +![Architecture Diagram](diagram.png) + +## Getting Started + +### Prerequisites + +- Node.js 18+ +- Claude Agent SDK credentials (set `ANTHROPIC_API_KEY` environment variable) + +### Installation + +```bash +npm install +``` + +### Running + +```bash +npm run dev +``` + +This starts both: +- **Backend** (Express + WebSocket) on http://localhost:3001 +- **Frontend** (Vite + React) on http://localhost:5173 + +Open http://localhost:5173 in your browser. + +## Production Considerations + +This is an example app for demonstration purposes. For production use, consider: + +1. **Isolate the Agent SDK** - Move the SDK into a separate container/service. This provides better security isolation since the agent has access to tools like Bash, file system operations, and web requests. + +2. **Persistent storage** - Replace the in-memory `ChatStore` with a database. Currently all chats are lost on server restart. + +3. **Transcript syncing** - For Agent Sessions to be persisted across server restarts, you'll need to persist and restore the SDK's conversation transcripts. The SDK maintains internal state for multi-turn conversations that must be synced with your storage. + +4. **Authentication** - Add user authentication and authorization. Currently anyone can access any chat. + +## Demo + +![Demo](demo.gif) \ No newline at end of file diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/App.tsx b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/App.tsx new file mode 100644 index 000000000..a0e466dd9 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/App.tsx @@ -0,0 +1,208 @@ +import { useState, useEffect, useCallback } from "react"; +import useWebSocket, { ReadyState } from "react-use-websocket"; +import { ChatList } from "./components/ChatList"; +import { ChatWindow } from "./components/ChatWindow"; + +interface Chat { + id: string; + title: string; + createdAt: string; + updatedAt: string; +} + +interface Message { + id: string; + role: "user" | "assistant" | "tool_use"; + content: string; + timestamp: string; + toolName?: string; + toolInput?: Record; +} + +// Use relative URLs - Vite will proxy to the backend +const API_BASE = "/api"; +const WS_URL = `ws://${window.location.hostname}:3001/ws`; + +export default function App() { + const [chats, setChats] = useState([]); + const [selectedChatId, setSelectedChatId] = useState(null); + const [messages, setMessages] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + // Handle WebSocket messages + const handleWSMessage = useCallback((message: any) => { + switch (message.type) { + case "connected": + console.log("Connected to server"); + break; + + case "history": + setMessages(message.messages || []); + break; + + case "user_message": + // User message already added locally + break; + + case "assistant_message": + setMessages((prev) => [ + ...prev, + { + id: crypto.randomUUID(), + role: "assistant", + content: message.content, + timestamp: new Date().toISOString(), + }, + ]); + setIsLoading(false); + break; + + case "tool_use": + // Add tool use to messages array so it persists + // Alternative: To show tool uses only while pending, store them in a + // separate `pendingToolUses` state and clear it on "assistant_message" or "result" + setMessages((prev) => [ + ...prev, + { + id: message.toolId, + role: "tool_use", + content: "", + timestamp: new Date().toISOString(), + toolName: message.toolName, + toolInput: message.toolInput, + }, + ]); + break; + + case "result": + setIsLoading(false); + // Refresh chat list to get updated titles + fetchChats(); + break; + + case "error": + console.error("Server error:", message.error); + setIsLoading(false); + break; + } + }, []); + + const { sendJsonMessage, readyState, lastJsonMessage } = useWebSocket(WS_URL, { + shouldReconnect: () => true, + reconnectAttempts: 10, + reconnectInterval: 3000, + }); + + const isConnected = readyState === ReadyState.OPEN; + + // Handle incoming WebSocket messages + useEffect(() => { + if (lastJsonMessage) { + handleWSMessage(lastJsonMessage); + } + }, [lastJsonMessage, handleWSMessage]); + + // Fetch all chats + const fetchChats = async () => { + try { + const res = await fetch(`${API_BASE}/chats`); + const data = await res.json(); + setChats(data); + } catch (error) { + console.error("Failed to fetch chats:", error); + } + }; + + // Create new chat + const createChat = async () => { + try { + const res = await fetch(`${API_BASE}/chats`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + }); + const chat = await res.json(); + setChats((prev) => [chat, ...prev]); + selectChat(chat.id); + } catch (error) { + console.error("Failed to create chat:", error); + } + }; + + // Delete chat + const deleteChat = async (chatId: string) => { + try { + await fetch(`${API_BASE}/chats/${chatId}`, { method: "DELETE" }); + setChats((prev) => prev.filter((c) => c.id !== chatId)); + if (selectedChatId === chatId) { + setSelectedChatId(null); + setMessages([]); + } + } catch (error) { + console.error("Failed to delete chat:", error); + } + }; + + // Select a chat + const selectChat = (chatId: string) => { + setSelectedChatId(chatId); + setMessages([]); + setIsLoading(false); + + // Subscribe to chat via WebSocket + sendJsonMessage({ type: "subscribe", chatId }); + }; + + // Send a message + const handleSendMessage = (content: string) => { + if (!selectedChatId || !isConnected) return; + + // Add message optimistically + setMessages((prev) => [ + ...prev, + { + id: crypto.randomUUID(), + role: "user", + content, + timestamp: new Date().toISOString(), + }, + ]); + + setIsLoading(true); + + // Send via WebSocket + sendJsonMessage({ + type: "chat", + content, + chatId: selectedChatId, + }); + }; + + // Initial fetch + useEffect(() => { + fetchChats(); + }, []); + + return ( +
+ {/* Sidebar */} +
+ +
+ + {/* Main chat area */} + +
+ ); +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/components/ChatList.tsx b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/components/ChatList.tsx new file mode 100644 index 000000000..aa411d4ad --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/components/ChatList.tsx @@ -0,0 +1,82 @@ +import React from "react"; + +interface Chat { + id: string; + title: string; + createdAt: string; + updatedAt: string; +} + +interface ChatListProps { + chats: Chat[]; + selectedChatId: string | null; + onSelectChat: (chatId: string) => void; + onNewChat: () => void; + onDeleteChat: (chatId: string) => void; +} + +export function ChatList({ + chats, + selectedChatId, + onSelectChat, + onNewChat, + onDeleteChat, +}: ChatListProps) { + return ( +
+ {/* Header */} +
+ +
+ + {/* Chat list */} +
+ {chats.length === 0 ? ( +
+

No chats yet

+

Click "New Chat" to start

+
+ ) : ( +
+ {chats.map((chat) => ( +
onSelectChat(chat.id)} + > + 💬 + {chat.title} + +
+ ))} +
+ )} +
+ + {/* Footer */} +
+

+ Simple Chat App +

+
+
+ ); +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/components/ChatWindow.tsx b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/components/ChatWindow.tsx new file mode 100644 index 000000000..aa1dca1b3 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/components/ChatWindow.tsx @@ -0,0 +1,185 @@ +import React, { useState, useRef, useEffect } from "react"; + +interface Message { + id: string; + role: "user" | "assistant" | "tool_use"; + content: string; + timestamp: string; + toolName?: string; + toolInput?: Record; +} + +interface ChatWindowProps { + chatId: string | null; + messages: Message[]; + isConnected: boolean; + isLoading: boolean; + onSendMessage: (content: string) => void; +} + +function ToolUseBlock({ message }: { message: Message }) { + const [isExpanded, setIsExpanded] = useState(false); + + const getToolSummary = () => { + const input = message.toolInput || {}; + switch (message.toolName) { + case "Read": + return input.file_path; + case "Write": + case "Edit": + return input.file_path; + case "Bash": + return input.command?.slice(0, 60) + (input.command?.length > 60 ? "..." : ""); + case "Grep": + return `"${input.pattern}" in ${input.path || "."}`; + case "Glob": + return input.pattern; + case "WebSearch": + return input.query; + case "WebFetch": + return input.url; + default: + return JSON.stringify(input).slice(0, 50); + } + }; + + return ( +
+ + {isExpanded && ( +
+
+            {JSON.stringify(message.toolInput, null, 2)}
+          
+
+ )} +
+ ); +} + +function MessageBubble({ message }: { message: Message }) { + const isUser = message.role === "user"; + + return ( +
+
+

{message.content}

+
+
+ ); +} + +export function ChatWindow({ + chatId, + messages, + isConnected, + isLoading, + onSendMessage, +}: ChatWindowProps) { + const [input, setInput] = useState(""); + const messagesEndRef = useRef(null); + + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages]); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!input.trim() || !chatId || isLoading || !isConnected) return; + onSendMessage(input.trim()); + setInput(""); + }; + + if (!chatId) { + return ( +
+
+

Welcome to Simple Chat

+

Select a chat or create a new one to get started

+
+
+ ); + } + + return ( +
+ {/* Header */} +
+

Chat

+
+ {isConnected ? ( + ● Connected + ) : ( + ○ Disconnected + )} +
+
+ + {/* Messages */} +
+ {messages.length === 0 ? ( +
+

Start a conversation

+
+ ) : ( + <> + {messages.map((msg) => + msg.role === "tool_use" ? ( + + ) : ( + + ) + )} + {isLoading && ( +
+ + Thinking... +
+ )} + + )} +
+
+ + {/* Input */} +
+
+ setInput(e.target.value)} + placeholder={isConnected ? "Type a message..." : "Connecting..."} + disabled={!isConnected || isLoading} + className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:bg-gray-100" + /> + +
+
+
+ ); +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/globals.css b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/globals.css new file mode 100644 index 000000000..b5c61c956 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/index.html b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/index.html new file mode 100644 index 000000000..94ec820c5 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/index.html @@ -0,0 +1,12 @@ + + + + + + Simple Chat App + + +
+ + + diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/index.tsx b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/index.tsx new file mode 100644 index 000000000..b305c9904 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/client/index.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import App from "./App"; +import "./globals.css"; + +const container = document.getElementById("root"); +if (container) { + const root = createRoot(container); + root.render(); +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/demo.gif b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/demo.gif new file mode 100644 index 000000000..cc6d9df63 Binary files /dev/null and b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/demo.gif differ diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/diagram.png b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/diagram.png new file mode 100644 index 000000000..79539e6b5 Binary files /dev/null and b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/diagram.png differ diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/package-lock.json b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/package-lock.json new file mode 100644 index 000000000..0c7babfaf --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/package-lock.json @@ -0,0 +1,5312 @@ +{ + "name": "simple-chatapp", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "simple-chatapp", + "version": "1.0.0", + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "^0.1.28", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-use-websocket": "^4.13.0", + "uuid": "^10.0.0", + "ws": "^8.18.0" + }, + "devDependencies": { + "@types/cors": "^2.8.17", + "@types/express": "^4.17.21", + "@types/node": "^22.0.0", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "@types/uuid": "^10.0.0", + "@types/ws": "^8.5.12", + "@vitejs/plugin-react": "^4.3.0", + "autoprefixer": "^10.4.20", + "concurrently": "^9.0.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.14", + "tsx": "^4.19.0", + "typescript": "^5.5.0", + "vite": "^5.4.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@anthropic-ai/claude-agent-sdk": { + "version": "0.1.53", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.1.53.tgz", + "integrity": "sha512-k8qsWx2Ey3Y1qNdarS9VFFaJk+H+lEmH6AWtBbDRwQkYcdlltjZPZ8IJ71Eo683oNbwQMeepmJ4AAYMmK8EH0g==", + "license": "SEE LICENSE IN README.md", + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "^0.33.5", + "@img/sharp-darwin-x64": "^0.33.5", + "@img/sharp-linux-arm": "^0.33.5", + "@img/sharp-linux-arm64": "^0.33.5", + "@img/sharp-linux-x64": "^0.33.5", + "@img/sharp-linuxmusl-arm64": "^0.33.5", + "@img/sharp-linuxmusl-x64": "^0.33.5", + "@img/sharp-win32-x64": "^0.33.5" + }, + "peerDependencies": { + "zod": "^3.24.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", + "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", + "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", + "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", + "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", + "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", + "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", + "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", + "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", + "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", + "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", + "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", + "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", + "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", + "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", + "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", + "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", + "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", + "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", + "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", + "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", + "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", + "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/mime/1.3.5/mime-1.3.5.tgz", + "integrity": "sha1-HvMC4Bz30rWg+lJnkMkSO/HQZpA=", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/node/-/node-22.19.0.tgz", + "integrity": "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==", + "dev": true, + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.25", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/react/-/react-18.3.25.tgz", + "integrity": "sha512-oSVZmGtDPmRZtVDqvdKUi/qgCsWp5IDY29wp8na8Bj4B3cc99hfNzvNhlMkVVxctkAOGUA3Km7MMpBHAnWfcIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/send": { + "version": "1.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/send/-/send-1.2.0.tgz", + "integrity": "sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/async-generator-function": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/async-generator-function/-/async-generator-function-1.0.0.tgz", + "integrity": "sha512-+NAXNqgCrB95ya4Sr66i1CL2hqLVckAk7xwRYWdcm39/ELQ6YNn1aw5r0bdQtqNZgQpEWzc5yc/igXc7aL5SLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.25", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz", + "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/browserslist/-/browserslist-4.28.0.tgz", + "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.25", + "caniuse-lite": "^1.0.30001754", + "electron-to-chromium": "^1.5.249", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001754", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", + "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.249", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", + "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/get-intrinsic/-/get-intrinsic-1.3.1.tgz", + "integrity": "sha512-fk1ZVEeOX9hVZ6QzoBNEC55+Ucqg4sTVwrVuigZhuRPESVFpMyXnd3sbXvPOwp7Y9riVyANiqhEuRF0G1aVSeQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "async-generator-function": "^1.0.0", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-use-websocket": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/react-use-websocket/-/react-use-websocket-4.13.0.tgz", + "integrity": "sha512-anMuVoV//g2N76Wxqvqjjo1X48r9Np3y1/gMl7arX84tAPXdy5R7sB5lO5hvCzQRYjqXwV8XMAiEBOUbyrZFrw==", + "license": "MIT" + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.53.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/rollup/-/rollup-4.53.2.tgz", + "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.2", + "@rollup/rollup-android-arm64": "4.53.2", + "@rollup/rollup-darwin-arm64": "4.53.2", + "@rollup/rollup-darwin-x64": "4.53.2", + "@rollup/rollup-freebsd-arm64": "4.53.2", + "@rollup/rollup-freebsd-x64": "4.53.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", + "@rollup/rollup-linux-arm-musleabihf": "4.53.2", + "@rollup/rollup-linux-arm64-gnu": "4.53.2", + "@rollup/rollup-linux-arm64-musl": "4.53.2", + "@rollup/rollup-linux-loong64-gnu": "4.53.2", + "@rollup/rollup-linux-ppc64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-musl": "4.53.2", + "@rollup/rollup-linux-s390x-gnu": "4.53.2", + "@rollup/rollup-linux-x64-gnu": "4.53.2", + "@rollup/rollup-linux-x64-musl": "4.53.2", + "@rollup/rollup-openharmony-arm64": "4.53.2", + "@rollup/rollup-win32-arm64-msvc": "4.53.2", + "@rollup/rollup-win32-ia32-msvc": "4.53.2", + "@rollup/rollup-win32-x64-gnu": "4.53.2", + "@rollup/rollup-win32-x64-msvc": "4.53.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/thenify/3.3.1/thenify-3.3.1.tgz", + "integrity": "sha1-iTLmhqQGYDigFt2eLKRq3Zg4qV8=", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.20.6", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/tsx/-/tsx-4.20.6.tgz", + "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/package.json b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/package.json new file mode 100644 index 000000000..623189b7a --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/package.json @@ -0,0 +1,41 @@ +{ + "name": "simple-chatapp", + "version": "1.0.0", + "type": "module", + "description": "A simple chat application with Claude Agent SDK", + "scripts": { + "dev": "concurrently \"npm run dev:server\" \"npm run dev:client\"", + "dev:server": "tsx watch server/server.ts", + "dev:client": "vite --port 5173", + "start": "tsx server/server.ts", + "build": "vite build" + }, + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "^0.1.28", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-use-websocket": "^4.13.0", + "uuid": "^10.0.0", + "ws": "^8.18.0" + }, + "devDependencies": { + "@types/cors": "^2.8.17", + "@types/express": "^4.17.21", + "@types/node": "^22.0.0", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "@types/uuid": "^10.0.0", + "@types/ws": "^8.5.12", + "@vitejs/plugin-react": "^4.3.0", + "autoprefixer": "^10.4.20", + "concurrently": "^9.0.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.14", + "tsx": "^4.19.0", + "typescript": "^5.5.0", + "vite": "^5.4.0" + } +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/postcss.config.js b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/postcss.config.js new file mode 100644 index 000000000..2aa7205d4 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/ai-client.ts b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/ai-client.ts new file mode 100644 index 000000000..ee20f13d9 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/ai-client.ts @@ -0,0 +1,107 @@ +import { query } from "@anthropic-ai/claude-agent-sdk"; + +const SYSTEM_PROMPT = `You are a helpful AI assistant. You can help users with a wide variety of tasks including: +- Answering questions +- Writing and editing text +- Coding and debugging +- Analysis and research +- Creative tasks + +Be concise but thorough in your responses.`; + +type UserMessage = { + type: "user"; + message: { role: "user"; content: string }; +}; + +// Simple async queue - messages go in via push(), come out via async iteration +class MessageQueue { + private messages: UserMessage[] = []; + private waiting: ((msg: UserMessage) => void) | null = null; + private closed = false; + + push(content: string) { + const msg: UserMessage = { + type: "user", + message: { + role: "user", + content, + }, + }; + + if (this.waiting) { + // Someone is waiting for a message - give it to them + this.waiting(msg); + this.waiting = null; + } else { + // No one waiting - queue it + this.messages.push(msg); + } + } + + async *[Symbol.asyncIterator](): AsyncIterableIterator { + while (!this.closed) { + if (this.messages.length > 0) { + yield this.messages.shift()!; + } else { + // Wait for next message + yield await new Promise((resolve) => { + this.waiting = resolve; + }); + } + } + } + + close() { + this.closed = true; + } +} + +export class AgentSession { + private queue = new MessageQueue(); + private outputIterator: AsyncIterator | null = null; + + constructor() { + // Start the query immediately with the queue as input + // Cast to any - SDK accepts simpler message format at runtime + this.outputIterator = query({ + prompt: this.queue as any, + options: { + maxTurns: 100, + model: "opus", + allowedTools: [ + "Bash", + "Read", + "Write", + "Edit", + "Glob", + "Grep", + "WebSearch", + "WebFetch", + ], + systemPrompt: SYSTEM_PROMPT, + }, + })[Symbol.asyncIterator](); + } + + // Send a message to the agent + sendMessage(content: string) { + this.queue.push(content); + } + + // Get the output stream + async *getOutputStream() { + if (!this.outputIterator) { + throw new Error("Session not initialized"); + } + while (true) { + const { value, done } = await this.outputIterator.next(); + if (done) break; + yield value; + } + } + + close() { + this.queue.close(); + } +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/chat-store.ts b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/chat-store.ts new file mode 100644 index 000000000..1a98f926a --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/chat-store.ts @@ -0,0 +1,81 @@ +import { v4 as uuidv4 } from "uuid"; +import type { Chat, ChatMessage } from "./types.js"; + +// Simple in-memory store for chats +class ChatStore { + private chats: Map = new Map(); + private messages: Map = new Map(); + + createChat(title?: string): Chat { + const id = uuidv4(); + const now = new Date().toISOString(); + const chat: Chat = { + id, + title: title || "New Chat", + createdAt: now, + updatedAt: now, + }; + this.chats.set(id, chat); + this.messages.set(id, []); + return chat; + } + + getChat(id: string): Chat | undefined { + return this.chats.get(id); + } + + getAllChats(): Chat[] { + return Array.from(this.chats.values()).sort( + (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime() + ); + } + + updateChatTitle(id: string, title: string): Chat | undefined { + const chat = this.chats.get(id); + if (chat) { + chat.title = title; + chat.updatedAt = new Date().toISOString(); + } + return chat; + } + + deleteChat(id: string): boolean { + this.messages.delete(id); + return this.chats.delete(id); + } + + addMessage(chatId: string, message: Omit): ChatMessage { + const messages = this.messages.get(chatId); + if (!messages) { + throw new Error(`Chat ${chatId} not found`); + } + + const newMessage: ChatMessage = { + id: uuidv4(), + chatId, + timestamp: new Date().toISOString(), + ...message, + }; + messages.push(newMessage); + + // Update chat's updatedAt + const chat = this.chats.get(chatId); + if (chat) { + chat.updatedAt = newMessage.timestamp; + + // Auto-generate title from first user message if still "New Chat" + if (chat.title === "New Chat" && message.role === "user") { + chat.title = message.content.slice(0, 50) + (message.content.length > 50 ? "..." : ""); + } + } + + return newMessage; + } + + getMessages(chatId: string): ChatMessage[] { + return this.messages.get(chatId) || []; + } +} + +// Singleton instance +export const chatStore = new ChatStore(); diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/server.ts b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/server.ts new file mode 100644 index 000000000..1c8106bfc --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/server.ts @@ -0,0 +1,165 @@ +import "dotenv/config"; +import express from "express"; +import cors from "cors"; +import { createServer } from "http"; +import { WebSocketServer, WebSocket } from "ws"; +import path from "path"; +import { fileURLToPath } from "url"; +import type { WSClient, IncomingWSMessage } from "./types.js"; +import { chatStore } from "./chat-store.js"; +import { Session } from "./session.js"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const PORT = process.env.PORT || 3001; + +// Express app +const app = express(); +app.use(cors()); +app.use(express.json()); + +// Serve static files from client directory +app.use("/client", express.static(path.join(__dirname, "../client"))); + +// Serve index.html at root +app.get("/", (req, res) => { + res.sendFile(path.join(__dirname, "../client/index.html")); +}); + +// Session management +const sessions: Map = new Map(); + +function getOrCreateSession(chatId: string): Session { + let session = sessions.get(chatId); + if (!session) { + session = new Session(chatId); + sessions.set(chatId, session); + } + return session; +} + +// REST API: Get all chats +app.get("/api/chats", (req, res) => { + const chats = chatStore.getAllChats(); + res.json(chats); +}); + +// REST API: Create new chat +app.post("/api/chats", (req, res) => { + const chat = chatStore.createChat(req.body?.title); + res.status(201).json(chat); +}); + +// REST API: Get single chat +app.get("/api/chats/:id", (req, res) => { + const chat = chatStore.getChat(req.params.id); + if (!chat) { + return res.status(404).json({ error: "Chat not found" }); + } + res.json(chat); +}); + +// REST API: Delete chat +app.delete("/api/chats/:id", (req, res) => { + const deleted = chatStore.deleteChat(req.params.id); + if (!deleted) { + return res.status(404).json({ error: "Chat not found" }); + } + const session = sessions.get(req.params.id); + if (session) { + session.close(); + sessions.delete(req.params.id); + } + res.json({ success: true }); +}); + +// REST API: Get chat messages +app.get("/api/chats/:id/messages", (req, res) => { + const messages = chatStore.getMessages(req.params.id); + res.json(messages); +}); + +// Create HTTP server +const server = createServer(app); + +// WebSocket server +const wss = new WebSocketServer({ server, path: "/ws" }); + +wss.on("connection", (ws: WSClient) => { + console.log("WebSocket client connected"); + ws.isAlive = true; + + ws.send(JSON.stringify({ type: "connected", message: "Connected to chat server" })); + + ws.on("pong", () => { + ws.isAlive = true; + }); + + ws.on("message", (data) => { + try { + const message: IncomingWSMessage = JSON.parse(data.toString()); + + switch (message.type) { + case "subscribe": { + const session = getOrCreateSession(message.chatId); + session.subscribe(ws); + console.log(`Client subscribed to chat ${message.chatId}`); + + // Send existing messages + const messages = chatStore.getMessages(message.chatId); + ws.send(JSON.stringify({ + type: "history", + messages, + chatId: message.chatId, + })); + break; + } + + case "chat": { + const session = getOrCreateSession(message.chatId); + session.subscribe(ws); + session.sendMessage(message.content); + break; + } + + default: + console.warn("Unknown message type:", (message as any).type); + } + } catch (error) { + console.error("Error handling WebSocket message:", error); + ws.send(JSON.stringify({ type: "error", error: "Invalid message format" })); + } + }); + + ws.on("close", () => { + console.log("WebSocket client disconnected"); + // Unsubscribe from all sessions + for (const session of sessions.values()) { + session.unsubscribe(ws); + } + }); +}); + +// Heartbeat to detect dead connections +const heartbeat = setInterval(() => { + wss.clients.forEach((ws) => { + const client = ws as WSClient; + if (client.isAlive === false) { + return client.terminate(); + } + client.isAlive = false; + client.ping(); + }); +}, 30000); + +wss.on("close", () => { + clearInterval(heartbeat); +}); + +// Start server +server.listen(PORT, () => { + console.log(`Server running at http://localhost:${PORT}`); + console.log(`WebSocket endpoint available at ws://localhost:${PORT}/ws`); + console.log(`Visit http://localhost:${PORT} to view the chat interface`); +}); diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/session.ts b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/session.ts new file mode 100644 index 000000000..dd0a02b45 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/session.ts @@ -0,0 +1,143 @@ +import type { WSClient } from "./types.js"; +import { AgentSession } from "./ai-client.js"; +import { chatStore } from "./chat-store.js"; + +// Session manages a single chat conversation with a long-lived agent +export class Session { + public readonly chatId: string; + private subscribers: Set = new Set(); + private agentSession: AgentSession; + private isListening = false; + + constructor(chatId: string) { + this.chatId = chatId; + this.agentSession = new AgentSession(); + } + + // Start listening to agent output (call once) + private async startListening() { + if (this.isListening) return; + this.isListening = true; + + try { + for await (const message of this.agentSession.getOutputStream()) { + this.handleSDKMessage(message); + } + } catch (error) { + console.error(`Error in session ${this.chatId}:`, error); + this.broadcastError((error as Error).message); + } + } + + // Send a user message to the agent + sendMessage(content: string) { + // Store user message + chatStore.addMessage(this.chatId, { + role: "user", + content, + }); + + // Broadcast user message to subscribers + this.broadcast({ + type: "user_message", + content, + chatId: this.chatId, + }); + + // Send to agent first (this starts the session if needed) + this.agentSession.sendMessage(content); + + // Start listening if not already + if (!this.isListening) { + this.startListening(); + } + } + + private handleSDKMessage(message: any) { + if (message.type === "assistant") { + const content = message.message.content; + + if (typeof content === "string") { + chatStore.addMessage(this.chatId, { + role: "assistant", + content, + }); + this.broadcast({ + type: "assistant_message", + content, + chatId: this.chatId, + }); + } else if (Array.isArray(content)) { + for (const block of content) { + if (block.type === "text") { + chatStore.addMessage(this.chatId, { + role: "assistant", + content: block.text, + }); + this.broadcast({ + type: "assistant_message", + content: block.text, + chatId: this.chatId, + }); + } else if (block.type === "tool_use") { + this.broadcast({ + type: "tool_use", + toolName: block.name, + toolId: block.id, + toolInput: block.input, + chatId: this.chatId, + }); + } + } + } + } else if (message.type === "result") { + this.broadcast({ + type: "result", + success: message.subtype === "success", + chatId: this.chatId, + cost: message.total_cost_usd, + duration: message.duration_ms, + }); + } + } + + subscribe(client: WSClient) { + this.subscribers.add(client); + client.sessionId = this.chatId; + } + + unsubscribe(client: WSClient) { + this.subscribers.delete(client); + } + + hasSubscribers(): boolean { + return this.subscribers.size > 0; + } + + private broadcast(message: any) { + const messageStr = JSON.stringify(message); + for (const client of this.subscribers) { + try { + if (client.readyState === client.OPEN) { + client.send(messageStr); + } + } catch (error) { + console.error("Error broadcasting to client:", error); + this.subscribers.delete(client); + } + } + } + + private broadcastError(error: string) { + this.broadcast({ + type: "error", + error, + chatId: this.chatId, + }); + } + + // Close the session + close() { + this.agentSession.close(); + } +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/types.ts b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/types.ts new file mode 100644 index 000000000..ca8e3d450 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/server/types.ts @@ -0,0 +1,38 @@ +import type { WebSocket } from "ws"; + +// WebSocket client with session data +export interface WSClient extends WebSocket { + sessionId?: string; + isAlive?: boolean; +} + +// Chat stored in memory +export interface Chat { + id: string; + title: string; + createdAt: string; + updatedAt: string; +} + +// Message stored in memory +export interface ChatMessage { + id: string; + chatId: string; + role: "user" | "assistant"; + content: string; + timestamp: string; +} + +// WebSocket incoming messages +export interface WSChatMessage { + type: "chat"; + content: string; + chatId: string; +} + +export interface WSSubscribeMessage { + type: "subscribe"; + chatId: string; +} + +export type IncomingWSMessage = WSChatMessage | WSSubscribeMessage; diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/tailwind.config.js b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/tailwind.config.js new file mode 100644 index 000000000..eabe9c517 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./client/**/*.{js,ts,jsx,tsx,html}"], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/tsconfig.json b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/tsconfig.json new file mode 100644 index 000000000..c08ea3b21 --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "jsx": "react-jsx", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "outDir": "./dist", + "rootDir": "." + }, + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules", "dist"] +} diff --git a/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/vite.config.ts b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/vite.config.ts new file mode 100644 index 000000000..4da70038c --- /dev/null +++ b/apps/ai-observability/claude-agent-sdk/typescript-simple-chatapp/vite.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + root: "client", + server: { + proxy: { + "/api": "http://localhost:3001", + "/ws": { + target: "ws://localhost:3001", + ws: true, + }, + }, + }, + build: { + outDir: "../dist", + }, +}); diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/README.md b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/README.md new file mode 100644 index 000000000..756ade6eb --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/README.md @@ -0,0 +1,38 @@ +# Financial Research Agent Example + +This example shows how you might compose a richer financial research agent using the Agents SDK. The pattern is similar to the `research_bot` example, but with more specialized sub‑agents and a verification step. + +The flow is: + +1. **Planning**: A planner agent turns the end user’s request into a list of search terms relevant to financial analysis – recent news, earnings calls, corporate filings, industry commentary, etc. +2. **Search**: A search agent uses the built‑in `WebSearchTool` to retrieve terse summaries for each search term. (You could also add `FileSearchTool` if you have indexed PDFs or 10‑Ks.) +3. **Sub‑analysts**: Additional agents (e.g. a fundamentals analyst and a risk analyst) are exposed as tools so the writer can call them inline and incorporate their outputs. +4. **Writing**: A senior writer agent brings together the search snippets and any sub‑analyst summaries into a long‑form markdown report plus a short executive summary. +5. **Verification**: A final verifier agent audits the report for obvious inconsistencies or missing sourcing. + +You can run the example with: + +```bash +python -m examples.financial_research_agent.main +``` + +and enter a query like: + +``` +Write up an analysis of Apple Inc.'s most recent quarter. +``` + +### Starter prompt + +The writer agent is seeded with instructions similar to: + +``` +You are a senior financial analyst. You will be provided with the original query +and a set of raw search summaries. Your job is to synthesize these into a +long‑form markdown report (at least several paragraphs) with a short executive +summary. You also have access to tools like `fundamentals_analysis` and +`risk_analysis` to get short specialist write‑ups if you want to incorporate them. +Add a few follow‑up questions for further research. +``` + +You can tweak these prompts and sub‑agents to suit your own data sources and preferred report structure. diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/__init__.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/__init__.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/financials_agent.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/financials_agent.py new file mode 100644 index 000000000..953531f28 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/financials_agent.py @@ -0,0 +1,23 @@ +from pydantic import BaseModel + +from agents import Agent + +# A sub‑agent focused on analyzing a company's fundamentals. +FINANCIALS_PROMPT = ( + "You are a financial analyst focused on company fundamentals such as revenue, " + "profit, margins and growth trajectory. Given a collection of web (and optional file) " + "search results about a company, write a concise analysis of its recent financial " + "performance. Pull out key metrics or quotes. Keep it under 2 paragraphs." +) + + +class AnalysisSummary(BaseModel): + summary: str + """Short text summary for this aspect of the analysis.""" + + +financials_agent = Agent( + name="FundamentalsAnalystAgent", + instructions=FINANCIALS_PROMPT, + output_type=AnalysisSummary, +) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/planner_agent.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/planner_agent.py new file mode 100644 index 000000000..14aaa0b10 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/planner_agent.py @@ -0,0 +1,35 @@ +from pydantic import BaseModel + +from agents import Agent + +# Generate a plan of searches to ground the financial analysis. +# For a given financial question or company, we want to search for +# recent news, official filings, analyst commentary, and other +# relevant background. +PROMPT = ( + "You are a financial research planner. Given a request for financial analysis, " + "produce a set of web searches to gather the context needed. Aim for recent " + "headlines, earnings calls or 10‑K snippets, analyst commentary, and industry background. " + "Output between 5 and 15 search terms to query for." +) + + +class FinancialSearchItem(BaseModel): + reason: str + """Your reasoning for why this search is relevant.""" + + query: str + """The search term to feed into a web (or file) search.""" + + +class FinancialSearchPlan(BaseModel): + searches: list[FinancialSearchItem] + """A list of searches to perform.""" + + +planner_agent = Agent( + name="FinancialPlannerAgent", + instructions=PROMPT, + model="o3-mini", + output_type=FinancialSearchPlan, +) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/risk_agent.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/risk_agent.py new file mode 100644 index 000000000..e24deb4e0 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/risk_agent.py @@ -0,0 +1,22 @@ +from pydantic import BaseModel + +from agents import Agent + +# A sub‑agent specializing in identifying risk factors or concerns. +RISK_PROMPT = ( + "You are a risk analyst looking for potential red flags in a company's outlook. " + "Given background research, produce a short analysis of risks such as competitive threats, " + "regulatory issues, supply chain problems, or slowing growth. Keep it under 2 paragraphs." +) + + +class AnalysisSummary(BaseModel): + summary: str + """Short text summary for this aspect of the analysis.""" + + +risk_agent = Agent( + name="RiskAnalystAgent", + instructions=RISK_PROMPT, + output_type=AnalysisSummary, +) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/search_agent.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/search_agent.py new file mode 100644 index 000000000..aee37d048 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/search_agent.py @@ -0,0 +1,27 @@ +from pydantic import BaseModel + +from agents import Agent, ModelSettings, WebSearchTool + +# Given a search term, use web search to pull back a brief summary. +# Summaries should be concise but capture the main financial points. +INSTRUCTIONS = ( + "You are a research assistant specializing in financial topics. " + "Given a search term, use web search to retrieve up‑to‑date context and " + "produce a short summary of at most 300 words. Focus on key numbers, events, " + "or quotes that will be useful to a financial analyst." +) + + +class FinancialSearchSummary(BaseModel): + summary: str + """A concise summary of the search findings.""" + + +search_agent = Agent( + name="FinancialSearchAgent", + model="gpt-5.6-sol", + instructions=INSTRUCTIONS, + tools=[WebSearchTool()], + model_settings=ModelSettings(response_include=["web_search_call.action.sources"]), + output_type=FinancialSearchSummary, +) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/verifier_agent.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/verifier_agent.py new file mode 100644 index 000000000..46f59be77 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/verifier_agent.py @@ -0,0 +1,48 @@ +from typing import Literal + +from pydantic import BaseModel + +from agents import Agent + +# Agent to sanity‑check a synthesized report for consistency and recall. +# This can be used to flag potential gaps or obvious mistakes. +VERIFIER_PROMPT = ( + "You are a meticulous evidence auditor. You will receive an original request, an explicit " + "research cutoff date, a financial report, and structured web research evidence with source " + "URLs. Judge the report only against that supplied evidence; do not reject or approve claims " + "based on your own memory. Check that material numeric and time-sensitive claims are supported " + "by the evidence, that citations use supplied URLs, that the report is internally consistent, " + "and that uncertainty is appropriately caveated. Treat information published on or before the " + "research cutoff as potentially available. Mark unsupported claims separately from claims that " + "the evidence directly contradicts." +) + + +class VerificationIssue(BaseModel): + claim: str + """The report claim that needs attention.""" + + category: Literal["unsupported", "contradicted", "stale_or_unreleased", "other"] + """The evidence problem associated with the claim.""" + + explanation: str + """Why the evidence does not support the claim.""" + + source_urls: list[str] + """Relevant supplied source URLs, if any.""" + + +class VerificationResult(BaseModel): + verified: bool + """Whether the report is coherent and supported by the supplied evidence.""" + + issues: list[VerificationIssue] + """Evidence-based issues that must be corrected before publication.""" + + +verifier_agent = Agent( + name="VerificationAgent", + instructions=VERIFIER_PROMPT, + model="gpt-5.6-sol", + output_type=VerificationResult, +) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/writer_agent.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/writer_agent.py new file mode 100644 index 000000000..0db7295a7 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/agents/writer_agent.py @@ -0,0 +1,42 @@ +from pydantic import BaseModel + +from agents import Agent + +# Writer agent brings together the raw search results and optionally calls out +# to sub‑analyst tools for specialized commentary, then returns a cohesive markdown report. +WRITER_PROMPT = ( + "You are a senior financial analyst. You will be provided with the original query and " + "a set of raw search summaries. Your task is to synthesize these into a long‑form markdown " + "report (at least several paragraphs) including a short executive summary and follow‑up " + "questions. If needed, you can call the available analysis tools (e.g. fundamentals_analysis, " + "risk_analysis) to get short specialist write‑ups to incorporate. Every material numeric or " + "time-sensitive claim must include an inline Markdown citation using a URL supplied in the " + "research evidence. Never invent or alter a source URL." +) + +REVISION_PROMPT = ( + f"{WRITER_PROMPT} You are revising an existing report after evidence verification. Address " + "every verification issue, remove claims that cannot be supported, preserve valid analysis, " + "and return a complete replacement report rather than a patch or commentary." +) + + +class FinancialReportData(BaseModel): + short_summary: str + """A short 2‑3 sentence executive summary.""" + + markdown_report: str + """The full markdown report.""" + + follow_up_questions: list[str] + """Suggested follow‑up questions for further research.""" + + +# Note: We will attach handoffs to specialist analyst agents at runtime in the manager. +# This shows how an agent can use handoffs to delegate to specialized subagents. +writer_agent = Agent( + name="FinancialWriterAgent", + instructions=WRITER_PROMPT, + model="gpt-5.6-sol", + output_type=FinancialReportData, +) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/main.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/main.py new file mode 100644 index 000000000..e490b0b1d --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/main.py @@ -0,0 +1,23 @@ +import asyncio + +from examples.auto_mode import input_with_fallback + +from .manager import FinancialResearchManager + + +# Entrypoint for the financial bot example. +# Run this as `python -m examples.financial_research_agent.main` and enter a +# financial research query, for example: +# "Write up an analysis of Apple Inc.'s most recent quarter." +async def main() -> None: + query = input_with_fallback( + "Enter a financial research query: ", + "Write a short analysis of Apple's long-term revenue drivers and key risks. " + "Avoid making claims about unreleased quarterly results.", + ) + mgr = FinancialResearchManager() + await mgr.run(query) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/manager.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/manager.py new file mode 100644 index 000000000..4ac0ad584 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/manager.py @@ -0,0 +1,265 @@ +from __future__ import annotations + +import asyncio +import json +import time +from collections.abc import Sequence +from datetime import datetime, timezone + +from pydantic import BaseModel +from rich.console import Console + +from agents import Runner, RunResult, RunResultStreaming, custom_span, gen_trace_id, trace +from examples.web_search_utils import extract_url_citations, extract_web_search_source_urls + +from .agents.financials_agent import financials_agent +from .agents.planner_agent import FinancialSearchItem, FinancialSearchPlan, planner_agent +from .agents.risk_agent import risk_agent +from .agents.search_agent import FinancialSearchSummary, search_agent +from .agents.verifier_agent import VerificationResult, verifier_agent +from .agents.writer_agent import REVISION_PROMPT, FinancialReportData, writer_agent +from .printer import Printer + + +class FinancialSource(BaseModel): + title: str + url: str + + +class FinancialSearchEvidence(BaseModel): + query: str + reason: str + summary: str + sources: list[FinancialSource] + retrieved_at: str + + +def _extract_financial_sources(items: Sequence[object]) -> list[FinancialSource]: + sources: list[FinancialSource] = [] + seen: set[str] = set() + + for citation in extract_url_citations(items): + if citation.url in seen: + continue + seen.add(citation.url) + sources.append(FinancialSource(title=citation.title, url=citation.url)) + + for url in extract_web_search_source_urls(items): + if url in seen: + continue + seen.add(url) + sources.append(FinancialSource(title=url, url=url)) + + return sources + + +async def _summary_extractor(run_result: RunResult | RunResultStreaming) -> str: + """Custom output extractor for sub‑agents that return an AnalysisSummary.""" + # The financial/risk analyst agents emit an AnalysisSummary with a `summary` field. + # We want the tool call to return just that summary text so the writer can drop it inline. + return str(run_result.final_output.summary) + + +class FinancialResearchManager: + """ + Orchestrates the full flow: planning, searching, sub‑analysis, writing, and verification. + """ + + def __init__(self) -> None: + self.console = Console() + self.printer = Printer(self.console) + self.research_cutoff = datetime.now(timezone.utc).date().isoformat() + + async def run(self, query: str) -> None: + trace_id = gen_trace_id() + try: + with trace("Financial research trace", trace_id=trace_id): + self.printer.update_item( + "trace_id", + f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}", + is_done=True, + hide_checkmark=True, + ) + self.printer.update_item("start", "Starting financial research...", is_done=True) + search_plan = await self._plan_searches(query) + search_results = await self._perform_searches(search_plan) + report, verification = await self._produce_verified_report(query, search_results) + + final_report = f"Report summary\n\n{report.short_summary}" + self.printer.update_item("final_report", final_report, is_done=True) + finally: + self.printer.end() + + # Print to stdout + print("\n\n=====REPORT=====\n\n") + print(f"Report:\n{report.markdown_report}") + print("\n\n=====FOLLOW UP QUESTIONS=====\n\n") + print("\n".join(report.follow_up_questions)) + print("\n\n=====VERIFICATION=====\n\n") + print(verification) + + async def _produce_verified_report( + self, + query: str, + search_results: Sequence[FinancialSearchEvidence], + ) -> tuple[FinancialReportData, VerificationResult]: + report = await self._write_report(query, search_results) + verification = await self._verify_report(query, report, search_results) + if verification.verified: + return report, verification + + report = await self._revise_report(query, report, search_results, verification) + verification = await self._verify_report(query, report, search_results) + if not verification.verified: + raise RuntimeError( + "Financial report failed evidence verification after one revision: " + f"{verification.model_dump_json()}" + ) + return report, verification + + async def _plan_searches(self, query: str) -> FinancialSearchPlan: + self.printer.update_item("planning", "Planning searches...") + result = await Runner.run(planner_agent, f"Query: {query}") + self.printer.update_item( + "planning", + f"Will perform {len(result.final_output.searches)} searches", + is_done=True, + ) + return result.final_output_as(FinancialSearchPlan) + + async def _perform_searches( + self, search_plan: FinancialSearchPlan + ) -> Sequence[FinancialSearchEvidence]: + with custom_span("Search the web"): + self.printer.update_item("searching", "Searching...") + tasks = [asyncio.create_task(self._search(item)) for item in search_plan.searches] + results: list[FinancialSearchEvidence] = [] + num_completed = 0 + num_succeeded = 0 + num_failed = 0 + for task in asyncio.as_completed(tasks): + result = await task + if result is not None: + results.append(result) + num_succeeded += 1 + else: + num_failed += 1 + num_completed += 1 + status = f"Searching... {num_completed}/{len(tasks)} finished" + if num_failed: + status += f" ({num_succeeded} succeeded, {num_failed} failed)" + self.printer.update_item( + "searching", + status, + ) + summary = f"Searches finished: {num_succeeded}/{len(tasks)} succeeded" + if num_failed: + summary += f", {num_failed} failed" + self.printer.update_item("searching", summary, is_done=True) + return results + + async def _search(self, item: FinancialSearchItem) -> FinancialSearchEvidence | None: + input_data = f"Search term: {item.query}\nReason: {item.reason}" + try: + result = await Runner.run(search_agent, input_data) + search_summary = result.final_output_as(FinancialSearchSummary) + sources = _extract_financial_sources(result.new_items) + if not sources: + return None + return FinancialSearchEvidence( + query=item.query, + reason=item.reason, + summary=search_summary.summary, + sources=sources, + retrieved_at=self.research_cutoff, + ) + except Exception: + return None + + async def _write_report( + self, + query: str, + search_results: Sequence[FinancialSearchEvidence], + ) -> FinancialReportData: + # Expose the specialist analysts as tools so the writer can invoke them inline + # and still produce the final FinancialReportData output. + fundamentals_tool = financials_agent.as_tool( + tool_name="fundamentals_analysis", + tool_description="Use to get a short write‑up of key financial metrics", + custom_output_extractor=_summary_extractor, + ) + risk_tool = risk_agent.as_tool( + tool_name="risk_analysis", + tool_description="Use to get a short write‑up of potential red flags", + custom_output_extractor=_summary_extractor, + ) + writer_with_tools = writer_agent.clone(tools=[fundamentals_tool, risk_tool]) + self.printer.update_item("writing", "Thinking about report...") + input_data = self._report_input(query, search_results) + result = Runner.run_streamed(writer_with_tools, input_data) + update_messages = [ + "Planning report structure...", + "Writing sections...", + "Finalizing report...", + ] + last_update = time.time() + next_message = 0 + async for _ in result.stream_events(): + if time.time() - last_update > 5 and next_message < len(update_messages): + self.printer.update_item("writing", update_messages[next_message]) + next_message += 1 + last_update = time.time() + self.printer.mark_item_done("writing") + return result.final_output_as(FinancialReportData) + + async def _revise_report( + self, + query: str, + report: FinancialReportData, + search_results: Sequence[FinancialSearchEvidence], + verification: VerificationResult, + ) -> FinancialReportData: + self.printer.update_item("revising", "Revising report from verification feedback...") + revision_agent = writer_agent.clone(instructions=REVISION_PROMPT) + input_data = ( + f"{self._report_input(query, search_results)}\n" + f"Existing report:\n{report.model_dump_json()}\n" + f"Verification feedback:\n{verification.model_dump_json()}" + ) + result = await Runner.run(revision_agent, input_data) + self.printer.mark_item_done("revising") + return result.final_output_as(FinancialReportData) + + async def _verify_report( + self, + query: str, + report: FinancialReportData, + search_results: Sequence[FinancialSearchEvidence], + ) -> VerificationResult: + self.printer.update_item("verifying", "Verifying report...") + input_data = json.dumps( + { + "original_query": query, + "research_cutoff": self.research_cutoff, + "report": report.model_dump(mode="json"), + "evidence": [item.model_dump(mode="json") for item in search_results], + }, + ensure_ascii=False, + ) + result = await Runner.run(verifier_agent, input_data) + self.printer.mark_item_done("verifying") + return result.final_output_as(VerificationResult) + + def _report_input( + self, + query: str, + search_results: Sequence[FinancialSearchEvidence], + ) -> str: + return json.dumps( + { + "original_query": query, + "research_cutoff": self.research_cutoff, + "evidence": [item.model_dump(mode="json") for item in search_results], + }, + ensure_ascii=False, + ) diff --git a/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/printer.py b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/printer.py new file mode 100644 index 000000000..4c1a4944d --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/python-financial-research-agent/printer.py @@ -0,0 +1,46 @@ +from typing import Any + +from rich.console import Console, Group +from rich.live import Live +from rich.spinner import Spinner + + +class Printer: + """ + Simple wrapper to stream status updates. Used by the financial bot + manager as it orchestrates planning, search and writing. + """ + + def __init__(self, console: Console) -> None: + self.live = Live(console=console) + self.items: dict[str, tuple[str, bool]] = {} + self.hide_done_ids: set[str] = set() + self.live.start() + + def end(self) -> None: + self.live.stop() + + def hide_done_checkmark(self, item_id: str) -> None: + self.hide_done_ids.add(item_id) + + def update_item( + self, item_id: str, content: str, is_done: bool = False, hide_checkmark: bool = False + ) -> None: + self.items[item_id] = (content, is_done) + if hide_checkmark: + self.hide_done_ids.add(item_id) + self.flush() + + def mark_item_done(self, item_id: str) -> None: + self.items[item_id] = (self.items[item_id][0], True) + self.flush() + + def flush(self) -> None: + renderables: list[Any] = [] + for item_id, (content, is_done) in self.items.items(): + if is_done: + prefix = "✅ " if item_id not in self.hide_done_ids else "" + renderables.append(prefix + content) + else: + renderables.append(Spinner("dots", text=content)) + self.live.update(Group(*renderables)) diff --git a/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/README.md b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/README.md new file mode 100644 index 000000000..69ba7a3e0 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/README.md @@ -0,0 +1,20 @@ +# Financial Research Agent + +This example demonstrates a multi-agent workflow that produces a short financial analysis report. + +The entrypoint in `main.ts` prompts for a query, then traces the run and hands control to `FinancialResearchManager`. + +The manager orchestrates several specialized agents: + +1. **Planner** – creates a list of search tasks for the query. +2. **Search** – runs each search in parallel and gathers summaries. +3. **Writer** – synthesizes the search results, optionally calling fundamentals and risk analyst tools. +4. **Verifier** – checks the final report for consistency and issues. + +After running these steps the manager prints a short summary, the full markdown report, suggested follow-up questions, and verification results. + +Run the example with: + +```bash +pnpm examples:financial-research-agent +``` diff --git a/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/agents.ts b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/agents.ts new file mode 100644 index 000000000..1e29460b0 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/agents.ts @@ -0,0 +1,124 @@ +import { Agent, webSearchTool } from '@openai/agents'; +import { z } from 'zod'; + +// --- Fundamentals Analyst Agent --- +export const financialsPrompt = `You are a financial analyst focused on company fundamentals such as revenue, profit, margins and growth trajectory. +Given a collection of web (and optional file) search results about a company, write a concise analysis of its recent financial performance. +Pull out key metrics or quotes. Keep it under 2 paragraphs.`; + +export const AnalysisSummary = z.object({ + summary: z + .string() + .describe('Short text summary for this aspect of the analysis.'), +}); + +export const financialsAgent = new Agent({ + name: 'FundamentalsAnalystAgent', + instructions: financialsPrompt, + outputType: AnalysisSummary, +}); + +// --- Financial Research Planner Agent --- +export const plannerPrompt = `You are a financial research planner. +Given a request for financial analysis, produce a set of web searches to gather the context needed. +Aim for recent headlines, earnings calls or 10-K snippets, analyst commentary, and industry background. +Prioritize official investor-relations releases and SEC filings for reported results. +Output between 5 and 15 search terms to query for.`; + +export const FinancialSearchItem = z.object({ + reason: z + .string() + .describe('Your reasoning for why this search is relevant.'), + query: z + .string() + .describe('The search term to feed into a web (or file) search.'), +}); + +export type FinancialSearchItem = z.infer; + +export const FinancialSearchPlan = z.object({ + searches: z + .array(FinancialSearchItem) + .describe('A list of searches to perform.'), +}); + +export type FinancialSearchPlan = z.infer; + +export const plannerAgent = new Agent({ + name: 'FinancialPlannerAgent', + instructions: plannerPrompt, + model: 'gpt-5.4', + outputType: FinancialSearchPlan, +}); + +// --- Risk Analyst Agent --- +export const riskPrompt = `You are a risk analyst looking for potential red flags in a company's outlook. +Given background research, produce a short analysis of risks such as competitive threats, regulatory issues, supply chain problems, or slowing growth. +Keep it under 2 paragraphs.`; + +export const riskAgent = new Agent({ + name: 'RiskAnalystAgent', + instructions: riskPrompt, + outputType: AnalysisSummary, +}); + +// --- Financial Search Agent --- +export const searchAgentPrompt = `You are a research assistant specializing in financial topics. +Given a search term, use web search to retrieve up-to-date context and produce a short summary of at most 300 words. +Focus on key numbers, events, or quotes that will be useful to a financial analyst. +Prefer primary sources and include source names and URLs for the facts you summarize. Never fabricate a URL.`; + +export const searchAgent = new Agent({ + name: 'FinancialSearchAgent', + instructions: searchAgentPrompt, + model: 'gpt-5.4', + tools: [webSearchTool()], +}); + +// --- Verification Agent --- +export const verifierPrompt = `You are a meticulous auditor. You will receive a financial analysis report and the source summaries used to write it. +Verify the report against those source summaries rather than relying on prior knowledge. +Do not reject newer information merely because it is unfamiliar, but reject claims that are unsupported, internally inconsistent, or missing clear sourcing. +When the report is verified, return an empty issues string. Otherwise, point out the specific issues or uncertainties.`; + +export const VerificationResult = z.object({ + verified: z + .boolean() + .describe('Whether the report seems coherent and plausible.'), + issues: z + .string() + .describe('If not verified, describe the main issues or concerns.'), +}); + +export type VerificationResult = z.infer; + +export const verifierAgent = new Agent({ + name: 'VerificationAgent', + instructions: verifierPrompt, + model: 'gpt-5.4', + outputType: VerificationResult, +}); + +// --- Financial Writer Agent --- +export const writerPrompt = `You are a senior financial analyst. +You will be provided with the original query and a set of raw search summaries. +Your task is to synthesize these into a long-form markdown report (at least several paragraphs) including a short executive summary and follow-up questions. +Use only facts supported by the supplied summaries, preserve their source URLs as inline Markdown citations, and clearly label uncertainty or conflicting information. +If needed, you can call the available analysis tools (e.g. fundamentals_analysis, risk_analysis) to get short specialist write-ups to incorporate.`; + +export const FinancialReportData = z.object({ + short_summary: z.string().describe('A short 2-3 sentence executive summary.'), + markdown_report: z.string().describe('The full markdown report.'), + follow_up_questions: z + .array(z.string()) + .describe('Suggested follow-up questions for further research.'), +}); + +export type FinancialReportData = z.infer; + +export const writerAgent = new Agent({ + name: 'FinancialWriterAgent', + instructions: writerPrompt, + model: 'gpt-5.4', + outputType: FinancialReportData, +}); diff --git a/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/main.ts b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/main.ts new file mode 100644 index 000000000..e8cd8de04 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/main.ts @@ -0,0 +1,26 @@ +import { withTrace } from '@openai/agents'; +import { FinancialResearchManager } from './manager'; + +// Entrypoint for the financial bot example. +// Run this as `npx tsx examples/financial-research-agent/main.ts` and enter a financial research query, for example: +// "Write up an analysis of Apple Inc.'s most recent quarter." + +async function main() { + const readline = await import('readline'); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + rl.question('Enter a financial research query: ', async (query: string) => { + rl.close(); + await withTrace('Financial research workflow', async () => { + const manager = new FinancialResearchManager(); + await manager.run(query); + }); + }); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/manager.ts b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/manager.ts new file mode 100644 index 000000000..8f804c1a0 --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/manager.ts @@ -0,0 +1,117 @@ +import { Agent, run, RunResult } from '@openai/agents'; +import { financialsAgent } from './agents'; +import { + plannerAgent, + FinancialSearchItem, + FinancialSearchPlan, +} from './agents'; +import { riskAgent } from './agents'; +import { searchAgent } from './agents'; +import { verifierAgent, VerificationResult } from './agents'; +import { writerAgent, FinancialReportData } from './agents'; + +function formatSearchResults(searchResults: string[]): string { + return searchResults + .map((result, index) => `Source summary ${index + 1}:\n${result}`) + .join('\n\n'); +} + +// Custom output extractor for sub-agents that return an AnalysisSummary +async function summaryExtractor( + runResult: RunResult>, +): Promise { + return String(runResult.finalOutput.summary); +} + +export class FinancialResearchManager { + async run(query: string): Promise { + console.log(`[start] Starting financial research...`); + const searchPlan = await this.planSearches(query); + const searchResults = await this.performSearches(searchPlan); + const report = await this.writeReport(query, searchResults); + const verification = await this.verifyReport(report, searchResults); + const finalReport = `Report summary\n\n${report.short_summary}`; + console.log(finalReport); + console.log('\n\n=====REPORT=====\n\n'); + console.log(`Report:\n${report.markdown_report}`); + console.log('\n\n=====FOLLOW UP QUESTIONS=====\n\n'); + console.log(report.follow_up_questions.join('\n')); + console.log('\n\n=====VERIFICATION=====\n\n'); + console.log(verification); + } + + async planSearches(query: string): Promise { + console.log(`[planning] Planning searches...`); + const result = await run(plannerAgent, `Query: ${query}`); + console.log( + `[planning] Will perform ${result.finalOutput?.searches.length} searches`, + ); + return result.finalOutput!; + } + + async performSearches(searchPlan: FinancialSearchPlan): Promise { + // Run all searches in parallel and log progress as each completes + console.log(`[searching] Searching...`); + let numCompleted = 0; + const results: (string | null)[] = new Array(searchPlan.searches.length); + await Promise.all( + searchPlan.searches.map(async (item, i) => { + const result = await this.search(item); + results[i] = result; + numCompleted++; + console.log( + `[searching] Searching... ${numCompleted}/${searchPlan.searches.length} completed`, + ); + }), + ); + console.log(`[searching] Done searching.`); + // Filter out nulls and preserve order + return results.filter((r): r is string => r !== null); + } + + async search(item: FinancialSearchItem): Promise { + const inputData = `Search term: ${item.query}\nReason: ${item.reason}`; + try { + const result = await run(searchAgent, inputData); + return String(result.finalOutput); + } catch { + return null; + } + } + + async writeReport( + query: string, + searchResults: string[], + ): Promise { + // Expose the specialist analysts as tools + const fundamentalsTool = financialsAgent.asTool({ + toolName: 'fundamentals_analysis', + toolDescription: 'Use to get a short write-up of key financial metrics', + customOutputExtractor: summaryExtractor, + }); + const riskTool = riskAgent.asTool({ + toolName: 'risk_analysis', + toolDescription: 'Use to get a short write-up of potential red flags', + customOutputExtractor: summaryExtractor, + }); + const writerWithTools = writerAgent.clone({ + tools: [fundamentalsTool, riskTool], + }); + console.log(`[writing] Thinking about report...`); + const inputData = `Original query: ${query}\n\n${formatSearchResults(searchResults)}`; + const result = await run(writerWithTools, inputData); + console.log(`[writing] Done writing report.`); + return result.finalOutput!; + } + + async verifyReport( + report: FinancialReportData, + searchResults: string[], + ): Promise { + console.log(`[verifying] Verifying report...`); + const inputData = `Report:\n${report.markdown_report}\n\nSource summaries:\n${formatSearchResults(searchResults)}`; + const result = await run(verifierAgent, inputData); + console.log(`[verifying] Done verifying report.`); + return result.finalOutput!; + } +} diff --git a/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/package.json b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/package.json new file mode 100644 index 000000000..51d2e567b --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/package.json @@ -0,0 +1,12 @@ +{ + "private": true, + "name": "financial-research-agent", + "dependencies": { + "@openai/agents": "workspace:*", + "zod": "^4.0.0" + }, + "scripts": { + "build-check": "tsc --noEmit", + "start": "tsx main.ts" + } +} diff --git a/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/tsconfig.json b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/tsconfig.json new file mode 100644 index 000000000..150a0961f --- /dev/null +++ b/apps/ai-observability/open-ai-agents-sdk/typescript-financial-research-agent/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.examples.json" +} diff --git a/apps/ai-observability/vercel-ai/next-agent/.gitignore b/apps/ai-observability/vercel-ai/next-agent/.gitignore new file mode 100644 index 000000000..d3ff89366 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +# persistence +.chats +.streams +.env.local.example +.env.local diff --git a/apps/ai-observability/vercel-ai/next-agent/README.md b/apps/ai-observability/vercel-ai/next-agent/README.md new file mode 100644 index 000000000..99b14d08f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/README.md @@ -0,0 +1 @@ +A minimal example to show code modularization with agents, tools, and components. diff --git a/apps/ai-observability/vercel-ai/next-agent/agent/weather-agent.ts b/apps/ai-observability/vercel-ai/next-agent/agent/weather-agent.ts new file mode 100644 index 000000000..b20b974e3 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/agent/weather-agent.ts @@ -0,0 +1,16 @@ +import { weatherTool } from '@/tool/weather-tool'; +import { openai } from '@ai-sdk/openai'; +import { ToolLoopAgent, type InferAgentUIMessage } from 'ai'; +export const weatherAgent = new ToolLoopAgent({ + model: openai('gpt-4o'), + instructions: 'You are a helpful assistant.', + tools: { + weather: weatherTool, + }, + experimental_telemetry: { + isEnabled: true, + functionId: 'weather-agent', + }, +}); + +export type WeatherAgentUIMessage = InferAgentUIMessage; diff --git a/apps/ai-observability/vercel-ai/next-agent/app/api/chat/route.ts b/apps/ai-observability/vercel-ai/next-agent/app/api/chat/route.ts new file mode 100644 index 000000000..990b9112f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/app/api/chat/route.ts @@ -0,0 +1,11 @@ +import { weatherAgent } from '@/agent/weather-agent'; +import { createAgentUIStreamResponse } from 'ai'; + +export async function POST(request: Request) { + const { messages } = await request.json(); + + return createAgentUIStreamResponse({ + agent: weatherAgent, + uiMessages: messages, + }); +} diff --git a/apps/ai-observability/vercel-ai/next-agent/app/favicon.ico b/apps/ai-observability/vercel-ai/next-agent/app/favicon.ico new file mode 100644 index 000000000..718d6fea4 Binary files /dev/null and b/apps/ai-observability/vercel-ai/next-agent/app/favicon.ico differ diff --git a/apps/ai-observability/vercel-ai/next-agent/app/globals.css b/apps/ai-observability/vercel-ai/next-agent/app/globals.css new file mode 100644 index 000000000..b5c61c956 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/app/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/ai-observability/vercel-ai/next-agent/app/layout.tsx b/apps/ai-observability/vercel-ai/next-agent/app/layout.tsx new file mode 100644 index 000000000..d29a5479c --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/app/layout.tsx @@ -0,0 +1,18 @@ +import './globals.css'; + +export const metadata = { + title: 'AI SDK - Next.js OpenAI Examples', + description: 'Examples of using the AI SDK with Next.js and OpenAI.', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/apps/ai-observability/vercel-ai/next-agent/app/page.tsx b/apps/ai-observability/vercel-ai/next-agent/app/page.tsx new file mode 100644 index 000000000..b2903418b --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/app/page.tsx @@ -0,0 +1,40 @@ +'use client'; + +import { useChat } from '@ai-sdk/react'; +import ChatInput from '@/component/chat-input'; +import type { WeatherAgentUIMessage } from '@/agent/weather-agent'; +import WeatherView from '@/component/weather-view'; + +export default function Chat() { + const { status, sendMessage, messages } = useChat(); + + return ( +
+ {messages?.map(message => ( +
+ {`${message.role}: `} + {message.parts.map((part, index) => { + switch (part.type) { + case 'text': + return
{part.text}
; + + case 'step-start': + return index > 0 ? ( +
+
+
+ ) : null; + + case 'tool-weather': { + return ; + } + } + })} +
+
+ ))} + + sendMessage({ text })} /> +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next-agent/component/chat-input.tsx b/apps/ai-observability/vercel-ai/next-agent/component/chat-input.tsx new file mode 100644 index 000000000..7d374c3bf --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/component/chat-input.tsx @@ -0,0 +1,41 @@ +import { useState } from 'react'; + +export default function ChatInput({ + status, + onSubmit, + stop, +}: { + status: string; + onSubmit: (text: string) => void; + stop?: () => void; +}) { + const [text, setText] = useState(''); + + return ( +
{ + e.preventDefault(); + if (text.trim() === '') return; + onSubmit(text); + setText(''); + }} + > + setText(e.target.value)} + /> + {stop && (status === 'streaming' || status === 'submitted') && ( + + )} +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next-agent/component/weather-view.tsx b/apps/ai-observability/vercel-ai/next-agent/component/weather-view.tsx new file mode 100644 index 000000000..c6646da95 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/component/weather-view.tsx @@ -0,0 +1,29 @@ +import type { WeatherUIToolInvocation } from '@/tool/weather-tool'; + +export default function WeatherView({ + invocation, +}: { + invocation: WeatherUIToolInvocation; +}) { + switch (invocation.state) { + // example of pre-rendering streaming tool calls: + case 'input-streaming': + return
{JSON.stringify(invocation.input, null, 2)}
; + case 'input-available': + return ( +
+ Getting weather information for {invocation.input.city}... +
+ ); + case 'output-available': + return ( +
+ {invocation.output.state === 'loading' + ? 'Fetching weather information...' + : `Weather in ${invocation.input.city}: ${invocation.output.weather}`} +
+ ); + case 'output-error': + return
Error: {invocation.errorText}
; + } +} diff --git a/apps/ai-observability/vercel-ai/next-agent/instrumentation.ts b/apps/ai-observability/vercel-ai/next-agent/instrumentation.ts new file mode 100644 index 000000000..767f803cf --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/instrumentation.ts @@ -0,0 +1,19 @@ +import { NodeSDK } from '@opentelemetry/sdk-node'; +import { resourceFromAttributes } from '@opentelemetry/resources'; +import { PostHogSpanProcessor } from '@posthog/ai/otel'; + +export function register() { + const sdk = new NodeSDK({ + resource: resourceFromAttributes({ + 'service.name': 'next-agent', + }), + spanProcessors: [ + new PostHogSpanProcessor({ + apiKey: process.env.POSTHOG_API_KEY!, + host: process.env.POSTHOG_HOST!, + }), + ], + }); + + sdk.start(); +} diff --git a/apps/ai-observability/vercel-ai/next-agent/package.json b/apps/ai-observability/vercel-ai/next-agent/package.json new file mode 100644 index 000000000..efe2cc283 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/package.json @@ -0,0 +1,35 @@ +{ + "name": "@example/next-agent", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@ai-sdk/openai": "workspace:*", + "@ai-sdk/react": "workspace:*", + "@opentelemetry/resources": "^1.30.1", + "@opentelemetry/sdk-node": "^0.57.2", + "@posthog/ai": "^0.3.0", + "@vercel/blob": "^0.26.0", + "ai": "workspace:*", + "next": "^15.5.18", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-markdown": "9.0.1", + "resumable-stream": "^2.2.12", + "zod": "3.25.76" + }, + "devDependencies": { + "@types/node": "22.19.19", + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.7", + "autoprefixer": "^10.5.0", + "postcss": "^8.5.14", + "tailwindcss": "^3.4.19", + "typescript": "5.8.3" + } +} diff --git a/apps/ai-observability/vercel-ai/next-agent/postcss.config.js b/apps/ai-observability/vercel-ai/next-agent/postcss.config.js new file mode 100644 index 000000000..12a703d90 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/ai-observability/vercel-ai/next-agent/tailwind.config.js b/apps/ai-observability/vercel-ai/next-agent/tailwind.config.js new file mode 100644 index 000000000..db68cff57 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/tailwind.config.js @@ -0,0 +1,18 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme: { + extend: { + backgroundImage: { + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': + 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + }, + }, + }, + plugins: [], +}; diff --git a/apps/ai-observability/vercel-ai/next-agent/tool/weather-tool.ts b/apps/ai-observability/vercel-ai/next-agent/tool/weather-tool.ts new file mode 100644 index 000000000..39fb819c8 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/tool/weather-tool.ts @@ -0,0 +1,25 @@ +import { tool, type UIToolInvocation } from 'ai'; +import { z } from 'zod'; + +export const weatherTool = tool({ + description: 'Get the weather in a location', + inputSchema: z.object({ city: z.string() }), + async *execute({ city }: { city: string }) { + yield { state: 'loading' as const }; + + // Add artificial delay of 5 seconds + await new Promise(resolve => setTimeout(resolve, 2000)); + + const weatherOptions = ['sunny', 'cloudy', 'rainy', 'snowy', 'windy']; + const weather = + weatherOptions[Math.floor(Math.random() * weatherOptions.length)]; + + yield { + state: 'ready' as const, + temperature: 72, + weather, + }; + }, +}); + +export type WeatherUIToolInvocation = UIToolInvocation; diff --git a/apps/ai-observability/vercel-ai/next-agent/tsconfig.json b/apps/ai-observability/vercel-ai/next-agent/tsconfig.json new file mode 100644 index 000000000..6144a4217 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-agent/tsconfig.json @@ -0,0 +1,56 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ], + "@util/*": [ + "./util/*" + ] + }, + "composite": true, + "noEmit": true + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ], + "references": [ + { + "path": "../../packages/ai" + }, + { + "path": "../../packages/openai" + }, + { + "path": "../../packages/react" + } + ] +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/.env.local.example b/apps/ai-observability/vercel-ai/next-fastapi/.env.local.example new file mode 100644 index 000000000..b0baed7d3 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/.env.local.example @@ -0,0 +1,3 @@ +# You must first activate a Billing Account here: https://platform.openai.com/account/billing/overview +# Then get your OpenAI API Key here: https://platform.openai.com/account/api-keys +OPENAI_API_KEY=xxxxxxx diff --git a/apps/ai-observability/vercel-ai/next-fastapi/.gitignore b/apps/ai-observability/vercel-ai/next-fastapi/.gitignore new file mode 100644 index 000000000..cde004d53 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/.gitignore @@ -0,0 +1,40 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# python +venv/ +.env +__pycache__ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/ai-observability/vercel-ai/next-fastapi/README.md b/apps/ai-observability/vercel-ai/next-fastapi/README.md new file mode 100644 index 000000000..e2578e2a7 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/README.md @@ -0,0 +1,41 @@ +# AI SDK, Next.js, and FastAPI Examples + +These examples show you how to use the [AI SDK](https://ai-sdk.dev/docs) with [Next.js](https://nextjs.org) and [FastAPI](https://fastapi.tiangolo.com). + +## How to use + +Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: + +```bash +npx create-next-app --example https://github.com/vercel/ai/tree/main/examples/next-fastapi next-fastapi-app +``` + +```bash +yarn create next-app --example https://github.com/vercel/ai/tree/main/examples/next-fastapi next-fastapi-app +``` + +```bash +pnpm create next-app --example https://github.com/vercel/ai/tree/main/examples/next-fastapi next-fastapi-app +``` + +You will also need [Python 3.6+](https://www.python.org/downloads) and [virtualenv](https://virtualenv.pypa.io/en/latest/installation.html) installed to run the FastAPI server. + +To run the example locally you need to: + +1. Sign up at [OpenAI's Developer Platform](https://platform.openai.com/signup). +2. Go to [OpenAI's dashboard](https://platform.openai.com/account/api-keys) and create an API KEY. +3. Set the required environment variables as shown in [the example env file](./.env.local.example) but in a new file called `.env.local`. +4. `virtualenv venv` to create a python virtual environment. +5. `source venv/bin/activate` to activate the python virtual environment. +6. `pip install -r requirements.txt` to install the required python dependencies. +7. `pnpm install` to install the required dependencies. +8. `pnpm dev` to launch the development server. + +## Learn More + +To learn more about the AI SDK, Next.js, and FastAPI take a look at the following resources: + +- [AI SDK Docs](https://ai-sdk.dev/docs) - view documentation and reference for the AI SDK. +- [Vercel AI Playground](https://ai-sdk.dev/playground) - try different models and choose the best one for your use case. +- [Next.js Docs](https://nextjs.org/docs) - learn about Next.js features and API. +- [FastAPI Docs](https://fastapi.tiangolo.com) - learn about FastAPI features and API. diff --git a/apps/ai-observability/vercel-ai/next-fastapi/api/index.py b/apps/ai-observability/vercel-ai/next-fastapi/api/index.py new file mode 100644 index 000000000..3cdc9b190 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/api/index.py @@ -0,0 +1,135 @@ +import os +import json +from typing import List +from pydantic import BaseModel +from dotenv import load_dotenv +from fastapi import FastAPI, Query +from fastapi.responses import StreamingResponse +from openai import OpenAI +from .utils.prompt import ClientMessage, convert_to_openai_messages +from .utils.tools import get_current_weather + + +load_dotenv(".env.local") + +app = FastAPI() + +client = OpenAI( + api_key=os.environ.get("OPENAI_API_KEY"), +) + + +class Request(BaseModel): + messages: List[ClientMessage] + + +available_tools = { + "get_current_weather": get_current_weather, +} + + +def stream_text(messages: List[ClientMessage], protocol: str = 'data'): + stream = client.chat.completions.create( + messages=messages, + model="gpt-4o", + stream=True, + tools=[{ + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA", + }, + "unit": { + "type": "string", + "enum": ["celsius", "fahrenheit"]}, + }, + "required": ["location", "unit"], + }, + }, + }] + ) + + # When protocol is set to "text", you will send a stream of plain text chunks + # https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol#text-stream-protocol + + if (protocol == 'text'): + for chunk in stream: + for choice in chunk.choices: + if choice.finish_reason == "stop": + break + else: + yield "{text}".format(text=choice.delta.content) + + # When protocol is set to "data", you will send a stream data part chunks + # https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol#data-stream-protocol + + elif (protocol == 'data'): + draft_tool_calls = [] + draft_tool_calls_index = -1 + + for chunk in stream: + for choice in chunk.choices: + if choice.finish_reason == "stop": + continue + + elif choice.finish_reason == "tool_calls": + for tool_call in draft_tool_calls: + yield '9:{{"toolCallId":"{id}","toolName":"{name}","args":{args}}}\n'.format( + id=tool_call["id"], + name=tool_call["name"], + args=tool_call["arguments"]) + + for tool_call in draft_tool_calls: + tool_result = available_tools[tool_call["name"]]( + **json.loads(tool_call["arguments"])) + + yield 'a:{{"toolCallId":"{id}","toolName":"{name}","args":{args},"result":{result}}}\n'.format( + id=tool_call["id"], + name=tool_call["name"], + args=tool_call["arguments"], + result=json.dumps(tool_result)) + + elif choice.delta.tool_calls: + for tool_call in choice.delta.tool_calls: + id = tool_call.id + name = tool_call.function.name + arguments = tool_call.function.arguments + + if (id is not None): + draft_tool_calls_index += 1 + draft_tool_calls.append( + {"id": id, "name": name, "arguments": ""}) + + else: + draft_tool_calls[draft_tool_calls_index]["arguments"] += arguments + + else: + yield '0:{text}\n'.format(text=json.dumps(choice.delta.content)) + + if chunk.choices == []: + usage = chunk.usage + prompt_tokens = usage.prompt_tokens + completion_tokens = usage.completion_tokens + + yield 'd:{{"finishReason":"{reason}","usage":{{"promptTokens":{prompt},"completionTokens":{completion}}}}}\n'.format( + reason="tool-calls" if len( + draft_tool_calls) > 0 else "stop", + prompt=prompt_tokens, + completion=completion_tokens + ) + + +@app.post("/api/chat") +async def handle_chat_data(request: Request, protocol: str = Query('data')): + messages = request.messages + openai_messages = convert_to_openai_messages(messages) + + response = StreamingResponse(stream_text(openai_messages, protocol)) + response.headers['x-vercel-ai-data-stream'] = 'v1' + return response diff --git a/apps/ai-observability/vercel-ai/next-fastapi/api/utils/__init__.py b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/ai-observability/vercel-ai/next-fastapi/api/utils/prompt.py b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/prompt.py new file mode 100644 index 000000000..6674b85e0 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/prompt.py @@ -0,0 +1,75 @@ +import json +from pydantic import BaseModel +from typing import List, Optional +from .types import ClientAttachment, ToolInvocation + + +class ClientMessage(BaseModel): + role: str + content: str + experimental_attachments: Optional[List[ClientAttachment]] = None + toolInvocations: Optional[List[ToolInvocation]] = None + + +def convert_to_openai_messages(messages: List[ClientMessage]): + openai_messages = [] + + for message in messages: + parts = [] + + parts.append({ + 'type': 'text', + 'text': message.content + }) + + if (message.experimental_attachments): + for attachment in message.experimental_attachments: + if (attachment.contentType.startswith('image')): + parts.append({ + 'type': 'image_url', + 'image_url': { + 'url': attachment.url + } + }) + + elif (attachment.contentType.startswith('text')): + parts.append({ + 'type': 'text', + 'text': attachment.url + }) + + if (message.toolInvocations): + tool_calls = [ + { + 'id': tool_invocation.toolCallId, + 'type': 'function', + 'function': { + 'name': tool_invocation.toolName, + 'arguments': json.dumps(tool_invocation.args) + } + } + for tool_invocation in message.toolInvocations] + + openai_messages.append({ + "role": 'assistant', + "tool_calls": tool_calls + }) + + tool_results = [ + { + 'role': 'tool', + 'content': json.dumps(tool_invocation.result), + 'tool_call_id': tool_invocation.toolCallId + } + for tool_invocation in message.toolInvocations] + + openai_messages.extend(tool_results) + + continue + + openai_messages.append({ + "role": message.role, + "content": parts + }) + + return openai_messages diff --git a/apps/ai-observability/vercel-ai/next-fastapi/api/utils/tools.py b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/tools.py new file mode 100644 index 000000000..f6d151444 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/tools.py @@ -0,0 +1,14 @@ +import random + + +def get_current_weather(location, unit="fahrenheit"): + if unit == "celsius": + temperature = random.randint(-34, 43) + else: + temperature = random.randint(-30, 110) + + return { + "temperature": temperature, + "unit": unit, + "location": location, + } diff --git a/apps/ai-observability/vercel-ai/next-fastapi/api/utils/types.py b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/types.py new file mode 100644 index 000000000..5c467d8dc --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/api/utils/types.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel + + +class ClientAttachment(BaseModel): + name: str + contentType: str + url: str + + +class ToolInvocation(BaseModel): + toolCallId: str + toolName: str + args: dict + result: dict diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/01-chat-text/layout.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/01-chat-text/layout.tsx new file mode 100644 index 000000000..519f1785b --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/01-chat-text/layout.tsx @@ -0,0 +1,9 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'useChat', +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/01-chat-text/page.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/01-chat-text/page.tsx new file mode 100644 index 000000000..a5fe4497c --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/01-chat-text/page.tsx @@ -0,0 +1,51 @@ +'use client'; + +import { Card } from '@/app/components'; +import { useChat } from '@ai-sdk/react'; +import { TextStreamChatTransport } from 'ai'; +import { useState } from 'react'; + +export default function Page() { + const [input, setInput] = useState(''); + const { messages, sendMessage, status } = useChat({ + transport: new TextStreamChatTransport({ + api: '/api/chat?protocol=text', + }), + }); + + return ( +
+
+ {messages.map(message => ( +
+
{`${message.role}: `}
+
+ {message.parts + .map(part => (part.type === 'text' ? part.text : '')) + .join('')} +
+
+ ))} +
+ + {messages.length === 0 && } + +
{ + e.preventDefault(); + sendMessage({ text: input }); + setInput(''); + }} + className="fixed bottom-0 flex flex-col w-full border-t" + > + setInput(e.target.value)} + className="w-full p-4 bg-transparent outline-none" + disabled={status !== 'ready'} + /> +
+
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/02-chat-data/layout.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/02-chat-data/layout.tsx new file mode 100644 index 000000000..519f1785b --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/02-chat-data/layout.tsx @@ -0,0 +1,9 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'useChat', +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/02-chat-data/page.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/02-chat-data/page.tsx new file mode 100644 index 000000000..e95f5ca78 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/02-chat-data/page.tsx @@ -0,0 +1,64 @@ +'use client'; + +import { Card } from '@/app/components'; +import { useChat } from '@ai-sdk/react'; +import { getStaticToolName, isStaticToolUIPart } from 'ai'; +import { GeistMono } from 'geist/font/mono'; +import { useState } from 'react'; + +export default function Page() { + const [input, setInput] = useState(''); + const { messages, sendMessage, status } = useChat(); + + return ( +
+
+ {messages.map(message => ( +
+
{`${message.role}: `}
+ +
+ {message.parts.map((part, index) => { + if (part.type === 'text') { + return
{part.text}
; + } else if (isStaticToolUIPart(part)) { + return ( +
+ {`${getStaticToolName(part)}(${JSON.stringify( + part.input, + null, + 2, + )})`} +
+ ); + } + })} +
+
+ ))} +
+ + {messages.length === 0 && } + +
{ + e.preventDefault(); + sendMessage({ text: input }); + setInput(''); + }} + className="flex fixed bottom-0 flex-col w-full border-t" + > + setInput(e.target.value)} + className="p-4 w-full bg-transparent outline-none" + disabled={status !== 'ready'} + /> +
+
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/03-chat-attachments/layout.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/03-chat-attachments/layout.tsx new file mode 100644 index 000000000..97369b1f4 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/03-chat-attachments/layout.tsx @@ -0,0 +1,9 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'useChat with attachments', +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/03-chat-attachments/page.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/03-chat-attachments/page.tsx new file mode 100644 index 000000000..173b4da7f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/(examples)/03-chat-attachments/page.tsx @@ -0,0 +1,108 @@ +'use client'; + +import { Card } from '@/app/components'; +/* eslint-disable @next/next/no-img-element */ +import { useChat } from '@ai-sdk/react'; +import { useRef, useState } from 'react'; + +export default function Page() { + const [input, setInput] = useState(''); + const { messages, sendMessage, status } = useChat(); + + const [files, setFiles] = useState(undefined); + const fileInputRef = useRef(null); + + return ( +
+
+ {messages.map(message => ( +
+
{`${message.role}: `}
+
+ {message.parts.map((part, index) => { + if (part.type === 'text') { + return
{part.text}
; + } + if ( + part.type === 'file' && + part.mediaType?.startsWith('image/') + ) { + return ( +
+ +
+ ); + } + })} +
+
+ ))} +
+ + {messages.length === 0 && } + +
{ + sendMessage({ text: input, files }); + setInput(''); + setFiles(undefined); + + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + }} + className="fixed bottom-0 flex flex-col w-full gap-3 p-4 border-t h-28" + > +
+ {files + ? Array.from(files).map(attachment => { + const { type } = attachment; + + if (type.startsWith('image/')) { + return ( +
+ {attachment.name} + + {attachment.name} + +
+ ); + } else if (type.startsWith('text/')) { + return ( +
+
+ {attachment.name} +
+ ); + } + }) + : ''} +
+ { + if (event.target.files) { + setFiles(event.target.files); + } + }} + multiple + ref={fileInputRef} + /> + setInput(e.target.value)} + className="w-full bg-transparent outline-none" + disabled={status !== 'ready'} + /> + +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/components.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/components.tsx new file mode 100644 index 000000000..99ee81168 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/components.tsx @@ -0,0 +1,99 @@ +import { GeistMono } from 'geist/font/mono'; +import Link from 'next/link'; +import type { ReactNode } from 'react'; + +const Code = ({ children }: { children: ReactNode }) => { + return ( + + {children} + + ); +}; + +export const Card = ({ type }: { type: string }) => { + return type === 'chat-text' ? ( +
+
+
+ Stream Chat Completions +
+
+

+ The useChat hook can be integrated with a Python + FastAPI backend to stream chat completions in real-time. The most + basic setup involves streaming plain text chunks by setting the{' '} + streamProtocol to text. +

+ +

+ To make your responses streamable, you will have to use the{' '} + StreamingResponse class provided by FastAPI. +

+
+
+
+ ) : type === 'chat-data' ? ( +
+
+
+ Stream Chat Completions with Tools +
+
+

+ The useChat hook can be integrated with a Python + FastAPI backend to stream chat completions in real-time. However, + the most basic setup that involves streaming plain text chunks by + setting the streamProtocol to text is + limited. +

+ +

+ As a result, setting the streamProtocol to data allows + you to stream chunks that include information about tool calls and + results. +

+ +

+ To make your responses streamable, you will have to use the{' '} + StreamingResponse class provided by FastAPI. You will + also have to ensure that your chunks follow the{' '} + + data stream protocol + {' '} + and that the response has x-vercel-ai-data-stream{' '} + header set to v1. +

+
+
+
+ ) : type === 'chat-attachments' ? ( +
+
+
+ Stream Chat Completions with Attachments +
+
+

+ The useChat hook can be integrated with a Python + FastAPI backend to stream chat completions in real-time. To make + your responses streamable, you will have to use the{' '} + StreamingResponse class provided by FastAPI. +

+ +

+ Furthermore, you can send files along with your messages by setting{' '} + experimental_attachments to true in{' '} + handleSubmit. This will allow you to use process these + attachments in your FastAPI backend. +

+
+
+
+ ) : null; +}; diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/favicon.ico b/apps/ai-observability/vercel-ai/next-fastapi/app/favicon.ico new file mode 100644 index 000000000..718d6fea4 Binary files /dev/null and b/apps/ai-observability/vercel-ai/next-fastapi/app/favicon.ico differ diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/globals.css b/apps/ai-observability/vercel-ai/next-fastapi/app/globals.css new file mode 100644 index 000000000..426d8b2c4 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/globals.css @@ -0,0 +1,9 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --foreground-rgb: 0, 0, 0; + --background-start-rgb: 214, 219, 220; + --background-end-rgb: 255, 255, 255; +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/icons.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/icons.tsx new file mode 100644 index 000000000..7d04f2ac7 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/icons.tsx @@ -0,0 +1,106 @@ +export const LogoPython = () => ( + + + + + + + + + + + + + + +); + +export const LogoNext = () => ( + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/layout.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/layout.tsx new file mode 100644 index 000000000..41afbb6d6 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/layout.tsx @@ -0,0 +1,31 @@ +import './globals.css'; +import { LogoNext, LogoPython } from './icons'; +import Link from 'next/link'; +import { GeistSans } from 'geist/font/sans'; + +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'AI SDK and FastAPI Examples', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + +
+ +
+
+ +
+ + {children} + + + ); +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/app/page.tsx b/apps/ai-observability/vercel-ai/next-fastapi/app/page.tsx new file mode 100644 index 000000000..5402cb20d --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/app/page.tsx @@ -0,0 +1,29 @@ +import Link from 'next/link'; + +const examples = [ + { + title: 'useChat', + link: '/01-chat-text', + }, + { + title: 'useChat with tools', + link: '/02-chat-data', + }, + { + title: 'useChat with attachments', + link: '/03-chat-attachments', + }, +]; + +export default function Home() { + return ( +
+ {examples.map((example, index) => ( + +
{index + 1}.
+
{example.title}
+ + ))} +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/next.config.ts b/apps/ai-observability/vercel-ai/next-fastapi/next.config.ts new file mode 100644 index 000000000..eae91ef3f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/next.config.ts @@ -0,0 +1,31 @@ +import type { NextConfig } from 'next'; + +const nextConfig: NextConfig = { + rewrites: async () => { + return [ + { + source: '/api/:path*', + destination: + process.env.NODE_ENV === 'development' + ? 'http://127.0.0.1:8000/api/:path*' + : '/api/', + }, + { + source: '/docs', + destination: + process.env.NODE_ENV === 'development' + ? 'http://127.0.0.1:8000/docs' + : '/api/docs', + }, + { + source: '/openapi.json', + destination: + process.env.NODE_ENV === 'development' + ? 'http://127.0.0.1:8000/openapi.json' + : '/api/openapi.json', + }, + ]; + }, +}; + +export default nextConfig; diff --git a/apps/ai-observability/vercel-ai/next-fastapi/package.json b/apps/ai-observability/vercel-ai/next-fastapi/package.json new file mode 100644 index 000000000..a765a51c6 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/package.json @@ -0,0 +1,31 @@ +{ + "name": "@example/next-fastapi", + "version": "0.0.0", + "private": true, + "scripts": { + "fastapi-dev": "pip3 install -r requirements.txt && python3 -m uvicorn api.index:app --reload", + "next-dev": "next dev", + "dev": "concurrently \"npm run next-dev\" \"npm run fastapi-dev\"", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@ai-sdk/react": "workspace:*", + "ai": "workspace:*", + "geist": "^1.7.0", + "next": "^15.5.18", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/node": "22.19.19", + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.7", + "autoprefixer": "^10.5.0", + "concurrently": "^9.2.1", + "postcss": "^8.5.14", + "tailwindcss": "^3.4.19", + "typescript": "5.8.3" + } +} diff --git a/apps/ai-observability/vercel-ai/next-fastapi/postcss.config.js b/apps/ai-observability/vercel-ai/next-fastapi/postcss.config.js new file mode 100644 index 000000000..12a703d90 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/ai-observability/vercel-ai/next-fastapi/public/next.svg b/apps/ai-observability/vercel-ai/next-fastapi/public/next.svg new file mode 100644 index 000000000..5174b28c5 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/ai-observability/vercel-ai/next-fastapi/public/vercel.svg b/apps/ai-observability/vercel-ai/next-fastapi/public/vercel.svg new file mode 100644 index 000000000..d2f842227 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/ai-observability/vercel-ai/next-fastapi/requirements.txt b/apps/ai-observability/vercel-ai/next-fastapi/requirements.txt new file mode 100644 index 000000000..769e76c94 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/requirements.txt @@ -0,0 +1,36 @@ +annotated-types==0.7.0 +anyio==4.4.0 +certifi==2024.7.4 +click==8.1.7 +distro==1.9.0 +dnspython==2.6.1 +email_validator==2.2.0 +fastapi==0.111.1 +fastapi-cli==0.0.4 +h11==0.14.0 +httpcore==1.0.5 +httptools==0.6.1 +httpx==0.27.0 +idna==3.7 +Jinja2==3.1.5 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +mdurl==0.1.2 +openai==1.37.1 +pydantic==2.8.2 +pydantic_core==2.20.1 +Pygments==2.18.0 +python-dotenv==1.0.1 +python-multipart==0.0.9 +PyYAML==6.0.1 +rich==13.7.1 +shellingham==1.5.4 +sniffio==1.3.1 +starlette==0.37.2 +tqdm==4.66.4 +typer==0.12.3 +typing_extensions==4.12.2 +uvicorn==0.30.3 +uvloop==0.19.0 +watchfiles==0.22.0 +websockets==12.0 diff --git a/apps/ai-observability/vercel-ai/next-fastapi/tailwind.config.js b/apps/ai-observability/vercel-ai/next-fastapi/tailwind.config.js new file mode 100644 index 000000000..db68cff57 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/tailwind.config.js @@ -0,0 +1,18 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme: { + extend: { + backgroundImage: { + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': + 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + }, + }, + }, + plugins: [], +}; diff --git a/apps/ai-observability/vercel-ai/next-fastapi/tsconfig.json b/apps/ai-observability/vercel-ai/next-fastapi/tsconfig.json new file mode 100644 index 000000000..ca2c43155 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next-fastapi/tsconfig.json @@ -0,0 +1,50 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + }, + "composite": true, + "noEmit": true + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ], + "references": [ + { + "path": "../../packages/ai" + }, + { + "path": "../../packages/react" + } + ] +} diff --git a/apps/ai-observability/vercel-ai/next/.env.local.example b/apps/ai-observability/vercel-ai/next/.env.local.example new file mode 100644 index 000000000..0de7a3364 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/.env.local.example @@ -0,0 +1,8 @@ +# Required for AI Gateway authentication when running locally. +AI_GATEWAY_API_KEY="" + +# Alternatively, authenticate with a Vercel OIDC token. +# VERCEL_OIDC_TOKEN="" + +# Required for resumable streams. The Redis server must support pub/sub. +REDIS_URL="" diff --git a/apps/ai-observability/vercel-ai/next/.gitignore b/apps/ai-observability/vercel-ai/next/.gitignore new file mode 100644 index 000000000..d186e8809 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/.gitignore @@ -0,0 +1,39 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +# persistence +.chats +.streams diff --git a/apps/ai-observability/vercel-ai/next/README.md b/apps/ai-observability/vercel-ai/next/README.md new file mode 100644 index 000000000..0d0d46892 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/README.md @@ -0,0 +1,54 @@ +# Next.js Chat Example + +A minimal Next.js chat application for testing message persistence, server-side +rendering (SSR), and resumable streams. + +## Prerequisites + +- Node.js 22, 24, or 26 +- pnpm 10 or later +- An [AI Gateway API key](https://vercel.com/ai-gateway) +- A Redis database with pub/sub support for resumable streams + +## Setup + +From the repository root, install dependencies and build the workspace +packages: + +```bash +pnpm install +pnpm build +``` + +Copy the example environment file: + +```bash +cp examples/next/.env.local.example examples/next/.env.local +``` + +Then set these values in `examples/next/.env.local`: + +- `AI_GATEWAY_API_KEY`: authenticates requests to the AI Gateway. A + `VERCEL_OIDC_TOKEN` can be used instead. +- `REDIS_URL`: connects `resumable-stream` to Redis. + +## Run locally + +```bash +cd examples/next +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000). + +## Test the example + +Send a message to create a chat. The example stores chat data as JSON files in +`examples/next/.chats` so that reloading a chat URL renders its saved messages +on the server. + +To test stream resumption, request a long response and reload the page while it +is still streaming. The client reconnects to the active stream through Redis. + +The file-based chat store is for local demonstration only and is not suitable +for production use. diff --git a/apps/ai-observability/vercel-ai/next/app/actions.ts b/apps/ai-observability/vercel-ai/next/app/actions.ts new file mode 100644 index 000000000..ed9a05bc6 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/actions.ts @@ -0,0 +1,12 @@ +'use server'; + +import { revalidatePath } from 'next/cache'; + +export async function invalidateRouterCache() { + /* + * note: this path does not exist, but it will + * trigger a client-side reload. + */ + revalidatePath('/just-trigger-client-reload'); + await Promise.resolve(); +} diff --git a/apps/ai-observability/vercel-ai/next/app/api/chat/[id]/stream/route.ts b/apps/ai-observability/vercel-ai/next/app/api/chat/[id]/stream/route.ts new file mode 100644 index 000000000..8dee299ed --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/api/chat/[id]/stream/route.ts @@ -0,0 +1,43 @@ +import { readChat, saveChat } from '@util/chat-store'; +import { UI_MESSAGE_STREAM_HEADERS } from 'ai'; +import { after } from 'next/server'; +import { createResumableStreamContext } from 'resumable-stream'; + +export async function GET( + request: Request, + { params }: { params: Promise<{ id: string }> }, +) { + const { id } = await params; + + const chat = await readChat(id); + + if (chat.activeStreamId == null) { + // no content response when there is no active stream + return new Response(null, { status: 204 }); + } + + const streamContext = createResumableStreamContext({ + waitUntil: after, + }); + + return new Response( + await streamContext.resumeExistingStream(chat.activeStreamId), + { headers: UI_MESSAGE_STREAM_HEADERS }, + ); +} + +// DELETE route to stop the stream +export async function DELETE( + request: Request, + { params }: { params: Promise<{ id: string }> }, +) { + const { id } = await params; + + const chat = await readChat(id); + + console.log('canceling stream for chat', id); + + await saveChat({ ...chat, canceledAt: Date.now() }); + + return new Response(null, { status: 200 }); +} diff --git a/apps/ai-observability/vercel-ai/next/app/api/chat/route.ts b/apps/ai-observability/vercel-ai/next/app/api/chat/route.ts new file mode 100644 index 000000000..3b2d25d25 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/api/chat/route.ts @@ -0,0 +1,108 @@ +import type { MyUIMessage } from '@/util/chat-schema'; +import { readChat, saveChat } from '@util/chat-store'; +import { + convertToModelMessages, + createUIMessageStreamResponse, + generateId, + streamText, + toUIMessageStream, +} from 'ai'; +import { after } from 'next/server'; +import { createResumableStreamContext } from 'resumable-stream'; +import throttle from 'throttleit'; + +export async function POST(req: Request) { + const { + message, + id, + trigger, + messageId, + }: { + message: MyUIMessage | undefined; + id: string; + trigger: 'submit-message' | 'regenerate-message'; + messageId: string | undefined; + } = await req.json(); + + const chat = await readChat(id); + let messages: MyUIMessage[] = chat.messages; + + if (trigger === 'submit-message') { + if (messageId != null) { + const messageIndex = messages.findIndex(m => m.id === messageId); + + if (messageIndex === -1) { + throw new Error(`message ${messageId} not found`); + } + + messages = messages.slice(0, messageIndex); + messages.push(message!); + } else { + messages = [...messages, message!]; + } + } else if (trigger === 'regenerate-message') { + const messageIndex = + messageId == null + ? messages.length - 1 + : messages.findIndex(message => message.id === messageId); + + if (messageIndex === -1) { + throw new Error(`message ${messageId} not found`); + } + + // set the messages to the message before the assistant message + messages = messages.slice( + 0, + messages[messageIndex].role === 'assistant' + ? messageIndex + : messageIndex + 1, + ); + } + + // save the user message + saveChat({ id, messages, activeStreamId: null }); + + const userStopSignal = new AbortController(); + + const result = streamText({ + model: 'openai/gpt-5-mini', + messages: await convertToModelMessages(messages), + abortSignal: userStopSignal.signal, + // throttle reading from chat store to max once per second + onChunk: throttle(async () => { + const { canceledAt } = await readChat(id); + if (canceledAt) { + userStopSignal.abort(); + } + }, 1000), + onAbort: () => { + console.log('aborted'); + }, + }); + + return createUIMessageStreamResponse({ + stream: toUIMessageStream({ + stream: result.stream, + originalMessages: messages, + generateMessageId: generateId, + messageMetadata: ({ part }) => { + if (part.type === 'start') { + return { createdAt: Date.now() }; + } + }, + onFinish: ({ messages }) => { + saveChat({ id, messages, activeStreamId: null }); + }, + }), + async consumeSseStream({ stream }) { + const streamId = generateId(); + + // send the sse stream into a resumable stream sink as well: + const streamContext = createResumableStreamContext({ waitUntil: after }); + await streamContext.createNewResumableStream(streamId, () => stream); + + // update the chat with the streamId + saveChat({ id, activeStreamId: streamId }); + }, + }); +} diff --git a/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/chat-input.tsx b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/chat-input.tsx new file mode 100644 index 000000000..3eaff27b3 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/chat-input.tsx @@ -0,0 +1,45 @@ +import { useState } from 'react'; + +export default function ChatInput({ + status, + onSubmit, + inputRef, + stop, +}: { + status: string; + onSubmit: (text: string) => void; + inputRef: React.RefObject; + stop: () => void; +}) { + const [text, setText] = useState(''); + + return ( + <> + {(status === 'streaming' || status === 'submitted') && ( + + )} +
{ + e.preventDefault(); + if (text.trim() === '') return; + onSubmit(text); + setText(''); + }} + > + setText(e.target.value)} + /> +
+ + ); +} diff --git a/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/chat.tsx b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/chat.tsx new file mode 100644 index 000000000..920dbf2b9 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/chat.tsx @@ -0,0 +1,103 @@ +'use client'; + +import { invalidateRouterCache } from '@/app/actions'; +import type { MyUIMessage } from '@/util/chat-schema'; +import { useChat } from '@ai-sdk/react'; +import { DefaultChatTransport } from 'ai'; +import { useEffect, useRef } from 'react'; +import ChatInput from './chat-input'; +import Message from './message'; + +export default function ChatComponent({ + chatData, + isNewChat = false, + resume = false, +}: { + chatData: { id: string; messages: MyUIMessage[] }; + isNewChat?: boolean; + resume?: boolean; +}) { + const inputRef = useRef(null); + + const { status, sendMessage, messages, regenerate, stop } = useChat({ + id: chatData.id, + messages: chatData.messages, + resume, + transport: new DefaultChatTransport({ + prepareSendMessagesRequest: ({ id, messages, trigger, messageId }) => { + switch (trigger) { + case 'regenerate-message': + // omit messages data transfer, only send the messageId: + return { + body: { + trigger: 'regenerate-message', + id, + messageId, + }, + }; + + case 'submit-message': + // only send the last message to the server to limit the request size: + return { + body: { + trigger: 'submit-message', + id, + message: messages[messages.length - 1], + messageId, + }, + }; + } + }, + }), + onFinish(options) { + console.log('onFinish', options); + + // for new chats, the router cache needs to be invalidated so + // navigation to the previous page triggers SSR correctly + if (isNewChat) { + invalidateRouterCache(); + } + + // focus the input field again after the response is finished + requestAnimationFrame(() => { + inputRef.current?.focus(); + }); + }, + }); + + // activate the input field + useEffect(() => { + inputRef.current?.focus(); + }, []); + + return ( +
+ {messages.map(message => ( + + ))} + { + // send stop with chat id to the new api route + fetch(`/api/chat/${chatData.id}/stream`, { + method: 'DELETE', + }); + }} + onSubmit={text => { + sendMessage({ text, metadata: { createdAt: Date.now() } }); + + if (isNewChat) { + window.history.pushState(null, '', `/chat/${chatData.id}`); + } + }} + inputRef={inputRef} + /> +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/message.tsx b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/message.tsx new file mode 100644 index 000000000..33db9f3b2 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/message.tsx @@ -0,0 +1,60 @@ +import type { MyUIMessage } from '@/util/chat-schema'; +import type { ChatStatus } from 'ai'; + +export default function Message({ + message, + status, + regenerate, + sendMessage, +}: { + status: ChatStatus; + message: MyUIMessage; + regenerate: ({ messageId }: { messageId: string }) => void; + sendMessage: ({ + text, + messageId, + }: { + text: string; + messageId?: string; + }) => void; +}) { + const date = message.metadata?.createdAt + ? new Date(message.metadata.createdAt).toLocaleString() + : ''; + const isUser = message.role === 'user'; + + return ( +
+
{date}
+
{isUser ? 'User:' : 'AI:'}
+
+ {message.parts + .map(part => (part.type === 'text' ? part.text : '')) + .join('')} +
+ {message.role === 'user' && ( + <> + + + + )} +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/page.tsx b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/page.tsx new file mode 100644 index 000000000..d60ba719e --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/chat/[chatId]/page.tsx @@ -0,0 +1,29 @@ +import { readAllChats, readChat } from '@util/chat-store'; +import Link from 'next/link'; +import Chat from './chat'; + +export default async function Page(props: { + params: Promise<{ chatId: string }>; +}) { + const { chatId } = await props.params; // get the chat ID from the URL + const chatData = await readChat(chatId); // load the chat + const chats = await readAllChats(); // load all chats + + // filter to 5 most recent chats + const recentChats = chats + .sort((a, b) => b.createdAt - a.createdAt) + .slice(0, 5); + + return ( +
+
    + {recentChats.map(chat => ( +
  • + {chat.id} +
  • + ))} +
+ ; +
+ ); +} diff --git a/apps/ai-observability/vercel-ai/next/app/favicon.ico b/apps/ai-observability/vercel-ai/next/app/favicon.ico new file mode 100644 index 000000000..718d6fea4 Binary files /dev/null and b/apps/ai-observability/vercel-ai/next/app/favicon.ico differ diff --git a/apps/ai-observability/vercel-ai/next/app/globals.css b/apps/ai-observability/vercel-ai/next/app/globals.css new file mode 100644 index 000000000..b5c61c956 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/ai-observability/vercel-ai/next/app/layout.tsx b/apps/ai-observability/vercel-ai/next/app/layout.tsx new file mode 100644 index 000000000..d29a5479c --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/layout.tsx @@ -0,0 +1,18 @@ +import './globals.css'; + +export const metadata = { + title: 'AI SDK - Next.js OpenAI Examples', + description: 'Examples of using the AI SDK with Next.js and OpenAI.', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/apps/ai-observability/vercel-ai/next/app/page.tsx b/apps/ai-observability/vercel-ai/next/app/page.tsx new file mode 100644 index 000000000..ef5d77206 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/app/page.tsx @@ -0,0 +1,6 @@ +import { generateId } from 'ai'; +import Chat from './chat/[chatId]/chat'; + +export default async function ChatPage() { + return ; +} diff --git a/apps/ai-observability/vercel-ai/next/package.json b/apps/ai-observability/vercel-ai/next/package.json new file mode 100644 index 000000000..56f181409 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/package.json @@ -0,0 +1,32 @@ +{ + "name": "@example/next", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@ai-sdk/react": "workspace:*", + "@vercel/blob": "^0.26.0", + "ai": "workspace:*", + "next": "^15.5.18", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-markdown": "9.0.1", + "resumable-stream": "^2.2.12", + "throttleit": "2.1.0", + "zod": "3.25.76" + }, + "devDependencies": { + "@types/node": "22.19.19", + "@types/react": "^18.3.28", + "@types/react-dom": "^18.3.7", + "autoprefixer": "^10.5.0", + "postcss": "^8.5.14", + "tailwindcss": "^3.4.19", + "typescript": "5.8.3" + } +} diff --git a/apps/ai-observability/vercel-ai/next/postcss.config.js b/apps/ai-observability/vercel-ai/next/postcss.config.js new file mode 100644 index 000000000..12a703d90 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/ai-observability/vercel-ai/next/tailwind.config.js b/apps/ai-observability/vercel-ai/next/tailwind.config.js new file mode 100644 index 000000000..db68cff57 --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/tailwind.config.js @@ -0,0 +1,18 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', + ], + theme: { + extend: { + backgroundImage: { + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': + 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + }, + }, + }, + plugins: [], +}; diff --git a/apps/ai-observability/vercel-ai/next/tsconfig.json b/apps/ai-observability/vercel-ai/next/tsconfig.json new file mode 100644 index 000000000..f944b4e5f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"], + "@util/*": ["./util/*"] + }, + "composite": true, + "noEmit": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"], + "references": [ + { + "path": "../../packages/ai" + }, + { + "path": "../../packages/react" + } + ] +} diff --git a/apps/ai-observability/vercel-ai/next/util/chat-schema.ts b/apps/ai-observability/vercel-ai/next/util/chat-schema.ts new file mode 100644 index 000000000..0ffce613f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/util/chat-schema.ts @@ -0,0 +1,18 @@ +import type { UIDataTypes, UIMessage } from 'ai'; +import { z } from 'zod'; + +export const myMessageMetadataSchema = z.object({ + createdAt: z.number(), +}); + +export type MyMessageMetadata = z.infer; + +export type MyUIMessage = UIMessage; + +export type ChatData = { + id: string; + messages: MyUIMessage[]; + createdAt: number; + activeStreamId: string | null; + canceledAt: number | null; +}; diff --git a/apps/ai-observability/vercel-ai/next/util/chat-store.ts b/apps/ai-observability/vercel-ai/next/util/chat-store.ts new file mode 100644 index 000000000..33f83405f --- /dev/null +++ b/apps/ai-observability/vercel-ai/next/util/chat-store.ts @@ -0,0 +1,124 @@ +import { generateId } from 'ai'; +import { existsSync, mkdirSync } from 'fs'; +import { readdir, readFile, writeFile } from 'fs/promises'; +import path from 'path'; +import type { ChatData, MyUIMessage } from './chat-schema'; + +// example implementation for demo purposes +// in a real app, you would save the chat to a database +// and use the id from the database entry + +// Treat chat IDs as opaque tokens before using them in file paths. +const chatIdRegex = /^[A-Za-z0-9_-]+$/; + +export async function createChat(): Promise { + const id = generateId(); + await getChatFile(id); + return id; +} + +export async function saveChat({ + id, + activeStreamId, + messages, + canceledAt, +}: { + id: string; + activeStreamId?: string | null; + messages?: MyUIMessage[]; + canceledAt?: number | null; +}): Promise { + const chat = await readChat(id); + + if (messages !== undefined) { + chat.messages = messages; + } + + if (activeStreamId !== undefined) { + chat.activeStreamId = activeStreamId; + } + + if (canceledAt !== undefined) { + chat.canceledAt = canceledAt; + } + + await writeChat(chat); +} + +export async function appendMessageToChat({ + id, + message, +}: { + id: string; + message: MyUIMessage; +}): Promise { + const chat = await readChat(id); + chat.messages.push(message); + await writeChat(chat); +} + +async function writeChat(chat: ChatData) { + await writeFile(await getChatFile(chat.id), JSON.stringify(chat, null, 2)); +} + +// TODO return null if the chat does not exist +export async function readChat(id: string): Promise { + return JSON.parse(await readFile(await getChatFile(id), 'utf8')); +} + +export async function readAllChats(): Promise { + const chatDir = getChatDir(); + const files = await readdir(chatDir, { withFileTypes: true }); + return Promise.all( + files + .filter(file => file.isFile()) + .map(file => file.name.match(/^([A-Za-z0-9_-]+)\.json$/)?.[1]) + .filter(id => id != null) + .map(async id => readChat(id)), + ); +} + +async function getChatFile(id: string): Promise { + const chatDir = getChatDir(); + const chatFile = getSafeChatFilePath({ chatDir, id }); + + if (!existsSync(chatDir)) mkdirSync(chatDir, { recursive: true }); + + if (!existsSync(chatFile)) { + const blankChat: ChatData = { + id, + messages: [], + createdAt: Date.now(), + activeStreamId: null, + canceledAt: null, + }; + await writeFile(chatFile, JSON.stringify(blankChat, null, 2)); + } + + return chatFile; +} + +function getChatDir(): string { + return path.resolve(process.cwd(), '.chats'); +} + +function getSafeChatFilePath({ + chatDir, + id, +}: { + chatDir: string; + id: string; +}): string { + if (!chatIdRegex.test(id)) { + throw new Error('Invalid chat ID'); + } + + const chatFile = path.resolve(chatDir, `${id}.json`); + + // Defense in depth: keep the resolved file inside the chat directory. + if (!chatFile.startsWith(`${chatDir}${path.sep}`)) { + throw new Error('Invalid chat ID'); + } + + return chatFile; +}