diff --git a/Dockerfile b/Dockerfile index 022b553..a9dc972 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ FROM node:20-alpine AS production # Install system dependencies for production RUN apk add --no-cache \ docker \ - docker-compose \ + docker \ postgresql-client # Create app user diff --git a/EMPIRE_CONTAINER_SELF_HEALING_SOLUTION.md b/EMPIRE_CONTAINER_SELF_HEALING_SOLUTION.md deleted file mode 100644 index 5714ae1..0000000 --- a/EMPIRE_CONTAINER_SELF_HEALING_SOLUTION.md +++ /dev/null @@ -1,414 +0,0 @@ -# Empire Container Self-Healing Solution - -## Problem Analysis - -The Empire container was experiencing unexpected shutdowns and recovery loop failures, causing service interruptions and preventing proper Empire functionality. - -### Original Issues Identified - -**1. Container Recovery Loop Bug** -``` -Error: Container name "/attacknode-empire" is already in use -Error: Container name "/empire-data" is already in use -``` - -**2. Container Exit Analysis** -- Empire containers starting successfully but exiting unexpectedly -- Health monitor detecting failures but unable to recover due to naming conflicts -- Infinite recovery loops creating system instability - -**3. Inadequate Cleanup Process** -- Existing containers not properly removed before recreation -- Zombie containers causing naming conflicts -- Volume and network cleanup insufficient - -## Comprehensive Self-Healing Solution - -### 1. **Enhanced Empire Health Monitor** (`server/services/empire-health-monitor.ts`) - -**Key Improvements:** -- **Complete Container Cleanup**: Comprehensive removal of all Empire-related containers -- **Improved Setup Detection**: Better recognition of Empire startup completion -- **Progressive Recovery**: Multiple recovery levels with proper cleanup -- **Robust Error Handling**: Detailed logging and error analysis - -**Enhanced Features:** -```typescript -// Improved setup completion detection -private checkSetupCompleted(logs: string): boolean { - const hasStartupComplete = logs.includes('Application startup complete'); - const hasUvicornRunning = logs.includes('Uvicorn running on'); - const hasEmpireStarting = logs.includes('Empire starting up'); - - return hasStartupComplete && hasUvicornRunning && hasEmpireStarting; -} - -// Complete container cleanup -private async completeContainerCleanup(): Promise { - // Stop all Empire containers - // Remove all Empire containers - // Clean up orphaned containers - // Verify cleanup completion -} -``` - -### 2. **Empire Container Repair Script** (`fix-empire-container.sh`) - -**Comprehensive Troubleshooting Tool:** -- **System Resource Monitoring**: Memory, CPU, disk space analysis -- **Port Availability Checking**: Conflict detection for ports 1337/5000 -- **Container Lifecycle Management**: Start, stop, restart, cleanup operations -- **Exit Code Analysis**: Detailed container failure diagnosis - -**Advanced Features:** -```bash -# Container exit code analysis -case $exit_code in - 0) "Container exited normally" - 1) "Container exited with general error" - 137) "Container killed by SIGKILL (OOM or manual)" - 143) "Container terminated by SIGTERM" -esac - -# Progressive startup with retry logic -start_empire_container() { - for attempt in 1 to MAX_RETRIES; do - if start_empire_container_single; then - return 0 - fi - exponential_backoff_wait - done -} -``` - -### 3. **Intelligent Container Management** - -**Container Lifecycle Improvements:** -- **Unique Container Naming**: Prevents naming conflicts -- **Proper Cleanup Sequence**: Stop → Remove → Prune → Verify -- **Volume Management**: Persistent data handling across restarts -- **Health Check Integration**: Docker-native health monitoring - -**Recovery Strategy:** -```bash -# Level 1: Simple restart -docker restart attacknode-empire - -# Level 2: Clean recreation -complete_cleanup && start_empire_container - -# Level 3: Aggressive recovery -remove_all_empire_containers && rebuild_from_scratch -``` - -## Implementation Details - -### Enhanced Health Monitoring - -**Health Check Components:** -- **Container Status**: Running, stopped, crashed analysis -- **API Responsiveness**: Empire REST API health verification -- **Database Connectivity**: SQLite database access testing -- **Starkiller UI**: Web interface availability checking -- **Process Monitoring**: Empire process lifecycle tracking - -**Recovery Triggers:** -- **Container Exit**: Automatic restart on unexpected shutdown -- **API Failure**: Service restart when API becomes unresponsive -- **Database Issues**: Database repair and container recreation -- **Resource Exhaustion**: Cleanup and resource optimization - -### Container Cleanup Process - -**Comprehensive Cleanup Steps:** -1. **Stop All Empire Containers**: Graceful shutdown with timeout -2. **Remove Container Instances**: Force removal of all Empire containers -3. **Clean Orphaned Resources**: Remove unused containers and networks -4. **Verify Cleanup**: Ensure no naming conflicts remain -5. **Prepare Environment**: Setup volumes and permissions - -**Cleanup Implementation:** -```typescript -private async completeContainerCleanup(): Promise { - // Stop containers with timeout - const stopCommands = [ - 'docker stop attacknode-empire --time 5', - 'docker stop empire-data --time 5', - 'docker stop $(docker ps -q --filter "name=empire") --time 5' - ]; - - // Remove containers forcefully - const removeCommands = [ - 'docker rm -f attacknode-empire', - 'docker rm -f empire-data', - 'docker rm -f $(docker ps -aq --filter "name=empire")' - ]; - - // Clean up orphaned containers - await execAsync('docker container prune -f'); -} -``` - -### Container Startup Optimization - -**Startup Sequence:** -1. **Image Pull**: Ensure latest Empire image is available -2. **Data Container**: Create persistent data container -3. **Main Container**: Start Empire with proper configuration -4. **Readiness Check**: Wait for complete initialization -5. **Health Verification**: Confirm all services are operational - -**Startup Verification:** -```bash -wait_for_container_ready() { - while [ $elapsed -lt $STARTUP_TIMEOUT ]; do - # Check container is running - if ! docker ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}" | grep -q "Up"; then - return 1 - fi - - # Check Empire startup indicators - local logs=$(get_container_logs "$CONTAINER_NAME" 50) - if echo "$logs" | grep -q "Application startup complete" && \ - echo "$logs" | grep -q "Uvicorn running on"; then - return 0 - fi - - sleep 5 - done -} -``` - -## Usage Instructions - -### 1. **Automatic Self-Healing** -The enhanced health monitor runs automatically and handles: -- **Container Failures**: Automatic restart and recovery -- **Service Degradation**: Proactive health monitoring -- **Resource Issues**: Cleanup and optimization -- **Naming Conflicts**: Complete container cleanup - -### 2. **Manual Troubleshooting** - -**Basic Diagnostics:** -```bash -# Run comprehensive diagnostics -./fix-empire-container.sh --diagnose - -# Check container status -./fix-empire-container.sh --status - -# View container logs -./fix-empire-container.sh --logs -``` - -**Container Management:** -```bash -# Repair container issues -./fix-empire-container.sh --repair - -# Clean up containers -./fix-empire-container.sh --cleanup - -# Restart Empire container -./fix-empire-container.sh --restart -``` - -**Emergency Recovery:** -```bash -# Create emergency recovery script -./fix-empire-container.sh --recovery - -# Run emergency recovery -./empire-recovery.sh -``` - -### 3. **Health Monitor Integration** - -**Manual Health Monitor Control:** -```typescript -// Restart Empire manually -await empireHealthMonitor.restartEmpire(); - -// Get detailed status -const status = await empireHealthMonitor.getDetailedStatus(); - -// Check health status -const health = empireHealthMonitor.getLastHealthStatus(); -``` - -## Troubleshooting Guide - -### Common Container Issues - -**1. Container Exits Immediately** -```bash -# Check exit code and reason -./fix-empire-container.sh --diagnose - -# Analyze container logs -docker logs attacknode-empire --tail 50 - -# Check system resources -free -h && df -h -``` - -**2. Naming Conflicts** -```bash -# Clean up all Empire containers -./fix-empire-container.sh --cleanup - -# Restart with clean environment -./fix-empire-container.sh --repair -``` - -**3. Port Conflicts** -```bash -# Check port usage -netstat -tlnp | grep -E ':1337|:5000' - -# Kill conflicting processes -sudo fuser -k 1337/tcp 5000/tcp -``` - -**4. Database Issues** -```bash -# Check database file -docker exec attacknode-empire ls -la /empire/empire.db - -# Recreate container with fresh database -./fix-empire-container.sh --cleanup && ./fix-empire-container.sh --repair -``` - -### System Resource Issues - -**Memory Problems:** -```bash -# Check available memory -free -h - -# Clean up Docker resources -docker system prune -a - -# Restart with limited resources -docker run --memory=1g --cpus=1 ... -``` - -**Disk Space Issues:** -```bash -# Check disk usage -df -h - -# Clean up Docker images -docker image prune -a - -# Clean up volumes -docker volume prune -``` - -## Performance Optimization - -### Container Resource Management - -**Memory Optimization:** -- **Container Limits**: Set appropriate memory limits -- **Garbage Collection**: Regular cleanup of unused resources -- **Volume Management**: Efficient storage utilization - -**CPU Optimization:** -- **Process Monitoring**: Track Empire process performance -- **Load Balancing**: Distribute container load -- **Resource Limits**: Prevent CPU exhaustion - -### Network Performance - -**Port Management:** -- **Port Conflict Detection**: Automatic port availability checking -- **Network Optimization**: Container network configuration -- **Connection Pooling**: Efficient network resource usage - -## Monitoring and Alerting - -### Health Metrics - -**Container Health:** -- **Uptime Monitoring**: Track container availability -- **Resource Usage**: Monitor CPU, memory, disk usage -- **Error Rate**: Track container failure frequency -- **Recovery Time**: Measure self-healing effectiveness - -**Application Health:** -- **API Response Time**: Monitor Empire API performance -- **Database Performance**: Track database query times -- **UI Accessibility**: Monitor Starkiller interface availability - -### Alerting System - -**Alert Conditions:** -- **Container Failures**: Multiple consecutive failures -- **Resource Exhaustion**: High CPU/memory usage -- **API Unresponsiveness**: Service degradation -- **Recovery Failures**: Self-healing system issues - -**Alert Actions:** -- **Automatic Recovery**: Trigger self-healing processes -- **Notification**: Send alerts to administrators -- **Logging**: Record incidents for analysis -- **Escalation**: Progressive response to persistent issues - -## Security Considerations - -### Container Security - -**Access Control:** -- **User Permissions**: Proper Docker access management -- **Container Isolation**: Network and process isolation -- **Volume Security**: Secure data persistence - -**Network Security:** -- **Port Exposure**: Minimize exposed ports -- **Network Segmentation**: Isolate Empire network traffic -- **SSL/TLS**: Secure communication channels - -### Data Protection - -**Database Security:** -- **Access Control**: Restrict database access -- **Backup Strategy**: Regular database backups -- **Encryption**: Encrypt sensitive data - -**Log Security:** -- **Log Rotation**: Prevent log file growth -- **Access Logging**: Monitor system access -- **Audit Trail**: Maintain security audit logs - -## Future Enhancements - -### Planned Improvements - -1. **Advanced Monitoring**: Enhanced metrics collection and analysis -2. **Predictive Healing**: Machine learning for failure prediction -3. **Cluster Support**: Multi-container Empire deployments -4. **Integration**: Enhanced integration with monitoring systems - -### Scalability Improvements - -1. **Load Balancing**: Multiple Empire instance support -2. **High Availability**: Failover and redundancy -3. **Performance Tuning**: Optimization for high-load scenarios -4. **Resource Scaling**: Dynamic resource allocation - -## Conclusion - -The Empire Container Self-Healing Solution provides: - -1. **Automatic Recovery**: Comprehensive container failure detection and recovery -2. **Robust Cleanup**: Complete container cleanup preventing naming conflicts -3. **Intelligent Monitoring**: Advanced health monitoring with detailed diagnostics -4. **Troubleshooting Tools**: Comprehensive diagnostic and repair capabilities -5. **Performance Optimization**: Resource management and performance tuning -6. **Security**: Secure container management and data protection - -This solution ensures Empire runs reliably with automatic recovery from container failures, providing long-term stability and minimal downtime. - -The system operates transparently, automatically detecting and repairing container issues while providing detailed diagnostics for manual troubleshooting when needed. diff --git a/EMPIRE_SELF_HEALING_SOLUTION.md b/EMPIRE_SELF_HEALING_SOLUTION.md deleted file mode 100644 index c4f5fc9..0000000 --- a/EMPIRE_SELF_HEALING_SOLUTION.md +++ /dev/null @@ -1,422 +0,0 @@ -# Empire Self-Healing Solution - -## Problem Analysis - -The Empire C2 framework container was experiencing startup failures with the following symptoms: - -### Original Error Symptoms -- Container would start but exit immediately -- No logs visible or accessible -- API not responding on port 1337 -- Starkiller UI not accessible on port 5000 - -### Root Cause Analysis -Through systematic debugging, we discovered: - -1. **Command Structure Change**: The Empire framework changed its command structure in newer versions - - Old format: `python3 empire --rest --restport 1337 --socketport 5000` - - New format: `python3 empire.py setup --reset && python3 empire.py server` - -2. **Installation Path Change**: Empire moved from `/opt/Empire` to `/empire/` - -3. **Configuration Changes**: Empire now uses YAML configuration files instead of command-line parameters - -4. **Setup Requirement**: Empire requires explicit setup before the server can start - -## Self-Healing Solution Implementation - -### 1. Updated Docker Configuration - -**File**: `server/services/docker.ts` - -```typescript -this.containerConfigs.set('empire', { - name: 'empire', - image: 'bcsecurity/empire:latest', - port: 1337, - category: 'security', - description: 'PowerShell Empire C2 framework', - icon: 'Crown', - additionalPorts: [5001], // External port 5001 maps to internal port 5000 - environment: { - STAGING_KEY: 'EmPiRe_StAgInG_KeY', - EMPIRE_USERNAME: 'empireadmin', - EMPIRE_PASSWORD: 'password123' - }, - volumes: [ - 'uploads/empire/data:/empire/data:rw', - 'uploads/empire/downloads:/empire/downloads:rw' - ], - customStartCommand: [ - 'sh', '-c', - 'cd /empire && python3 empire.py setup --reset && python3 empire.py server' - ] -}); -``` - -### 2. Empire Health Monitor - -**File**: `server/services/empire-health-monitor.ts` - -#### Key Features: -- **Continuous Health Monitoring**: Checks Empire health every 30 seconds -- **Multi-layered Health Checks**: - - Container status monitoring - - API response verification - - Database connectivity checks - - Starkiller UI availability - - Log analysis for error detection - -#### Health Check Components: - -```typescript -interface EmpireHealthStatus { - isRunning: boolean; - apiResponding: boolean; - databaseConnected: boolean; - setupCompleted: boolean; - starkiller: boolean; - containerId?: string; - containerStatus?: string; - uptime?: number; - errors: string[]; - warnings: string[]; -} -``` - -#### Auto-Recovery Mechanisms: - -1. **Standard Recovery Process**: - - Stop failing container - - Remove container - - Setup volume permissions - - Start new container with proper initialization - - Wait for readiness verification - -2. **Aggressive Recovery Process** (fallback): - - Force stop all Empire containers - - Clean up volumes - - Pull fresh image - - Reset permissions - - Start with minimal configuration - -### 3. Volume Management - -#### Volume Directory Structure: -``` -uploads/empire/ -├── data/ # Empire persistent data -└── downloads/ # Empire downloads -``` - -#### Permission Management: -- Automatic creation of volume directories -- Proper permissions (755) for container access -- Automatic permission repair on failure - -### 4. Error Detection and Analysis - -#### Log Analysis Patterns: -- **Database Errors**: Connection failures, permission issues -- **Permission Errors**: File system access problems -- **Port Binding Errors**: Network configuration issues -- **Module Import Errors**: Python dependency problems - -#### Error Categories: -- **Critical Errors**: Prevent Empire from starting -- **Warnings**: May impact functionality but not critical - -### 5. Recovery Strategies - -#### Immediate Recovery Actions: -1. **Container Restart**: For transient failures -2. **Volume Permission Repair**: For file system issues -3. **Image Refresh**: For corrupted images -4. **Configuration Reset**: For persistent setup issues - -#### Progressive Recovery Approach: -1. **First Attempt**: Standard recovery with current configuration -2. **Second Attempt**: Aggressive recovery with fresh setup -3. **Third Attempt**: Minimal configuration fallback - -## Configuration Details - -### Empire Configuration (config.yaml) -```yaml -api: - ip: 0.0.0.0 - port: 1337 - secure: false -database: - use: sqlite - sqlite: - location: empire.db -starkiller: - enabled: true -``` - -### Docker Command Structure -```bash -docker run -d \ - --name attacknode-empire \ - --restart unless-stopped \ - -p 1337:1337 \ - -p 5001:5000 \ - -v /path/to/uploads/empire/data:/empire/data:rw \ - -v /path/to/uploads/empire/downloads:/empire/downloads:rw \ - bcsecurity/empire:latest \ - sh -c 'cd /empire && python3 empire.py setup --reset -y && python3 empire.py server' -``` - -## Testing and Verification - -### 1. Health Check Verification - -Test the health monitoring system: - -```bash -# Check container status -docker ps --filter "name=attacknode-empire" - -# Check Empire API -curl -s http://localhost:1337/api/version - -# Check Starkiller UI -curl -s http://localhost:5001 - -# Check container logs -docker logs attacknode-empire --tail 50 -``` - -### 2. Recovery Testing - -Simulate failures to test recovery: - -```bash -# Force stop container to test recovery -docker stop attacknode-empire - -# Remove container to test full recovery -docker rm attacknode-empire - -# Test volume permission issues -sudo chmod 000 uploads/empire/data/ -``` - -### 3. API Endpoint Testing - -Verify Empire API functionality: - -```bash -# Get Empire version -curl -X GET http://localhost:1337/api/version - -# List listeners -curl -X GET http://localhost:1337/api/listeners - -# Get Empire stats -curl -X GET http://localhost:1337/api/stats -``` - -## Monitoring and Alerting - -### 1. Health Status Monitoring - -The Empire health monitor provides: -- Real-time health status -- Historical health data -- Error trend analysis -- Performance metrics - -### 2. Log Monitoring - -Comprehensive log analysis for: -- Startup sequences -- Error patterns -- Performance issues -- Security events - -### 3. Alerting System - -Automated alerts for: -- Container failures -- API unavailability -- Database issues -- Permission problems - -## Maintenance and Troubleshooting - -### 1. Regular Maintenance - -**Daily Tasks**: -- Check health status -- Review error logs -- Verify API functionality - -**Weekly Tasks**: -- Update Empire image -- Clean up old containers -- Review volume usage - -**Monthly Tasks**: -- Full system health check -- Performance optimization -- Security review - -### 2. Common Issues and Solutions - -#### Issue: Container Exits Immediately -**Symptoms**: Container starts but exits quickly -**Solution**: Check Empire setup command completion -```bash -docker logs attacknode-empire | grep -i "setup\|error\|failed" -``` - -#### Issue: API Not Responding -**Symptoms**: Port 1337 not accessible -**Solution**: Verify Empire server startup -```bash -docker exec attacknode-empire netstat -tlnp | grep 1337 -``` - -#### Issue: Database Connection Failed -**Symptoms**: Empire can't access SQLite database -**Solution**: Check volume permissions -```bash -docker exec attacknode-empire ls -la /empire/empire.db -``` - -#### Issue: Starkiller UI Not Available -**Symptoms**: Port 5000 not accessible -**Solution**: Verify Starkiller configuration -```bash -docker exec attacknode-empire netstat -tlnp | grep 5000 -``` - -### 3. Manual Recovery Procedures - -#### Complete System Reset: -```bash -# Stop all Empire containers -docker stop $(docker ps -q --filter "name=empire") - -# Remove containers -docker rm $(docker ps -aq --filter "name=empire") - -# Clean volumes -sudo rm -rf uploads/empire/data/* -sudo rm -rf uploads/empire/downloads/* - -# Restart Empire service -# The health monitor will automatically detect and recover -``` - -## Performance Optimization - -### 1. Resource Management - -**Memory Optimization**: -- Monitor Empire memory usage -- Implement memory limits if needed -- Regular cleanup of temporary files - -**CPU Optimization**: -- Monitor CPU usage patterns -- Optimize container scheduling -- Balance load across system - -### 2. Network Performance - -**Port Management**: -- Dedicated ports for Empire services -- Proper firewall configuration -- Network monitoring - -**API Performance**: -- Connection pooling -- Request rate limiting -- Response caching where appropriate - -## Security Considerations - -### 1. Container Security - -**Image Security**: -- Use official Empire images -- Regular security updates -- Vulnerability scanning - -**Runtime Security**: -- Minimal privileges -- Network isolation -- Resource limits - -### 2. Data Security - -**Volume Security**: -- Proper file permissions -- Regular backup procedures -- Encryption at rest - -**Network Security**: -- TLS/SSL configuration -- Network segmentation -- Access control - -## Integration with Attack Node Platform - -### 1. API Integration - -Empire health status is integrated with the main platform: -- Health status API endpoints -- Real-time monitoring dashboard -- Automated recovery reporting - -### 2. User Interface Integration - -The web interface provides: -- Empire status monitoring -- One-click recovery actions -- Log viewing capabilities -- Performance metrics - -## Future Enhancements - -### 1. Advanced Monitoring - -**Planned Features**: -- Machine learning-based anomaly detection -- Predictive failure analysis -- Performance trend analysis -- Automated optimization suggestions - -### 2. Enhanced Recovery - -**Planned Improvements**: -- Multi-stage recovery strategies -- Backup and restore capabilities -- Configuration versioning -- Rollback mechanisms - -### 3. Integration Improvements - -**Planned Enhancements**: -- Better dashboard integration -- Enhanced API monitoring -- Improved user notifications -- Advanced reporting capabilities - -## Conclusion - -The Empire self-healing solution provides: - -1. **Robust Health Monitoring**: Continuous monitoring with multiple health indicators -2. **Automatic Recovery**: Progressive recovery strategies for different failure types -3. **Comprehensive Logging**: Detailed logging for troubleshooting and analysis -4. **Performance Optimization**: Resource management and performance tuning -5. **Security**: Proper security measures and access controls -6. **Integration**: Seamless integration with the Attack Node platform - -This solution ensures Empire C2 framework reliability and availability while providing administrators with the tools needed for effective management and troubleshooting. - -The self-healing system operates transparently in the background, automatically detecting and resolving issues while maintaining detailed logs for audit and analysis purposes. diff --git a/client/src/pages/container-management.tsx b/client/src/pages/container-management.tsx index b9e84c5..59fc489 100644 --- a/client/src/pages/container-management.tsx +++ b/client/src/pages/container-management.tsx @@ -34,7 +34,6 @@ const getContainerIcon = (config: any) => { const iconMap: any = { kali: Shield, vscode: Code, - empire: Crown, bbot: Search, maltego: Network, postgres: Database, diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index b19b473..bf75322 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -93,7 +93,7 @@ services: start_period: 60s attacknode-vscode: - image: kasmweb/vs-code:1.17.0 + image: kasmweb/vs-code:1.17.0-rolling-weekly restart: unless-stopped ports: - "6903:6901" @@ -111,38 +111,9 @@ services: retries: 3 start_period: 30s - empire-data: - image: bcsecurity/empire:latest - restart: "no" - volumes: - - empire_data:/empire - command: ["true"] - networks: - - attack-node - - attacknode-empire: - image: bcsecurity/empire:latest - restart: unless-stopped - ports: - - "1337:1337" - - "5000:5000" - volumes_from: - - empire-data - depends_on: - - empire-data - stdin_open: true - tty: true - networks: - - attack-node - healthcheck: - test: ["CMD", "pgrep", "-f", "empire"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s attacknode-maltego: - image: kasmweb/maltego:1.17.0-rolling-daily + image: kasmweb/maltego:1.17.0-rolling-weekly restart: unless-stopped ports: - "6904:6901" @@ -165,4 +136,3 @@ networks: volumes: postgres_data: redis_data: - empire_data: diff --git a/docker-compose.yml b/docker-compose.yml index 134a8a1..fd1129f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -70,7 +70,7 @@ services: start_period: 60s attacknode-vscode: - image: kasmweb/vs-code:1.17.0 + image: kasmweb/vs-code:1.17.0-rolling-weekly restart: unless-stopped ports: - "6903:6901" @@ -86,34 +86,9 @@ services: retries: 3 start_period: 30s - empire-data: - image: bcsecurity/empire:latest - restart: "no" - volumes: - - empire_data:/empire - command: ["true"] - - attacknode-empire: - image: bcsecurity/empire:latest - restart: unless-stopped - ports: - - "1337:1337" - - "5000:5000" - volumes_from: - - empire-data - depends_on: - - empire-data - stdin_open: true - tty: true - healthcheck: - test: ["CMD", "pgrep", "-f", "empire"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s attacknode-maltego: - image: kasmweb/maltego:1.17.0-rolling-daily + image: kasmweb/maltego:1.17.0-rolling-weekly restart: unless-stopped ports: - "6904:6901" @@ -130,4 +105,3 @@ services: volumes: postgres_data: redis_data: - empire_data: diff --git a/AUTO_STARTUP_CONFIGURATION_SUMMARY.md b/docs/AUTO_STARTUP_CONFIGURATION_SUMMARY.md similarity index 100% rename from AUTO_STARTUP_CONFIGURATION_SUMMARY.md rename to docs/AUTO_STARTUP_CONFIGURATION_SUMMARY.md diff --git a/DEPLOYMENT_GUIDE.md b/docs/DEPLOYMENT_GUIDE.md similarity index 100% rename from DEPLOYMENT_GUIDE.md rename to docs/DEPLOYMENT_GUIDE.md diff --git a/DJANGO_SELF_HEALING_SOLUTION.md b/docs/DJANGO_SELF_HEALING_SOLUTION.md similarity index 100% rename from DJANGO_SELF_HEALING_SOLUTION.md rename to docs/DJANGO_SELF_HEALING_SOLUTION.md diff --git a/DNS_SELF_HEALING_SOLUTION.md b/docs/DNS_SELF_HEALING_SOLUTION.md similarity index 100% rename from DNS_SELF_HEALING_SOLUTION.md rename to docs/DNS_SELF_HEALING_SOLUTION.md diff --git a/ENHANCED_DJANGO_SELF_HEALING_SOLUTION.md b/docs/ENHANCED_DJANGO_SELF_HEALING_SOLUTION.md similarity index 100% rename from ENHANCED_DJANGO_SELF_HEALING_SOLUTION.md rename to docs/ENHANCED_DJANGO_SELF_HEALING_SOLUTION.md diff --git a/IMPLEMENTATION_SUMMARY.md b/docs/IMPLEMENTATION_SUMMARY.md similarity index 100% rename from IMPLEMENTATION_SUMMARY.md rename to docs/IMPLEMENTATION_SUMMARY.md diff --git a/NETWORK_SELF_HEALING_SOLUTION.md b/docs/NETWORK_SELF_HEALING_SOLUTION.md similarity index 100% rename from NETWORK_SELF_HEALING_SOLUTION.md rename to docs/NETWORK_SELF_HEALING_SOLUTION.md diff --git a/REDIS_SELF_HEALING_SOLUTION.md b/docs/REDIS_SELF_HEALING_SOLUTION.md similarity index 100% rename from REDIS_SELF_HEALING_SOLUTION.md rename to docs/REDIS_SELF_HEALING_SOLUTION.md diff --git a/SELF_HEALING_IMPLEMENTATION_SUMMARY.md b/docs/SELF_HEALING_IMPLEMENTATION_SUMMARY.md similarity index 100% rename from SELF_HEALING_IMPLEMENTATION_SUMMARY.md rename to docs/SELF_HEALING_IMPLEMENTATION_SUMMARY.md diff --git a/fix-empire-container.sh b/fix-empire-container.sh deleted file mode 100755 index d80db1b..0000000 --- a/fix-empire-container.sh +++ /dev/null @@ -1,703 +0,0 @@ -#!/bin/bash - -# Empire Container Troubleshooting & Self-Healing Script -# This script provides comprehensive Empire container diagnosis and repair - -set -e - -echo "🏴‍☠️ Empire Container Troubleshooting & Self-Healing System" -echo "===========================================================" -echo "" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -MAGENTA='\033[0;35m' -NC='\033[0m' # No Color - -# Configuration -CONTAINER_NAME="attacknode-empire" -DATA_CONTAINER="empire-data" -EMPIRE_IMAGE="bcsecurity/empire:latest" -API_PORT="1337" -STARKILLER_PORT="5000" -LOG_FILE="logs/empire-container-repair.log" -MAX_RETRIES=3 -STARTUP_TIMEOUT=180 - -# Function to print colored output -print_status() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_empire() { - echo -e "${MAGENTA}[EMPIRE]${NC} $1" -} - -print_docker() { - echo -e "${CYAN}[DOCKER]${NC} $1" -} - -# Enhanced logging function -log_message() { - local level=$1 - local message=$2 - local timestamp=$(date '+%Y-%m-%d %H:%M:%S') - - # Create logs directory if it doesn't exist - mkdir -p logs - - # Log to file - echo "[$timestamp] [$level] $message" >> "$LOG_FILE" - - # Also print to console - case $level in - "INFO") print_status "$message" ;; - "SUCCESS") print_success "$message" ;; - "WARNING") print_warning "$message" ;; - "ERROR") print_error "$message" ;; - "EMPIRE") print_empire "$message" ;; - "DOCKER") print_docker "$message" ;; - esac -} - -# Check if running as root or with sudo access -check_permissions() { - log_message "INFO" "Checking permissions..." - - if ! docker info >/dev/null 2>&1; then - if ! sudo docker info >/dev/null 2>&1; then - log_message "ERROR" "Cannot access Docker daemon. Please ensure Docker is running and you have proper permissions." - exit 1 - else - log_message "WARNING" "Using sudo for Docker commands" - DOCKER_CMD="sudo docker" - fi - else - DOCKER_CMD="docker" - fi - - log_message "SUCCESS" "Docker access confirmed" -} - -# Check system resources -check_system_resources() { - log_message "INFO" "Checking system resources..." - - # Check available memory - local available_memory=$(free -m | awk 'NR==2{printf "%.1f", $7/1024 }') - if (( $(echo "$available_memory < 1.0" | bc -l) )); then - log_message "WARNING" "Low available memory: ${available_memory}GB" - else - log_message "SUCCESS" "Available memory: ${available_memory}GB" - fi - - # Check disk space - local disk_usage=$(df -h / | awk 'NR==2{print $5}' | sed 's/%//') - if [ "$disk_usage" -gt 90 ]; then - log_message "WARNING" "High disk usage: ${disk_usage}%" - else - log_message "SUCCESS" "Disk usage: ${disk_usage}%" - fi - - # Check CPU load - local cpu_load=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//') - log_message "INFO" "CPU load average: $cpu_load" -} - -# Check port availability -check_port_availability() { - log_message "INFO" "Checking port availability..." - - local ports=("$API_PORT" "$STARKILLER_PORT") - - for port in "${ports[@]}"; do - if netstat -tlnp 2>/dev/null | grep -q ":$port "; then - local process=$(netstat -tlnp 2>/dev/null | grep ":$port " | awk '{print $7}' | head -1) - log_message "WARNING" "Port $port is in use by: $process" - else - log_message "SUCCESS" "Port $port is available" - fi - done -} - -# Get container status -get_container_status() { - local container_name=$1 - - if $DOCKER_CMD ps -a --format "{{.Names}}" | grep -q "^${container_name}$"; then - local status=$($DOCKER_CMD ps -a --filter "name=${container_name}" --format "{{.Status}}") - echo "$status" - else - echo "not_found" - fi -} - -# Get container logs -get_container_logs() { - local container_name=$1 - local lines=${2:-50} - - if $DOCKER_CMD ps -a --format "{{.Names}}" | grep -q "^${container_name}$"; then - $DOCKER_CMD logs "$container_name" --tail "$lines" 2>&1 - else - echo "Container not found" - fi -} - -# Analyze container exit reason -analyze_container_exit() { - local container_name=$1 - - log_message "INFO" "Analyzing container exit reason..." - - if $DOCKER_CMD ps -a --format "{{.Names}}" | grep -q "^${container_name}$"; then - local exit_code=$($DOCKER_CMD inspect "$container_name" --format "{{.State.ExitCode}}") - local exit_reason=$($DOCKER_CMD inspect "$container_name" --format "{{.State.Error}}") - local finished_at=$($DOCKER_CMD inspect "$container_name" --format "{{.State.FinishedAt}}") - - log_message "INFO" "Container exit code: $exit_code" - log_message "INFO" "Container finished at: $finished_at" - - if [ -n "$exit_reason" ] && [ "$exit_reason" != "" ]; then - log_message "ERROR" "Container exit reason: $exit_reason" - fi - - # Analyze exit code - case $exit_code in - 0) log_message "SUCCESS" "Container exited normally" ;; - 1) log_message "ERROR" "Container exited with general error" ;; - 125) log_message "ERROR" "Docker daemon error" ;; - 126) log_message "ERROR" "Container command not executable" ;; - 127) log_message "ERROR" "Container command not found" ;; - 130) log_message "WARNING" "Container terminated by SIGINT" ;; - 137) log_message "WARNING" "Container killed by SIGKILL (OOM or manual)" ;; - 143) log_message "WARNING" "Container terminated by SIGTERM" ;; - *) log_message "WARNING" "Container exited with code: $exit_code" ;; - esac - else - log_message "ERROR" "Container not found for analysis" - fi -} - -# Comprehensive container diagnostics -diagnose_container() { - log_message "INFO" "Running comprehensive container diagnostics..." - echo "" - - # Check Empire main container - print_status "Empire Main Container Status:" - echo "==============================" - - local main_status=$(get_container_status "$CONTAINER_NAME") - echo "Status: $main_status" - - if [ "$main_status" != "not_found" ]; then - if [[ "$main_status" == *"Up"* ]]; then - print_success "Empire container is running" - else - print_error "Empire container is not running" - analyze_container_exit "$CONTAINER_NAME" - fi - else - print_error "Empire container not found" - fi - echo "" - - # Check Empire data container - print_status "Empire Data Container Status:" - echo "============================" - - local data_status=$(get_container_status "$DATA_CONTAINER") - echo "Status: $data_status" - - if [ "$data_status" != "not_found" ]; then - print_success "Empire data container exists" - else - print_warning "Empire data container not found" - fi - echo "" - - # Check container logs - print_status "Recent Container Logs:" - echo "=====================" - - local logs=$(get_container_logs "$CONTAINER_NAME" 20) - echo "$logs" - echo "" - - # Check resource usage - print_status "Container Resource Usage:" - echo "========================" - - if [[ "$main_status" == *"Up"* ]]; then - $DOCKER_CMD stats "$CONTAINER_NAME" --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}" 2>/dev/null || echo "Stats not available" - else - echo "Container not running - no stats available" - fi - echo "" - - # Check Empire-specific diagnostics - check_empire_health -} - -# Check Empire application health -check_empire_health() { - print_status "Empire Application Health:" - echo "=========================" - - # Check if API is responding - echo -n "API Health (port $API_PORT): " - - # Try multiple Empire API endpoints - local api_healthy=false - local endpoints=("http://localhost:$API_PORT/api/admin/users" "http://localhost:$API_PORT/api/users" "http://localhost:$API_PORT/api/" "http://localhost:$API_PORT/") - - for endpoint in "${endpoints[@]}"; do - if curl -s -I "$endpoint" --max-time 5 2>/dev/null | grep -E "HTTP/1.1 (200|401|403)" >/dev/null; then - api_healthy=true - break - fi - done - - # Fallback: check if Empire process is running - if [ "$api_healthy" = false ]; then - if $DOCKER_CMD exec "$CONTAINER_NAME" pgrep -f "empire" >/dev/null 2>&1; then - api_healthy=true - fi - fi - - if [ "$api_healthy" = true ]; then - print_success "OK" - else - print_error "FAILED" - fi - - # Check if Starkiller is responding - echo -n "Starkiller Health (port $STARKILLER_PORT): " - if curl -s -f "http://localhost:$STARKILLER_PORT" --max-time 5 >/dev/null 2>&1; then - print_success "OK" - else - print_error "FAILED" - fi - - # Check Empire database - echo -n "Database Health: " - if $DOCKER_CMD exec "$CONTAINER_NAME" ls -la /empire/empire.db >/dev/null 2>&1; then - print_success "OK" - else - print_error "FAILED" - fi - - # Check Empire processes - echo -n "Empire Processes: " - if $DOCKER_CMD exec "$CONTAINER_NAME" pgrep -f "empire" >/dev/null 2>&1; then - print_success "OK" - else - print_error "FAILED" - fi - - echo "" -} - -# Complete container cleanup -complete_cleanup() { - log_message "INFO" "Performing complete container cleanup..." - - # Stop containers - log_message "INFO" "Stopping Empire containers..." - $DOCKER_CMD stop "$CONTAINER_NAME" --time 10 2>/dev/null || true - $DOCKER_CMD stop "$DATA_CONTAINER" --time 10 2>/dev/null || true - - # Remove containers - log_message "INFO" "Removing Empire containers..." - $DOCKER_CMD rm -f "$CONTAINER_NAME" 2>/dev/null || true - $DOCKER_CMD rm -f "$DATA_CONTAINER" 2>/dev/null || true - - # Clean up any Empire-related containers - log_message "INFO" "Cleaning up orphaned Empire containers..." - $DOCKER_CMD rm -f $($DOCKER_CMD ps -aq --filter "name=empire") 2>/dev/null || true - - # Clean up unused containers - $DOCKER_CMD container prune -f 2>/dev/null || true - - log_message "SUCCESS" "Container cleanup completed" -} - -# Setup Empire volumes -setup_volumes() { - log_message "INFO" "Setting up Empire volumes..." - - local volume_dirs=( - "uploads/empire/data" - "uploads/empire/downloads" - "uploads/empire/logs" - ) - - for dir in "${volume_dirs[@]}"; do - if [ ! -d "$dir" ]; then - mkdir -p "$dir" - chmod 755 "$dir" - log_message "INFO" "Created volume directory: $dir" - else - log_message "INFO" "Volume directory exists: $dir" - fi - done - - log_message "SUCCESS" "Empire volumes setup completed" -} - -# Start Empire container with retry logic -start_empire_container() { - log_message "INFO" "Starting Empire container with retry logic..." - - local attempt=1 - - while [ $attempt -le $MAX_RETRIES ]; do - log_message "INFO" "Start attempt $attempt of $MAX_RETRIES" - - if [ $attempt -gt 1 ]; then - log_message "INFO" "Waiting 10 seconds before retry..." - sleep 10 - fi - - # Try to start Empire container - if start_empire_container_single; then - log_message "SUCCESS" "Empire container started successfully" - return 0 - else - log_message "ERROR" "Empire container start attempt $attempt failed" - ((attempt++)) - fi - done - - log_message "ERROR" "Failed to start Empire container after $MAX_RETRIES attempts" - return 1 -} - -# Start Empire container (single attempt) -start_empire_container_single() { - # Step 1: Pull Empire image - log_message "INFO" "Pulling Empire image..." - if ! $DOCKER_CMD pull "$EMPIRE_IMAGE"; then - log_message "ERROR" "Failed to pull Empire image" - return 1 - fi - - # Step 2: Create data container - log_message "INFO" "Creating Empire data container..." - if ! $DOCKER_CMD create -v /empire --name "$DATA_CONTAINER" "$EMPIRE_IMAGE" >/dev/null 2>&1; then - log_message "ERROR" "Failed to create Empire data container" - return 1 - fi - - # Step 3: Start main container - log_message "INFO" "Starting Empire main container..." - if ! $DOCKER_CMD run -d -it \ - --name "$CONTAINER_NAME" \ - --restart unless-stopped \ - -p "$API_PORT:$API_PORT" \ - -p "$STARKILLER_PORT:$STARKILLER_PORT" \ - --volumes-from "$DATA_CONTAINER" \ - "$EMPIRE_IMAGE" >/dev/null 2>&1; then - log_message "ERROR" "Failed to start Empire main container" - return 1 - fi - - # Step 4: Wait for container to be ready - if wait_for_container_ready; then - return 0 - else - return 1 - fi -} - -# Wait for container to be ready -wait_for_container_ready() { - log_message "INFO" "Waiting for Empire container to be ready..." - - local start_time=$(date +%s) - local timeout=$STARTUP_TIMEOUT - - while [ $(($(date +%s) - start_time)) -lt $timeout ]; do - # Check if container is running - if ! $DOCKER_CMD ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}" | grep -q "Up"; then - log_message "WARNING" "Container stopped unexpectedly" - return 1 - fi - - # Check Empire startup indicators - local logs=$(get_container_logs "$CONTAINER_NAME" 50) - - if echo "$logs" | grep -q "Application startup complete" && \ - echo "$logs" | grep -q "Uvicorn running on"; then - log_message "SUCCESS" "Empire container is ready" - return 0 - fi - - # Check for startup errors - if echo "$logs" | grep -qi "error\|exception\|failed"; then - log_message "ERROR" "Empire startup errors detected" - return 1 - fi - - sleep 5 - done - - log_message "ERROR" "Empire container failed to become ready within timeout" - return 1 -} - -# Test Empire functionality -test_empire_functionality() { - log_message "INFO" "Testing Empire functionality..." - - # Test API endpoint - log_message "INFO" "Testing Empire API..." - local api_attempts=20 - local api_attempt=1 - - while [ $api_attempt -le $api_attempts ]; do - if curl -s -f "http://localhost:$API_PORT/api/version" --max-time 5 >/dev/null 2>&1; then - log_message "SUCCESS" "Empire API is responding" - break - fi - - if [ $api_attempt -eq $api_attempts ]; then - log_message "WARNING" "Empire API not responding (this may be normal during initialization)" - fi - - sleep 5 - ((api_attempt++)) - done - - # Test Starkiller UI - log_message "INFO" "Testing Starkiller UI..." - if curl -s -f "http://localhost:$STARKILLER_PORT" --max-time 5 >/dev/null 2>&1; then - log_message "SUCCESS" "Starkiller UI is accessible" - else - log_message "WARNING" "Starkiller UI not accessible (this may be normal during initialization)" - fi - - # Test container health - log_message "INFO" "Testing container health..." - if $DOCKER_CMD ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}" | grep -q "Up"; then - log_message "SUCCESS" "Empire container is running" - else - log_message "ERROR" "Empire container is not running" - fi -} - -# Display comprehensive status -display_status() { - echo "" - echo "==========================================" - print_status "Empire Container Status Report" - echo "==========================================" - echo "" - - # Container status - echo "Container Status:" - echo "================" - $DOCKER_CMD ps -a --filter "name=empire" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || echo "No Empire containers found" - echo "" - - # Network status - echo "Network Status:" - echo "==============" - netstat -tlnp 2>/dev/null | grep -E ":$API_PORT|:$STARKILLER_PORT" || echo "No Empire ports active" - echo "" - - # Recent logs - echo "Recent Logs (last 10 lines):" - echo "============================" - get_container_logs "$CONTAINER_NAME" 10 - echo "" - - # Resource usage - echo "Resource Usage:" - echo "==============" - if $DOCKER_CMD ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}" | grep -q "Up"; then - $DOCKER_CMD stats "$CONTAINER_NAME" --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}" 2>/dev/null || echo "Stats not available" - else - echo "Container not running - no stats available" - fi - echo "" -} - -# Create Empire recovery script -create_recovery_script() { - log_message "INFO" "Creating Empire recovery script..." - - cat > empire-recovery.sh << 'EOF' -#!/bin/bash -# Emergency Empire Recovery Script - -echo "🚨 Emergency Empire Recovery" -echo "==========================" - -# Stop and remove all Empire containers -echo "Stopping Empire containers..." -sudo docker stop attacknode-empire empire-data 2>/dev/null || true - -echo "Removing Empire containers..." -sudo docker rm -f attacknode-empire empire-data 2>/dev/null || true - -# Clean up -echo "Cleaning up..." -sudo docker container prune -f 2>/dev/null || true - -echo "Starting Empire recovery..." -./fix-empire-container.sh --repair - -echo "Emergency recovery completed!" -EOF - - chmod +x empire-recovery.sh - log_message "SUCCESS" "Emergency recovery script created: empire-recovery.sh" -} - -# Main function -main() { - case "${1:-}" in - --diagnose|-d) - check_permissions - check_system_resources - check_port_availability - diagnose_container - ;; - --repair|-r) - check_permissions - log_message "INFO" "Starting Empire container repair..." - complete_cleanup - setup_volumes - if start_empire_container; then - test_empire_functionality - display_status - log_message "SUCCESS" "Empire container repair completed successfully" - else - log_message "ERROR" "Empire container repair failed" - exit 1 - fi - ;; - --cleanup|-c) - check_permissions - complete_cleanup - ;; - --restart|-restart) - check_permissions - log_message "INFO" "Restarting Empire container..." - $DOCKER_CMD restart "$CONTAINER_NAME" 2>/dev/null || true - wait_for_container_ready - test_empire_functionality - ;; - --logs|-l) - check_permissions - echo "Empire Container Logs:" - echo "=====================" - get_container_logs "$CONTAINER_NAME" 100 - ;; - --status|-s) - check_permissions - display_status - ;; - --recovery|-recovery) - create_recovery_script - ;; - --help|-h) - echo "Empire Container Troubleshooting & Self-Healing System" - echo "" - echo "Usage: $0 [OPTIONS]" - echo "" - echo "Options:" - echo " --diagnose, -d Run comprehensive container diagnostics" - echo " --repair, -r Repair Empire container issues" - echo " --cleanup, -c Clean up Empire containers" - echo " --restart Restart Empire container" - echo " --logs, -l Show Empire container logs" - echo " --status, -s Show Empire container status" - echo " --recovery Create emergency recovery script" - echo " --help, -h Show this help message" - echo "" - echo "Examples:" - echo " $0 --diagnose # Run full diagnostics" - echo " $0 --repair # Repair container issues" - echo " $0 --restart # Restart Empire container" - echo " $0 --status # Show status" - echo "" - exit 0 - ;; - "") - # Default: run diagnostics and repair if needed - echo "Running Empire container diagnostics and repair..." - echo "" - - # Clear log file - > "$LOG_FILE" - - # Check permissions - check_permissions - - # Check system resources - check_system_resources - - # Check port availability - check_port_availability - - # Run diagnostics - diagnose_container - - # Check if repair is needed - local main_status=$(get_container_status "$CONTAINER_NAME") - if [ "$main_status" = "not_found" ] || [[ "$main_status" != *"Up"* ]]; then - echo "" - print_warning "Empire container issues detected. Attempting repair..." - complete_cleanup - setup_volumes - if start_empire_container; then - test_empire_functionality - else - print_error "Empire container repair failed" - exit 1 - fi - else - print_success "Empire container is healthy" - fi - - # Display final status - display_status - - # Create recovery script - create_recovery_script - - echo "" - log_message "SUCCESS" "Empire container troubleshooting completed" - echo "Log file: $LOG_FILE" - echo "Recovery script: empire-recovery.sh" - echo "" - ;; - *) - echo "Unknown option: $1" - echo "Use --help for usage information" - exit 1 - ;; - esac -} - -# Run main function -main "$@" diff --git a/install-empire-enhanced.sh b/install-empire-enhanced.sh deleted file mode 100755 index 30ce88a..0000000 --- a/install-empire-enhanced.sh +++ /dev/null @@ -1,694 +0,0 @@ -#!/bin/bash - -# Enhanced Empire Installation Script with Network Self-Healing -# This script implements robust Empire deployment with network error recovery - -set -e - -echo "🔥 Enhanced Empire Installation Script with Network Self-Healing" -echo "===============================================================" -echo "" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Configuration -MAX_RETRIES=5 -RETRY_DELAY=5 -PULL_TIMEOUT=300 -NETWORK_CHECK_TIMEOUT=30 - -# Function to print colored output -print_status() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_network() { - echo -e "${CYAN}[NETWORK]${NC} $1" -} - -# Function to wait for user input -wait_for_input() { - echo -e "${YELLOW}Press Enter to continue...${NC}" - read -r -} - -# Enhanced logging function -log_message() { - local level=$1 - local message=$2 - local timestamp=$(date '+%Y-%m-%d %H:%M:%S') - - # Create logs directory if it doesn't exist - mkdir -p logs - - # Log to file - echo "[$timestamp] [$level] $message" >> logs/empire-install.log - - # Also print to console - case $level in - "INFO") print_status "$message" ;; - "SUCCESS") print_success "$message" ;; - "WARNING") print_warning "$message" ;; - "ERROR") print_error "$message" ;; - "NETWORK") print_network "$message" ;; - esac -} - -# Check if Docker is available -check_docker() { - log_message "INFO" "Checking Docker availability..." - - if ! command -v docker &> /dev/null; then - log_message "ERROR" "Docker is not installed or not in PATH" - exit 1 - fi - - if ! docker info &> /dev/null 2>&1; then - log_message "ERROR" "Docker daemon is not running" - exit 1 - fi - - log_message "SUCCESS" "Docker is available and running" -} - -# Check internet connectivity -check_internet() { - log_message "NETWORK" "Checking internet connectivity..." - - local test_urls=( - "https://www.google.com" - "https://1.1.1.1" - "https://8.8.8.8" - ) - - for url in "${test_urls[@]}"; do - if curl -s -f --max-time 5 "$url" > /dev/null 2>&1; then - log_message "SUCCESS" "Internet connectivity confirmed" - return 0 - fi - done - - log_message "ERROR" "No internet connectivity detected" - return 1 -} - -# Check DNS resolution -check_dns() { - log_message "NETWORK" "Checking DNS resolution..." - - local domains=( - "registry-1.docker.io" - "docker.io" - "github.com" - ) - - for domain in "${domains[@]}"; do - if nslookup "$domain" > /dev/null 2>&1; then - log_message "SUCCESS" "DNS resolution working" - return 0 - fi - done - - log_message "ERROR" "DNS resolution failed" - return 1 -} - -# Check Docker Hub connectivity -check_docker_hub() { - log_message "NETWORK" "Checking Docker Hub connectivity..." - - local registry_endpoints=( - "https://registry-1.docker.io/v2/" - "https://index.docker.io/v1/" - ) - - for endpoint in "${registry_endpoints[@]}"; do - if curl -s -f --max-time 10 "$endpoint" > /dev/null 2>&1; then - log_message "SUCCESS" "Docker Hub is reachable" - return 0 - fi - done - - log_message "WARNING" "Docker Hub may be unreachable" - return 1 -} - -# Network diagnostics and repair -repair_network() { - log_message "NETWORK" "Attempting comprehensive network repair..." - - # Use enhanced DNS repair script if available - if [ -f "fix-dns-resolution.sh" ]; then - log_message "NETWORK" "Using enhanced DNS repair system..." - - # Run DNS repair with auto-repair mode - if ./fix-dns-resolution.sh --auto-repair; then - log_message "SUCCESS" "Enhanced DNS repair successful" - - # Verify network recovery - if check_internet && check_dns; then - log_message "SUCCESS" "Network repair successful" - return 0 - fi - else - log_message "WARNING" "Enhanced DNS repair failed, trying fallback..." - fi - fi - - # Fallback to basic repair if enhanced repair isn't available or failed - log_message "NETWORK" "Using fallback DNS repair..." - - # Flush DNS cache - log_message "NETWORK" "Flushing DNS cache..." - sudo systemctl restart systemd-resolved 2>/dev/null || \ - sudo /etc/init.d/dns-clean restart 2>/dev/null || \ - sudo dscacheutil -flushcache 2>/dev/null || \ - log_message "WARNING" "Could not flush DNS cache" - - # Add reliable DNS servers - log_message "NETWORK" "Adding reliable DNS servers..." - local dns_servers=("8.8.8.8" "1.1.1.1" "9.9.9.9") - - # Backup original resolv.conf - sudo cp /etc/resolv.conf /etc/resolv.conf.backup.$(date +%s) 2>/dev/null || true - - # Add DNS servers - for dns in "${dns_servers[@]}"; do - if ! grep -q "nameserver $dns" /etc/resolv.conf 2>/dev/null; then - echo "nameserver $dns" | sudo tee -a /etc/resolv.conf > /dev/null 2>&1 || true - fi - done - - # Wait for DNS changes to take effect - sleep 3 - - # Verify network recovery - if check_internet && check_dns; then - log_message "SUCCESS" "Network repair successful" - return 0 - else - log_message "ERROR" "Network repair failed" - return 1 - fi -} - -# Enhanced Docker image pull with retry and network repair -pull_empire_image() { - log_message "INFO" "Pulling Empire image with enhanced retry logic..." - - local image_name="bcsecurity/empire:latest" - local attempt=1 - - while [ $attempt -le $MAX_RETRIES ]; do - log_message "INFO" "Pull attempt $attempt of $MAX_RETRIES for $image_name" - - # Calculate exponential backoff delay - local backoff_delay=$((RETRY_DELAY * (2 ** (attempt - 1)))) - - if [ $attempt -gt 1 ]; then - log_message "INFO" "Waiting ${backoff_delay}s before retry..." - sleep $backoff_delay - fi - - # Try different pull strategies - local pull_commands=( - "docker pull $image_name" - "docker pull $image_name --disable-content-trust" - "docker pull $image_name --platform linux/amd64" - ) - - for cmd in "${pull_commands[@]}"; do - log_message "INFO" "Trying: $cmd" - - if timeout $PULL_TIMEOUT $cmd 2>&1 | tee -a logs/empire-install.log; then - log_message "SUCCESS" "Successfully pulled $image_name" - return 0 - else - log_message "WARNING" "Pull command failed: $cmd" - fi - done - - # If we're halfway through retries, attempt network repair - if [ $attempt -eq $((MAX_RETRIES / 2)) ]; then - log_message "INFO" "Attempting network repair mid-retry..." - repair_network || log_message "WARNING" "Network repair failed, continuing with retries" - fi - - ((attempt++)) - done - - log_message "ERROR" "Failed to pull Empire image after $MAX_RETRIES attempts" - return 1 -} - -# Check for existing Empire installations -check_existing_empire() { - log_message "INFO" "Checking for existing Empire installations..." - - local containers_found=false - - # Check for containers - if docker ps -a --filter "name=attacknode-empire" --format "{{.Names}}" | grep -q "attacknode-empire"; then - log_message "WARNING" "Found existing Empire container" - containers_found=true - fi - - if docker ps -a --filter "name=empire-data" --format "{{.Names}}" | grep -q "empire-data"; then - log_message "WARNING" "Found existing Empire data container" - containers_found=true - fi - - if [ "$containers_found" = true ]; then - echo "" - log_message "WARNING" "Existing Empire installation detected" - echo "This will remove existing containers and create new ones." - echo "All data will be preserved in the data container." - echo "" - echo "Continue? (y/N)" - read -r response - - if [[ ! "$response" =~ ^[Yy]$ ]]; then - log_message "INFO" "Installation cancelled by user" - exit 0 - fi - fi -} - -# Clean up existing Empire containers -cleanup_existing() { - log_message "INFO" "Cleaning up existing Empire containers..." - - # Stop and remove main container - if docker ps -a --filter "name=attacknode-empire" --format "{{.Names}}" | grep -q "attacknode-empire"; then - log_message "INFO" "Stopping existing Empire container..." - docker stop attacknode-empire 2>/dev/null || true - docker rm attacknode-empire 2>/dev/null || true - log_message "SUCCESS" "Existing Empire container removed" - fi - - # Remove data container if requested - if docker ps -a --filter "name=empire-data" --format "{{.Names}}" | grep -q "empire-data"; then - log_message "INFO" "Removing existing Empire data container..." - docker rm empire-data 2>/dev/null || true - log_message "SUCCESS" "Existing Empire data container removed" - fi - - # Clean up any orphaned containers - log_message "INFO" "Cleaning up orphaned containers..." - docker container prune -f 2>/dev/null || true -} - -# Network health pre-check -network_health_check() { - log_message "NETWORK" "Performing comprehensive network health check..." - - local health_checks=( - "check_internet" - "check_dns" - "check_docker_hub" - ) - - local failed_checks=0 - - for check in "${health_checks[@]}"; do - if ! $check; then - ((failed_checks++)) - fi - done - - if [ $failed_checks -gt 0 ]; then - log_message "WARNING" "$failed_checks network health checks failed" - log_message "INFO" "Attempting network repair..." - - if repair_network; then - log_message "SUCCESS" "Network issues resolved" - else - log_message "ERROR" "Network issues persist, installation may fail" - echo "" - echo "Network issues detected. Continue anyway? (y/N)" - read -r response - - if [[ ! "$response" =~ ^[Yy]$ ]]; then - log_message "INFO" "Installation cancelled due to network issues" - exit 1 - fi - fi - else - log_message "SUCCESS" "All network health checks passed" - fi -} - -# Create Empire containers with data persistence -create_empire_containers() { - log_message "INFO" "Creating Empire containers with data persistence..." - - # Step 1: Create data container - log_message "INFO" "Creating Empire data container..." - if docker create -v /empire --name empire-data bcsecurity/empire:latest; then - log_message "SUCCESS" "Empire data container created successfully" - else - log_message "ERROR" "Failed to create Empire data container" - return 1 - fi - - # Step 2: Start main container - log_message "INFO" "Starting Empire main container..." - if docker run -d -it \ - --name attacknode-empire \ - --restart unless-stopped \ - -p 1337:1337 \ - -p 5000:5000 \ - --volumes-from empire-data \ - bcsecurity/empire:latest; then - log_message "SUCCESS" "Empire main container started successfully" - else - log_message "ERROR" "Failed to start Empire main container" - return 1 - fi - - return 0 -} - -# Wait for Empire to initialize -wait_for_empire() { - log_message "INFO" "Waiting for Empire to initialize..." - - local max_wait=300 # 5 minutes - local check_interval=5 - local elapsed=0 - - while [ $elapsed -lt $max_wait ]; do - if docker ps --filter "name=attacknode-empire" --format "{{.Status}}" | grep -q "Up"; then - log_message "SUCCESS" "Empire container is running" - break - fi - - if [ $elapsed -eq $max_wait ]; then - log_message "ERROR" "Empire failed to start within timeout" - log_message "INFO" "Container logs:" - docker logs attacknode-empire 2>&1 | tail -20 | tee -a logs/empire-install.log - return 1 - fi - - sleep $check_interval - elapsed=$((elapsed + check_interval)) - - if [ $((elapsed % 30)) -eq 0 ]; then - log_message "INFO" "Still waiting... (${elapsed}s elapsed)" - fi - done - - # Additional wait for Empire services to fully initialize - log_message "INFO" "Waiting for Empire services to fully initialize..." - sleep 30 - - return 0 -} - -# Test Empire installation -test_empire() { - log_message "INFO" "Testing Empire installation..." - - # Test container status - if docker ps --filter "name=attacknode-empire" --format "{{.Names}}" | grep -q "attacknode-empire"; then - log_message "SUCCESS" "Empire container is running" - else - log_message "ERROR" "Empire container is not running" - return 1 - fi - - # Test API connectivity with retry - log_message "INFO" "Testing Empire API connectivity..." - local api_attempts=20 - local api_attempt=1 - - while [ $api_attempt -le $api_attempts ]; do - if curl -s -f --max-time 5 http://localhost:1337/api/version > /dev/null 2>&1; then - log_message "SUCCESS" "Empire API is responding" - break - fi - - if [ $api_attempt -eq $api_attempts ]; then - log_message "WARNING" "Empire API not responding yet (this may be normal during initialization)" - fi - - sleep 5 - ((api_attempt++)) - done - - # Test Starkiller UI - log_message "INFO" "Testing Starkiller UI connectivity..." - if curl -s -f --max-time 5 http://localhost:5000 > /dev/null 2>&1; then - log_message "SUCCESS" "Starkiller UI is accessible" - else - log_message "WARNING" "Starkiller UI not accessible yet (this may be normal during initialization)" - fi - - return 0 -} - -# Display comprehensive installation results -display_results() { - echo "" - echo "==========================================" - log_message "INFO" "Empire Installation Results" - echo "==========================================" - echo "" - - # Container status - echo "Container Status:" - docker ps --filter "name=attacknode-empire" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || echo "No containers found" - echo "" - - # Data container status - echo "Data Container Status:" - docker ps -a --filter "name=empire-data" --format "table {{.Names}}\t{{.Status}}" 2>/dev/null || echo "No data container found" - echo "" - - # Network status - echo "Network Status:" - netstat -tlnp 2>/dev/null | grep -E ':1337|:5000' || echo "No active ports found" - echo "" - - # Volume status - echo "Volume Status:" - docker inspect empire-data --format "{{.Mounts}}" 2>/dev/null || echo "Volume information unavailable" - echo "" - - # Recent logs - echo "Recent Logs (last 10 lines):" - docker logs attacknode-empire --tail 10 2>/dev/null || echo "No logs available" - echo "" - - # Resource usage - echo "Resource Usage:" - docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" attacknode-empire 2>/dev/null || echo "Stats unavailable" - echo "" -} - -# Create troubleshooting guide -create_troubleshooting_guide() { - log_message "INFO" "Creating troubleshooting guide..." - - cat > Empire_Troubleshooting_Guide.md << 'EOF' -# Empire Troubleshooting Guide - -## Common Issues and Solutions - -### 1. Container Not Starting -**Symptoms**: Empire container exits immediately -**Solutions**: -- Check logs: `docker logs attacknode-empire` -- Verify ports are available: `netstat -tlnp | grep -E ':1337|:5000'` -- Restart container: `docker restart attacknode-empire` - -### 2. API Not Responding -**Symptoms**: Cannot connect to http://localhost:1337 -**Solutions**: -- Wait for full initialization (can take 2-3 minutes) -- Check container status: `docker ps --filter "name=attacknode-empire"` -- Verify firewall settings: `sudo ufw status` - -### 3. Network Issues -**Symptoms**: TLS handshake timeout, DNS resolution failures -**Solutions**: -- Check internet connectivity: `ping 8.8.8.8` -- Verify DNS settings: `nslookup registry-1.docker.io` -- Run network repair: `./install-empire-enhanced.sh --network-repair` - -### 4. Data Container Issues -**Symptoms**: Data not persisting between restarts -**Solutions**: -- Check data container: `docker ps -a --filter "name=empire-data"` -- Verify volume mounts: `docker inspect empire-data` -- Recreate data container if needed - -## Manual Recovery Commands - -### Complete Reinstallation -```bash -# Stop and remove all Empire containers -docker stop attacknode-empire empire-data 2>/dev/null || true -docker rm attacknode-empire empire-data 2>/dev/null || true - -# Pull fresh image -docker pull bcsecurity/empire:latest - -# Recreate containers -docker create -v /empire --name empire-data bcsecurity/empire:latest -docker run -d -it --name attacknode-empire --restart unless-stopped \ - -p 1337:1337 -p 5000:5000 --volumes-from empire-data bcsecurity/empire:latest -``` - -### Network Diagnostics -```bash -# Check Docker Hub connectivity -curl -s -f --max-time 10 https://registry-1.docker.io/v2/ - -# Check DNS resolution -nslookup registry-1.docker.io - -# Check proxy settings -env | grep -i proxy -``` - -## Log Files -- Installation logs: `logs/empire-install.log` -- Container logs: `docker logs attacknode-empire` -- Network logs: `logs/network-health.log` - -## Support Resources -- Empire Documentation: https://bc-security.gitbook.io/empire-wiki/ -- Docker Documentation: https://docs.docker.com/ -- Network Troubleshooting: Check firewall, proxy, and DNS settings -EOF - - log_message "SUCCESS" "Troubleshooting guide created: Empire_Troubleshooting_Guide.md" -} - -# Main installation function -main() { - echo "Starting enhanced Empire installation with network self-healing..." - echo "" - - # Create logs directory - mkdir -p logs - - # Clear previous installation log - > logs/empire-install.log - - # Pre-installation checks - check_docker - check_existing_empire - - # Network health assessment and repair - network_health_check - - # Clean up existing installation - cleanup_existing - - # Enhanced image pull with retry - if ! pull_empire_image; then - log_message "ERROR" "Failed to pull Empire image" - log_message "INFO" "Check logs/empire-install.log for details" - exit 1 - fi - - # Create Empire containers - if ! create_empire_containers; then - log_message "ERROR" "Failed to create Empire containers" - exit 1 - fi - - # Wait for Empire to be ready - if ! wait_for_empire; then - log_message "ERROR" "Empire failed to initialize properly" - exit 1 - fi - - # Test installation - test_empire - - # Display results - display_results - - # Create troubleshooting guide - create_troubleshooting_guide - - echo "" - echo "🎉 Enhanced Empire Installation Complete!" - echo "========================================" - echo "" - log_message "SUCCESS" "Empire has been successfully installed with network self-healing capabilities" - log_message "INFO" "The installation includes robust error recovery and troubleshooting tools" - echo "" - log_message "INFO" "Access Empire:" - echo " - Empire API: http://localhost:1337" - echo " - Starkiller UI: http://localhost:5000" - echo "" - log_message "INFO" "Default Credentials:" - echo " - Username: empireadmin" - echo " - Password: password123" - echo "" - log_message "INFO" "Management Commands:" - echo " - View logs: docker logs attacknode-empire" - echo " - Restart: docker restart attacknode-empire" - echo " - Stop: docker stop attacknode-empire" - echo " - Remove: docker rm attacknode-empire empire-data" - echo "" - log_message "INFO" "Troubleshooting:" - echo " - Installation logs: logs/empire-install.log" - echo " - Troubleshooting guide: Empire_Troubleshooting_Guide.md" - echo " - Network repair: ./install-empire-enhanced.sh --network-repair" - echo "" - log_message "SUCCESS" "The self-healing system will automatically monitor and recover Empire" - echo "" -} - -# Handle command line arguments -case "${1:-}" in - --network-repair) - echo "🔧 Network Repair Mode" - echo "=====================" - repair_network - exit $? - ;; - --help|-h) - echo "Enhanced Empire Installation Script" - echo "" - echo "Usage: $0 [OPTIONS]" - echo "" - echo "Options:" - echo " --network-repair Run network diagnostics and repair" - echo " --help, -h Show this help message" - echo "" - exit 0 - ;; - "") - # Default installation - main "$@" - ;; - *) - echo "Unknown option: $1" - echo "Use --help for usage information" - exit 1 - ;; -esac diff --git a/install-empire.sh b/install-empire.sh deleted file mode 100755 index fcf9dd3..0000000 --- a/install-empire.sh +++ /dev/null @@ -1,258 +0,0 @@ -#!/bin/bash - -# Empire Installation Script -# This script implements the successful Empire deployment pattern using data containers - -set -e - -echo "🔥 Empire Installation Script" -echo "=============================" -echo "" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Function to print colored output -print_status() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# Check if Docker is available -check_docker() { - print_status "Checking Docker availability..." - - if ! command -v docker &> /dev/null; then - print_error "Docker is not installed or not in PATH" - exit 1 - fi - - if ! docker info &> /dev/null; then - print_error "Docker daemon is not running" - exit 1 - fi - - print_success "Docker is available and running" -} - -# Clean up any existing Empire containers -cleanup_existing() { - print_status "Cleaning up existing Empire containers..." - - # Stop and remove main container - if docker ps -a --filter "name=attacknode-empire" --format "{{.Names}}" | grep -q "attacknode-empire"; then - print_status "Stopping existing Empire container..." - docker stop attacknode-empire 2>/dev/null || true - docker rm attacknode-empire 2>/dev/null || true - print_success "Existing Empire container removed" - fi - - # Remove data container - if docker ps -a --filter "name=empire-data" --format "{{.Names}}" | grep -q "empire-data"; then - print_status "Removing existing Empire data container..." - docker rm empire-data 2>/dev/null || true - print_success "Existing Empire data container removed" - fi -} - -# Install Empire using data container pattern -install_empire() { - print_status "Installing Empire using data container pattern..." - - # Step 1: Pull the Empire image - print_status "Pulling Empire image..." - if docker pull bcsecurity/empire:latest; then - print_success "Empire image pulled successfully" - else - print_error "Failed to pull Empire image" - exit 1 - fi - - # Step 2: Create data container with persistent storage - print_status "Creating Empire data container..." - if docker create -v /empire --name empire-data bcsecurity/empire:latest; then - print_success "Empire data container created successfully" - else - print_error "Failed to create Empire data container" - exit 1 - fi - - # Step 3: Start main container with data container volumes - print_status "Starting Empire main container..." - if docker run -d -it \ - --name attacknode-empire \ - --restart unless-stopped \ - -p 1337:1337 \ - -p 5000:5000 \ - --volumes-from empire-data \ - bcsecurity/empire:latest; then - print_success "Empire main container started successfully" - else - print_error "Failed to start Empire main container" - exit 1 - fi -} - -# Wait for Empire to be ready -wait_for_empire() { - print_status "Waiting for Empire to initialize..." - - local max_attempts=30 - local attempt=1 - - while [ $attempt -le $max_attempts ]; do - print_status "Checking Empire status... (attempt $attempt/$max_attempts)" - - if docker ps --filter "name=attacknode-empire" --format "{{.Status}}" | grep -q "Up"; then - print_success "Empire container is running" - break - fi - - if [ $attempt -eq $max_attempts ]; then - print_error "Empire failed to start within timeout" - print_status "Container logs:" - docker logs attacknode-empire 2>&1 | tail -20 - return 1 - fi - - sleep 5 - ((attempt++)) - done - - # Additional wait for Empire services to initialize - print_status "Waiting for Empire services to initialize..." - sleep 15 -} - -# Test Empire installation -test_empire() { - print_status "Testing Empire installation..." - - # Test container status - if docker ps --filter "name=attacknode-empire" --format "{{.Names}}" | grep -q "attacknode-empire"; then - print_success "Empire container is running" - else - print_error "Empire container is not running" - return 1 - fi - - # Test API connectivity - print_status "Testing Empire API connectivity..." - local api_attempts=10 - local api_attempt=1 - - while [ $api_attempt -le $api_attempts ]; do - if curl -s -f --max-time 5 http://localhost:1337/api/version &> /dev/null; then - print_success "Empire API is responding" - break - fi - - if [ $api_attempt -eq $api_attempts ]; then - print_warning "Empire API not responding yet (this may be normal during initialization)" - fi - - sleep 3 - ((api_attempt++)) - done - - # Test Starkiller UI - print_status "Testing Starkiller UI connectivity..." - if curl -s -f --max-time 5 http://localhost:5000 &> /dev/null; then - print_success "Starkiller UI is accessible" - else - print_warning "Starkiller UI not accessible yet (this may be normal during initialization)" - fi -} - -# Display installation results -display_results() { - print_status "Empire Installation Results:" - echo "=============================" - echo "" - - # Container status - echo "Container Status:" - docker ps --filter "name=attacknode-empire" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null || echo "No containers found" - echo "" - - # Data container status - echo "Data Container Status:" - docker ps -a --filter "name=empire-data" --format "table {{.Names}}\t{{.Status}}" 2>/dev/null || echo "No data container found" - echo "" - - # Port status - echo "Port Status:" - netstat -tlnp 2>/dev/null | grep -E ':1337|:5000' || echo "No ports found" - echo "" - - # Recent logs - echo "Recent Logs (last 10 lines):" - docker logs attacknode-empire --tail 10 2>/dev/null || echo "No logs available" - echo "" -} - -# Main installation function -main() { - echo "Starting Empire installation..." - echo "" - - # Pre-installation checks - check_docker - - # Clean up existing installation - cleanup_existing - - # Install Empire - install_empire - - # Wait for Empire to be ready - wait_for_empire - - # Test installation - test_empire - - # Display results - display_results - - echo "" - echo "🎉 Empire Installation Complete!" - echo "=================================" - echo "" - print_success "Empire has been successfully installed and deployed" - print_status "The installation uses Docker data containers for persistent storage" - echo "" - print_status "Access Empire:" - echo " - Empire API: http://localhost:1337" - echo " - Starkiller UI: http://localhost:5000" - echo "" - print_status "Default Credentials:" - echo " - Username: empireadmin" - echo " - Password: password123" - echo "" - print_status "Management Commands:" - echo " - View logs: docker logs attacknode-empire" - echo " - Restart: docker restart attacknode-empire" - echo " - Stop: docker stop attacknode-empire" - echo " - Remove: docker rm attacknode-empire empire-data" - echo "" - print_status "The self-healing system will automatically monitor and recover Empire if issues occur" - echo "" -} - -# Run main function -main "$@" diff --git a/logs/empire-container-repair.log b/logs/empire-container-repair.log deleted file mode 100644 index a35b241..0000000 --- a/logs/empire-container-repair.log +++ /dev/null @@ -1,33 +0,0 @@ -[2025-07-14 16:52:25] [INFO] Checking permissions... -[2025-07-14 16:52:25] [SUCCESS] Docker access confirmed -[2025-07-14 16:52:44] [INFO] Checking permissions... -[2025-07-14 16:52:44] [SUCCESS] Docker access confirmed -[2025-07-14 16:53:10] [INFO] Checking permissions... -[2025-07-14 16:53:10] [SUCCESS] Docker access confirmed -[2025-07-14 16:53:10] [INFO] Starting Empire container repair... -[2025-07-14 16:53:10] [INFO] Performing complete container cleanup... -[2025-07-14 16:53:10] [INFO] Stopping Empire containers... -[2025-07-14 16:53:20] [INFO] Removing Empire containers... -[2025-07-14 16:53:20] [INFO] Cleaning up orphaned Empire containers... -[2025-07-14 16:53:20] [SUCCESS] Container cleanup completed -[2025-07-14 16:53:20] [INFO] Setting up Empire volumes... -[2025-07-14 16:53:20] [INFO] Volume directory exists: uploads/empire/data -[2025-07-14 16:53:20] [INFO] Volume directory exists: uploads/empire/downloads -[2025-07-14 16:53:20] [INFO] Created volume directory: uploads/empire/logs -[2025-07-14 16:53:20] [SUCCESS] Empire volumes setup completed -[2025-07-14 16:53:20] [INFO] Starting Empire container with retry logic... -[2025-07-14 16:53:20] [INFO] Start attempt 1 of 3 -[2025-07-14 16:53:20] [INFO] Pulling Empire image... -[2025-07-14 16:53:21] [INFO] Creating Empire data container... -[2025-07-14 16:53:21] [INFO] Starting Empire main container... -[2025-07-14 16:53:21] [INFO] Waiting for Empire container to be ready... -[2025-07-14 16:53:31] [SUCCESS] Empire container is ready -[2025-07-14 16:53:31] [SUCCESS] Empire container started successfully -[2025-07-14 16:53:31] [INFO] Testing Empire functionality... -[2025-07-14 16:53:31] [INFO] Testing Empire API... -[2025-07-14 16:55:07] [WARNING] Empire API not responding (this may be normal during initialization) -[2025-07-14 16:55:12] [INFO] Testing Starkiller UI... -[2025-07-14 16:55:12] [WARNING] Starkiller UI not accessible (this may be normal during initialization) -[2025-07-14 16:55:12] [INFO] Testing container health... -[2025-07-14 16:55:12] [ERROR] Empire container is not running -[2025-07-14 16:55:12] [SUCCESS] Empire container repair completed successfully diff --git a/logs/empire-health.log b/logs/empire-health.log deleted file mode 100644 index 8d4d17f..0000000 --- a/logs/empire-health.log +++ /dev/null @@ -1,1550 +0,0 @@ -[2025-07-14T21:39:59.763Z] [INFO] Starting Empire health monitoring -[2025-07-14T21:39:59.831Z] [ERROR] Empire health check failed (1/3): Health check failed: Error: Container attacknode-empire not found or not accessible -[2025-07-14T21:40:30.162Z] [ERROR] Empire health check failed (2/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:40:30.163Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T21:41:00.178Z] [ERROR] Empire health check failed (3/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:41:00.178Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:41:00.179Z] [INFO] Starting Empire recovery process -[2025-07-14T21:41:00.179Z] [INFO] Stopping Empire container -[2025-07-14T21:41:10.419Z] [INFO] Removing Empire container -[2025-07-14T21:41:10.491Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:41:10.499Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:41:10.499Z] [INFO] Starting new Empire container -[2025-07-14T21:41:10.499Z] [INFO] Pulling Empire image... -[2025-07-14T21:41:10.920Z] [INFO] Creating Empire data container... -[2025-07-14T21:41:11.010Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "fd7431428ead84d9546be2191e58bcc4ccdb7c6ae6a585131cd8843e8fd807ae". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:41:11.010Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:41:12.065Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "54a1698afeee5699463031af10d99b30d3e13f38fcd9ac103b449b1a354fcc30". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:41:12.065Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "54a1698afeee5699463031af10d99b30d3e13f38fcd9ac103b449b1a354fcc30". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:41:30.084Z] [ERROR] Empire health check failed (4/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:41:30.084Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:41:30.084Z] [INFO] Starting Empire recovery process -[2025-07-14T21:41:30.085Z] [INFO] Stopping Empire container -[2025-07-14T21:41:40.406Z] [INFO] Removing Empire container -[2025-07-14T21:41:40.477Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:41:40.485Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:41:40.486Z] [INFO] Starting new Empire container -[2025-07-14T21:41:40.486Z] [INFO] Pulling Empire image... -[2025-07-14T21:41:41.021Z] [INFO] Creating Empire data container... -[2025-07-14T21:41:41.088Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "689f13c3637d09233b99c7981b74593732b9d08641c5a2a93902f8812d046007". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:41:41.089Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:41:41.990Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "df3e227ee91064cd686776980502402ec7262feb84e3fc053b53b1bafa5a462e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:41:41.990Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "df3e227ee91064cd686776980502402ec7262feb84e3fc053b53b1bafa5a462e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:41:59.796Z] [ERROR] Empire health check failed (5/3): Empire container is not running -[2025-07-14T21:41:59.797Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:41:59.797Z] [INFO] Starting Empire recovery process -[2025-07-14T21:41:59.798Z] [INFO] Stopping Empire container -[2025-07-14T21:41:59.836Z] [INFO] Removing Empire container -[2025-07-14T21:41:59.878Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:41:59.886Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:41:59.896Z] [INFO] Starting new Empire container -[2025-07-14T21:41:59.897Z] [INFO] Pulling Empire image... -[2025-07-14T21:42:00.334Z] [INFO] Creating Empire data container... -[2025-07-14T21:42:00.591Z] [INFO] Starting Empire main container... -[2025-07-14T21:42:30.204Z] [ERROR] Empire health check failed (6/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:42:30.204Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:42:30.204Z] [INFO] Starting Empire recovery process -[2025-07-14T21:42:30.205Z] [INFO] Stopping Empire container -[2025-07-14T21:42:40.498Z] [INFO] Removing Empire container -[2025-07-14T21:42:40.571Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:42:40.578Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:42:40.578Z] [INFO] Starting new Empire container -[2025-07-14T21:42:40.579Z] [INFO] Pulling Empire image... -[2025-07-14T21:42:41.058Z] [INFO] Creating Empire data container... -[2025-07-14T21:42:41.125Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "7e86f73f5edc7080a61b143f4c3f99f495ca4de85d8c5eb8346220209df4ffb0". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:42:41.125Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:42:42.078Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "724da3211dcc29f863c2c86925fa6a6d58e6731b013c4a425271b802e72b215b". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:42:42.078Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "724da3211dcc29f863c2c86925fa6a6d58e6731b013c4a425271b802e72b215b". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:42:59.794Z] [ERROR] Empire health check failed (7/3): Empire container is not running -[2025-07-14T21:42:59.794Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:42:59.794Z] [INFO] Starting Empire recovery process -[2025-07-14T21:42:59.794Z] [INFO] Stopping Empire container -[2025-07-14T21:42:59.833Z] [INFO] Removing Empire container -[2025-07-14T21:42:59.870Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:42:59.878Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:42:59.878Z] [INFO] Starting new Empire container -[2025-07-14T21:42:59.878Z] [INFO] Pulling Empire image... -[2025-07-14T21:43:00.318Z] [INFO] Creating Empire data container... -[2025-07-14T21:43:00.594Z] [INFO] Starting Empire main container... -[2025-07-14T21:43:30.115Z] [ERROR] Empire health check failed (8/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:43:30.115Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:43:30.115Z] [INFO] Starting Empire recovery process -[2025-07-14T21:43:30.116Z] [INFO] Stopping Empire container -[2025-07-14T21:43:40.382Z] [INFO] Removing Empire container -[2025-07-14T21:43:40.436Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:43:40.443Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:43:40.443Z] [INFO] Starting new Empire container -[2025-07-14T21:43:40.444Z] [INFO] Pulling Empire image... -[2025-07-14T21:43:40.979Z] [INFO] Creating Empire data container... -[2025-07-14T21:43:41.032Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "b95c76cdfadd5ed95bfbeb368d66b98ff34a08c2f55c5968758d6d698b168191". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:43:41.032Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:43:41.930Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "af97df4ba1f4dcb027f825546e8f9bca027efdce5dbdc9b6d3c6fd1818211c8e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:43:41.931Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "af97df4ba1f4dcb027f825546e8f9bca027efdce5dbdc9b6d3c6fd1818211c8e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:43:59.790Z] [ERROR] Empire health check failed (9/3): Empire container is not running -[2025-07-14T21:43:59.790Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:43:59.790Z] [INFO] Starting Empire recovery process -[2025-07-14T21:43:59.791Z] [INFO] Stopping Empire container -[2025-07-14T21:43:59.817Z] [INFO] Removing Empire container -[2025-07-14T21:43:59.848Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:43:59.854Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:43:59.854Z] [INFO] Starting new Empire container -[2025-07-14T21:43:59.854Z] [INFO] Pulling Empire image... -[2025-07-14T21:44:00.309Z] [INFO] Creating Empire data container... -[2025-07-14T21:44:00.553Z] [INFO] Starting Empire main container... -[2025-07-14T21:44:01.321Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:44:01.322Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:44:07.585Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "5c55bf5569ef0924494f1a561477661eb345911de1424f9e8921df60431f9b7e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:44:07.586Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "5c55bf5569ef0924494f1a561477661eb345911de1424f9e8921df60431f9b7e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:44:29.791Z] [ERROR] Empire health check failed (10/3): Empire container is not running -[2025-07-14T21:44:29.791Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:44:29.791Z] [INFO] Starting Empire recovery process -[2025-07-14T21:44:29.791Z] [INFO] Stopping Empire container -[2025-07-14T21:44:29.820Z] [INFO] Removing Empire container -[2025-07-14T21:44:29.852Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:44:29.859Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:44:29.859Z] [INFO] Starting new Empire container -[2025-07-14T21:44:29.859Z] [INFO] Pulling Empire image... -[2025-07-14T21:44:30.335Z] [INFO] Creating Empire data container... -[2025-07-14T21:44:30.591Z] [INFO] Starting Empire main container... -[2025-07-14T21:45:00.119Z] [ERROR] Empire health check failed (11/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:45:00.120Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:45:00.120Z] [INFO] Starting Empire recovery process -[2025-07-14T21:45:00.120Z] [INFO] Stopping Empire container -[2025-07-14T21:45:10.367Z] [INFO] Removing Empire container -[2025-07-14T21:45:10.421Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:45:10.428Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:45:10.428Z] [INFO] Starting new Empire container -[2025-07-14T21:45:10.429Z] [INFO] Pulling Empire image... -[2025-07-14T21:45:10.909Z] [INFO] Creating Empire data container... -[2025-07-14T21:45:10.969Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "7325ac1e408e4a5102a51e4bfb62a7f41d31a6b33938162e216a317893130392". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:45:10.969Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:45:11.161Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:45:11.162Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:45:11.795Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "694ada39a0013363c28ced375207efe1f7d4b9f0dacda69e5997fe16234051d2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:45:11.796Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "694ada39a0013363c28ced375207efe1f7d4b9f0dacda69e5997fe16234051d2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:45:11.825Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "694ada39a0013363c28ced375207efe1f7d4b9f0dacda69e5997fe16234051d2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:45:11.825Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "694ada39a0013363c28ced375207efe1f7d4b9f0dacda69e5997fe16234051d2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:45:29.798Z] [ERROR] Empire health check failed (12/3): Empire container is not running -[2025-07-14T21:45:29.799Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:45:29.799Z] [INFO] Starting Empire recovery process -[2025-07-14T21:45:29.799Z] [INFO] Stopping Empire container -[2025-07-14T21:45:29.827Z] [INFO] Removing Empire container -[2025-07-14T21:45:29.861Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:45:29.867Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:45:29.868Z] [INFO] Starting new Empire container -[2025-07-14T21:45:29.868Z] [INFO] Pulling Empire image... -[2025-07-14T21:45:30.375Z] [INFO] Creating Empire data container... -[2025-07-14T21:45:30.623Z] [INFO] Starting Empire main container... -[2025-07-14T21:46:00.140Z] [ERROR] Empire health check failed (13/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:46:00.141Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:46:00.141Z] [INFO] Starting Empire recovery process -[2025-07-14T21:46:00.141Z] [INFO] Stopping Empire container -[2025-07-14T21:46:10.392Z] [INFO] Removing Empire container -[2025-07-14T21:46:10.448Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:46:10.455Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:46:10.455Z] [INFO] Starting new Empire container -[2025-07-14T21:46:10.455Z] [INFO] Pulling Empire image... -[2025-07-14T21:46:10.917Z] [INFO] Creating Empire data container... -[2025-07-14T21:46:10.969Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "ed461a08d9f69434020404da7f1002fe41350ca85f7acea23e5d0f1658ef0f60". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:46:10.970Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:46:11.157Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:46:11.157Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:46:11.785Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "90419b931a1cf6e9798f38babd47f9dbca4473b72a2ffc546d18597240870e6c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:46:11.786Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "90419b931a1cf6e9798f38babd47f9dbca4473b72a2ffc546d18597240870e6c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:46:11.844Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "90419b931a1cf6e9798f38babd47f9dbca4473b72a2ffc546d18597240870e6c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:46:11.845Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "90419b931a1cf6e9798f38babd47f9dbca4473b72a2ffc546d18597240870e6c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:46:29.802Z] [ERROR] Empire health check failed (14/3): Empire container is not running -[2025-07-14T21:46:29.802Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:46:29.802Z] [INFO] Starting Empire recovery process -[2025-07-14T21:46:29.803Z] [INFO] Stopping Empire container -[2025-07-14T21:46:29.831Z] [INFO] Removing Empire container -[2025-07-14T21:46:29.863Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:46:29.870Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:46:29.871Z] [INFO] Starting new Empire container -[2025-07-14T21:46:29.871Z] [INFO] Pulling Empire image... -[2025-07-14T21:46:30.347Z] [INFO] Creating Empire data container... -[2025-07-14T21:46:30.601Z] [INFO] Starting Empire main container... -[2025-07-14T21:46:31.274Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:46:31.275Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:46:37.427Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "73be3572c44c70ed55d7031533da5c55bf08ec55c90ae383b39b8938b49d760a". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:46:37.427Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "73be3572c44c70ed55d7031533da5c55bf08ec55c90ae383b39b8938b49d760a". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:46:59.809Z] [ERROR] Empire health check failed (15/3): Empire container is not running -[2025-07-14T21:46:59.809Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:46:59.810Z] [INFO] Starting Empire recovery process -[2025-07-14T21:46:59.810Z] [INFO] Stopping Empire container -[2025-07-14T21:46:59.844Z] [INFO] Removing Empire container -[2025-07-14T21:46:59.882Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:46:59.889Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:46:59.890Z] [INFO] Starting new Empire container -[2025-07-14T21:46:59.890Z] [INFO] Pulling Empire image... -[2025-07-14T21:47:00.379Z] [INFO] Creating Empire data container... -[2025-07-14T21:47:00.706Z] [INFO] Starting Empire main container... -[2025-07-14T21:47:30.114Z] [ERROR] Empire health check failed (16/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:47:30.114Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:47:30.115Z] [INFO] Starting Empire recovery process -[2025-07-14T21:47:30.115Z] [INFO] Stopping Empire container -[2025-07-14T21:47:40.362Z] [INFO] Removing Empire container -[2025-07-14T21:47:40.417Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:47:40.424Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:47:40.424Z] [INFO] Starting new Empire container -[2025-07-14T21:47:40.425Z] [INFO] Pulling Empire image... -[2025-07-14T21:47:40.888Z] [INFO] Creating Empire data container... -[2025-07-14T21:47:40.940Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "52a4525d4d9740d40fc8c6197c2a06052410b9af0ed30afc19287c585ee3c0c4". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:47:40.941Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:47:41.218Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:47:41.219Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:47:41.805Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "6891dba276e5f5df0d47b7954cf5b56dfaf56f6a06e60082556b400239f9a992". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:47:41.805Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "6891dba276e5f5df0d47b7954cf5b56dfaf56f6a06e60082556b400239f9a992". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:47:41.806Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "6891dba276e5f5df0d47b7954cf5b56dfaf56f6a06e60082556b400239f9a992". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:47:41.807Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "6891dba276e5f5df0d47b7954cf5b56dfaf56f6a06e60082556b400239f9a992". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:47:59.803Z] [ERROR] Empire health check failed (17/3): Empire container is not running -[2025-07-14T21:47:59.804Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:47:59.804Z] [INFO] Starting Empire recovery process -[2025-07-14T21:47:59.804Z] [INFO] Stopping Empire container -[2025-07-14T21:47:59.835Z] [INFO] Removing Empire container -[2025-07-14T21:47:59.866Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:47:59.872Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:47:59.873Z] [INFO] Starting new Empire container -[2025-07-14T21:47:59.873Z] [INFO] Pulling Empire image... -[2025-07-14T21:48:00.305Z] [INFO] Creating Empire data container... -[2025-07-14T21:48:00.558Z] [INFO] Starting Empire main container... -[2025-07-14T21:48:30.136Z] [ERROR] Empire health check failed (18/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:48:30.137Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:48:30.137Z] [INFO] Starting Empire recovery process -[2025-07-14T21:48:30.137Z] [INFO] Stopping Empire container -[2025-07-14T21:48:40.392Z] [INFO] Removing Empire container -[2025-07-14T21:48:40.446Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:48:40.455Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:48:40.456Z] [INFO] Starting new Empire container -[2025-07-14T21:48:40.457Z] [INFO] Pulling Empire image... -[2025-07-14T21:48:40.969Z] [INFO] Creating Empire data container... -[2025-07-14T21:48:41.028Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "bc04db3dfb35ca1f4d8fb03a76982b0ac0a7da5b81882d8506b834531e7f28a4". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:48:41.029Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:48:41.240Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:48:41.240Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:48:41.867Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "05011ab1af26383c1fd697b378b03744d10160a8763ab5d595e3d34c131a6189". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:48:41.868Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "05011ab1af26383c1fd697b378b03744d10160a8763ab5d595e3d34c131a6189". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:48:41.903Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "05011ab1af26383c1fd697b378b03744d10160a8763ab5d595e3d34c131a6189". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:48:41.905Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "05011ab1af26383c1fd697b378b03744d10160a8763ab5d595e3d34c131a6189". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:48:59.815Z] [ERROR] Empire health check failed (19/3): Empire container is not running -[2025-07-14T21:48:59.815Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:48:59.816Z] [INFO] Starting Empire recovery process -[2025-07-14T21:48:59.816Z] [INFO] Stopping Empire container -[2025-07-14T21:48:59.850Z] [INFO] Removing Empire container -[2025-07-14T21:48:59.886Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:48:59.893Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:48:59.893Z] [INFO] Starting new Empire container -[2025-07-14T21:48:59.894Z] [INFO] Pulling Empire image... -[2025-07-14T21:49:00.331Z] [INFO] Creating Empire data container... -[2025-07-14T21:49:00.653Z] [INFO] Starting Empire main container... -[2025-07-14T21:49:01.397Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:49:01.397Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:49:07.568Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "aa2b3aaadf1ee449557d1d3ad2f67e7103d1aa0be4d55116344c202daf0df5d7". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:49:07.568Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "aa2b3aaadf1ee449557d1d3ad2f67e7103d1aa0be4d55116344c202daf0df5d7". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:49:29.817Z] [ERROR] Empire health check failed (20/3): Empire container is not running -[2025-07-14T21:49:29.817Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:49:29.818Z] [INFO] Starting Empire recovery process -[2025-07-14T21:49:29.818Z] [INFO] Stopping Empire container -[2025-07-14T21:49:29.851Z] [INFO] Removing Empire container -[2025-07-14T21:49:29.888Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:49:29.896Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:49:29.896Z] [INFO] Starting new Empire container -[2025-07-14T21:49:29.896Z] [INFO] Pulling Empire image... -[2025-07-14T21:49:30.366Z] [INFO] Creating Empire data container... -[2025-07-14T21:49:30.687Z] [INFO] Starting Empire main container... -[2025-07-14T21:50:00.225Z] [ERROR] Empire health check failed (21/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:50:00.225Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:50:00.225Z] [INFO] Starting Empire recovery process -[2025-07-14T21:50:00.225Z] [INFO] Stopping Empire container -[2025-07-14T21:50:10.552Z] [INFO] Removing Empire container -[2025-07-14T21:50:10.627Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:50:10.635Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:50:10.635Z] [INFO] Starting new Empire container -[2025-07-14T21:50:10.636Z] [INFO] Pulling Empire image... -[2025-07-14T21:50:11.101Z] [INFO] Creating Empire data container... -[2025-07-14T21:50:11.168Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "3849a2365913356058feab2d1bf5e7b19c3f41d070dc59faa7ea26eaf26e6510". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:50:11.168Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:50:11.364Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:50:11.364Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:50:11.994Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "7cde869d99cafc1d1227939bee02ade870f0b136a87e3af389796f09085ada41". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:50:11.994Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "7cde869d99cafc1d1227939bee02ade870f0b136a87e3af389796f09085ada41". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:50:12.046Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "7cde869d99cafc1d1227939bee02ade870f0b136a87e3af389796f09085ada41". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:50:12.047Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "7cde869d99cafc1d1227939bee02ade870f0b136a87e3af389796f09085ada41". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:50:29.815Z] [ERROR] Empire health check failed (22/3): Empire container is not running -[2025-07-14T21:50:29.816Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:50:29.816Z] [INFO] Starting Empire recovery process -[2025-07-14T21:50:29.816Z] [INFO] Stopping Empire container -[2025-07-14T21:50:29.849Z] [INFO] Removing Empire container -[2025-07-14T21:50:29.884Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:50:29.891Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:50:29.891Z] [INFO] Starting new Empire container -[2025-07-14T21:50:29.891Z] [INFO] Pulling Empire image... -[2025-07-14T21:50:30.368Z] [INFO] Creating Empire data container... -[2025-07-14T21:50:30.692Z] [INFO] Starting Empire main container... -[2025-07-14T21:51:00.223Z] [ERROR] Empire health check failed (23/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:51:00.224Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:51:00.224Z] [INFO] Starting Empire recovery process -[2025-07-14T21:51:00.224Z] [INFO] Stopping Empire container -[2025-07-14T21:51:10.543Z] [INFO] Removing Empire container -[2025-07-14T21:51:10.614Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:51:10.621Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:51:10.622Z] [INFO] Starting new Empire container -[2025-07-14T21:51:10.622Z] [INFO] Pulling Empire image... -[2025-07-14T21:51:11.095Z] [INFO] Creating Empire data container... -[2025-07-14T21:51:11.161Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "b18fd118a15d3333ef4e575b027e1d3204ba27b740ab5ed97e97a1749e9529ab". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:51:11.161Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:51:11.466Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:51:11.467Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:51:12.040Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "f6aa7785d3af450855303e75e795747e0ce5301fc7d40a8fc1eaa2e85ea0f8d3". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:51:12.041Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "f6aa7785d3af450855303e75e795747e0ce5301fc7d40a8fc1eaa2e85ea0f8d3". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:51:12.042Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "f6aa7785d3af450855303e75e795747e0ce5301fc7d40a8fc1eaa2e85ea0f8d3". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:51:12.042Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "f6aa7785d3af450855303e75e795747e0ce5301fc7d40a8fc1eaa2e85ea0f8d3". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:51:29.821Z] [ERROR] Empire health check failed (24/3): Empire container is not running -[2025-07-14T21:51:29.821Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:51:29.821Z] [INFO] Starting Empire recovery process -[2025-07-14T21:51:29.822Z] [INFO] Stopping Empire container -[2025-07-14T21:51:29.855Z] [INFO] Removing Empire container -[2025-07-14T21:51:29.895Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:51:29.903Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:51:29.903Z] [INFO] Starting new Empire container -[2025-07-14T21:51:29.903Z] [INFO] Pulling Empire image... -[2025-07-14T21:51:30.400Z] [INFO] Creating Empire data container... -[2025-07-14T21:51:30.722Z] [INFO] Starting Empire main container... -[2025-07-14T21:51:31.370Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:51:31.370Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:51:37.614Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "7d368d64fb618c8d06139e78d7ab40face2fd9eb19d70d245ab1144e0c08096e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:51:37.615Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "7d368d64fb618c8d06139e78d7ab40face2fd9eb19d70d245ab1144e0c08096e". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:51:59.819Z] [ERROR] Empire health check failed (25/3): Empire container is not running -[2025-07-14T21:51:59.820Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:51:59.820Z] [INFO] Starting Empire recovery process -[2025-07-14T21:51:59.820Z] [INFO] Stopping Empire container -[2025-07-14T21:51:59.854Z] [INFO] Removing Empire container -[2025-07-14T21:51:59.890Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:51:59.896Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:51:59.897Z] [INFO] Starting new Empire container -[2025-07-14T21:51:59.897Z] [INFO] Pulling Empire image... -[2025-07-14T21:52:00.337Z] [INFO] Creating Empire data container... -[2025-07-14T21:52:00.664Z] [INFO] Starting Empire main container... -[2025-07-14T21:52:30.236Z] [ERROR] Empire health check failed (26/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:52:30.236Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:52:30.237Z] [INFO] Starting Empire recovery process -[2025-07-14T21:52:30.237Z] [INFO] Stopping Empire container -[2025-07-14T21:52:40.544Z] [INFO] Removing Empire container -[2025-07-14T21:52:40.613Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:52:40.620Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:52:40.621Z] [INFO] Starting new Empire container -[2025-07-14T21:52:40.621Z] [INFO] Pulling Empire image... -[2025-07-14T21:52:41.090Z] [INFO] Creating Empire data container... -[2025-07-14T21:52:41.162Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "a8c90e23a5425741b9a40a72e7f97c0b2a05c62b248eff5dce1e9a40ecf58e77". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:52:41.163Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:52:41.307Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:52:41.308Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:52:41.955Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "443f79234c229b75ba0d3e41632ed33aaf072cedce454c538875fa9d9f8ce6f0". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:52:41.955Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "443f79234c229b75ba0d3e41632ed33aaf072cedce454c538875fa9d9f8ce6f0". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:52:42.102Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "443f79234c229b75ba0d3e41632ed33aaf072cedce454c538875fa9d9f8ce6f0". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:52:42.102Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "443f79234c229b75ba0d3e41632ed33aaf072cedce454c538875fa9d9f8ce6f0". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:52:59.824Z] [ERROR] Empire health check failed (27/3): Empire container is not running -[2025-07-14T21:52:59.825Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:52:59.825Z] [INFO] Starting Empire recovery process -[2025-07-14T21:52:59.826Z] [INFO] Stopping Empire container -[2025-07-14T21:52:59.859Z] [INFO] Removing Empire container -[2025-07-14T21:52:59.895Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:52:59.902Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:52:59.902Z] [INFO] Starting new Empire container -[2025-07-14T21:52:59.902Z] [INFO] Pulling Empire image... -[2025-07-14T21:53:00.330Z] [INFO] Creating Empire data container... -[2025-07-14T21:53:00.651Z] [INFO] Starting Empire main container... -[2025-07-14T21:53:30.154Z] [ERROR] Empire health check failed (28/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:53:30.154Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:53:30.155Z] [INFO] Starting Empire recovery process -[2025-07-14T21:53:30.155Z] [INFO] Stopping Empire container -[2025-07-14T21:53:40.442Z] [INFO] Removing Empire container -[2025-07-14T21:53:40.514Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:53:40.521Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:53:40.522Z] [INFO] Starting new Empire container -[2025-07-14T21:53:40.522Z] [INFO] Pulling Empire image... -[2025-07-14T21:53:41.150Z] [INFO] Creating Empire data container... -[2025-07-14T21:53:41.215Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "c9851b2537b56fef10dd359e6ec1528dd1f5998d0c4867e6995e9345fb46ca33". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:53:41.216Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:53:42.269Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "19af4428ede56552064bfd1516c512621e1da6db3384d53bd0a5db5d3caf65ca". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:53:42.269Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "19af4428ede56552064bfd1516c512621e1da6db3384d53bd0a5db5d3caf65ca". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:53:46.656Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:53:46.657Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:53:47.581Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "6b6fedd966efd08c5278f4bfab5dc0fbc710c80357095778cc154384327ad91c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:53:47.581Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "6b6fedd966efd08c5278f4bfab5dc0fbc710c80357095778cc154384327ad91c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:53:59.820Z] [ERROR] Empire health check failed (29/3): Empire container is not running -[2025-07-14T21:53:59.821Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:53:59.830Z] [INFO] Starting Empire recovery process -[2025-07-14T21:53:59.830Z] [INFO] Stopping Empire container -[2025-07-14T21:53:59.864Z] [INFO] Removing Empire container -[2025-07-14T21:53:59.901Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:53:59.908Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:53:59.908Z] [INFO] Starting new Empire container -[2025-07-14T21:53:59.909Z] [INFO] Pulling Empire image... -[2025-07-14T21:54:00.357Z] [INFO] Creating Empire data container... -[2025-07-14T21:54:00.679Z] [INFO] Starting Empire main container... -[2025-07-14T21:54:11.669Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:54:11.670Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:54:17.982Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "a62010557465e26368819d2fb31409aebeabee5647b0b011b3072aafcbaba3ad". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:54:17.983Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "a62010557465e26368819d2fb31409aebeabee5647b0b011b3072aafcbaba3ad". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:54:29.814Z] [ERROR] Empire health check failed (30/3): Empire container is not running -[2025-07-14T21:54:29.814Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:54:29.814Z] [INFO] Starting Empire recovery process -[2025-07-14T21:54:29.814Z] [INFO] Stopping Empire container -[2025-07-14T21:54:29.842Z] [INFO] Removing Empire container -[2025-07-14T21:54:29.872Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:54:29.877Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:54:29.877Z] [INFO] Starting new Empire container -[2025-07-14T21:54:29.877Z] [INFO] Pulling Empire image... -[2025-07-14T21:54:30.289Z] [INFO] Creating Empire data container... -[2025-07-14T21:54:30.528Z] [INFO] Starting Empire main container... -[2025-07-14T21:55:00.226Z] [ERROR] Empire health check failed (31/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:55:00.227Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:55:00.227Z] [INFO] Starting Empire recovery process -[2025-07-14T21:55:00.227Z] [INFO] Stopping Empire container -[2025-07-14T21:55:10.514Z] [INFO] Removing Empire container -[2025-07-14T21:55:10.585Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:55:10.593Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:55:10.593Z] [INFO] Starting new Empire container -[2025-07-14T21:55:10.594Z] [INFO] Pulling Empire image... -[2025-07-14T21:55:11.067Z] [INFO] Creating Empire data container... -[2025-07-14T21:55:11.140Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "38acd05a9c48cad714861be4bb579750fc5cafa16396cd9572b54de9813a61f1". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:55:11.140Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:55:11.320Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:55:11.321Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:55:11.949Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "c612171c49399bfab63fee498b7bd6001c7306bb5e2186b2d596bc788a8825c2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:55:11.949Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "c612171c49399bfab63fee498b7bd6001c7306bb5e2186b2d596bc788a8825c2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:55:12.073Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "c612171c49399bfab63fee498b7bd6001c7306bb5e2186b2d596bc788a8825c2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:55:12.073Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "c612171c49399bfab63fee498b7bd6001c7306bb5e2186b2d596bc788a8825c2". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:55:29.822Z] [ERROR] Empire health check failed (32/3): Empire container is not running -[2025-07-14T21:55:29.823Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:55:29.828Z] [INFO] Starting Empire recovery process -[2025-07-14T21:55:29.829Z] [INFO] Stopping Empire container -[2025-07-14T21:55:29.863Z] [INFO] Removing Empire container -[2025-07-14T21:55:29.900Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:55:29.907Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:55:29.908Z] [INFO] Starting new Empire container -[2025-07-14T21:55:29.908Z] [INFO] Pulling Empire image... -[2025-07-14T21:55:30.354Z] [INFO] Creating Empire data container... -[2025-07-14T21:55:30.649Z] [INFO] Starting Empire main container... -[2025-07-14T21:56:00.239Z] [ERROR] Empire health check failed (33/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:56:00.240Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:56:00.240Z] [INFO] Starting Empire recovery process -[2025-07-14T21:56:00.240Z] [INFO] Stopping Empire container -[2025-07-14T21:56:10.550Z] [INFO] Removing Empire container -[2025-07-14T21:56:10.623Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:56:10.630Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:56:10.631Z] [INFO] Starting new Empire container -[2025-07-14T21:56:10.631Z] [INFO] Pulling Empire image... -[2025-07-14T21:56:11.090Z] [INFO] Creating Empire data container... -[2025-07-14T21:56:11.156Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "10e816405f59574445732984ba481b70a6dfff2cd8e67f0a8b77b0e1d4d8f0d6". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:56:11.156Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:56:11.490Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:56:11.491Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:56:12.035Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "06e023cc3b93e590b3eee0f82c7ba4afa288b812389d482081993116688bcd0c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:12.036Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "06e023cc3b93e590b3eee0f82c7ba4afa288b812389d482081993116688bcd0c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:12.059Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "06e023cc3b93e590b3eee0f82c7ba4afa288b812389d482081993116688bcd0c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:12.059Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "06e023cc3b93e590b3eee0f82c7ba4afa288b812389d482081993116688bcd0c". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:29.820Z] [ERROR] Empire health check failed (34/3): Empire container is not running -[2025-07-14T21:56:29.821Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:56:29.821Z] [INFO] Starting Empire recovery process -[2025-07-14T21:56:29.821Z] [INFO] Stopping Empire container -[2025-07-14T21:56:29.865Z] [INFO] Removing Empire container -[2025-07-14T21:56:29.902Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:56:29.910Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:56:29.910Z] [INFO] Starting new Empire container -[2025-07-14T21:56:29.910Z] [INFO] Pulling Empire image... -[2025-07-14T21:56:31.362Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:56:31.362Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:56:32.226Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "fe5d2065713fedb397d75d39fd81baaf22a67aecc3e5ae38f0f802566e4d784d". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:32.226Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "fe5d2065713fedb397d75d39fd81baaf22a67aecc3e5ae38f0f802566e4d784d". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:40.650Z] [INFO] Creating Empire data container... -[2025-07-14T21:56:40.961Z] [INFO] Starting Empire main container... -[2025-07-14T21:56:41.018Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker run -d -it --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 --volumes-from empire-data bcsecurity/empire:latest -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "fe5d2065713fedb397d75d39fd81baaf22a67aecc3e5ae38f0f802566e4d784d". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:41.018Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:56:42.021Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "c82b208328ca77f08ff5486e7c2b3e9a1c01793f10292648da7010da669fcc1a". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:42.021Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "c82b208328ca77f08ff5486e7c2b3e9a1c01793f10292648da7010da669fcc1a". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:56:59.819Z] [ERROR] Empire health check failed (35/3): Empire container is not running -[2025-07-14T21:56:59.819Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:56:59.819Z] [INFO] Starting Empire recovery process -[2025-07-14T21:56:59.820Z] [INFO] Stopping Empire container -[2025-07-14T21:56:59.853Z] [INFO] Removing Empire container -[2025-07-14T21:56:59.889Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:56:59.896Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:56:59.897Z] [INFO] Starting new Empire container -[2025-07-14T21:56:59.897Z] [INFO] Pulling Empire image... -[2025-07-14T21:57:00.365Z] [INFO] Creating Empire data container... -[2025-07-14T21:57:00.689Z] [INFO] Starting Empire main container... -[2025-07-14T21:57:30.242Z] [ERROR] Empire health check failed (36/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:57:30.243Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:57:30.243Z] [INFO] Starting Empire recovery process -[2025-07-14T21:57:30.243Z] [INFO] Stopping Empire container -[2025-07-14T21:57:40.550Z] [INFO] Removing Empire container -[2025-07-14T21:57:40.621Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:57:40.629Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:57:40.629Z] [INFO] Starting new Empire container -[2025-07-14T21:57:40.630Z] [INFO] Pulling Empire image... -[2025-07-14T21:57:41.088Z] [INFO] Creating Empire data container... -[2025-07-14T21:57:41.154Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "c4dedddb78a343b8133b684b95f3f979ca8c42e1c078e4ff42e311c03a87bce9". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:57:41.154Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:57:41.406Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:57:41.407Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:57:42.083Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "19bbc5f36a568eb9e3e6f9e15befbd6ae607ee437c85ce54e455a566cca1aa72". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:57:42.084Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "19bbc5f36a568eb9e3e6f9e15befbd6ae607ee437c85ce54e455a566cca1aa72". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:57:42.090Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "19bbc5f36a568eb9e3e6f9e15befbd6ae607ee437c85ce54e455a566cca1aa72". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:57:42.090Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "19bbc5f36a568eb9e3e6f9e15befbd6ae607ee437c85ce54e455a566cca1aa72". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:57:59.829Z] [ERROR] Empire health check failed (37/3): Empire container is not running -[2025-07-14T21:57:59.829Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:57:59.830Z] [INFO] Starting Empire recovery process -[2025-07-14T21:57:59.830Z] [INFO] Stopping Empire container -[2025-07-14T21:57:59.865Z] [INFO] Removing Empire container -[2025-07-14T21:57:59.903Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:57:59.911Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:57:59.911Z] [INFO] Starting new Empire container -[2025-07-14T21:57:59.911Z] [INFO] Pulling Empire image... -[2025-07-14T21:58:00.393Z] [INFO] Creating Empire data container... -[2025-07-14T21:58:00.692Z] [INFO] Starting Empire main container... -[2025-07-14T21:58:30.157Z] [ERROR] Empire health check failed (38/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T21:58:30.157Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:58:30.158Z] [INFO] Starting Empire recovery process -[2025-07-14T21:58:30.158Z] [INFO] Stopping Empire container -[2025-07-14T21:58:40.660Z] [INFO] Removing Empire container -[2025-07-14T21:58:40.716Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:58:40.723Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:58:40.723Z] [INFO] Starting new Empire container -[2025-07-14T21:58:40.723Z] [INFO] Pulling Empire image... -[2025-07-14T21:58:41.166Z] [INFO] Creating Empire data container... -[2025-07-14T21:58:41.222Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "aeb38a517bff85bf3b8601fdd3cc4dea001f64b9ec18c44dcc1648f1c5ab77ab". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T21:58:41.223Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:58:42.065Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "aee7d648f289a32324875cfa1d03b58836af2eabb0d6cfe336e3aa21aafb2d69". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:58:42.066Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "aee7d648f289a32324875cfa1d03b58836af2eabb0d6cfe336e3aa21aafb2d69". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:58:59.825Z] [ERROR] Empire health check failed (39/3): Empire container is not running -[2025-07-14T21:58:59.825Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:58:59.829Z] [INFO] Starting Empire recovery process -[2025-07-14T21:58:59.830Z] [INFO] Stopping Empire container -[2025-07-14T21:58:59.854Z] [INFO] Removing Empire container -[2025-07-14T21:58:59.885Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:58:59.892Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:58:59.892Z] [INFO] Starting new Empire container -[2025-07-14T21:58:59.892Z] [INFO] Pulling Empire image... -[2025-07-14T21:59:00.347Z] [INFO] Creating Empire data container... -[2025-07-14T21:59:00.600Z] [INFO] Starting Empire main container... -[2025-07-14T21:59:01.360Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T21:59:01.361Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T21:59:07.504Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "77ccddd5d36f333b632cf3f2a090f93a452982c587b60c5ffed16e48f110a34a". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:59:07.504Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "77ccddd5d36f333b632cf3f2a090f93a452982c587b60c5ffed16e48f110a34a". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T21:59:29.829Z] [ERROR] Empire health check failed (40/3): Empire container is not running -[2025-07-14T21:59:29.835Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T21:59:29.835Z] [INFO] Starting Empire recovery process -[2025-07-14T21:59:29.835Z] [INFO] Stopping Empire container -[2025-07-14T21:59:29.865Z] [INFO] Removing Empire container -[2025-07-14T21:59:29.894Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T21:59:29.900Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T21:59:29.901Z] [INFO] Starting new Empire container -[2025-07-14T21:59:29.901Z] [INFO] Pulling Empire image... -[2025-07-14T21:59:30.348Z] [INFO] Creating Empire data container... -[2025-07-14T21:59:30.596Z] [INFO] Starting Empire main container... -[2025-07-14T22:00:00.166Z] [ERROR] Empire health check failed (41/3): Empire setup has not completed successfully, Empire API is not responding on port 1337, Empire database connection failed -[2025-07-14T22:00:00.167Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:00:00.167Z] [INFO] Starting Empire recovery process -[2025-07-14T22:00:00.167Z] [INFO] Stopping Empire container -[2025-07-14T22:00:10.394Z] [INFO] Removing Empire container -[2025-07-14T22:00:10.450Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:00:10.458Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:00:10.458Z] [INFO] Starting new Empire container -[2025-07-14T22:00:10.459Z] [INFO] Pulling Empire image... -[2025-07-14T22:00:10.898Z] [INFO] Creating Empire data container... -[2025-07-14T22:00:10.963Z] [ERROR] Empire recovery failed: Error: Command failed: sudo docker create -v /empire --name empire-data bcsecurity/empire:latest -Error response from daemon: Conflict. The container name "/empire-data" is already in use by container "6602e7aecb8b6bd21212ad322d8c925d2dc14700f2b6014ba7cf584071beb847". You have to remove (or rename) that container to be able to reuse that name. - -[2025-07-14T22:00:10.963Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T22:00:11.242Z] [ERROR] Empire recovery failed: Error: Empire container failed to become ready within timeout -[2025-07-14T22:00:11.243Z] [INFO] Starting aggressive Empire recovery -[2025-07-14T22:00:11.852Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "a89d2e1921be084a3d10ccbbcf636bfafa825bcf55764309ff49700dbd5a8cfb". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T22:00:11.852Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "a89d2e1921be084a3d10ccbbcf636bfafa825bcf55764309ff49700dbd5a8cfb". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T22:00:11.857Z] [ERROR] Aggressive recovery failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "a89d2e1921be084a3d10ccbbcf636bfafa825bcf55764309ff49700dbd5a8cfb". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T22:00:11.858Z] [ERROR] Health check failed: Error: Command failed: sudo docker run -d --name attacknode-empire --restart unless-stopped -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest sh -c cd /empire && python3 empire.py setup --reset -y && python3 empire.py server -docker: Error response from daemon: Conflict. The container name "/attacknode-empire" is already in use by container "a89d2e1921be084a3d10ccbbcf636bfafa825bcf55764309ff49700dbd5a8cfb". You have to remove (or rename) that container to be able to reuse that name. - -Run 'docker run --help' for more information - -[2025-07-14T22:11:57.194Z] [INFO] Starting Empire health monitoring -[2025-07-14T22:11:57.448Z] [ERROR] Empire health check failed (1/3): Health check failed: Error: Container attacknode-empire not found or not accessible -[2025-07-14T22:12:27.729Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:12:27.730Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:12:57.668Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:12:57.668Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:12:57.669Z] [INFO] Starting Empire recovery process -[2025-07-14T22:12:57.669Z] [INFO] Performing complete container cleanup -[2025-07-14T22:13:03.319Z] [INFO] Container cleanup completed -[2025-07-14T22:13:03.336Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:13:03.344Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:13:03.344Z] [INFO] Starting new Empire container -[2025-07-14T22:13:03.345Z] [INFO] Pulling Empire image... -[2025-07-14T22:13:03.806Z] [INFO] Creating Empire data container... -[2025-07-14T22:13:04.027Z] [INFO] Starting Empire main container... -[2025-07-14T22:13:19.271Z] [INFO] Empire container is ready -[2025-07-14T22:13:19.271Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:13:19.271Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:13:27.699Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:13:27.699Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:13:57.679Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:13:57.680Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:14:27.685Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:14:27.685Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:14:27.686Z] [INFO] Starting Empire recovery process -[2025-07-14T22:14:27.686Z] [INFO] Performing complete container cleanup -[2025-07-14T22:14:33.344Z] [INFO] Container cleanup completed -[2025-07-14T22:14:33.354Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:14:33.364Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:14:33.365Z] [INFO] Starting new Empire container -[2025-07-14T22:14:33.365Z] [INFO] Pulling Empire image... -[2025-07-14T22:14:33.882Z] [INFO] Creating Empire data container... -[2025-07-14T22:14:34.191Z] [INFO] Starting Empire main container... -[2025-07-14T22:14:49.439Z] [INFO] Empire container is ready -[2025-07-14T22:14:49.439Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:14:49.439Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:14:57.720Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:14:57.720Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:15:27.673Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:15:27.674Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:15:57.705Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:15:57.705Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:15:57.706Z] [INFO] Starting Empire recovery process -[2025-07-14T22:15:57.706Z] [INFO] Performing complete container cleanup -[2025-07-14T22:16:03.352Z] [INFO] Container cleanup completed -[2025-07-14T22:16:03.361Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:16:03.369Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:16:03.369Z] [INFO] Starting new Empire container -[2025-07-14T22:16:03.370Z] [INFO] Pulling Empire image... -[2025-07-14T22:16:03.836Z] [INFO] Creating Empire data container... -[2025-07-14T22:16:04.129Z] [INFO] Starting Empire main container... -[2025-07-14T22:16:19.366Z] [INFO] Empire container is ready -[2025-07-14T22:16:19.367Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:16:19.367Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:16:27.747Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:16:27.747Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:16:57.697Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:16:57.697Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:17:27.693Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:17:27.694Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:17:27.694Z] [INFO] Starting Empire recovery process -[2025-07-14T22:17:27.694Z] [INFO] Performing complete container cleanup -[2025-07-14T22:17:33.331Z] [INFO] Container cleanup completed -[2025-07-14T22:17:33.342Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:17:33.352Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:17:33.352Z] [INFO] Starting new Empire container -[2025-07-14T22:17:33.352Z] [INFO] Pulling Empire image... -[2025-07-14T22:17:33.838Z] [INFO] Creating Empire data container... -[2025-07-14T22:17:34.120Z] [INFO] Starting Empire main container... -[2025-07-14T22:17:49.366Z] [INFO] Empire container is ready -[2025-07-14T22:17:49.367Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:17:49.367Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:17:57.764Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:17:57.764Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:18:27.711Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:18:27.712Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:18:57.702Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:18:57.703Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:18:57.703Z] [INFO] Starting Empire recovery process -[2025-07-14T22:18:57.703Z] [INFO] Performing complete container cleanup -[2025-07-14T22:19:03.365Z] [INFO] Container cleanup completed -[2025-07-14T22:19:03.374Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:19:03.382Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:19:03.382Z] [INFO] Starting new Empire container -[2025-07-14T22:19:03.382Z] [INFO] Pulling Empire image... -[2025-07-14T22:19:03.871Z] [INFO] Creating Empire data container... -[2025-07-14T22:19:04.150Z] [INFO] Starting Empire main container... -[2025-07-14T22:19:19.394Z] [INFO] Empire container is ready -[2025-07-14T22:19:19.395Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:19:19.395Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:19:27.746Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:19:27.746Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:19:57.711Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:19:57.711Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:20:27.713Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:20:27.713Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:20:27.713Z] [INFO] Starting Empire recovery process -[2025-07-14T22:20:27.714Z] [INFO] Performing complete container cleanup -[2025-07-14T22:20:33.385Z] [INFO] Container cleanup completed -[2025-07-14T22:20:33.396Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:20:33.406Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:20:33.407Z] [INFO] Starting new Empire container -[2025-07-14T22:20:33.407Z] [INFO] Pulling Empire image... -[2025-07-14T22:20:33.894Z] [INFO] Creating Empire data container... -[2025-07-14T22:20:34.176Z] [INFO] Starting Empire main container... -[2025-07-14T22:20:49.415Z] [INFO] Empire container is ready -[2025-07-14T22:20:49.415Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:20:49.416Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:20:57.768Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:20:57.769Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:21:27.723Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:21:27.724Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:21:57.720Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:21:57.721Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:21:57.721Z] [INFO] Starting Empire recovery process -[2025-07-14T22:21:57.721Z] [INFO] Performing complete container cleanup -[2025-07-14T22:22:03.386Z] [INFO] Container cleanup completed -[2025-07-14T22:22:03.396Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:22:03.406Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:22:03.406Z] [INFO] Starting new Empire container -[2025-07-14T22:22:03.406Z] [INFO] Pulling Empire image... -[2025-07-14T22:22:03.861Z] [INFO] Creating Empire data container... -[2025-07-14T22:22:04.157Z] [INFO] Starting Empire main container... -[2025-07-14T22:22:19.413Z] [INFO] Empire container is ready -[2025-07-14T22:22:19.413Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:22:19.414Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:22:27.761Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:22:27.761Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:22:57.722Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:22:57.722Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:23:27.718Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:23:27.718Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:23:27.718Z] [INFO] Starting Empire recovery process -[2025-07-14T22:23:27.718Z] [INFO] Performing complete container cleanup -[2025-07-14T22:23:33.379Z] [INFO] Container cleanup completed -[2025-07-14T22:23:33.390Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:23:33.399Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:23:33.400Z] [INFO] Starting new Empire container -[2025-07-14T22:23:33.400Z] [INFO] Pulling Empire image... -[2025-07-14T22:23:33.889Z] [INFO] Creating Empire data container... -[2025-07-14T22:23:34.170Z] [INFO] Starting Empire main container... -[2025-07-14T22:23:49.421Z] [INFO] Empire container is ready -[2025-07-14T22:23:49.422Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:23:49.422Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:23:57.760Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:23:57.761Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:24:27.718Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:24:27.719Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:24:57.733Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:24:57.733Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:24:57.734Z] [INFO] Starting Empire recovery process -[2025-07-14T22:24:57.734Z] [INFO] Performing complete container cleanup -[2025-07-14T22:25:03.404Z] [INFO] Container cleanup completed -[2025-07-14T22:25:03.414Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:25:03.423Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:25:03.423Z] [INFO] Starting new Empire container -[2025-07-14T22:25:03.424Z] [INFO] Pulling Empire image... -[2025-07-14T22:25:03.902Z] [INFO] Creating Empire data container... -[2025-07-14T22:25:04.213Z] [INFO] Starting Empire main container... -[2025-07-14T22:25:19.447Z] [INFO] Empire container is ready -[2025-07-14T22:25:19.447Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:25:19.447Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:25:27.774Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:25:27.774Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:25:57.721Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:25:57.721Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:26:27.763Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:26:27.764Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:26:27.764Z] [INFO] Starting Empire recovery process -[2025-07-14T22:26:27.764Z] [INFO] Performing complete container cleanup -[2025-07-14T22:26:33.432Z] [INFO] Container cleanup completed -[2025-07-14T22:26:33.443Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:26:33.453Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:26:33.453Z] [INFO] Starting new Empire container -[2025-07-14T22:26:33.454Z] [INFO] Pulling Empire image... -[2025-07-14T22:26:34.017Z] [INFO] Creating Empire data container... -[2025-07-14T22:26:34.323Z] [INFO] Starting Empire main container... -[2025-07-14T22:26:49.583Z] [INFO] Empire container is ready -[2025-07-14T22:26:49.583Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:26:49.583Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:26:57.787Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:26:57.787Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:27:27.754Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:27:27.755Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:27:57.748Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:27:57.748Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:27:57.749Z] [INFO] Starting Empire recovery process -[2025-07-14T22:27:57.749Z] [INFO] Performing complete container cleanup -[2025-07-14T22:28:03.400Z] [INFO] Container cleanup completed -[2025-07-14T22:28:03.410Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:28:03.420Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:28:03.420Z] [INFO] Starting new Empire container -[2025-07-14T22:28:03.421Z] [INFO] Pulling Empire image... -[2025-07-14T22:28:03.878Z] [INFO] Creating Empire data container... -[2025-07-14T22:28:04.175Z] [INFO] Starting Empire main container... -[2025-07-14T22:28:19.416Z] [INFO] Empire container is ready -[2025-07-14T22:28:19.417Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:28:19.417Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:28:27.780Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:28:27.780Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:28:57.738Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:28:57.739Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:29:27.753Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:29:27.753Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:29:27.754Z] [INFO] Starting Empire recovery process -[2025-07-14T22:29:27.754Z] [INFO] Performing complete container cleanup -[2025-07-14T22:29:33.407Z] [INFO] Container cleanup completed -[2025-07-14T22:29:33.416Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:29:33.426Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:29:33.427Z] [INFO] Starting new Empire container -[2025-07-14T22:29:33.427Z] [INFO] Pulling Empire image... -[2025-07-14T22:29:33.880Z] [INFO] Creating Empire data container... -[2025-07-14T22:29:34.186Z] [INFO] Starting Empire main container... -[2025-07-14T22:29:49.438Z] [INFO] Empire container is ready -[2025-07-14T22:29:49.438Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:29:49.438Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:29:57.770Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:29:57.771Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:30:27.755Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:30:27.756Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:30:57.765Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:30:57.765Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:30:57.765Z] [INFO] Starting Empire recovery process -[2025-07-14T22:30:57.766Z] [INFO] Performing complete container cleanup -[2025-07-14T22:31:03.431Z] [INFO] Container cleanup completed -[2025-07-14T22:31:03.440Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:31:03.450Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:31:03.451Z] [INFO] Starting new Empire container -[2025-07-14T22:31:03.451Z] [INFO] Pulling Empire image... -[2025-07-14T22:31:03.940Z] [INFO] Creating Empire data container... -[2025-07-14T22:31:04.247Z] [INFO] Starting Empire main container... -[2025-07-14T22:31:19.489Z] [INFO] Empire container is ready -[2025-07-14T22:31:19.489Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:31:19.489Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:31:27.787Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:31:27.788Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:31:57.759Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:31:57.759Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:32:27.760Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:32:27.760Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:32:27.761Z] [INFO] Starting Empire recovery process -[2025-07-14T22:32:27.761Z] [INFO] Performing complete container cleanup -[2025-07-14T22:32:33.428Z] [INFO] Container cleanup completed -[2025-07-14T22:32:33.438Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:32:33.448Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:32:33.448Z] [INFO] Starting new Empire container -[2025-07-14T22:32:33.448Z] [INFO] Pulling Empire image... -[2025-07-14T22:32:33.909Z] [INFO] Creating Empire data container... -[2025-07-14T22:32:34.220Z] [INFO] Starting Empire main container... -[2025-07-14T22:32:49.461Z] [INFO] Empire container is ready -[2025-07-14T22:32:49.461Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:32:49.461Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:32:57.818Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:32:57.819Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:33:27.758Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:33:27.758Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:33:57.786Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:33:57.786Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:33:57.787Z] [INFO] Starting Empire recovery process -[2025-07-14T22:33:57.787Z] [INFO] Performing complete container cleanup -[2025-07-14T22:34:03.469Z] [INFO] Container cleanup completed -[2025-07-14T22:34:03.479Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:34:03.489Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:34:03.490Z] [INFO] Starting new Empire container -[2025-07-14T22:34:03.490Z] [INFO] Pulling Empire image... -[2025-07-14T22:34:03.942Z] [INFO] Creating Empire data container... -[2025-07-14T22:34:04.259Z] [INFO] Starting Empire main container... -[2025-07-14T22:34:19.500Z] [INFO] Empire container is ready -[2025-07-14T22:34:19.500Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:34:19.500Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:34:27.817Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:34:27.817Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:34:57.771Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:34:57.771Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:35:27.780Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:35:27.781Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:35:27.781Z] [INFO] Starting Empire recovery process -[2025-07-14T22:35:27.781Z] [INFO] Performing complete container cleanup -[2025-07-14T22:35:33.433Z] [INFO] Container cleanup completed -[2025-07-14T22:35:33.443Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:35:33.453Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:35:33.454Z] [INFO] Starting new Empire container -[2025-07-14T22:35:33.454Z] [INFO] Pulling Empire image... -[2025-07-14T22:35:33.905Z] [INFO] Creating Empire data container... -[2025-07-14T22:35:34.203Z] [INFO] Starting Empire main container... -[2025-07-14T22:35:49.431Z] [INFO] Empire container is ready -[2025-07-14T22:35:49.432Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:35:49.432Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:35:57.816Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:35:57.816Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:36:27.789Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:36:27.790Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:36:57.796Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:36:57.796Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:36:57.797Z] [INFO] Starting Empire recovery process -[2025-07-14T22:36:57.797Z] [INFO] Performing complete container cleanup -[2025-07-14T22:37:03.460Z] [INFO] Container cleanup completed -[2025-07-14T22:37:03.470Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:37:03.480Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:37:03.480Z] [INFO] Starting new Empire container -[2025-07-14T22:37:03.480Z] [INFO] Pulling Empire image... -[2025-07-14T22:37:04.011Z] [INFO] Creating Empire data container... -[2025-07-14T22:37:04.306Z] [INFO] Starting Empire main container... -[2025-07-14T22:37:19.558Z] [INFO] Empire container is ready -[2025-07-14T22:37:19.558Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:37:19.559Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:37:27.820Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:37:27.820Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:37:57.783Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:37:57.783Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:38:27.772Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:38:27.773Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:38:27.773Z] [INFO] Starting Empire recovery process -[2025-07-14T22:38:27.773Z] [INFO] Performing complete container cleanup -[2025-07-14T22:38:33.421Z] [INFO] Container cleanup completed -[2025-07-14T22:38:33.431Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:38:33.441Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:38:33.441Z] [INFO] Starting new Empire container -[2025-07-14T22:38:33.442Z] [INFO] Pulling Empire image... -[2025-07-14T22:38:33.905Z] [INFO] Creating Empire data container... -[2025-07-14T22:38:34.185Z] [INFO] Starting Empire main container... -[2025-07-14T22:38:49.421Z] [INFO] Empire container is ready -[2025-07-14T22:38:49.421Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:38:49.421Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:38:57.841Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:38:57.841Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:39:27.797Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:39:27.798Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:39:57.805Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:39:57.805Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:39:57.805Z] [INFO] Starting Empire recovery process -[2025-07-14T22:39:57.806Z] [INFO] Performing complete container cleanup -[2025-07-14T22:40:03.465Z] [INFO] Container cleanup completed -[2025-07-14T22:40:03.475Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:40:03.485Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:40:03.485Z] [INFO] Starting new Empire container -[2025-07-14T22:40:03.486Z] [INFO] Pulling Empire image... -[2025-07-14T22:40:03.953Z] [INFO] Creating Empire data container... -[2025-07-14T22:40:04.267Z] [INFO] Starting Empire main container... -[2025-07-14T22:40:19.516Z] [INFO] Empire container is ready -[2025-07-14T22:40:19.516Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:40:19.516Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:40:27.828Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:40:27.828Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:40:57.798Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:40:57.799Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:41:27.804Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:41:27.805Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:41:27.805Z] [INFO] Starting Empire recovery process -[2025-07-14T22:41:27.805Z] [INFO] Performing complete container cleanup -[2025-07-14T22:41:33.448Z] [INFO] Container cleanup completed -[2025-07-14T22:41:33.458Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:41:33.469Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:41:33.470Z] [INFO] Starting new Empire container -[2025-07-14T22:41:33.470Z] [INFO] Pulling Empire image... -[2025-07-14T22:41:33.926Z] [INFO] Creating Empire data container... -[2025-07-14T22:41:34.253Z] [INFO] Starting Empire main container... -[2025-07-14T22:41:49.498Z] [INFO] Empire container is ready -[2025-07-14T22:41:49.498Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:41:49.498Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:41:57.865Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:41:57.866Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:42:27.734Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:42:27.735Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:42:57.798Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:42:57.799Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:42:57.799Z] [INFO] Starting Empire recovery process -[2025-07-14T22:42:57.799Z] [INFO] Performing complete container cleanup -[2025-07-14T22:43:03.459Z] [INFO] Container cleanup completed -[2025-07-14T22:43:03.469Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:43:03.479Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:43:03.479Z] [INFO] Starting new Empire container -[2025-07-14T22:43:03.479Z] [INFO] Pulling Empire image... -[2025-07-14T22:43:04.001Z] [INFO] Creating Empire data container... -[2025-07-14T22:43:04.301Z] [INFO] Starting Empire main container... -[2025-07-14T22:43:19.549Z] [INFO] Empire container is ready -[2025-07-14T22:43:19.550Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:43:19.550Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:43:27.840Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:43:27.840Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:43:57.821Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:43:57.822Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:44:27.807Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:44:27.807Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:44:27.807Z] [INFO] Starting Empire recovery process -[2025-07-14T22:44:27.807Z] [INFO] Performing complete container cleanup -[2025-07-14T22:44:33.460Z] [INFO] Container cleanup completed -[2025-07-14T22:44:33.470Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:44:33.479Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:44:33.480Z] [INFO] Starting new Empire container -[2025-07-14T22:44:33.480Z] [INFO] Pulling Empire image... -[2025-07-14T22:44:33.993Z] [INFO] Creating Empire data container... -[2025-07-14T22:44:34.292Z] [INFO] Starting Empire main container... -[2025-07-14T22:44:49.528Z] [INFO] Empire container is ready -[2025-07-14T22:44:49.529Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:44:49.529Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:44:57.851Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:44:57.852Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:45:27.816Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:45:27.817Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:45:57.808Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:45:57.809Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:45:57.809Z] [INFO] Starting Empire recovery process -[2025-07-14T22:45:57.809Z] [INFO] Performing complete container cleanup -[2025-07-14T22:46:03.442Z] [INFO] Container cleanup completed -[2025-07-14T22:46:03.450Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:46:03.458Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:46:03.459Z] [INFO] Starting new Empire container -[2025-07-14T22:46:03.459Z] [INFO] Pulling Empire image... -[2025-07-14T22:46:03.901Z] [INFO] Creating Empire data container... -[2025-07-14T22:46:04.153Z] [INFO] Starting Empire main container... -[2025-07-14T22:46:19.392Z] [INFO] Empire container is ready -[2025-07-14T22:46:19.393Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:46:19.393Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:46:27.855Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:46:27.856Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:46:57.814Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:46:57.815Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:47:27.821Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:47:27.822Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:47:27.822Z] [INFO] Starting Empire recovery process -[2025-07-14T22:47:27.822Z] [INFO] Performing complete container cleanup -[2025-07-14T22:47:33.481Z] [INFO] Container cleanup completed -[2025-07-14T22:47:33.491Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:47:33.501Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:47:33.502Z] [INFO] Starting new Empire container -[2025-07-14T22:47:33.502Z] [INFO] Pulling Empire image... -[2025-07-14T22:47:33.989Z] [INFO] Creating Empire data container... -[2025-07-14T22:47:34.316Z] [INFO] Starting Empire main container... -[2025-07-14T22:47:49.556Z] [INFO] Empire container is ready -[2025-07-14T22:47:49.556Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:47:49.556Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:47:57.868Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:47:57.868Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:48:27.827Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:48:27.827Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:48:57.826Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:48:57.827Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:48:57.828Z] [INFO] Starting Empire recovery process -[2025-07-14T22:48:57.828Z] [INFO] Performing complete container cleanup -[2025-07-14T22:49:03.485Z] [INFO] Container cleanup completed -[2025-07-14T22:49:03.496Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:49:03.506Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:49:03.506Z] [INFO] Starting new Empire container -[2025-07-14T22:49:03.507Z] [INFO] Pulling Empire image... -[2025-07-14T22:49:03.972Z] [INFO] Creating Empire data container... -[2025-07-14T22:49:04.286Z] [INFO] Starting Empire main container... -[2025-07-14T22:49:19.524Z] [INFO] Empire container is ready -[2025-07-14T22:49:19.525Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:49:19.525Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:49:27.851Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:49:27.851Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:49:57.865Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:49:57.865Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:50:27.841Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:50:27.842Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:50:27.842Z] [INFO] Starting Empire recovery process -[2025-07-14T22:50:27.842Z] [INFO] Performing complete container cleanup -[2025-07-14T22:50:33.495Z] [INFO] Container cleanup completed -[2025-07-14T22:50:33.505Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:50:33.515Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:50:33.515Z] [INFO] Starting new Empire container -[2025-07-14T22:50:33.515Z] [INFO] Pulling Empire image... -[2025-07-14T22:50:33.976Z] [INFO] Creating Empire data container... -[2025-07-14T22:50:34.280Z] [INFO] Starting Empire main container... -[2025-07-14T22:50:49.522Z] [INFO] Empire container is ready -[2025-07-14T22:50:49.523Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:50:49.523Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:50:57.878Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:50:57.879Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:51:27.842Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:51:27.842Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:51:57.829Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:51:57.829Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:51:57.829Z] [INFO] Starting Empire recovery process -[2025-07-14T22:51:57.829Z] [INFO] Performing complete container cleanup -[2025-07-14T22:52:03.489Z] [INFO] Container cleanup completed -[2025-07-14T22:52:03.499Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:52:03.509Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:52:03.509Z] [INFO] Starting new Empire container -[2025-07-14T22:52:03.509Z] [INFO] Pulling Empire image... -[2025-07-14T22:52:04.132Z] [INFO] Creating Empire data container... -[2025-07-14T22:52:04.469Z] [INFO] Starting Empire main container... -[2025-07-14T22:52:19.711Z] [INFO] Empire container is ready -[2025-07-14T22:52:19.711Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:52:19.712Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:52:27.871Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:52:27.872Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:52:57.840Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:52:57.840Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:53:27.861Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:53:27.862Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:53:27.862Z] [INFO] Starting Empire recovery process -[2025-07-14T22:53:27.862Z] [INFO] Performing complete container cleanup -[2025-07-14T22:53:33.519Z] [INFO] Container cleanup completed -[2025-07-14T22:53:33.529Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:53:33.539Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:53:33.539Z] [INFO] Starting new Empire container -[2025-07-14T22:53:33.540Z] [INFO] Pulling Empire image... -[2025-07-14T22:53:34.016Z] [INFO] Creating Empire data container... -[2025-07-14T22:53:34.304Z] [INFO] Starting Empire main container... -[2025-07-14T22:53:49.561Z] [INFO] Empire container is ready -[2025-07-14T22:53:49.561Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:53:49.561Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:53:57.881Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:53:57.881Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:54:27.847Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:54:27.847Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:54:57.851Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:54:57.852Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:54:57.852Z] [INFO] Starting Empire recovery process -[2025-07-14T22:54:57.852Z] [INFO] Performing complete container cleanup -[2025-07-14T22:55:03.509Z] [INFO] Container cleanup completed -[2025-07-14T22:55:03.520Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:55:03.531Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:55:03.531Z] [INFO] Starting new Empire container -[2025-07-14T22:55:03.531Z] [INFO] Pulling Empire image... -[2025-07-14T22:55:03.996Z] [INFO] Creating Empire data container... -[2025-07-14T22:55:04.320Z] [INFO] Starting Empire main container... -[2025-07-14T22:55:19.560Z] [INFO] Empire container is ready -[2025-07-14T22:55:19.560Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:55:19.560Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:55:27.888Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:55:27.889Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:55:57.860Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:55:57.861Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:56:27.850Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:56:27.850Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:56:27.850Z] [INFO] Starting Empire recovery process -[2025-07-14T22:56:27.851Z] [INFO] Performing complete container cleanup -[2025-07-14T22:56:33.493Z] [INFO] Container cleanup completed -[2025-07-14T22:56:33.503Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:56:33.514Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:56:33.514Z] [INFO] Starting new Empire container -[2025-07-14T22:56:33.514Z] [INFO] Pulling Empire image... -[2025-07-14T22:56:33.986Z] [INFO] Creating Empire data container... -[2025-07-14T22:56:34.296Z] [INFO] Starting Empire main container... -[2025-07-14T22:56:49.545Z] [INFO] Empire container is ready -[2025-07-14T22:56:49.545Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:56:49.546Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:56:57.933Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:56:57.933Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:57:27.866Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:57:27.866Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:57:57.861Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:57:57.861Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:57:57.861Z] [INFO] Starting Empire recovery process -[2025-07-14T22:57:57.861Z] [INFO] Performing complete container cleanup -[2025-07-14T22:58:03.524Z] [INFO] Container cleanup completed -[2025-07-14T22:58:03.534Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:58:03.544Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:58:03.544Z] [INFO] Starting new Empire container -[2025-07-14T22:58:03.544Z] [INFO] Pulling Empire image... -[2025-07-14T22:58:04.014Z] [INFO] Creating Empire data container... -[2025-07-14T22:58:04.327Z] [INFO] Starting Empire main container... -[2025-07-14T22:58:19.586Z] [INFO] Empire container is ready -[2025-07-14T22:58:19.586Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:58:19.587Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:58:27.930Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:58:27.931Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:58:57.879Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T22:58:57.879Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:59:27.875Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T22:59:27.876Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T22:59:27.876Z] [INFO] Starting Empire recovery process -[2025-07-14T22:59:27.876Z] [INFO] Performing complete container cleanup -[2025-07-14T22:59:33.526Z] [INFO] Container cleanup completed -[2025-07-14T22:59:33.536Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T22:59:33.546Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T22:59:33.546Z] [INFO] Starting new Empire container -[2025-07-14T22:59:33.546Z] [INFO] Pulling Empire image... -[2025-07-14T22:59:34.006Z] [INFO] Creating Empire data container... -[2025-07-14T22:59:34.287Z] [INFO] Starting Empire main container... -[2025-07-14T22:59:49.533Z] [INFO] Empire container is ready -[2025-07-14T22:59:49.533Z] [INFO] Empire recovery completed successfully -[2025-07-14T22:59:49.533Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T22:59:57.925Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T22:59:57.926Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:00:27.872Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T23:00:27.872Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:00:57.875Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T23:00:57.876Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T23:00:57.876Z] [INFO] Starting Empire recovery process -[2025-07-14T23:00:57.876Z] [INFO] Performing complete container cleanup -[2025-07-14T23:01:03.553Z] [INFO] Container cleanup completed -[2025-07-14T23:01:03.563Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T23:01:03.573Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T23:01:03.573Z] [INFO] Starting new Empire container -[2025-07-14T23:01:03.574Z] [INFO] Pulling Empire image... -[2025-07-14T23:01:04.056Z] [INFO] Creating Empire data container... -[2025-07-14T23:01:04.348Z] [INFO] Starting Empire main container... -[2025-07-14T23:01:19.603Z] [INFO] Empire container is ready -[2025-07-14T23:01:19.603Z] [INFO] Empire recovery completed successfully -[2025-07-14T23:01:19.603Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:01:27.900Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T23:01:27.900Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:01:57.874Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T23:01:57.874Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:02:27.883Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T23:02:27.884Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T23:02:27.884Z] [INFO] Starting Empire recovery process -[2025-07-14T23:02:27.884Z] [INFO] Performing complete container cleanup -[2025-07-14T23:02:33.544Z] [INFO] Container cleanup completed -[2025-07-14T23:02:33.554Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T23:02:33.565Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T23:02:33.565Z] [INFO] Starting new Empire container -[2025-07-14T23:02:33.565Z] [INFO] Pulling Empire image... -[2025-07-14T23:02:34.021Z] [INFO] Creating Empire data container... -[2025-07-14T23:02:34.304Z] [INFO] Starting Empire main container... -[2025-07-14T23:02:49.549Z] [INFO] Empire container is ready -[2025-07-14T23:02:49.550Z] [INFO] Empire recovery completed successfully -[2025-07-14T23:02:49.550Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:02:57.939Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T23:02:57.939Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:03:27.900Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T23:03:27.901Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:03:57.887Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T23:03:57.888Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T23:03:57.888Z] [INFO] Starting Empire recovery process -[2025-07-14T23:03:57.888Z] [INFO] Performing complete container cleanup -[2025-07-14T23:04:03.549Z] [INFO] Container cleanup completed -[2025-07-14T23:04:03.559Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T23:04:03.569Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T23:04:03.569Z] [INFO] Starting new Empire container -[2025-07-14T23:04:03.570Z] [INFO] Pulling Empire image... -[2025-07-14T23:04:04.047Z] [INFO] Creating Empire data container... -[2025-07-14T23:04:04.363Z] [INFO] Starting Empire main container... -[2025-07-14T23:04:19.605Z] [INFO] Empire container is ready -[2025-07-14T23:04:19.606Z] [INFO] Empire recovery completed successfully -[2025-07-14T23:04:19.606Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:04:27.928Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T23:04:27.928Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:04:57.876Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T23:04:57.876Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:05:27.876Z] [ERROR] Empire health check failed (3/3): Empire database connection failed -[2025-07-14T23:05:27.877Z] [ERROR] Maximum consecutive failures reached, attempting recovery -[2025-07-14T23:05:27.877Z] [INFO] Starting Empire recovery process -[2025-07-14T23:05:27.877Z] [INFO] Performing complete container cleanup -[2025-07-14T23:05:33.533Z] [INFO] Container cleanup completed -[2025-07-14T23:05:33.543Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/data -[2025-07-14T23:05:33.554Z] [INFO] Volume directory prepared: /home/cmndcntrl/code/attack-node/uploads/empire/downloads -[2025-07-14T23:05:33.554Z] [INFO] Starting new Empire container -[2025-07-14T23:05:33.554Z] [INFO] Pulling Empire image... -[2025-07-14T23:05:34.120Z] [INFO] Creating Empire data container... -[2025-07-14T23:05:34.422Z] [INFO] Starting Empire main container... -[2025-07-14T23:05:49.669Z] [INFO] Empire container is ready -[2025-07-14T23:05:49.669Z] [INFO] Empire recovery completed successfully -[2025-07-14T23:05:49.669Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:05:57.880Z] [ERROR] Empire health check failed (1/3): Empire database connection failed -[2025-07-14T23:05:57.881Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  -[2025-07-14T23:06:27.804Z] [ERROR] Empire health check failed (2/3): Empire database connection failed -[2025-07-14T23:06:27.804Z] [WARN] Empire warnings: Starkiller UI may not be accessible, Warning detected: [WARNING]: Using SQLite may result in performance issues and some functions may be disabled. , Warning detected: [WARNING]: Consider using MySQL instead.  diff --git a/logs/empire-install.log b/logs/empire-install.log deleted file mode 100644 index c99b298..0000000 --- a/logs/empire-install.log +++ /dev/null @@ -1,8 +0,0 @@ -[2025-07-14 15:44:50] [INFO] Checking Docker availability... -[2025-07-14 15:44:50] [SUCCESS] Docker is available and running -[2025-07-14 15:44:50] [INFO] Checking for existing Empire installations... -[2025-07-14 15:44:50] [NETWORK] Performing comprehensive network health check... -[2025-07-14 15:44:50] [NETWORK] Checking internet connectivity... -[2025-07-14 15:44:51] [SUCCESS] Internet connectivity confirmed -[2025-07-14 15:44:51] [NETWORK] Checking DNS resolution... -[2025-07-14 15:44:51] [ERROR] DNS resolution failed diff --git a/fix-django-errors.sh b/maintenance/fix-django-errors.sh similarity index 98% rename from fix-django-errors.sh rename to maintenance/fix-django-errors.sh index e08d143..0457c08 100755 --- a/fix-django-errors.sh +++ b/maintenance/fix-django-errors.sh @@ -29,13 +29,13 @@ run_docker() { fi } -# Function to run docker-compose command with fallback to sudo +# Function to run docker compose command with fallback to sudo run_docker_compose() { - if docker-compose "$@" 2>/dev/null; then + if docker compose "$@" 2>/dev/null; then return 0 else - log "Docker-compose command failed, trying with sudo..." - sudo docker-compose "$@" + log "Docker compose command failed, trying with sudo..." + sudo docker compose "$@" fi } diff --git a/fix-dns-resolution.sh b/maintenance/fix-dns-resolution.sh similarity index 100% rename from fix-dns-resolution.sh rename to maintenance/fix-dns-resolution.sh diff --git a/fix-postgres-permissions.sh b/maintenance/fix-postgres-permissions.sh similarity index 100% rename from fix-postgres-permissions.sh rename to maintenance/fix-postgres-permissions.sh diff --git a/fix-redis-permissions.sh b/maintenance/fix-redis-permissions.sh similarity index 100% rename from fix-redis-permissions.sh rename to maintenance/fix-redis-permissions.sh diff --git a/fix-redis-rdb-format.sh b/maintenance/fix-redis-rdb-format.sh similarity index 100% rename from fix-redis-rdb-format.sh rename to maintenance/fix-redis-rdb-format.sh diff --git a/test-startup-containers.sh b/maintenance/test-startup-containers.sh similarity index 100% rename from test-startup-containers.sh rename to maintenance/test-startup-containers.sh diff --git a/mcp/package.json b/mcp/package.json new file mode 100644 index 0000000..27a58ea --- /dev/null +++ b/mcp/package.json @@ -0,0 +1,34 @@ +{ + "name": "attack-node-mcp-server", + "version": "1.0.0", + "description": "MCP server for attack-node cybersecurity testing capabilities", + "type": "module", + "main": "build/index.js", + "bin": { + "attack-node-mcp": "build/index.js" + }, + "scripts": { + "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", + "dev": "tsx watch src/index.ts", + "start": "node build/index.js" + }, + "dependencies": { + "@modelcontextprotocol/sdk": "^1.17.2", + "axios": "^1.6.0", + "ws": "^8.18.0", + "zod": "^3.24.2" + }, + "devDependencies": { + "@types/node": "^20.16.11", + "@types/ws": "^8.5.13", + "tsx": "^4.19.1", + "typescript": "^5.6.3" + }, + "keywords": [ + "mcp", + "cybersecurity", + "penetration-testing", + "attack-simulation" + ], + "license": "MIT" +} diff --git a/mcp/server.py b/mcp/server.py new file mode 100644 index 0000000..856c9f3 --- /dev/null +++ b/mcp/server.py @@ -0,0 +1,800 @@ +#!/usr/bin/env python3 +""" +Attack Node MCP Server - Cybersecurity Testing and Attack Simulation + +This MCP server exposes penetration testing, vulnerability assessment, +and attack simulation capabilities from the attack-node environment. +""" + +import asyncio +import json +import logging +import sys +import os +import subprocess +from pathlib import Path +from typing import Any, Dict, List, Optional +import requests +import time + +# Add the tools directory to the Python path +sys.path.insert(0, str(Path(__file__).parent.parent.parent / "tools")) + +from mcp.server.models import InitializationOptions +from mcp.server import NotificationOptions, Server +from mcp.types import ( + Resource, + Tool, + TextContent, + ImageContent, + EmbeddedResource, + LoggingLevel +) +import mcp.types as types + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger("attack-node-mcp-server") + +class AttackNodeMCPServer: + """ + Attack Node MCP Server for cybersecurity testing and attack simulation. + """ + + def __init__(self): + self.server = Server("attack-node-mcp-server") + self.tools_path = Path(__file__).parent.parent.parent / "tools" + self.base_url = os.environ.get('ATTACK_NODE_BASE_URL', 'http://localhost:5173') + self.empire_base_url = os.environ.get('EMPIRE_BASE_URL', 'http://localhost:1337') + self.empire_token = os.environ.get('EMPIRE_API_TOKEN') + self.test_history = {} + + # Initialize session for HTTP requests + self.session = requests.Session() + self.session.headers.update({ + 'User-Agent': 'Attack-Node-MCP-Server/1.0.0', + 'Content-Type': 'application/json' + }) + + logger.info(f"Attack Node MCP Server initialized") + logger.info(f"Tools path: {self.tools_path}") + logger.info(f"Base URL: {self.base_url}") + + def setup_handlers(self): + """Set up MCP request handlers.""" + + @self.server.list_resources() + async def handle_list_resources() -> list[Resource]: + """List available attack-node resources.""" + return [ + Resource( + uri="attack-node://tools/list", + name="Available Attack Tools", + description="List of all available cybersecurity testing tools", + mimeType="application/json" + ), + Resource( + uri="attack-node://status/health", + name="Attack Node Health Status", + description="Current health and status of attack-node services", + mimeType="application/json" + ), + Resource( + uri="attack-node://history/tests", + name="Test Execution History", + description="History of executed security tests and their results", + mimeType="application/json" + ), + Resource( + uri="attack-node://empire/listeners", + name="Empire C2 Listeners", + description="Active PowerShell Empire command and control listeners", + mimeType="application/json" + ) + ] + + @self.server.read_resource() + async def handle_read_resource(uri: types.AnyUrl) -> str: + """Read attack-node resource content.""" + uri_str = str(uri) + + if uri_str == "attack-node://tools/list": + return await self.get_available_tools() + elif uri_str == "attack-node://status/health": + return await self.get_health_status() + elif uri_str == "attack-node://history/tests": + return await self.get_test_history() + elif uri_str == "attack-node://empire/listeners": + return await self.get_empire_listeners() + else: + raise ValueError(f"Unknown resource: {uri_str}") + + @self.server.list_tools() + async def handle_list_tools() -> list[Tool]: + """List available attack-node tools.""" + return [ + Tool( + name="test_web_vulnerabilities", + description="Test web applications for injection vulnerabilities (SQL, NoSQL, Command)", + inputSchema={ + "type": "object", + "properties": { + "target_url": { + "type": "string", + "description": "URL of the target web application to test" + }, + "parameters": { + "type": "array", + "items": {"type": "string"}, + "description": "List of parameters to test for injection vulnerabilities" + } + }, + "required": ["target_url"] + } + ), + Tool( + name="analyze_cross_site_vulnerabilities", + description="Test for Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)", + inputSchema={ + "type": "object", + "properties": { + "target_url": { + "type": "string", + "description": "URL of the target web application to test" + } + }, + "required": ["target_url"] + } + ), + Tool( + name="evaluate_authentication_security", + description="Assess authentication implementation security including brute force protection and session management", + inputSchema={ + "type": "object", + "properties": { + "login_url": { + "type": "string", + "description": "URL of the login page" + }, + "auth_flow": { + "type": "object", + "properties": { + "username_field": {"type": "string"}, + "password_field": {"type": "string"}, + "submit_button": {"type": "string"}, + "csrf_token_field": {"type": "string"}, + "redirect_url": {"type": "string"} + }, + "required": ["username_field", "password_field", "submit_button"], + "description": "Authentication flow configuration" + } + }, + "required": ["login_url", "auth_flow"] + } + ), + Tool( + name="scan_framework_security", + description="Analyze web application framework security configurations", + inputSchema={ + "type": "object", + "properties": { + "target_url": { + "type": "string", + "description": "URL of the target application" + }, + "framework_hints": { + "type": "array", + "items": {"type": "string"}, + "description": "Known or suspected frameworks (optional)" + } + }, + "required": ["target_url"] + } + ), + Tool( + name="generate_vulnerability_report", + description="Generate comprehensive vulnerability assessment reports", + inputSchema={ + "type": "object", + "properties": { + "scan_results": { + "type": "array", + "items": {"type": "object"}, + "description": "Array of scan result objects" + }, + "target_info": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "url": {"type": "string"}, + "description": {"type": "string"} + }, + "description": "Information about the target" + }, + "report_format": { + "type": "string", + "enum": ["json", "html", "pdf", "markdown"], + "default": "json", + "description": "Output format for the report" + } + }, + "required": ["scan_results", "target_info"] + } + ), + Tool( + name="orchestrate_burp_scan", + description="Orchestrate Burp Suite Professional scans through API integration", + inputSchema={ + "type": "object", + "properties": { + "target_url": { + "type": "string", + "description": "Target URL for Burp Suite scan" + }, + "scan_config": { + "type": "object", + "properties": { + "scope": {"type": "array", "items": {"type": "string"}}, + "excluded_paths": {"type": "array", "items": {"type": "string"}}, + "scan_speed": {"type": "string", "enum": ["fast", "normal", "thorough"]}, + "passive_scanning": {"type": "boolean"}, + "active_scanning": {"type": "boolean"} + }, + "description": "Burp Suite scan configuration" + } + }, + "required": ["target_url"] + } + ), + Tool( + name="start_empire_listener", + description="Start PowerShell Empire listener for command and control operations", + inputSchema={ + "type": "object", + "properties": { + "listener_name": { + "type": "string", + "description": "Name for the Empire listener" + }, + "listener_type": { + "type": "string", + "enum": ["http", "https", "dbx", "meterpreter"], + "default": "http", + "description": "Type of Empire listener" + }, + "port": { + "type": "number", + "description": "Port for the listener", + "minimum": 1, + "maximum": 65535 + }, + "host": { + "type": "string", + "default": "0.0.0.0", + "description": "Host address for the listener" + } + }, + "required": ["listener_name", "port"] + } + ), + Tool( + name="generate_empire_payload", + description="Generate PowerShell Empire payloads for various target systems", + inputSchema={ + "type": "object", + "properties": { + "listener_name": { + "type": "string", + "description": "Name of the Empire listener to use" + }, + "payload_type": { + "type": "string", + "enum": ["powershell", "python", "csharp", "macro", "ducky"], + "description": "Type of payload to generate" + }, + "target_os": { + "type": "string", + "enum": ["windows", "linux", "macos"], + "description": "Target operating system" + }, + "evasion": { + "type": "boolean", + "default": False, + "description": "Enable evasion techniques" + } + }, + "required": ["listener_name", "payload_type", "target_os"] + } + ) + ] + + @self.server.call_tool() + async def handle_call_tool(name: str, arguments: dict[str, Any] | None) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: + """Handle tool execution requests.""" + + if arguments is None: + arguments = {} + + try: + if name == "test_web_vulnerabilities": + return await self.execute_web_vulnerability_test(arguments) + elif name == "analyze_cross_site_vulnerabilities": + return await self.execute_cross_site_analysis(arguments) + elif name == "evaluate_authentication_security": + return await self.execute_auth_security_evaluation(arguments) + elif name == "scan_framework_security": + return await self.execute_framework_security_scan(arguments) + elif name == "generate_vulnerability_report": + return await self.execute_vulnerability_report_generation(arguments) + elif name == "orchestrate_burp_scan": + return await self.execute_burp_scan_orchestration(arguments) + elif name == "start_empire_listener": + return await self.execute_empire_listener_start(arguments) + elif name == "generate_empire_payload": + return await self.execute_empire_payload_generation(arguments) + else: + raise ValueError(f"Unknown tool: {name}") + + except Exception as e: + logger.error(f"Error executing tool {name}: {e}") + return [ + types.TextContent( + type="text", + text=f"Error executing {name}: {str(e)}" + ) + ] + + async def execute_web_vulnerability_test(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Execute web vulnerability testing.""" + target_url = args.get("target_url") + parameters = args.get("parameters", []) + + try: + result = await self.execute_python_tool( + 'bug_hunter.WebVulnerabilityTester', + 'test_injection_vulnerabilities', + {'target_url': target_url, 'parameters': parameters} + ) + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_cross_site_analysis(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Execute cross-site vulnerability analysis.""" + target_url = args.get("target_url") + + try: + result = await self.execute_python_tool( + 'bug_hunter.WebVulnerabilityTester', + 'analyze_cross_site_vulnerabilities', + {'target_url': target_url} + ) + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_auth_security_evaluation(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Execute authentication security evaluation.""" + login_url = args.get("login_url") + auth_flow = args.get("auth_flow") + + try: + result = await self.execute_python_tool( + 'bug_hunter.WebVulnerabilityTester', + 'evaluate_authentication_security', + {'login_url': login_url, 'auth_flow': auth_flow} + ) + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_framework_security_scan(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Execute framework security scan.""" + target_url = args.get("target_url") + framework_hints = args.get("framework_hints", []) + + try: + result = await self.execute_python_tool( + 'bug_hunter.FrameworkSecurityAnalyzer', + 'analyze_framework_security', + {'target_url': target_url, 'framework_hints': framework_hints} + ) + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_vulnerability_report_generation(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Execute vulnerability report generation.""" + scan_results = args.get("scan_results") + target_info = args.get("target_info") + report_format = args.get("report_format", "json") + + try: + result = await self.execute_python_tool( + 'bug_hunter.VulnerabilityReportGenerator', + 'generate_comprehensive_report', + { + 'scan_results': scan_results, + 'target_info': target_info, + 'report_format': report_format + } + ) + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_burp_scan_orchestration(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Execute Burp Suite scan orchestration.""" + target_url = args.get("target_url") + scan_config = args.get("scan_config", {}) + + try: + result = await self.execute_python_tool( + 'burpsuite_operator.BurpScanOrchestrator', + 'orchestrate_comprehensive_scan', + {'target_url': target_url, 'scan_config': scan_config} + ) + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_empire_listener_start(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Start PowerShell Empire listener.""" + listener_name = args.get("listener_name") + listener_type = args.get("listener_type", "http") + port = args.get("port") + host = args.get("host", "0.0.0.0") + + try: + if not self.empire_token: + raise ValueError("Empire API token not configured. Set EMPIRE_API_TOKEN environment variable.") + + # Start Empire listener via API + empire_response = self.session.post( + f"{self.empire_base_url}/api/listeners", + json={ + "name": listener_name, + "template": listener_type, + "options": { + "Host": host, + "Port": str(port) + } + }, + headers={"Authorization": f"Bearer {self.empire_token}"} + ) + + if empire_response.status_code == 200: + result = { + "success": True, + "listener_id": empire_response.json().get("id"), + "listener_name": listener_name, + "listener_type": listener_type, + "host": host, + "port": port, + "status": "started", + "empire_response": empire_response.json() + } + else: + result = { + "success": False, + "error": f"Empire API error: {empire_response.status_code} - {empire_response.text}" + } + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + async def execute_empire_payload_generation(self, args: Dict[str, Any]) -> List[types.TextContent]: + """Generate PowerShell Empire payload.""" + listener_name = args.get("listener_name") + payload_type = args.get("payload_type") + target_os = args.get("target_os") + evasion = args.get("evasion", False) + + try: + if not self.empire_token: + raise ValueError("Empire API token not configured. Set EMPIRE_API_TOKEN environment variable.") + + # Get listener information + listeners_response = self.session.get( + f"{self.empire_base_url}/api/listeners", + headers={"Authorization": f"Bearer {self.empire_token}"} + ) + + if listeners_response.status_code != 200: + raise ValueError(f"Failed to get listeners: {listeners_response.text}") + + listeners = listeners_response.json().get("listeners", []) + listener = next((l for l in listeners if l.get("name") == listener_name), None) + + if not listener: + raise ValueError(f"Listener '{listener_name}' not found") + + # Generate stager + stager_name = self.map_payload_type_to_stager(payload_type, target_os) + stager_response = self.session.post( + f"{self.empire_base_url}/api/stagers", + json={ + "StagerName": stager_name, + "Listener": listener_name, + "options": { + "Evasion": evasion + } + }, + headers={"Authorization": f"Bearer {self.empire_token}"} + ) + + if stager_response.status_code == 200: + stager_data = stager_response.json() + result = { + "success": True, + "listener_name": listener_name, + "payload_type": payload_type, + "target_os": target_os, + "evasion": evasion, + "payload": stager_data.get("stager") or stager_data.get("output"), + "empire_response": stager_data + } + else: + result = { + "success": False, + "error": f"Empire stager generation failed: {stager_response.status_code} - {stager_response.text}" + } + + return [types.TextContent(type="text", text=json.dumps(result, indent=2))] + + except Exception as e: + return [types.TextContent( + type="text", + text=json.dumps({"success": False, "error": str(e)}, indent=2) + )] + + def map_payload_type_to_stager(self, payload_type: str, target_os: str) -> str: + """Map payload type and OS to Empire stager name.""" + stager_map = { + "powershell": { + "windows": "windows/launcher_bat", + "linux": "linux/launcher", + "macos": "osx/launcher" + }, + "python": { + "windows": "windows/launcher_py", + "linux": "linux/launcher", + "macos": "osx/launcher" + }, + "csharp": { + "windows": "windows/csharp_exe", + "linux": "linux/csharp_exe", + "macos": "osx/csharp_exe" + }, + "macro": { + "windows": "windows/macro", + "linux": "windows/macro", + "macos": "windows/macro" + }, + "ducky": { + "windows": "windows/ducky", + "linux": "linux/ducky", + "macos": "osx/ducky" + } + } + + return stager_map.get(payload_type, {}).get(target_os, "windows/launcher_bat") + + async def execute_python_tool(self, module_path: str, method: str, args: Dict[str, Any]) -> Dict[str, Any]: + """Execute a Python tool method.""" + try: + # Create a script to execute the tool + script_content = f''' +import sys +import json +import os +sys.path.append("{str(self.tools_path)}") + +try: + from {module_path} import {module_path.split(".")[-1]} + + tool_instance = {module_path.split(".")[-1]}() + args = {json.dumps(args)} + + if hasattr(tool_instance, "{method}"): + result = getattr(tool_instance, "{method}")(**args) + print(json.dumps(result)) + else: + print(json.dumps({{"success": False, "error": "Method {method} not found"}})) +except Exception as e: + print(json.dumps({{"success": False, "error": str(e)}})) +''' + + # Execute the script + process = subprocess.run( + ['python', '-c', script_content], + cwd=str(self.tools_path), + capture_output=True, + text=True, + timeout=300 # 5 minute timeout + ) + + if process.returncode == 0: + try: + return json.loads(process.stdout.strip()) + except json.JSONDecodeError: + return {"success": False, "error": f"Failed to parse tool output: {process.stdout}"} + else: + return {"success": False, "error": f"Tool execution failed: {process.stderr}"} + + except subprocess.TimeoutExpired: + return {"success": False, "error": "Tool execution timed out"} + except Exception as e: + return {"success": False, "error": f"Failed to execute tool: {str(e)}"} + + async def get_available_tools(self) -> str: + """Get list of available tools.""" + tools_data = { + "web_vulnerability_testing": [ + "test_injection_vulnerabilities", + "analyze_cross_site_vulnerabilities", + "evaluate_authentication_security" + ], + "framework_analysis": [ + "scan_framework_security", + "analyze_security_headers", + "check_security_configurations" + ], + "reporting": [ + "generate_vulnerability_report", + "create_executive_summary", + "export_findings" + ], + "burp_suite_integration": [ + "orchestrate_burp_scan", + "process_burp_results", + "assess_burp_findings" + ], + "empire_c2": [ + "start_empire_listener", + "generate_empire_payload", + "manage_empire_agents" + ] + } + + return json.dumps(tools_data, indent=2) + + async def get_health_status(self) -> str: + """Get attack-node health status.""" + health_data = { + "timestamp": time.time(), + "services": {}, + "overall_status": "healthy" + } + + # Check web server + try: + response = self.session.get(f"{self.base_url}/api/health", timeout=5) + health_data["services"]["web_server"] = { + "status": "healthy" if response.status_code == 200 else "unhealthy", + "response_time": response.elapsed.total_seconds(), + "last_check": time.time() + } + except Exception as e: + health_data["services"]["web_server"] = { + "status": "unhealthy", + "error": str(e), + "last_check": time.time() + } + + # Check Empire C2 + try: + response = self.session.get(f"{self.empire_base_url}/api/version", timeout=5) + health_data["services"]["empire_c2"] = { + "status": "healthy" if response.status_code == 200 else "unhealthy", + "response_time": response.elapsed.total_seconds(), + "last_check": time.time() + } + except Exception as e: + health_data["services"]["empire_c2"] = { + "status": "unhealthy", + "error": str(e), + "last_check": time.time() + } + + # Check Python tools availability + try: + test_result = await self.execute_python_tool( + 'bug_hunter.WebVulnerabilityTester', + '__init__', + {} + ) + health_data["services"]["python_tools"] = { + "status": "healthy", + "tools_path": str(self.tools_path), + "last_check": time.time() + } + except Exception as e: + health_data["services"]["python_tools"] = { + "status": "unhealthy", + "error": str(e), + "last_check": time.time() + } + + # Determine overall status + failed_services = [name for name, service in health_data["services"].items() if service["status"] != "healthy"] + if failed_services: + health_data["overall_status"] = "degraded" if len(failed_services) < len(health_data["services"]) else "unhealthy" + + return json.dumps(health_data, indent=2) + + async def get_test_history(self) -> str: + """Get test execution history.""" + history_data = { + "total_tests": len(self.test_history), + "recent_tests": list(self.test_history.values())[-10:], # Last 10 tests + "test_types": { + "web_vulnerability": len([t for t in self.test_history.values() if t.get("type") == "web_vulnerability"]), + "cross_site": len([t for t in self.test_history.values() if t.get("type") == "cross_site"]), + "authentication": len([t for t in self.test_history.values() if t.get("type") == "authentication"]), + "framework_scan": len([t for t in self.test_history.values() if t.get("type") == "framework_scan"]), + "burp_scan": len([t for t in self.test_history.values() if t.get("type") == "burp_scan"]) + }, + "timestamp": time.time() + } + + return json.dumps(history_data, indent=2) + + async def get_empire_listeners(self) -> str: + """Get active Empire C2 listeners.""" + try: + if not self.empire_token: + return json.dumps({"error": "Empire API token not configured"}, indent=2) + + response = self.session.get( + f"{self.empire_base_url}/api/listeners", + headers={"Authorization": f"Bearer {self.empire_token}"} + ) + + if response.status_code == 200: + listeners_data = response.json() + return json.dumps({ + "success": True, + "listeners": listeners_data.get("listeners", []), + "total_listeners": len(listeners_data.get("listeners", [])), + "timestamp": time.time() + }, indent=2) + else: + return json.dumps({ + "success": False, + "error": f"Empire API error: {response.status_code} - {response diff --git a/mcp/src/index.ts b/mcp/src/index.ts new file mode 100644 index 0000000..1e6f4a0 --- /dev/null +++ b/mcp/src/index.ts @@ -0,0 +1,806 @@ +#!/usr/bin/env node +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { + CallToolRequestSchema, + ErrorCode, + ListResourcesRequestSchema, + ListResourceTemplatesRequestSchema, + ListToolsRequestSchema, + McpError, + ReadResourceRequestSchema, +} from '@modelcontextprotocol/sdk/types.js'; +import { spawn } from 'child_process'; +import { promises as fs } from 'fs'; +import path from 'path'; +import axios from 'axios'; + +interface ToolExecutionResult { + success: boolean; + data?: any; + error?: string; + execution_time?: number; +} + +class AttackNodeMCPServer { + private server: Server; + private toolsPath: string; + private baseUrl: string; + + constructor() { + this.server = new Server( + { + name: 'attack-node-mcp-server', + version: '1.0.0', + }, + { + capabilities: { + resources: {}, + tools: {}, + }, + } + ); + + // Set paths relative to the project root + this.toolsPath = path.resolve(process.cwd(), '../..', 'tools'); + this.baseUrl = process.env.ATTACK_NODE_BASE_URL || 'http://localhost:5173'; + + this.setupResourceHandlers(); + this.setupToolHandlers(); + + // Error handling + this.server.onerror = (error) => console.error('[MCP Error]', error); + process.on('SIGINT', async () => { + await this.server.close(); + process.exit(0); + }); + } + + private setupResourceHandlers() { + // Static resources for attack-node capabilities + this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({ + resources: [ + { + uri: 'attack-node://tools/list', + name: 'Available Attack Tools', + mimeType: 'application/json', + description: 'List of all available cybersecurity testing tools' + }, + { + uri: 'attack-node://status/health', + name: 'Attack Node Health Status', + mimeType: 'application/json', + description: 'Current health and status of attack-node services' + }, + { + uri: 'attack-node://history/tests', + name: 'Test Execution History', + mimeType: 'application/json', + description: 'History of executed security tests and their results' + } + ], + })); + + // Dynamic resource templates + this.server.setRequestHandler( + ListResourceTemplatesRequestSchema, + async () => ({ + resourceTemplates: [ + { + uriTemplate: 'attack-node://results/{test_id}', + name: 'Test Results', + mimeType: 'application/json', + description: 'Detailed results for a specific test execution' + }, + { + uriTemplate: 'attack-node://reports/{report_type}/{target}', + name: 'Security Reports', + mimeType: 'application/json', + description: 'Generated security reports for specific targets' + } + ], + }) + ); + + this.server.setRequestHandler( + ReadResourceRequestSchema, + async (request) => { + const uri = request.params.uri; + + if (uri === 'attack-node://tools/list') { + return this.getAvailableTools(); + } + + if (uri === 'attack-node://status/health') { + return this.getHealthStatus(); + } + + if (uri === 'attack-node://history/tests') { + return this.getTestHistory(); + } + + // Handle dynamic resources + const resultMatch = uri.match(/^attack-node:\/\/results\/(.+)$/); + if (resultMatch) { + return this.getTestResults(resultMatch[1]); + } + + const reportMatch = uri.match(/^attack-node:\/\/reports\/(.+)\/(.+)$/); + if (reportMatch) { + return this.getSecurityReport(reportMatch[1], reportMatch[2]); + } + + throw new McpError( + ErrorCode.InvalidRequest, + `Unknown resource: ${uri}` + ); + } + ); + } + + private setupToolHandlers() { + this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ + tools: [ + { + name: 'test_web_vulnerabilities', + description: 'Test web applications for injection vulnerabilities (SQL, NoSQL, Command)', + inputSchema: { + type: 'object', + properties: { + target_url: { + type: 'string', + description: 'URL of the target web application to test' + }, + parameters: { + type: 'array', + items: { type: 'string' }, + description: 'List of parameters to test for injection vulnerabilities' + } + }, + required: ['target_url'] + } + }, + { + name: 'analyze_cross_site_vulnerabilities', + description: 'Test for Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)', + inputSchema: { + type: 'object', + properties: { + target_url: { + type: 'string', + description: 'URL of the target web application to test' + } + }, + required: ['target_url'] + } + }, + { + name: 'evaluate_authentication_security', + description: 'Assess authentication implementation security including brute force protection and session management', + inputSchema: { + type: 'object', + properties: { + login_url: { + type: 'string', + description: 'URL of the login page' + }, + auth_flow: { + type: 'object', + properties: { + username_field: { type: 'string', description: 'Name of the username input field' }, + password_field: { type: 'string', description: 'Name of the password input field' }, + submit_button: { type: 'string', description: 'Selector for the submit button' }, + csrf_token_field: { type: 'string', description: 'Name of the CSRF token field (optional)' }, + redirect_url: { type: 'string', description: 'Expected redirect URL after login (optional)' }, + test_credentials: { + type: 'array', + items: { + type: 'object', + properties: { + username: { type: 'string' }, + password: { type: 'string' } + } + }, + description: 'List of test credentials to try (optional)' + } + }, + required: ['username_field', 'password_field', 'submit_button'], + description: 'Authentication flow configuration' + } + }, + required: ['login_url', 'auth_flow'] + } + }, + { + name: 'scan_framework_security', + description: 'Analyze web application framework security configurations and implementations', + inputSchema: { + type: 'object', + properties: { + target_url: { + type: 'string', + description: 'URL of the target application' + }, + framework_hints: { + type: 'array', + items: { type: 'string' }, + description: 'Known or suspected frameworks (optional)' + } + }, + required: ['target_url'] + } + }, + { + name: 'generate_vulnerability_report', + description: 'Generate comprehensive vulnerability assessment reports', + inputSchema: { + type: 'object', + properties: { + scan_results: { + type: 'array', + items: { type: 'object' }, + description: 'Array of scan result objects' + }, + target_info: { + type: 'object', + properties: { + name: { type: 'string' }, + url: { type: 'string' }, + description: { type: 'string' } + }, + description: 'Information about the target' + }, + report_format: { + type: 'string', + enum: ['json', 'html', 'pdf', 'markdown'], + default: 'json', + description: 'Output format for the report' + } + }, + required: ['scan_results', 'target_info'] + } + }, + { + name: 'orchestrate_burp_scan', + description: 'Orchestrate Burp Suite Professional scans through API integration', + inputSchema: { + type: 'object', + properties: { + target_url: { + type: 'string', + description: 'Target URL for Burp Suite scan' + }, + scan_config: { + type: 'object', + properties: { + scope: { type: 'array', items: { type: 'string' } }, + excluded_paths: { type: 'array', items: { type: 'string' } }, + scan_speed: { type: 'string', enum: ['fast', 'normal', 'thorough'] }, + passive_scanning: { type: 'boolean' }, + active_scanning: { type: 'boolean' } + }, + description: 'Burp Suite scan configuration' + } + }, + required: ['target_url'] + } + }, + ], + })); + + this.server.setRequestHandler(CallToolRequestSchema, async (request) => { + const { name, arguments: args } = request.params; + + switch (name) { + case 'test_web_vulnerabilities': + return this.executeWebVulnerabilityTest(args); + case 'analyze_cross_site_vulnerabilities': + return this.executeCrossSiteAnalysis(args); + case 'evaluate_authentication_security': + return this.executeAuthSecurityEvaluation(args); + case 'scan_framework_security': + return this.executeFrameworkSecurityScan(args); + case 'generate_vulnerability_report': + return this.executeVulnerabilityReportGeneration(args); + case 'orchestrate_burp_scan': + return this.executeBurpScanOrchestration(args); + default: + throw new McpError( + ErrorCode.MethodNotFound, + `Unknown tool: ${name}` + ); + } + }); + } + + private async executeWebVulnerabilityTest(args: any): Promise { + const { target_url, parameters } = args; + + try { + const result = await this.executePythonTool('bug_hunter/WebVulnerabilityTester.py', 'test_injection_vulnerabilities', { + target_url, + parameters: parameters || [] + }); + + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Error executing web vulnerability test: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + + private async executeCrossSiteAnalysis(args: any): Promise { + const { target_url } = args; + + try { + const result = await this.executePythonTool('bug_hunter/WebVulnerabilityTester.py', 'analyze_cross_site_vulnerabilities', { + target_url + }); + + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Error executing cross-site vulnerability analysis: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + + private async executeAuthSecurityEvaluation(args: any): Promise { + const { login_url, auth_flow } = args; + + try { + const result = await this.executePythonTool('bug_hunter/WebVulnerabilityTester.py', 'evaluate_authentication_security', { + login_url, + auth_flow + }); + + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Error executing authentication security evaluation: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + + private async executeFrameworkSecurityScan(args: any): Promise { + const { target_url, framework_hints } = args; + + try { + const result = await this.executePythonTool('bug_hunter/FrameworkSecurityAnalyzer.py', 'analyze_framework_security', { + target_url, + framework_hints: framework_hints || [] + }); + + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Error executing framework security scan: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + + private async executeVulnerabilityReportGeneration(args: any): Promise { + const { scan_results, target_info, report_format } = args; + + try { + const result = await this.executePythonTool('bug_hunter/VulnerabilityReportGenerator.py', 'generate_comprehensive_report', { + scan_results, + target_info, + report_format: report_format || 'json' + }); + + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Error generating vulnerability report: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + + private async executeBurpScanOrchestration(args: any): Promise { + const { target_url, scan_config } = args; + + try { + const result = await this.executePythonTool('burpsuite_operator/BurpScanOrchestrator.py', 'orchestrate_comprehensive_scan', { + target_url, + scan_config: scan_config || {} + }); + + return { + content: [ + { + type: 'text', + text: JSON.stringify(result, null, 2) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Error orchestrating Burp Suite scan: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + + + private async executePythonTool(toolPath: string, method: string, args: any): Promise { + return new Promise((resolve, reject) => { + // Create a temporary script to execute the Python tool + const scriptContent = ` +import sys +import json +import os +sys.path.append('${this.toolsPath}') + +# Import the tool +from ${toolPath.replace('/', '.').replace('.py', '')} import ${this.getClassNameFromPath(toolPath)} + +# Create instance and execute method +tool_instance = ${this.getClassNameFromPath(toolPath)}() +args = json.loads('${JSON.stringify(args)}') + +try: + if hasattr(tool_instance, '${method}'): + result = getattr(tool_instance, '${method}')(**args) + print(json.dumps(result)) + else: + print(json.dumps({"success": False, "error": "Method ${method} not found"})) +except Exception as e: + print(json.dumps({"success": False, "error": str(e)})) +`; + + const pythonProcess = spawn('python', ['-c', scriptContent], { + cwd: this.toolsPath + }); + + let output = ''; + let errorOutput = ''; + + pythonProcess.stdout.on('data', (data) => { + output += data.toString(); + }); + + pythonProcess.stderr.on('data', (data) => { + errorOutput += data.toString(); + }); + + pythonProcess.on('close', (code) => { + if (code === 0) { + try { + const result = JSON.parse(output.trim()); + resolve(result); + } catch (parseError) { + reject(new Error(`Failed to parse Python tool output: ${output}`)); + } + } else { + reject(new Error(`Python tool execution failed: ${errorOutput}`)); + } + }); + + pythonProcess.on('error', (error) => { + reject(new Error(`Failed to spawn Python process: ${error.message}`)); + }); + }); + } + + private getClassNameFromPath(toolPath: string): string { + const filename = path.basename(toolPath, '.py'); + return filename; + } + + private async getAvailableTools(): Promise { + try { + const toolsData = { + web_vulnerability_testing: [ + 'test_injection_vulnerabilities', + 'analyze_cross_site_vulnerabilities', + 'evaluate_authentication_security' + ], + framework_analysis: [ + 'scan_framework_security', + 'analyze_security_headers', + 'check_security_configurations' + ], + reporting: [ + 'generate_vulnerability_report', + 'create_executive_summary', + 'export_findings' + ], + burp_suite_integration: [ + 'orchestrate_burp_scan', + 'process_burp_results', + 'assess_burp_findings' + ], + }; + + return { + contents: [ + { + uri: 'attack-node://tools/list', + mimeType: 'application/json', + text: JSON.stringify(toolsData, null, 2) + } + ] + }; + } catch (error) { + throw new McpError( + ErrorCode.InternalError, + `Failed to get available tools: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + private async getHealthStatus(): Promise { + try { + // Check health of various attack-node services + const healthData = { + timestamp: new Date().toISOString(), + services: { + web_server: await this.checkServiceHealth(`${this.baseUrl}/api/health`), + burp_suite: await this.checkServiceHealth('http://localhost:1337/burp/api/health'), + python_tools: await this.checkPythonToolsHealth() + }, + overall_status: 'healthy' + }; + + // Determine overall status + const failedServices = Object.entries(healthData.services).filter(([_, status]) => (status as any).status !== 'healthy'); + if (failedServices.length > 0) { + healthData.overall_status = failedServices.length === Object.keys(healthData.services).length ? 'unhealthy' : 'degraded'; + } + + return { + contents: [ + { + uri: 'attack-node://status/health', + mimeType: 'application/json', + text: JSON.stringify(healthData, null, 2) + } + ] + }; + } catch (error) { + throw new McpError( + ErrorCode.InternalError, + `Failed to get health status: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + private async getTestHistory(): Promise { + try { + // This would typically come from a database or log files + // For now, return a placeholder structure + const historyData = { + total_tests: 0, + recent_tests: [], + test_types: { + web_vulnerability: 0, + cross_site: 0, + authentication: 0, + framework_scan: 0, + burp_scan: 0 + } + }; + + return { + contents: [ + { + uri: 'attack-node://history/tests', + mimeType: 'application/json', + text: JSON.stringify(historyData, null, 2) + } + ] + }; + } catch (error) { + throw new McpError( + ErrorCode.InternalError, + `Failed to get test history: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + private async getTestResults(testId: string): Promise { + try { + // This would typically fetch from database + // For now, return a placeholder + const resultsData = { + test_id: testId, + status: 'completed', + results: {}, + timestamp: new Date().toISOString() + }; + + return { + contents: [ + { + uri: `attack-node://results/${testId}`, + mimeType: 'application/json', + text: JSON.stringify(resultsData, null, 2) + } + ] + }; + } catch (error) { + throw new McpError( + ErrorCode.InternalError, + `Failed to get test results: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + private async getSecurityReport(reportType: string, target: string): Promise { + try { + // This would typically generate or fetch existing reports + const reportData = { + report_type: reportType, + target: decodeURIComponent(target), + generated_at: new Date().toISOString(), + findings: [] + }; + + return { + contents: [ + { + uri: `attack-node://reports/${reportType}/${target}`, + mimeType: 'application/json', + text: JSON.stringify(reportData, null, 2) + } + ] + }; + } catch (error) { + throw new McpError( + ErrorCode.InternalError, + `Failed to get security report: ${error instanceof Error ? error.message : String(error)}` + ); + } + } + + private async checkServiceHealth(url: string): Promise { + try { + const response = await axios.get(url, { timeout: 5000 }); + return { + status: 'healthy', + response_time: response.headers['x-response-time'] || 'unknown', + last_check: new Date().toISOString() + }; + } catch (error) { + return { + status: 'unhealthy', + error: error instanceof Error ? error.message : String(error), + last_check: new Date().toISOString() + }; + } + } + + private async checkPythonToolsHealth(): Promise { + try { + // Test if Python and required tools are available + return new Promise((resolve) => { + const pythonProcess = spawn('python', ['-c', 'import sys; print("Python available")'], { + cwd: this.toolsPath + }); + + let output = ''; + let errorOutput = ''; + + pythonProcess.stdout.on('data', (data: any) => { + output += data.toString(); + }); + + pythonProcess.stderr.on('data', (data: any) => { + errorOutput += data.toString(); + }); + + pythonProcess.on('close', (code: number) => { + if (code === 0) { + resolve({ + status: 'healthy', + python_version: output.trim(), + tools_path: this.toolsPath, + last_check: new Date().toISOString() + }); + } else { + resolve({ + status: 'unhealthy', + error: errorOutput || 'Python not available', + last_check: new Date().toISOString() + }); + } + }); + + pythonProcess.on('error', (error: Error) => { + resolve({ + status: 'unhealthy', + error: `Failed to spawn Python: ${error.message}`, + last_check: new Date().toISOString() + }); + }); + }); + } catch (error) { + return { + status: 'unhealthy', + error: error instanceof Error ? error.message : String(error), + last_check: new Date().toISOString() + }; + } + } + + async run() { + const transport = new StdioServerTransport(); + await this.server.connect(transport); + console.error('Attack Node MCP server running on stdio'); + } +} + +const server = new AttackNodeMCPServer(); +server.run().catch(console.error); diff --git a/mcp/start-server.bat b/mcp/start-server.bat new file mode 100644 index 0000000..f5cb312 --- /dev/null +++ b/mcp/start-server.bat @@ -0,0 +1,42 @@ +@echo off +echo Starting Attack Node MCP Server... + +REM Check if Node.js is available +node --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo Node.js is not installed or not in PATH + echo Please install Node.js from https://nodejs.org/ + pause + exit /b 1 +) + +REM Change to MCP directory +cd /d "%~dp0" + +REM Install dependencies if node_modules doesn't exist +if not exist "node_modules" ( + echo Installing dependencies... + npm install + if %errorlevel% neq 0 ( + echo Failed to install dependencies + pause + exit /b 1 + ) +) + +REM Build the project if build directory doesn't exist +if not exist "build" ( + echo Building project... + npm run build + if %errorlevel% neq 0 ( + echo Failed to build project + pause + exit /b 1 + ) +) + +REM Start the MCP server +echo Starting MCP server... +node build/index.js + +pause diff --git a/mcp/tsconfig.json b/mcp/tsconfig.json new file mode 100644 index 0000000..970e8e8 --- /dev/null +++ b/mcp/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "allowJs": true, + "sourceMap": true, + "outDir": "./build", + "rootDir": "./src", + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleDetection": "force", + "resolveJsonModule": true, + "isolatedModules": true, + "verbatimModuleSyntax": false, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "build" + ] +} diff --git a/package-lock.json b/package-lock.json index e55019d..be7b328 100644 --- a/package-lock.json +++ b/package-lock.json @@ -157,9 +157,9 @@ } }, "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { - "version": "18.19.115", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.115.tgz", - "integrity": "sha512-kNrFiTgG4a9JAn1LMQeLOv3MvXIPokzXziohMrMsvpYgLpdEt/mMiVYc4sGKtDfyxM5gIDF4VgrPRyCw4fHOYg==", + "version": "18.19.123", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.123.tgz", + "integrity": "sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -172,24 +172,24 @@ "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@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.25.9", + "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", - "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", "dev": true, "license": "MIT", "engines": { @@ -197,22 +197,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", + "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.3", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -228,15 +228,16 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", - "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -244,14 +245,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", + "@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" @@ -260,30 +261,40 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@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.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@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.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -293,9 +304,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "license": "MIT", "engines": { @@ -303,9 +314,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -313,9 +324,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, "license": "MIT", "engines": { @@ -323,9 +334,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { @@ -333,26 +344,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", + "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.28.2" }, "bin": { "parser": "bin/babel-parser.js" @@ -362,13 +374,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@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.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -378,13 +390,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@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.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -394,56 +406,57 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@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.26.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", - "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", + "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -946,9 +959,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", "cpu": [ "ppc64" ], @@ -963,9 +976,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", "cpu": [ "arm" ], @@ -980,9 +993,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", "cpu": [ "arm64" ], @@ -997,9 +1010,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", "cpu": [ "x64" ], @@ -1014,9 +1027,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", "cpu": [ "arm64" ], @@ -1031,9 +1044,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", "cpu": [ "x64" ], @@ -1048,9 +1061,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", "cpu": [ "arm64" ], @@ -1065,9 +1078,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", "cpu": [ "x64" ], @@ -1082,9 +1095,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", "cpu": [ "arm" ], @@ -1099,9 +1112,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", "cpu": [ "arm64" ], @@ -1116,9 +1129,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", "cpu": [ "ia32" ], @@ -1133,9 +1146,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", "cpu": [ "loong64" ], @@ -1150,9 +1163,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", "cpu": [ "mips64el" ], @@ -1167,9 +1180,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", "cpu": [ "ppc64" ], @@ -1184,9 +1197,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", "cpu": [ "riscv64" ], @@ -1201,9 +1214,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", "cpu": [ "s390x" ], @@ -1218,9 +1231,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", "cpu": [ "x64" ], @@ -1235,9 +1248,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", "cpu": [ "arm64" ], @@ -1252,9 +1265,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", "cpu": [ "x64" ], @@ -1269,9 +1282,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", "cpu": [ "arm64" ], @@ -1286,9 +1299,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", "cpu": [ "x64" ], @@ -1302,10 +1315,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", "cpu": [ "x64" ], @@ -1320,9 +1350,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", "cpu": [ "arm64" ], @@ -1337,9 +1367,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", "cpu": [ "ia32" ], @@ -1354,9 +1384,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", "cpu": [ "x64" ], @@ -1371,28 +1401,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", - "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.9" + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.13", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", - "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz", + "integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==", + "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.9" + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", - "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.5.tgz", + "integrity": "sha512-HDO/1/1oH9fjj4eLgegrlH3dklZpHtUYYFiVwMUwfGvk9jWDRWqkklA2/NFScknrcNSspbV868WjXORvreDX+Q==", + "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.0.0" + "@floating-ui/dom": "^1.7.3" }, "peerDependencies": { "react": ">=16.8.0", @@ -1400,14 +1433,16 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", - "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" }, "node_modules/@hookform/resolvers": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz", "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==", + "license": "MIT", "peerDependencies": { "react-hook-form": "^7.0.0" } @@ -1429,18 +1464,38 @@ "node": ">=12" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@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" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -1452,25 +1507,16 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1498,9 +1544,9 @@ } }, "node_modules/@neondatabase/serverless/node_modules/pg-types": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", - "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.1.0.tgz", + "integrity": "sha512-o2XFanIMy/3+mThw69O8d4n1E5zsLhdO+OPqswezu7Z5ekP4hYDqlDjlmOpYMbzY2Br0ufCwJLdDIXeNVwcWFg==", "license": "MIT", "dependencies": { "pg-int8": "1.0.1", @@ -1589,6 +1635,13 @@ "node": ">= 8" } }, + "node_modules/@petamoriken/float16": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz", + "integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==", + "dev": true, + "license": "MIT" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1602,27 +1655,30 @@ "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==" + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", - "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" }, "node_modules/@radix-ui/react-accordion": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.4.tgz", - "integrity": "sha512-SGCxlSBaMvEzDROzyZjsVNzu9XY5E28B3k8jOENyrz6csOv/pG1eHyYfLJai1n9tRjwG61coXDhfpgtxKxUv5g==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collapsible": "1.1.4", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1640,16 +1696,17 @@ } }, "node_modules/@radix-ui/react-alert-dialog": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.7.tgz", - "integrity": "sha512-7Gx1gcoltd0VxKoR8mc+TAVbzvChJyZryZsTam0UhoL92z0L+W8ovxvcgvd+nkz24y7Qc51JQKBAGe4+825tYw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dialog": "1.1.7", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0" + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1667,11 +1724,12 @@ } }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.3.tgz", - "integrity": "sha512-2dvVU4jva0qkNZH6HHWuSz5FN5GeU5tymvCgutF8WaXz9WnD1NgUhy73cqzkjkN4Zkn8lfTPv5JIfrC221W+Nw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.3" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1689,11 +1747,12 @@ } }, "node_modules/@radix-ui/react-aspect-ratio": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.3.tgz", - "integrity": "sha512-yIrYZUc2e/JtRkDpuJCmaR6kj/jzekDfQLcPFdEWzSOygCPy8poR4YcszaHP5A7mh25ncofHEpeTwfhxEuBv8Q==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.3" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1711,13 +1770,15 @@ } }, "node_modules/@radix-ui/react-avatar": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.4.tgz", - "integrity": "sha512-+kBesLBzwqyDiYCtYFK+6Ktf+N7+Y6QOTUueLGLIbLZ/YeyFW6bsBGDsN+5HxHpM55C90u5fxsg0ErxzXTcwKA==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "license": "MIT", "dependencies": { "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { @@ -1736,16 +1797,17 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.5.tgz", - "integrity": "sha512-B0gYIVxl77KYDR25AY9EGe/G//ef85RVBIxQvK+m5pxAC7XihAc/8leMHhDvjvhDu02SBSb6BuytlWr/G7F3+g==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, @@ -1765,17 +1827,18 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.4.tgz", - "integrity": "sha512-u7LCw1EYInQtBNLGjm9nZ89S/4GcvX1UR5XbekEgnQae2Hkpq39ycJ1OhdeN1/JDfVNG91kWaWoest127TaEKQ==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { @@ -1794,14 +1857,15 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.3.tgz", - "integrity": "sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1822,6 +1886,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1836,6 +1901,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1847,16 +1913,17 @@ } }, "node_modules/@radix-ui/react-context-menu": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.7.tgz", - "integrity": "sha512-EwO3tyyqwGaLPg0P64jmIKJnBywD0yjiL1eRuMPyhUXPkWWpa5JPDS+oyeIWHy2JbhF+NUlfUPVq6vE7OqgZww==", + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz", + "integrity": "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-menu": "2.1.7", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1874,22 +1941,23 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.7.tgz", - "integrity": "sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.6", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, @@ -1912,6 +1980,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1923,13 +1992,14 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.6.tgz", - "integrity": "sha512-7gpgMT2gyKym9Jz2ZhlRXSg2y6cNQIK8d/cqBZ0RBCaps8pFryCWXiUKI+uHGFrhMrbGUP7U6PWgiXzIxoyF3Q==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, @@ -1949,17 +2019,18 @@ } }, "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.7.tgz", - "integrity": "sha512-7/1LiuNZuCQE3IzdicGoHdQOHkS2Q08+7p8w6TXZ6ZjgAULaCI85ZY15yPl4o4FVgoKLRT43/rsfNVN8osClQQ==", + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.7", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1977,9 +2048,10 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", - "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1991,12 +2063,13 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.3.tgz", - "integrity": "sha512-4XaDlq0bPt7oJwR+0k0clCiCO/7lO7NKZTAaJBYxDNQT/vj4ig0/UvctrRscZaFREpRvUTkpKR96ov1e6jptQg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { @@ -2015,19 +2088,20 @@ } }, "node_modules/@radix-ui/react-hover-card": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.7.tgz", - "integrity": "sha512-HwM03kP8psrv21J1+9T/hhxi0f5rARVbqIZl9+IAq13l4j4fX+oGIuxisukZZmebO7J35w9gpoILvtG8bbph0w==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.6", - "@radix-ui/react-popper": "1.2.3", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2048,6 +2122,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, @@ -2062,11 +2137,12 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.3.tgz", - "integrity": "sha512-zwSQ1NzSKG95yA0tvBMgv6XPHoqapJCcg9nsUBaQQ66iRBhZNhlpaQG2ERYYX4O4stkYFK5rxj5NsWfO9CS+Hg==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.3" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2084,25 +2160,26 @@ } }, "node_modules/@radix-ui/react-menu": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.7.tgz", - "integrity": "sha512-tBODsrk68rOi1/iQzbM54toFF+gSw/y+eQgttFflqlGekuSebNqvFNHjJgjqPhiMb4Fw9A0zNFly1QT6ZFdQ+Q==", + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.6", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.3", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-roving-focus": "1.1.3", - "@radix-ui/react-slot": "1.2.0", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" @@ -2123,20 +2200,21 @@ } }, "node_modules/@radix-ui/react-menubar": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.7.tgz", - "integrity": "sha512-YB2zFhGdZ5SWEgRS+PgrF7EkwpsjEHntIFB/LRbT49LJdnIeK/xQQyuwLiRcOCgTDN+ALlPXQ08f0P0+TfR41g==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", + "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.7", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-roving-focus": "1.1.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2154,24 +2232,25 @@ } }, "node_modules/@radix-ui/react-navigation-menu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.6.tgz", - "integrity": "sha512-HJqyzqG74Lj7KV58rk73i/B1nnopVyCfUmKgeGWWrZZiCuMNcY0KKugTrmqMbIeMliUnkBUDKCy9J6Mzl6xeWw==", + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.6", + "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.1.3" + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -2189,23 +2268,24 @@ } }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.7.tgz", - "integrity": "sha512-I38OYWDmJF2kbO74LX8UsFydSHWOJuQ7LxPnTefjxxvdvPLempvAnmsyX9UsBlywcbSGpRH7oMLfkUf+ij4nrw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.6", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.3", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, @@ -2225,15 +2305,16 @@ } }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.3.tgz", - "integrity": "sha512-iNb9LYUMkne9zIahukgQmHlSBp9XWGeQQ7FvUGNk45ywzOb6kQa+Ca38OphXlWDiKvyneo9S+KSJsLfLt8812A==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.3", + "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", @@ -2256,11 +2337,12 @@ } }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.5.tgz", - "integrity": "sha512-ps/67ZqsFm+Mb6lSPJpfhRLrVL2i2fntgCmGMqqth4eaGUf+knAuuRtWVJrNjUhExgmdRqftSgzpf0DF0n6yXA==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { @@ -2279,9 +2361,10 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.3.tgz", - "integrity": "sha512-IrVLIhskYhH3nLvtcBLQFZr61tBG7wx7O3kEmdzcYwRGAEBmBicGGL7ATzNgruYJ3xBTbuzEEq9OXJM3PAX3tA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" @@ -2302,11 +2385,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.3.tgz", - "integrity": "sha512-Pf/t/GkndH7CQ8wE2hbkXA+WyZ83fhQQn5DDmwDiDo6AwN/fhaH8oqZ0jRjMrO2iaMhDi6P1HRx6AZwyMinY1g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.0" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -2324,12 +2408,13 @@ } }, "node_modules/@radix-ui/react-progress": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.3.tgz", - "integrity": "sha512-F56aZPGTPb4qJQ/vDjnAq63oTu/DRoIG/Asb5XKOWj8rpefNLtUllR969j5QDN2sRrTk9VXIqQDRj5VvAuquaw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", + "license": "MIT", "dependencies": { "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.0.3" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2347,18 +2432,19 @@ } }, "node_modules/@radix-ui/react-radio-group": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.4.tgz", - "integrity": "sha512-oLz7ATfKgVTUbpr5OBu6Q7hQcnV22uPT306bmG0QwgnKqBStR98RfWfJGCfW/MmhL4ISmrmmBPBW+c77SDwV9g==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-roving-focus": "1.1.3", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, @@ -2378,19 +2464,20 @@ } }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.3.tgz", - "integrity": "sha512-ufbpLUjZiOg4iYgb2hQrWXEPYX6jOLBbR27bDyAff5GYMRrCzcze8lukjuXVUQvJ6HZe8+oL+hhswDcjmcgVyg==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2408,17 +2495,18 @@ } }, "node_modules/@radix-ui/react-scroll-area": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.4.tgz", - "integrity": "sha512-G9rdWTQjOR4sk76HwSdROhPU0jZWpfozn9skU1v4N0/g9k7TmswrJn8W8WMU+aYktnLLpk5LX6fofj2bGe5NFQ==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, @@ -2438,29 +2526,30 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.7.tgz", - "integrity": "sha512-exzGIRtc7S8EIM2KjFg+7lJZsH7O7tpaBaJbBNVDnOZNhtoQ2iV+iSNfi2Wth0m6h3trJkMVvzAehB3c6xj/3Q==", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.6", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.3", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.3", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.1.3", + "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, @@ -2480,11 +2569,12 @@ } }, "node_modules/@radix-ui/react-separator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.3.tgz", - "integrity": "sha512-2omrWKJvxR0U/tkIXezcc1nFMwtLU0+b/rDK40gnzJqTLWQ/TD/D5IYVefp9sC3QWfeQbpSbEA6op9MQKyaALQ==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.3" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2502,18 +2592,19 @@ } }, "node_modules/@radix-ui/react-slider": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.2.4.tgz", - "integrity": "sha512-Vr/OgNejNJPAghIhjS7Mf/2F/EXGDT0qgtiHf2BHz71+KqgN+jndFLKq5xAB9JOGejGzejfJLIvT04Do+yzhcg==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", + "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" @@ -2534,9 +2625,10 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", - "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, @@ -2551,15 +2643,16 @@ } }, "node_modules/@radix-ui/react-switch": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.4.tgz", - "integrity": "sha512-zGP6W8plLeogoeGMiTHJ/uvf+TE1C2chVsEwfP8YlvpQKJHktG+iCkUtCLGPAuDV8/qDSmIRPm4NggaTxFMVBQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, @@ -2579,18 +2672,19 @@ } }, "node_modules/@radix-ui/react-tabs": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.4.tgz", - "integrity": "sha512-fuHMHWSf5SRhXke+DbHXj2wVMo+ghVH30vhX3XVacdXqDl+J4XWafMIGOOER861QpBx1jxgwKXL2dQnfrsd8MQ==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-roving-focus": "1.1.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2608,23 +2702,23 @@ } }, "node_modules/@radix-ui/react-toast": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.7.tgz", - "integrity": "sha512-0IWTbAUKvzdpOaWDMZisXZvScXzF0phaQjWspK8RUMEUxjLbli+886mB/kXTIC3F+t5vQ0n0vYn+dsX8s+WdfA==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", + "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.6", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-visually-hidden": "1.1.3" + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -2642,13 +2736,14 @@ } }, "node_modules/@radix-ui/react-toggle": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.3.tgz", - "integrity": "sha512-Za5HHd9nvsiZ2t3EI/dVd4Bm/JydK+D22uHKk46fPtvuPxVCJBUo5mQybN+g5sZe35y7I6GDTTfdkVv5SnxlFg==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2666,17 +2761,18 @@ } }, "node_modules/@radix-ui/react-toggle-group": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.3.tgz", - "integrity": "sha512-khTzdGIxy8WurYUEUrapvj5aOev/tUA8TDEFi1D0Dn3yX+KR5AqjX0b7E5sL9ngRRpxDN2RRJdn5siasu5jtcg==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-roving-focus": "1.1.3", - "@radix-ui/react-toggle": "1.1.3", - "@radix-ui/react-use-controllable-state": "1.1.1" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2694,22 +2790,23 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.0.tgz", - "integrity": "sha512-b1Sdc75s7zN9B8ONQTGBSHL3XS8+IcjcOIY51fhM4R1Hx8s0YbgqgyNZiri4qcYMVZK8hfCZVBiyCm7N9rs0rw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.6", + "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.3", - "@radix-ui/react-portal": "1.1.5", - "@radix-ui/react-presence": "1.1.3", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-slot": "1.2.0", - "@radix-ui/react-use-controllable-state": "1.1.1", - "@radix-ui/react-visually-hidden": "1.1.3" + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -2730,6 +2827,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2741,11 +2839,31 @@ } }, "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.1.tgz", - "integrity": "sha512-YnEXIy8/ga01Y1PN0VfaNH//MhA91JlEGVBDxDzROqwrAtG5Yr2QGEPz8A/rJA3C7ZAHryOYGaUv8fLSW2H/mg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -2761,6 +2879,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, @@ -2774,10 +2893,29 @@ } } }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-layout-effect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2792,6 +2930,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2806,6 +2945,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", "dependencies": { "@radix-ui/rect": "1.1.1" }, @@ -2823,6 +2963,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, @@ -2837,11 +2978,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.3.tgz", - "integrity": "sha512-oXSF3ZQRd5fvomd9hmUCb2EHSZbPp3ZSHAHJJU/DlF9XoFkJBBW8RHU/E8WEH+RbSfJd/QFA0sl8ClJXknBwHQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.3" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2861,12 +3003,20 @@ "node_modules/@radix-ui/rect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==" + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@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.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.4.tgz", - "integrity": "sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", + "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", "cpu": [ "arm" ], @@ -2878,9 +3028,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.4.tgz", - "integrity": "sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", + "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", "cpu": [ "arm64" ], @@ -2892,9 +3042,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.4.tgz", - "integrity": "sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", + "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", "cpu": [ "arm64" ], @@ -2906,9 +3056,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.4.tgz", - "integrity": "sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", + "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", "cpu": [ "x64" ], @@ -2920,9 +3070,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.4.tgz", - "integrity": "sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", + "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", "cpu": [ "arm64" ], @@ -2934,9 +3084,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.4.tgz", - "integrity": "sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", + "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", "cpu": [ "x64" ], @@ -2948,9 +3098,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.4.tgz", - "integrity": "sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", + "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", "cpu": [ "arm" ], @@ -2962,9 +3112,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.4.tgz", - "integrity": "sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", + "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", "cpu": [ "arm" ], @@ -2976,9 +3126,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.4.tgz", - "integrity": "sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", + "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", "cpu": [ "arm64" ], @@ -2990,9 +3140,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.4.tgz", - "integrity": "sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", + "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", "cpu": [ "arm64" ], @@ -3003,10 +3153,24 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.4.tgz", - "integrity": "sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==", + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", + "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", + "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", "cpu": [ "ppc64" ], @@ -3018,9 +3182,23 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.4.tgz", - "integrity": "sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", + "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", + "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", "cpu": [ "riscv64" ], @@ -3032,9 +3210,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.4.tgz", - "integrity": "sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", + "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", "cpu": [ "s390x" ], @@ -3046,9 +3224,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.4.tgz", - "integrity": "sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", + "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", "cpu": [ "x64" ], @@ -3060,9 +3238,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.4.tgz", - "integrity": "sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", + "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", "cpu": [ "x64" ], @@ -3074,9 +3252,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.4.tgz", - "integrity": "sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", + "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", "cpu": [ "arm64" ], @@ -3088,9 +3266,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.4.tgz", - "integrity": "sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", + "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", "cpu": [ "ia32" ], @@ -3102,9 +3280,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.4.tgz", - "integrity": "sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", + "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", "cpu": [ "x64" ], @@ -3116,62 +3294,66 @@ ] }, "node_modules/@tailwindcss/node": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.3.tgz", - "integrity": "sha512-H/6r6IPFJkCfBJZ2dKZiPJ7Ueb2wbL592+9bQEl2r73qbX6yGnmQVIfiUvDRB2YI0a3PWDrzUwkvQx1XW1bNkA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.12.tgz", + "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==", "dev": true, + "license": "MIT", "dependencies": { - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.29.2", - "tailwindcss": "4.1.3" - } - }, - "node_modules/@tailwindcss/node/node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "dev": true, - "bin": { - "jiti": "lib/jiti-cli.mjs" + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.5.1", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.12" } }, "node_modules/@tailwindcss/node/node_modules/tailwindcss": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz", - "integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==", - "dev": true + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz", + "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==", + "dev": true, + "license": "MIT" }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.3.tgz", - "integrity": "sha512-t16lpHCU7LBxDe/8dCj9ntyNpXaSTAgxWm1u2XQP5NiIu4KGSyrDJJRlK9hJ4U9yJxx0UKCVI67MJWFNll5mOQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.12.tgz", + "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, "engines": { "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.3", - "@tailwindcss/oxide-darwin-arm64": "4.1.3", - "@tailwindcss/oxide-darwin-x64": "4.1.3", - "@tailwindcss/oxide-freebsd-x64": "4.1.3", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.3", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.3", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.3", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.3", - "@tailwindcss/oxide-linux-x64-musl": "4.1.3", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.3", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.3" + "@tailwindcss/oxide-android-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-x64": "4.1.12", + "@tailwindcss/oxide-freebsd-x64": "4.1.12", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.12", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-x64-musl": "4.1.12", + "@tailwindcss/oxide-wasm32-wasi": "4.1.12", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.12" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.3.tgz", - "integrity": "sha512-cxklKjtNLwFl3mDYw4XpEfBY+G8ssSg9ADL4Wm6//5woi3XGqlxFsnV5Zb6v07dxw1NvEX2uoqsxO/zWQsgR+g==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz", + "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -3181,13 +3363,14 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.3.tgz", - "integrity": "sha512-mqkf2tLR5VCrjBvuRDwzKNShRu99gCAVMkVsaEOFvv6cCjlEKXRecPu9DEnxp6STk5z+Vlbh1M5zY3nQCXMXhw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz", + "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3197,13 +3380,14 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.3.tgz", - "integrity": "sha512-7sGraGaWzXvCLyxrc7d+CCpUN3fYnkkcso3rCzwUmo/LteAl2ZGCDlGvDD8Y/1D3ngxT8KgDj1DSwOnNewKhmg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz", + "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3213,13 +3397,14 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.3.tgz", - "integrity": "sha512-E2+PbcbzIReaAYZe997wb9rId246yDkCwAakllAWSGqe6VTg9hHle67hfH6ExjpV2LSK/siRzBUs5wVff3RW9w==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz", + "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -3229,13 +3414,14 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.3.tgz", - "integrity": "sha512-GvfbJ8wjSSjbLFFE3UYz4Eh8i4L6GiEYqCtA8j2Zd2oXriPuom/Ah/64pg/szWycQpzRnbDiJozoxFU2oJZyfg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz", + "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3245,13 +3431,14 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.3.tgz", - "integrity": "sha512-35UkuCWQTeG9BHcBQXndDOrpsnt3Pj9NVIB4CgNiKmpG8GnCNXeMczkUpOoqcOhO6Cc/mM2W7kaQ/MTEENDDXg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz", + "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3261,13 +3448,14 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.3.tgz", - "integrity": "sha512-dm18aQiML5QCj9DQo7wMbt1Z2tl3Giht54uVR87a84X8qRtuXxUqnKQkRDK5B4bCOmcZ580lF9YcoMkbDYTXHQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz", + "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3277,13 +3465,14 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.3.tgz", - "integrity": "sha512-LMdTmGe/NPtGOaOfV2HuO7w07jI3cflPrVq5CXl+2O93DCewADK0uW1ORNAcfu2YxDUS035eY2W38TxrsqngxA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz", + "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3293,13 +3482,14 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.3.tgz", - "integrity": "sha512-aalNWwIi54bbFEizwl1/XpmdDrOaCjRFQRgtbv9slWjmNPuJJTIKPHf5/XXDARc9CneW9FkSTqTbyvNecYAEGw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz", + "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3308,14 +3498,45 @@ "node": ">= 10" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz", + "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@emnapi/wasi-threads": "^1.0.4", + "@napi-rs/wasm-runtime": "^0.2.12", + "@tybys/wasm-util": "^0.10.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.3.tgz", - "integrity": "sha512-PEj7XR4OGTGoboTIAdXicKuWl4EQIjKHKuR+bFy9oYN7CFZo0eu74+70O4XuERX4yjqVZGAkCdglBODlgqcCXg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz", + "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3325,13 +3546,14 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.3.tgz", - "integrity": "sha512-T8gfxECWDBENotpw3HR9SmNiHC9AOJdxs+woasRZ8Q/J4VHN0OMs7F+4yVNZ9EVN26Wv6mZbK0jv7eHYuLJLwA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz", + "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3341,9 +3563,9 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", - "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", "dev": true, "license": "MIT", "dependencies": { @@ -3353,47 +3575,35 @@ "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" - } - }, - "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "node_modules/@tailwindcss/vite": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.3.tgz", - "integrity": "sha512-lUI/QaDxLtlV52Lho6pu07CG9pSnRYLOPmKGIQjyHdTBagemc6HmgZxyjGAQ/5HMPrNeWBfTVIpQl0/jLXvWHQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.12.tgz", + "integrity": "sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==", "dev": true, + "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.1.3", - "@tailwindcss/oxide": "4.1.3", - "tailwindcss": "4.1.3" + "@tailwindcss/node": "4.1.12", + "@tailwindcss/oxide": "4.1.12", + "tailwindcss": "4.1.12" }, "peerDependencies": { - "vite": "^5.2.0 || ^6" + "vite": "^5.2.0 || ^6 || ^7" } }, "node_modules/@tailwindcss/vite/node_modules/tailwindcss": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz", - "integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==", - "dev": true + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz", + "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==", + "dev": true, + "license": "MIT" }, "node_modules/@tanstack/query-core": { - "version": "5.60.5", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.60.5.tgz", - "integrity": "sha512-jiS1aC3XI3BJp83ZiTuDLerTmn9P3U95r6p+6/SNauLJaYxfIC4dMuWygwnBHIZxjn2zJqEpj3nysmPieoxfPQ==", + "version": "5.85.3", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.3.tgz", + "integrity": "sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==", "license": "MIT", "funding": { "type": "github", @@ -3401,12 +3611,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.60.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.60.5.tgz", - "integrity": "sha512-M77bOsPwj1wYE56gk7iJvxGAr4IC12NWdIDhT+Eo8ldkWRHMvIR8I/rufIvT1OXoV/bl7EECwuRuMlxxWtvW2Q==", + "version": "5.85.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.3.tgz", + "integrity": "sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.60.5" + "@tanstack/query-core": "5.85.3" }, "funding": { "type": "github", @@ -3431,9 +3641,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", "dependencies": { @@ -3452,19 +3662,19 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.20.7" + "@babel/types": "^7.28.2" } }, "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "license": "MIT", "dependencies": { "@types/connect": "*", @@ -3520,33 +3730,33 @@ } }, "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "license": "MIT" }, "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", "license": "MIT", "dependencies": { "@types/d3-time": "*" } }, "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", "license": "MIT", "dependencies": { "@types/d3-path": "*" } }, "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", "license": "MIT" }, "node_modules/@types/d3-timer": { @@ -3565,9 +3775,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/estree-jsx": { @@ -3604,9 +3814,9 @@ } }, "node_modules/@types/express-session": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.0.tgz", - "integrity": "sha512-27JdDRgor6PoYlURY+Y5kCakqp5ulC0kmf7y+QwaY+hv9jEFuQOThgkjyA53RP3jmKuBsH5GR6qEfFmvb8mwOA==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.2.tgz", + "integrity": "sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg==", "dev": true, "license": "MIT", "dependencies": { @@ -3623,9 +3833,9 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "license": "MIT" }, "node_modules/@types/mdast": { @@ -3674,13 +3884,13 @@ } }, "node_modules/@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "license": "MIT", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" } }, "node_modules/@types/passport": { @@ -3717,9 +3927,9 @@ } }, "node_modules/@types/pg": { - "version": "8.15.4", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.4.tgz", - "integrity": "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==", + "version": "8.15.5", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.5.tgz", + "integrity": "sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3729,15 +3939,15 @@ } }, "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "license": "MIT" }, "node_modules/@types/range-parser": { @@ -3747,9 +3957,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", - "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "version": "18.3.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -3757,19 +3967,19 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "devOptional": true, "license": "MIT", - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", "license": "MIT", "dependencies": { "@types/mime": "^1", @@ -3777,9 +3987,9 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", "license": "MIT", "dependencies": { "@types/http-errors": "*", @@ -3794,9 +4004,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.13", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", - "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "dev": true, "license": "MIT", "dependencies": { @@ -3810,23 +4020,24 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", - "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.25.2", - "@babel/plugin-transform-react-jsx-self": "^7.24.7", - "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@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.14.2" + "react-refresh": "^0.17.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "node_modules/abort-controller": { @@ -3867,9 +4078,9 @@ } }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", "license": "MIT", "engines": { "node": ">=12" @@ -3922,9 +4133,9 @@ "license": "MIT" }, "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -3946,9 +4157,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", "dev": true, "funding": [ { @@ -3966,11 +4177,11 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -4051,9 +4262,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -4072,9 +4283,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.25.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.2.tgz", + "integrity": "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==", "dev": true, "funding": [ { @@ -4092,10 +4303,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" + "caniuse-lite": "^1.0.30001733", + "electron-to-chromium": "^1.5.199", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -4111,9 +4322,9 @@ "license": "MIT" }, "node_modules/bufferutil": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", - "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -4144,36 +4355,33 @@ "node": ">= 0.8" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" + "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": { @@ -4186,9 +4394,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "version": "1.0.30001735", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz", + "integrity": "sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==", "dev": true, "funding": [ { @@ -4292,10 +4500,21 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", "dependencies": { "clsx": "^2.1.1" }, @@ -4307,6 +4526,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -4315,6 +4535,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", @@ -4459,6 +4680,27 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -4615,15 +4857,16 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/kossnocorp" } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4656,23 +4899,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -4711,10 +4937,11 @@ } }, "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -4722,7 +4949,8 @@ "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" }, "node_modules/devlop": { "version": "1.1.0", @@ -4753,15 +4981,16 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "node_modules/dotenv": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.0.tgz", - "integrity": "sha512-Q4sgBT60gzd0BB0lSyYD3xM4YxrXA9y4uBDof1JNYGzOXrQdQ6yX+7XIAqoFOGQFOTK1D3Hts5OllpxMDZFONQ==", + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", + "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -4771,16 +5000,17 @@ } }, "node_modules/drizzle-kit": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.30.4.tgz", - "integrity": "sha512-B2oJN5UkvwwNHscPWXDG5KqAixu7AUzZ3qbe++KU9SsQ+cZWR4DXEPYcvWplyFAno0dhRJECNEhNxiDmFaPGyQ==", + "version": "0.30.6", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.30.6.tgz", + "integrity": "sha512-U4wWit0fyZuGuP7iNmRleQyK2V8wCuv57vf5l3MnG4z4fzNTjY/U13M8owyQ5RavqvqxBifWORaR3wIUzlN64g==", "dev": true, "license": "MIT", "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.19.7", - "esbuild-register": "^3.5.0" + "esbuild-register": "^3.5.0", + "gel": "^2.0.0" }, "bin": { "drizzle-kit": "bin.cjs" @@ -5334,9 +5564,9 @@ } }, "node_modules/drizzle-zod": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/drizzle-zod/-/drizzle-zod-0.7.0.tgz", - "integrity": "sha512-xgCRYYVEzRkeXTS33GSMgoowe3vKsMNBjSI+cwG1oLQVEhAWWbqtb/AAMlm7tkmV4fG/uJjEmWzdzlEmTgWOoQ==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/drizzle-zod/-/drizzle-zod-0.7.1.tgz", + "integrity": "sha512-nZzALOdz44/AL2U005UlmMqaQ1qe5JfanvLujiTHiiT8+vZJTBFhj3pY4Vk+L6UWyKFfNmLhk602Hn4kCTynKQ==", "license": "Apache-2.0", "peerDependencies": { "drizzle-orm": ">=0.36.0", @@ -5370,21 +5600,23 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.51", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz", - "integrity": "sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==", + "version": "1.5.203", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.203.tgz", + "integrity": "sha512-uz4i0vLhfm6dLZWbz/iH88KNDV+ivj5+2SA+utpgjKaj9Q0iDLuwk6Idhe9BTxciHudyx6IvTvijhkPvFGUQ0g==", "dev": true, "license": "ISC" }, "node_modules/embla-carousel": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", - "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==" + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", + "license": "MIT" }, "node_modules/embla-carousel-react": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz", "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==", + "license": "MIT", "dependencies": { "embla-carousel": "8.6.0", "embla-carousel-reactive-utils": "8.6.0" @@ -5397,6 +5629,7 @@ "version": "8.6.0", "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", + "license": "MIT", "peerDependencies": { "embla-carousel": "8.6.0" } @@ -5417,10 +5650,11 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -5429,6 +5663,19 @@ "node": ">=10.13.0" } }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -5527,9 +5774,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5540,31 +5787,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" } }, "node_modules/esbuild-register": { @@ -5714,16 +5962,16 @@ } }, "node_modules/express-session": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.1.tgz", - "integrity": "sha512-a5mtTqEaZvBCL9A9aqkrtfz+3SMDhOVUnjafjo+s7A9Txkq+SVX2DLvSp1Zrv4uCXa3lMSK3viWnh9Gg07PBUA==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz", + "integrity": "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==", "license": "MIT", "dependencies": { "cookie": "0.7.2", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", - "on-headers": "~1.0.2", + "on-headers": "~1.1.0", "parseurl": "~1.3.3", "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" @@ -5796,21 +6044,22 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "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.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -5829,9 +6078,9 @@ } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -5883,12 +6132,12 @@ "license": "MIT" }, "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -5899,9 +6148,9 @@ } }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -5957,19 +6206,19 @@ } }, "node_modules/framer-motion": { - "version": "11.13.1", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.13.1.tgz", - "integrity": "sha512-F40tpGTHByhn9h3zdBQPcEro+pSLtzARcocbNqAyfBI+u9S+KZuHH/7O9+z+GEkoF3eqFxfvVw0eBDytohwqmQ==", + "version": "11.18.2", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz", + "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==", "license": "MIT", "dependencies": { - "motion-dom": "^11.13.0", - "motion-utils": "^11.13.0", + "motion-dom": "^11.18.1", + "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/is-prop-valid": { @@ -6015,6 +6264,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gel": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gel/-/gel-2.1.1.tgz", + "integrity": "sha512-Newg9X7mRYskoBjSw70l1YnJ/ZGbq64VPyR821H5WVkTGpHG2O0mQILxCeUhxdYERLFY9B4tUyKLyf3uMTjtKw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@petamoriken/float16": "^3.8.7", + "debug": "^4.3.4", + "env-paths": "^3.0.0", + "semver": "^7.6.2", + "shell-quote": "^1.8.1", + "which": "^4.0.0" + }, + "bin": { + "gel": "dist/cli.mjs" + }, + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/gel/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -6053,6 +6336,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", "engines": { "node": ">=6" } @@ -6071,9 +6355,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", - "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6115,16 +6399,6 @@ "node": ">=10.13.0" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -6141,19 +6415,8 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true, + "license": "ISC" }, "node_modules/has-symbols": { "version": "1.1.0", @@ -6297,6 +6560,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", + "license": "MIT", "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" @@ -6357,9 +6621,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -6449,10 +6713,14 @@ "license": "MIT" }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } }, "node_modules/jackspeak": { "version": "3.4.3", @@ -6470,18 +6738,19 @@ } }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "dev": true, "license": "MIT", "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, "node_modules/jose": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.0.11.tgz", - "integrity": "sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.0.12.tgz", + "integrity": "sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -6494,9 +6763,9 @@ "license": "MIT" }, "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { @@ -6520,10 +6789,11 @@ } }, "node_modules/lightningcss": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", - "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", "dev": true, + "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" }, @@ -6535,26 +6805,27 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.29.2", - "lightningcss-darwin-x64": "1.29.2", - "lightningcss-freebsd-x64": "1.29.2", - "lightningcss-linux-arm-gnueabihf": "1.29.2", - "lightningcss-linux-arm64-gnu": "1.29.2", - "lightningcss-linux-arm64-musl": "1.29.2", - "lightningcss-linux-x64-gnu": "1.29.2", - "lightningcss-linux-x64-musl": "1.29.2", - "lightningcss-win32-arm64-msvc": "1.29.2", - "lightningcss-win32-x64-msvc": "1.29.2" + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", - "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -6568,13 +6839,14 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", - "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -6588,13 +6860,14 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", - "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "freebsd" @@ -6608,13 +6881,14 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", - "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", "cpu": [ "arm" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6628,13 +6902,14 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", - "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6648,13 +6923,14 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", - "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6668,13 +6944,14 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", - "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6688,13 +6965,14 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", - "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -6708,13 +6986,14 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", - "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -6728,13 +7007,14 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", - "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -6751,6 +7031,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -6836,10 +7117,21 @@ "version": "0.453.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.453.0.tgz", "integrity": "sha512-kL+RGZCcJi9BvJtzg2kshO192Ddy9hv3ij+cPrVPWSRzgCWCVazoQJxOjAwgK53NomL07HB7GPHW120FimjNhQ==", + "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -7855,6 +8147,19 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", @@ -7874,14 +8179,19 @@ } }, "node_modules/motion-dom": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.13.0.tgz", - "integrity": "sha512-Oc1MLGJQ6nrvXccXA89lXtOqFyBmvHtaDcTRGT66o8Czl7nuA8BeHAd9MQV1pQKX0d2RHFBFaw5g3k23hQJt0w==" + "version": "11.18.1", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", + "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==", + "license": "MIT", + "dependencies": { + "motion-utils": "^11.18.1" + } }, "node_modules/motion-utils": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.13.0.tgz", - "integrity": "sha512-lq6TzXkH5c/ysJQBxgLXgM01qwBH1b4goTPh57VvZWJbVJZF/0SB31UWEn4EIqbVPf3au88n2rvK17SpDTja1A==" + "version": "11.18.1", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz", + "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==", + "license": "MIT" }, "node_modules/ms": { "version": "2.1.3", @@ -7890,9 +8200,9 @@ "license": "MIT" }, "node_modules/multer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.1.tgz", - "integrity": "sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", + "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", "license": "MIT", "dependencies": { "append-field": "^1.0.0", @@ -7949,6 +8259,7 @@ "version": "0.4.6", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" @@ -8001,9 +8312,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.3.tgz", - "integrity": "sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "license": "MIT", "optional": true, "bin": { @@ -8013,9 +8324,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true, "license": "MIT" }, @@ -8039,9 +8350,9 @@ } }, "node_modules/oauth4webapi": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.5.5.tgz", - "integrity": "sha512-1K88D2GiAydGblHo39NBro5TebGXa+7tYoyIbxvqv3+haDDry7CBE1eSYuNbOSsYCCU6y0gdynVZAkm4YPw4hg==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.7.0.tgz", + "integrity": "sha512-Q52wTPUWPsVLVVmTViXPQFMW2h2xv2jnDGxypjpelCFKaOjLsm7AxYuOk1oQgFm95VNDbuggasu9htXrz6XwKw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -8066,9 +8377,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8096,18 +8407,18 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/openai": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/openai/-/openai-5.8.2.tgz", - "integrity": "sha512-8C+nzoHYgyYOXhHGN6r0fcb4SznuEn1R7YZMvlqDbnCuE0FM2mm3T1HiYW6WIcMS/F1Of2up/cSPjLPaWt0X9Q==", + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/openai/-/openai-5.12.2.tgz", + "integrity": "sha512-xqzHHQch5Tws5PcKR2xsZGX9xtch+JQFz5zb14dGqlshmmDAFBFEWmeIpf7wVqWV+w7Emj7jRgkNJakyKE0tYQ==", "license": "Apache-2.0", "bin": { "openai": "bin/cli" @@ -8126,13 +8437,13 @@ } }, "node_modules/openid-client": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.6.2.tgz", - "integrity": "sha512-Xya5TNMnnZuTM6DbHdB4q0S3ig2NTAELnii/ASie1xDEr8iiB8zZbO871OWBdrw++sd3hW6bqWjgcmSy1RTWHA==", + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.6.4.tgz", + "integrity": "sha512-PLWVhRksRnNH05sqeuCX/PR+1J70NyZcAcPske+FeF732KKONd3v0p5Utx1ro1iLfCglH8B3/+dA1vqIHDoIiA==", "license": "MIT", "dependencies": { - "jose": "^6.0.11", - "oauth4webapi": "^3.5.4" + "jose": "^6.0.12", + "oauth4webapi": "^3.7.0" }, "funding": { "url": "https://github.com/sponsors/panva" @@ -8389,18 +8700,18 @@ } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -8417,8 +8728,8 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -8521,7 +8832,7 @@ "postcss": "^8.2.14" } }, - "node_modules/postcss-selector-parser": { + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", @@ -8534,6 +8845,20 @@ "node": ">=4" } }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "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://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -8607,6 +8932,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8616,7 +8942,8 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" }, "node_modules/property-information": { "version": "7.1.0", @@ -8731,6 +9058,7 @@ "version": "8.10.1", "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "license": "MIT", "funding": { "type": "individual", "url": "https://github.com/sponsors/gpbl" @@ -8754,9 +9082,10 @@ } }, "node_modules/react-hook-form": { - "version": "7.55.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.55.0.tgz", - "integrity": "sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog==", + "version": "7.62.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz", + "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==", + "license": "MIT", "engines": { "node": ">=18.0.0" }, @@ -8769,9 +9098,9 @@ } }, "node_modules/react-icons": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz", - "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", "license": "MIT", "peerDependencies": { "react": "*" @@ -8811,9 +9140,9 @@ } }, "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "dev": true, "license": "MIT", "engines": { @@ -8821,9 +9150,10 @@ } }, "node_modules/react-remove-scroll": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", - "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", @@ -8848,6 +9178,7 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" @@ -8866,9 +9197,10 @@ } }, "node_modules/react-resizable-panels": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.7.tgz", - "integrity": "sha512-JtT6gI+nURzhMYQYsx8DKkx6bSoOGFp7A3CwMrOb8y5jFHFyqwo9m68UhmXRw57fRVJksFn1TSlm3ywEQ9vMgA==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.9.tgz", + "integrity": "sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ==", + "license": "MIT", "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" @@ -8878,6 +9210,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "license": "MIT", "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", @@ -8892,6 +9225,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" @@ -8913,6 +9247,7 @@ "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -8960,9 +9295,10 @@ } }, "node_modules/recharts": { - "version": "2.15.2", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.2.tgz", - "integrity": "sha512-xv9lVztv3ingk7V3Jf05wfAZbM9Q2umJzu5t/cfnAK7LUslNrGT7LPBr74G+ok8kSCeFMaePmWMg0rcYOnczTw==", + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", + "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "license": "MIT", "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", @@ -8990,11 +9326,6 @@ "decimal.js-light": "^2.4.1" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, "node_modules/regexparam": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-3.0.0.tgz", @@ -9071,18 +9402,21 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "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" } @@ -9098,9 +9432,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -9108,13 +9442,13 @@ } }, "node_modules/rollup": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.4.tgz", - "integrity": "sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", + "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -9124,24 +9458,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.4", - "@rollup/rollup-android-arm64": "4.24.4", - "@rollup/rollup-darwin-arm64": "4.24.4", - "@rollup/rollup-darwin-x64": "4.24.4", - "@rollup/rollup-freebsd-arm64": "4.24.4", - "@rollup/rollup-freebsd-x64": "4.24.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.4", - "@rollup/rollup-linux-arm-musleabihf": "4.24.4", - "@rollup/rollup-linux-arm64-gnu": "4.24.4", - "@rollup/rollup-linux-arm64-musl": "4.24.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.4", - "@rollup/rollup-linux-riscv64-gnu": "4.24.4", - "@rollup/rollup-linux-s390x-gnu": "4.24.4", - "@rollup/rollup-linux-x64-gnu": "4.24.4", - "@rollup/rollup-linux-x64-musl": "4.24.4", - "@rollup/rollup-win32-arm64-msvc": "4.24.4", - "@rollup/rollup-win32-ia32-msvc": "4.24.4", - "@rollup/rollup-win32-x64-msvc": "4.24.4", + "@rollup/rollup-android-arm-eabi": "4.46.2", + "@rollup/rollup-android-arm64": "4.46.2", + "@rollup/rollup-darwin-arm64": "4.46.2", + "@rollup/rollup-darwin-x64": "4.46.2", + "@rollup/rollup-freebsd-arm64": "4.46.2", + "@rollup/rollup-freebsd-x64": "4.46.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", + "@rollup/rollup-linux-arm-musleabihf": "4.46.2", + "@rollup/rollup-linux-arm64-gnu": "4.46.2", + "@rollup/rollup-linux-arm64-musl": "4.46.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", + "@rollup/rollup-linux-ppc64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-musl": "4.46.2", + "@rollup/rollup-linux-s390x-gnu": "4.46.2", + "@rollup/rollup-linux-x64-gnu": "4.46.2", + "@rollup/rollup-linux-x64-musl": "4.46.2", + "@rollup/rollup-win32-arm64-msvc": "4.46.2", + "@rollup/rollup-win32-ia32-msvc": "4.46.2", + "@rollup/rollup-win32-x64-msvc": "4.46.2", "fsevents": "~2.3.2" } }, @@ -9276,23 +9612,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -9320,16 +9639,83 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/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.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/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://registry.npmjs.org/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://registry.npmjs.org/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://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -9591,6 +9977,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" @@ -9600,6 +9987,7 @@ "version": "3.4.17", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -9636,19 +10024,87 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -9749,13 +10205,13 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", - "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", + "version": "4.20.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.4.tgz", + "integrity": "sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.23.0", + "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -9768,458 +10224,11 @@ "fsevents": "~2.3.3" } }, - "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", - "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", - "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", - "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", - "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", - "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", - "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", - "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", - "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", - "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", - "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", - "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", - "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", - "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", - "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", - "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", - "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", - "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", - "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", - "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", - "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", - "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", - "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", - "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", - "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/tsx/node_modules/esbuild": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", - "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.23.1", - "@esbuild/android-arm": "0.23.1", - "@esbuild/android-arm64": "0.23.1", - "@esbuild/android-x64": "0.23.1", - "@esbuild/darwin-arm64": "0.23.1", - "@esbuild/darwin-x64": "0.23.1", - "@esbuild/freebsd-arm64": "0.23.1", - "@esbuild/freebsd-x64": "0.23.1", - "@esbuild/linux-arm": "0.23.1", - "@esbuild/linux-arm64": "0.23.1", - "@esbuild/linux-ia32": "0.23.1", - "@esbuild/linux-loong64": "0.23.1", - "@esbuild/linux-mips64el": "0.23.1", - "@esbuild/linux-ppc64": "0.23.1", - "@esbuild/linux-riscv64": "0.23.1", - "@esbuild/linux-s390x": "0.23.1", - "@esbuild/linux-x64": "0.23.1", - "@esbuild/netbsd-x64": "0.23.1", - "@esbuild/openbsd-arm64": "0.23.1", - "@esbuild/openbsd-x64": "0.23.1", - "@esbuild/sunos-x64": "0.23.1", - "@esbuild/win32-arm64": "0.23.1", - "@esbuild/win32-ia32": "0.23.1", - "@esbuild/win32-x64": "0.23.1" - } - }, "node_modules/tw-animate-css": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.2.5.tgz", - "integrity": "sha512-ABzjfgVo+fDbhRREGL4KQZUqqdPgvc5zVrLyeW9/6mVqvaDepXc7EvedA+pYmMnIOsUAQMwcWzNvom26J2qYvQ==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.7.tgz", + "integrity": "sha512-lvLb3hTIpB5oGsk8JmLoAjeCHV58nKa2zHYn8yWOoG5JJusH3bhJlF2DLAZ/5NmJ+jyH3ssiAx/2KmbhavJy/A==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/Wombosvideo" } @@ -10378,9 +10387,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -10399,7 +10408,7 @@ "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -10412,6 +10421,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -10432,6 +10442,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -10450,12 +10461,12 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", "license": "MIT", "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/util-deprecate": { @@ -10486,6 +10497,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "license": "MIT", "dependencies": { "@radix-ui/react-dialog": "^1.1.1" }, @@ -10509,9 +10521,9 @@ } }, "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -11060,24 +11072,25 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/wouter": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/wouter/-/wouter-3.3.5.tgz", - "integrity": "sha512-bx3fLQAMn+EhYbBdY3W1gw9ZfO/uchudxYMwOIBzF3HVgqNEEIT199vEoh7FLTC0Vz5+rpMO6NdFsOkGX1QQCw==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/wouter/-/wouter-3.7.1.tgz", + "integrity": "sha512-od5LGmndSUzntZkE2R5CHhoiJ7YMuTIbiXsa0Anytc2RATekgv4sfWRAxLEULBrp7ADzinWQw8g470lkT8+fOw==", "license": "Unlicense", "dependencies": { "mitt": "^3.0.1", @@ -11180,9 +11193,9 @@ } }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -11217,35 +11230,36 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/zod": { - "version": "3.24.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", - "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } }, "node_modules/zod-validation-error": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.4.0.tgz", - "integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.5.3.tgz", + "integrity": "sha512-OT5Y8lbUadqVZCsnyFaTQ4/O2mys4tj7PqhdbBCp7McPwvIEKfPtdA6QfPeFQK2/Rz5LgwmAXRJTugBNBi0btw==", "license": "MIT", "engines": { "node": ">=18.0.0" }, "peerDependencies": { - "zod": "^3.18.0" + "zod": "^3.25.0 || ^4.0.0" } }, "node_modules/zwitch": { diff --git a/package.json b/package.json index bc3a54f..0604a15 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "check": "tsc", "db:push": "drizzle-kit push", "setup": "npm install && npm run db:push", - "docker:dev": "docker-compose up -d", - "docker:down": "docker-compose down" + "docker:dev": "docker compose up -d", + "docker:down": "docker compose down" }, "dependencies": { "@anthropic-ai/sdk": "^0.37.0", diff --git a/server/index.ts b/server/index.ts index d692043..52f6ecc 100644 --- a/server/index.ts +++ b/server/index.ts @@ -12,7 +12,6 @@ import { dockerRecoveryEngine } from "./services/docker-recovery-engine"; import { sysreptorLogMonitor } from "./services/sysreptor-log-monitor"; import { djangoHealthMonitor } from "./services/django-health-monitor"; import { djangoDatabaseValidator } from "./services/django-database-validator"; -import { empireHealthMonitor } from "./services/empire-health-monitor"; const app = express(); app.use(express.json({ limit: '1gb' })); @@ -219,25 +218,6 @@ app.use((req, res, next) => { log(`Warning: Failed to start Django health monitoring: ${error instanceof Error ? error.message : 'Unknown error'}`); } - // Start Empire health monitoring - log("Starting Empire health monitoring..."); - try { - // empireHealthMonitor starts automatically in constructor - log("Empire health monitoring started successfully"); - - // Perform initial Empire health check - log("Performing initial Empire health check..."); - const initialEmpireStatus = await empireHealthMonitor.checkHealth(); - if (initialEmpireStatus.errors.length === 0) { - log("Empire initial health check passed"); - } else { - log(`Empire initial health check failed - Issues: ${initialEmpireStatus.errors.join(', ')}`); - log("Empire self-healing system will attempt automatic recovery"); - } - - } catch (error) { - log(`Warning: Failed to start Empire health monitoring: ${error instanceof Error ? error.message : 'Unknown error'}`); - } log("Self-healing system activated successfully"); diff --git a/server/routes.ts b/server/routes.ts index 526cdf1..ea4ec73 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -452,6 +452,201 @@ export async function registerRoutes(app: Express): Promise { } }); + // OpenAI-compatible Chat Completions API endpoint + app.post("/api/chat/completions", async (req, res) => { + try { + // Validate API key + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return res.status(401).json({ + error: { + message: "You didn't provide an API key.", + type: "invalid_request_error", + code: "missing_api_key" + } + }); + } + + const apiKey = authHeader.substring(7); + + // Basic API key validation (you can enhance this) + if (!apiKey || apiKey.length < 10) { + return res.status(401).json({ + error: { + message: "Invalid API key provided.", + type: "invalid_request_error", + code: "invalid_api_key" + } + }); + } + + // Validate request format + const { messages, model, max_tokens, temperature, stream } = req.body; + + if (!messages || !Array.isArray(messages) || messages.length === 0) { + return res.status(400).json({ + error: { + message: "Missing required parameter: 'messages'.", + type: "invalid_request_error", + code: "missing_required_parameter" + } + }); + } + + // Extract the latest user message for processing + const userMessage = messages.filter(msg => msg.role === 'user').pop(); + if (!userMessage) { + return res.status(400).json({ + error: { + message: "No user message found in conversation.", + type: "invalid_request_error", + code: "invalid_messages" + } + }); + } + + // Check if this should be routed through researcher + const needsResearcher = /\b(workflow|orchestrat|complex|comprehensive|detailed|analysis|research)\b/i.test(userMessage.content); + + let responseContent: string; + let usage = { + prompt_tokens: JSON.stringify(messages).length / 4, // Rough estimate + completion_tokens: 0, + total_tokens: 0 + }; + + if (needsResearcher) { + // Route through researcher for complex queries + try { + // Extract header values and ensure they are strings + const threadId = Array.isArray(req.headers['x-chat-thread-id']) + ? req.headers['x-chat-thread-id'][0] + : req.headers['x-chat-thread-id'] || `thread_${Date.now()}`; + const userId = Array.isArray(req.headers['x-user-id']) + ? req.headers['x-user-id'][0] + : req.headers['x-user-id'] || 'anonymous'; + + const researcherResponse = await fetch('https://researcher.c3s.nexus/chat/completions', { + method: 'POST', + headers: { + 'Authorization': `Bearer ${apiKey}`, + 'Content-Type': 'application/json', + 'X-Origin-Endpoint': 'https://chat.attck.nexus', + 'X-Chat-Thread-ID': threadId, + 'X-User-ID': userId + }, + body: JSON.stringify({ + messages, + model: model || 'gpt-4o', + max_tokens: max_tokens || 2000, + temperature: temperature || 0.7 + }) + }); + + if (researcherResponse.ok) { + const researcherData = await researcherResponse.json(); + responseContent = researcherData.choices[0]?.message?.content || 'Researcher analysis completed.'; + usage.completion_tokens = researcherData.usage?.completion_tokens || responseContent.length / 4; + } else { + // Fallback to direct OpenAI + responseContent = await generateVulnerabilityReport( + "Chat Completion", + "P4", + userMessage.content + ); + usage.completion_tokens = responseContent.length / 4; + } + } catch (error) { + console.error('Researcher routing failed:', error); + // Fallback to direct OpenAI + responseContent = await generateVulnerabilityReport( + "Chat Completion", + "P4", + userMessage.content + ); + usage.completion_tokens = responseContent.length / 4; + } + } else { + // Direct processing for simple queries + if (userMessage.content.toLowerCase().includes('vulnerability') || + userMessage.content.toLowerCase().includes('security')) { + responseContent = await generateVulnerabilityReport( + "Security Analysis", + "P3", + userMessage.content + ); + } else { + // Generic response using OpenAI + const { analyzeVulnerability } = await import("./services/openai"); + try { + responseContent = await generateVulnerabilityReport( + "General Inquiry", + "P4", + userMessage.content + ); + } catch (error) { + responseContent = "I'm here to help with cybersecurity analysis and vulnerability research. How can I assist you with your security-related questions?"; + } + } + usage.completion_tokens = responseContent.length / 4; + } + + usage.total_tokens = usage.prompt_tokens + usage.completion_tokens; + + // Handle streaming response + if (stream) { + res.setHeader('Content-Type', 'text/event-stream'); + res.setHeader('Cache-Control', 'no-cache'); + res.setHeader('Connection', 'keep-alive'); + + const streamResponse = { + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion.chunk', + created: Math.floor(Date.now() / 1000), + model: model || 'gpt-4o', + choices: [{ + index: 0, + delta: { content: responseContent }, + finish_reason: 'stop' + }] + }; + + res.write(`data: ${JSON.stringify(streamResponse)}\n\n`); + res.write('data: [DONE]\n\n'); + res.end(); + } else { + // Standard JSON response + const response = { + id: `chatcmpl-${Date.now()}`, + object: 'chat.completion', + created: Math.floor(Date.now() / 1000), + model: model || 'gpt-4o', + choices: [{ + index: 0, + message: { + role: 'assistant', + content: responseContent + }, + finish_reason: 'stop' + }], + usage + }; + + res.json(response); + } + + } catch (error) { + console.error('Chat completions error:', error); + res.status(500).json({ + error: { + message: "The server encountered an error while processing your request.", + type: "server_error", + code: "internal_server_error" + } + }); + } + }); + // Dashboard analytics app.get("/api/dashboard/stats", async (req, res) => { try { diff --git a/server/services/django-database-validator.ts b/server/services/django-database-validator.ts index 05ed9b2..340b165 100644 --- a/server/services/django-database-validator.ts +++ b/server/services/django-database-validator.ts @@ -169,7 +169,7 @@ export class DjangoDatabaseValidator extends EventEmitter { if (!pgContainer) { result.issues.push('PostgreSQL container not found or not running'); - result.recommendations.push('Start PostgreSQL container using docker-compose up -d postgres'); + result.recommendations.push('Start PostgreSQL container using docker compose up -d postgres'); return result; } @@ -247,7 +247,7 @@ except Exception as e: } } else { result.issues.push('Django container is not running'); - result.recommendations.push('Start Django container using docker-compose up -d app'); + result.recommendations.push('Start Django container using docker compose up -d app'); } } catch (error) { @@ -481,8 +481,8 @@ except Exception as e: if (!pgContainer) { console.log('[DjangoDatabaseValidator] Starting PostgreSQL container...'); - await execAsync('docker-compose up -d postgres').catch(async () => { - return await execAsync('sudo docker-compose up -d postgres'); + await execAsync('docker compose up -d postgres').catch(async () => { + return await execAsync('sudo docker compose up -d postgres'); }); // Wait for PostgreSQL to be ready @@ -518,8 +518,8 @@ except Exception as e: // Ensure Django container is running if (!(await this.isContainerRunning(this.containerName))) { console.log('[DjangoDatabaseValidator] Starting Django container...'); - await execAsync('docker-compose up -d app').catch(async () => { - return await execAsync('sudo docker-compose up -d app'); + await execAsync('docker compose up -d app').catch(async () => { + return await execAsync('sudo docker compose up -d app'); }); // Wait for container to be ready diff --git a/server/services/django-health-monitor.ts b/server/services/django-health-monitor.ts index 9138c2a..a209911 100644 --- a/server/services/django-health-monitor.ts +++ b/server/services/django-health-monitor.ts @@ -422,8 +422,8 @@ export class DjangoHealthMonitor extends EventEmitter { await new Promise(resolve => setTimeout(resolve, 3000)); // Start container using docker-compose - await execAsync('docker-compose up -d app').catch(async () => { - return await execAsync('sudo docker-compose up -d app'); + await execAsync('docker compose up -d app').catch(async () => { + return await execAsync('sudo docker compose up -d app'); }); // Wait for container to be ready diff --git a/server/services/docker-recovery-engine.ts b/server/services/docker-recovery-engine.ts index 986ddcc..2cd1931 100644 --- a/server/services/docker-recovery-engine.ts +++ b/server/services/docker-recovery-engine.ts @@ -172,7 +172,6 @@ export class DockerRecoveryEngine extends EventEmitter { redis: { start: 6380, end: 6390 }, kali: { start: 6900, end: 6910 }, vscode: { start: 6920, end: 6930 }, - empire: { start: 1337, end: 1350 }, sysreptor: { start: 9000, end: 9010 }, bbot: { start: 8080, end: 8090 }, maltego: { start: 6940, end: 6950 }, @@ -551,8 +550,8 @@ export class DockerRecoveryEngine extends EventEmitter { // Restart using docker-compose try { - await execAsync('docker-compose up -d app').catch(async () => { - return await execAsync('sudo docker-compose up -d app'); + await execAsync('docker compose up -d app').catch(async () => { + return await execAsync('sudo docker compose up -d app'); }); // Wait for container to be ready @@ -1259,9 +1258,9 @@ except Exception as e: // Try to restart using docker-compose try { - console.log('[DockerRecoveryEngine] Attempting to restart sysreptor via docker-compose...'); - await execAsync('docker-compose up -d sysreptor').catch(async () => { - return await execAsync('sudo docker-compose up -d sysreptor'); + console.log('[DockerRecoveryEngine] Attempting to restart sysreptor via docker compose...'); + await execAsync('docker compose up -d sysreptor').catch(async () => { + return await execAsync('sudo docker compose up -d sysreptor'); }); // Wait for container to be ready diff --git a/server/services/docker.ts b/server/services/docker.ts index def3660..4200432 100644 --- a/server/services/docker.ts +++ b/server/services/docker.ts @@ -86,19 +86,6 @@ export class DockerService { volumes: ['uploads/docker:/home/kasm-user/shared:rw'] }); - this.containerConfigs.set('empire', { - name: 'empire', - image: 'bcsecurity/empire:latest', - port: 1337, - category: 'security', - description: 'PowerShell Empire C2 framework', - icon: 'Crown', - additionalPorts: [5000], // Direct port mapping 5000:5000 - environment: {}, // Use Empire defaults - volumes: [], // Using data container pattern instead - dataContainer: 'empire-data', // Flag for data container deployment - interactive: true // Use -it flag for interactive mode - }); this.containerConfigs.set('bbot', { name: 'bbot', @@ -752,40 +739,6 @@ WORKDIR /home/kasm-user } } - // Setup data container for persistent storage (Empire pattern) - private async setupDataContainer(config: ContainerConfig): Promise { - if (!config.dataContainer) { - return; - } - - const dataContainerName = config.dataContainer; - - try { - // Check if data container already exists - const { stdout } = await execAsync(`docker ps -aq --filter name="^${dataContainerName}$"`).catch(async () => { - return await execAsync(`sudo docker ps -aq --filter name="^${dataContainerName}$"`); - }); - - if (stdout.trim()) { - console.log(`[DockerService] Data container ${dataContainerName} already exists`); - return; - } - - // Create data container with volume - console.log(`[DockerService] Creating data container: ${dataContainerName}`); - const createCmd = `docker create -v /empire --name ${dataContainerName} ${config.image}`; - - await execAsync(createCmd).catch(async () => { - return await execAsync(`sudo ${createCmd}`); - }); - - console.log(`[DockerService] Data container ${dataContainerName} created successfully`); - - } catch (error) { - console.error(`[DockerService] Failed to setup data container ${dataContainerName}:`, error); - throw error; - } - } // New comprehensive container management methods async startContainer(containerName: string): Promise { @@ -874,10 +827,6 @@ WORKDIR /home/kasm-user private async buildDockerCommand(config: ContainerConfig): Promise { const containerName = `attacknode-${config.name}`; - // Handle data container pattern for Empire - if (config.dataContainer) { - await this.setupDataContainer(config); - } const dockerCmd = ['docker', 'run', '-d', '--name', containerName, '--restart', 'unless-stopped']; @@ -900,22 +849,13 @@ WORKDIR /home/kasm-user dockerCmd.push('-p', `0.0.0.0:${config.port}:${this.getContainerPort(config)}`); } - // Add additional ports - special handling for Empire + // Add additional ports if (config.additionalPorts) { for (const port of config.additionalPorts) { - if (config.name === 'empire') { - // For Empire, direct port mapping 5000:5000 - dockerCmd.push('-p', `0.0.0.0:${port}:5000`); - } else { - dockerCmd.push('-p', `0.0.0.0:${port}:${port}`); - } + dockerCmd.push('-p', `0.0.0.0:${port}:${port}`); } } - // Add volumes-from for data container pattern - if (config.dataContainer) { - dockerCmd.push('--volumes-from', config.dataContainer); - } // Add environment variables or env file if (config.name === 'sysreptor') { @@ -988,9 +928,6 @@ WORKDIR /home/kasm-user if (config.image.includes('redis')) { return '6379'; } - if (config.image.includes('empire')) { - return '1337'; - } if (config.image.includes('sysreptor')) { return '8000'; } @@ -1061,8 +998,6 @@ WORKDIR /home/kasm-user serviceWait = 5000; // PostgreSQL needs more time } else if (config?.name === 'redis') { serviceWait = 3000; // Redis needs some time - } else if (config?.name === 'empire') { - serviceWait = 10000; // Empire needs longer to initialize } else if (config?.name === 'sysreptor') { serviceWait = 8000; // Sysreptor needs time to connect to DB } @@ -1156,7 +1091,7 @@ WORKDIR /home/kasm-user // Initialize essential containers on startup async initializeEssentialContainers(): Promise { - const essentialContainers = ['kali', 'vscode', 'empire', 'maltego']; + const essentialContainers = ['kali', 'vscode', 'maltego']; for (const containerName of essentialContainers) { try { diff --git a/server/services/empire-health-monitor.ts b/server/services/empire-health-monitor.ts deleted file mode 100644 index 69fd129..0000000 --- a/server/services/empire-health-monitor.ts +++ /dev/null @@ -1,570 +0,0 @@ -import { exec } from 'child_process'; -import { promisify } from 'util'; -import fs from 'fs/promises'; -import path from 'path'; - -const execAsync = promisify(exec); - -interface EmpireHealthStatus { - isRunning: boolean; - apiResponding: boolean; - databaseConnected: boolean; - lastError?: string; - setupCompleted: boolean; - starkiller: boolean; - containerId?: string; - containerStatus?: string; - uptime?: number; - errors: string[]; - warnings: string[]; -} - -class EmpireHealthMonitor { - private monitoringInterval: NodeJS.Timeout | null = null; - private readonly checkInterval = 30000; // 30 seconds - private readonly containerName = 'attacknode-empire'; - private readonly logFile = path.join(process.cwd(), 'logs', 'empire-health.log'); - private lastHealthCheck: EmpireHealthStatus | null = null; - private consecutiveFailures = 0; - private readonly maxConsecutiveFailures = 3; - - constructor() { - this.ensureLogDirectory(); - this.startMonitoring(); - } - - private async ensureLogDirectory(): Promise { - const logDir = path.dirname(this.logFile); - try { - await fs.mkdir(logDir, { recursive: true }); - } catch (error) { - console.error('[EmpireHealthMonitor] Failed to create log directory:', error); - } - } - - private async logMessage(level: 'INFO' | 'WARN' | 'ERROR', message: string): Promise { - const timestamp = new Date().toISOString(); - const logEntry = `[${timestamp}] [${level}] ${message}\n`; - - try { - await fs.appendFile(this.logFile, logEntry); - } catch (error) { - console.error('[EmpireHealthMonitor] Failed to write to log file:', error); - } - - console.log(`[EmpireHealthMonitor] ${logEntry.trim()}`); - } - - public startMonitoring(): void { - if (this.monitoringInterval) { - clearInterval(this.monitoringInterval); - } - - this.logMessage('INFO', 'Starting Empire health monitoring'); - - this.monitoringInterval = setInterval(async () => { - try { - const health = await this.checkHealth(); - await this.handleHealthStatus(health); - } catch (error) { - await this.logMessage('ERROR', `Health check failed: ${error}`); - } - }, this.checkInterval); - - // Initial health check - this.checkHealth().then(health => this.handleHealthStatus(health)); - } - - public stopMonitoring(): void { - if (this.monitoringInterval) { - clearInterval(this.monitoringInterval); - this.monitoringInterval = null; - this.logMessage('INFO', 'Empire health monitoring stopped'); - } - } - - public async checkHealth(): Promise { - const health: EmpireHealthStatus = { - isRunning: false, - apiResponding: false, - databaseConnected: false, - setupCompleted: false, - starkiller: false, - errors: [], - warnings: [] - }; - - try { - // Check if container exists and is running - const containerInfo = await this.getContainerInfo(); - health.containerId = containerInfo.id; - health.containerStatus = containerInfo.status; - health.isRunning = containerInfo.status === 'running'; - health.uptime = containerInfo.uptime; - - if (!health.isRunning) { - health.errors.push('Empire container is not running'); - return health; - } - - // Check container logs for setup completion - const logs = await this.getContainerLogs(); - health.setupCompleted = this.checkSetupCompleted(logs); - - if (!health.setupCompleted) { - health.errors.push('Empire setup has not completed successfully'); - } - - // Check if API is responding - health.apiResponding = await this.checkApiHealth(); - - if (!health.apiResponding) { - health.errors.push('Empire API is not responding on port 1337'); - } - - // Check database connection (Empire uses SQLite by default) - health.databaseConnected = await this.checkDatabaseConnection(); - - if (!health.databaseConnected) { - health.errors.push('Empire database connection failed'); - } - - // Check if Starkiller is accessible - health.starkiller = await this.checkStarkiller(); - - if (!health.starkiller) { - health.warnings.push('Starkiller UI may not be accessible'); - } - - // Analyze logs for common issues - const logAnalysis = this.analyzeLogs(logs); - health.errors.push(...logAnalysis.errors); - health.warnings.push(...logAnalysis.warnings); - - } catch (error) { - health.errors.push(`Health check failed: ${error}`); - health.lastError = error instanceof Error ? error.message : String(error); - } - - this.lastHealthCheck = health; - return health; - } - - private async getContainerInfo(): Promise<{ - id: string; - status: string; - uptime?: number; - }> { - try { - const { stdout } = await execAsync(`docker inspect ${this.containerName} --format "{{.Id}}\t{{.State.Status}}\t{{.State.StartedAt}}"`) - .catch(async () => { - return await execAsync(`sudo docker inspect ${this.containerName} --format "{{.Id}}\t{{.State.Status}}\t{{.State.StartedAt}}"`); - }); - - const [id, status, startedAt] = stdout.trim().split('\t'); - - let uptime: number | undefined; - if (startedAt && status === 'running') { - const startTime = new Date(startedAt).getTime(); - uptime = Date.now() - startTime; - } - - return { id, status, uptime }; - } catch (error) { - throw new Error(`Container ${this.containerName} not found or not accessible`); - } - } - - private async getContainerLogs(): Promise { - try { - const { stdout } = await execAsync(`docker logs ${this.containerName} --tail 100`) - .catch(async () => { - return await execAsync(`sudo docker logs ${this.containerName} --tail 100`); - }); - return stdout; - } catch (error) { - throw new Error(`Failed to get container logs: ${error}`); - } - } - - private checkSetupCompleted(logs: string): boolean { - const setupIndicators = [ - 'Empire starting up', - 'Application startup complete', - 'Uvicorn running on', - 'Empire database initialized', - 'Starting Empire server', - 'Empire REST API running', - 'Empire started successfully', - 'Server running at', - 'Starkiller served at' - ]; - - // Check for the specific success pattern from the logs - const hasStartupComplete = logs.includes('Application startup complete'); - const hasUvicornRunning = logs.includes('Uvicorn running on'); - const hasEmpireStarting = logs.includes('Empire starting up'); - - // Empire is ready when we see the startup sequence complete - if (hasStartupComplete && hasUvicornRunning && hasEmpireStarting) { - return true; - } - - // Fallback to any of the indicators - return setupIndicators.some(indicator => - logs.toLowerCase().includes(indicator.toLowerCase()) - ); - } - - private async checkApiHealth(): Promise { - try { - // Try multiple Empire API endpoints - const endpoints = [ - 'http://localhost:1337/api/admin/users', - 'http://localhost:1337/api/users', - 'http://localhost:1337/api/', - 'http://localhost:1337/' - ]; - - for (const endpoint of endpoints) { - try { - const { stdout } = await execAsync(`curl -s -I ${endpoint} --max-time 5`) - .catch(() => ({ stdout: '' })); - - // Check for successful HTTP response codes (200, 401, 403 are all valid - means API is responding) - if (stdout.includes('HTTP/1.1 200') || - stdout.includes('HTTP/1.1 401') || - stdout.includes('HTTP/1.1 403')) { - return true; - } - } catch (error) { - continue; - } - } - - // Fallback: check if Empire process is running - try { - const { stdout } = await execAsync(`docker exec ${this.containerName} pgrep -f "empire" 2>/dev/null`) - .catch(() => ({ stdout: '' })); - - return stdout.trim().length > 0; - } catch (error) { - return false; - } - } catch (error) { - return false; - } - } - - private async checkDatabaseConnection(): Promise { - try { - // Check if Empire database file exists and is accessible - const { stdout } = await execAsync(`docker exec ${this.containerName} ls -la /empire/empire.db`) - .catch(async () => { - return await execAsync(`sudo docker exec ${this.containerName} ls -la /empire/empire.db`); - }); - - return stdout.includes('empire.db'); - } catch (error) { - return false; - } - } - - private async checkStarkiller(): Promise { - try { - // Check if Starkiller port is listening - const { stdout } = await execAsync(`docker exec ${this.containerName} netstat -tlnp | grep :5000`) - .catch(async () => { - return await execAsync(`sudo docker exec ${this.containerName} netstat -tlnp | grep :5000`); - }); - - return stdout.includes(':5000'); - } catch (error) { - return false; - } - } - - private analyzeLogs(logs: string): { errors: string[]; warnings: string[] } { - const errors: string[] = []; - const warnings: string[] = []; - - const logLines = logs.split('\n'); - - for (const line of logLines) { - const lowerLine = line.toLowerCase(); - - // Check for critical errors - if (lowerLine.includes('error') || lowerLine.includes('exception') || lowerLine.includes('failed')) { - if (lowerLine.includes('database')) { - errors.push('Database connection error detected in logs'); - } else if (lowerLine.includes('permission')) { - errors.push('Permission error detected in logs'); - } else if (lowerLine.includes('port') || lowerLine.includes('bind')) { - errors.push('Port binding error detected in logs'); - } else if (lowerLine.includes('import') || lowerLine.includes('module')) { - errors.push('Module import error detected in logs'); - } else { - errors.push(`General error detected: ${line.trim()}`); - } - } - - // Check for warnings - if (lowerLine.includes('warning') || lowerLine.includes('warn')) { - warnings.push(`Warning detected: ${line.trim()}`); - } - } - - return { errors: Array.from(new Set(errors)), warnings: Array.from(new Set(warnings)) }; - } - - private async handleHealthStatus(health: EmpireHealthStatus): Promise { - if (health.errors.length > 0) { - this.consecutiveFailures++; - await this.logMessage('ERROR', `Empire health check failed (${this.consecutiveFailures}/${this.maxConsecutiveFailures}): ${health.errors.join(', ')}`); - - if (this.consecutiveFailures >= this.maxConsecutiveFailures) { - await this.logMessage('ERROR', 'Maximum consecutive failures reached, attempting recovery'); - await this.attemptRecovery(); - } - } else { - if (this.consecutiveFailures > 0) { - await this.logMessage('INFO', 'Empire health recovered successfully'); - } - this.consecutiveFailures = 0; - } - - if (health.warnings.length > 0) { - await this.logMessage('WARN', `Empire warnings: ${health.warnings.join(', ')}`); - } - } - - private async attemptRecovery(): Promise { - await this.logMessage('INFO', 'Starting Empire recovery process'); - - try { - // Step 1: Comprehensive container cleanup - await this.completeContainerCleanup(); - - // Step 2: Ensure volume directories exist with proper permissions - await this.setupVolumes(); - - // Step 3: Start new container with proper initialization - await this.logMessage('INFO', 'Starting new Empire container'); - await this.startEmpireContainer(); - - // Step 4: Wait for container to be ready - await this.waitForContainerReady(); - - await this.logMessage('INFO', 'Empire recovery completed successfully'); - this.consecutiveFailures = 0; - - } catch (error) { - await this.logMessage('ERROR', `Empire recovery failed: ${error}`); - - // If recovery fails, try a more aggressive approach - await this.aggressiveRecovery(); - } - } - - private async completeContainerCleanup(): Promise { - await this.logMessage('INFO', 'Performing complete container cleanup'); - - // Step 1: Stop all Empire-related containers - const stopCommands = [ - `docker stop ${this.containerName} --time 5`, - `docker stop empire-data --time 5`, - `docker stop $(docker ps -q --filter "name=empire") --time 5` - ]; - - for (const cmd of stopCommands) { - try { - await execAsync(cmd).catch(() => execAsync(`sudo ${cmd}`)); - } catch (error) { - // Continue with cleanup even if some containers don't exist - } - } - - // Step 2: Remove all Empire-related containers - const removeCommands = [ - `docker rm -f ${this.containerName}`, - `docker rm -f empire-data`, - `docker rm -f $(docker ps -aq --filter "name=empire")` - ]; - - for (const cmd of removeCommands) { - try { - await execAsync(cmd).catch(() => execAsync(`sudo ${cmd}`)); - } catch (error) { - // Continue with cleanup even if some containers don't exist - } - } - - // Step 3: Clean up orphaned containers - try { - await execAsync('docker container prune -f').catch(() => execAsync('sudo docker container prune -f')); - } catch (error) { - // Continue cleanup - } - - // Step 4: Verify cleanup - await this.logMessage('INFO', 'Container cleanup completed'); - } - - private async setupVolumes(): Promise { - const volumeDirs = [ - path.join(process.cwd(), 'uploads', 'empire', 'data'), - path.join(process.cwd(), 'uploads', 'empire', 'downloads') - ]; - - for (const dir of volumeDirs) { - try { - await fs.mkdir(dir, { recursive: true }); - // Set permissions to be accessible by the container - await execAsync(`chmod 755 ${dir}`); - await this.logMessage('INFO', `Volume directory prepared: ${dir}`); - } catch (error) { - await this.logMessage('ERROR', `Failed to prepare volume directory ${dir}: ${error}`); - } - } - } - - private async startEmpireContainer(): Promise { - // Step 1: Pull the Empire image - await this.logMessage('INFO', 'Pulling Empire image...'); - await execAsync('docker pull bcsecurity/empire:latest') - .catch(async () => { - return await execAsync('sudo docker pull bcsecurity/empire:latest'); - }); - - // Step 2: Create data container - await this.logMessage('INFO', 'Creating Empire data container...'); - const dataContainerCmd = 'docker create -v /empire --name empire-data bcsecurity/empire:latest'; - await execAsync(dataContainerCmd) - .catch(async () => { - return await execAsync('sudo ' + dataContainerCmd); - }); - - // Step 3: Start main container with data container - await this.logMessage('INFO', 'Starting Empire main container...'); - const dockerCmd = [ - 'docker', 'run', '-d', '-it', - '--name', this.containerName, - '--restart', 'unless-stopped', - '-p', '1337:1337', - '-p', '5000:5000', - '--volumes-from', 'empire-data', - 'bcsecurity/empire:latest' - ]; - - await execAsync(dockerCmd.join(' ')) - .catch(async () => { - return await execAsync('sudo ' + dockerCmd.join(' ')); - }); - } - - private async waitForContainerReady(): Promise { - const maxWait = 120000; // 2 minutes - const startTime = Date.now(); - - while (Date.now() - startTime < maxWait) { - try { - const containerInfo = await this.getContainerInfo(); - if (containerInfo.status === 'running') { - // Give Empire time to initialize - await new Promise(resolve => setTimeout(resolve, 15000)); - - // Check if setup is complete - const logs = await this.getContainerLogs(); - if (this.checkSetupCompleted(logs)) { - await this.logMessage('INFO', 'Empire container is ready'); - return; - } - } - } catch (error) { - // Container might not be ready yet - } - - await new Promise(resolve => setTimeout(resolve, 5000)); - } - - throw new Error('Empire container failed to become ready within timeout'); - } - - private async aggressiveRecovery(): Promise { - await this.logMessage('INFO', 'Starting aggressive Empire recovery'); - - try { - // Stop all Empire-related containers - await execAsync(`docker stop $(docker ps -q --filter "name=empire") --time 5`) - .catch(() => {}); - - // Remove all Empire-related containers - await execAsync(`docker rm $(docker ps -aq --filter "name=empire")`) - .catch(() => {}); - - // Clean up volumes - await execAsync(`docker volume prune -f`) - .catch(() => {}); - - // Pull fresh image - await execAsync(`docker pull bcsecurity/empire:latest`) - .catch(async () => { - return await execAsync(`sudo docker pull bcsecurity/empire:latest`); - }); - - // Reset volume permissions - await execAsync(`sudo chown -R $USER:$USER ${process.cwd()}/uploads/empire/`) - .catch(() => {}); - - // Start with a simpler command - const simpleCmd = [ - 'docker', 'run', '-d', - '--name', this.containerName, - '--restart', 'unless-stopped', - '-p', '1337:1337', - '-p', '5000:5000', - 'bcsecurity/empire:latest', - 'sh', '-c', 'cd /empire && python3 empire.py setup --reset -y && python3 empire.py server' - ]; - - await execAsync(simpleCmd.join(' ')) - .catch(async () => { - return await execAsync('sudo ' + simpleCmd.join(' ')); - }); - - await this.logMessage('INFO', 'Aggressive Empire recovery completed'); - - } catch (error) { - await this.logMessage('ERROR', `Aggressive recovery failed: ${error}`); - throw error; - } - } - - public getLastHealthStatus(): EmpireHealthStatus | null { - return this.lastHealthCheck; - } - - public async restartEmpire(): Promise { - await this.logMessage('INFO', 'Manual Empire restart requested'); - this.consecutiveFailures = this.maxConsecutiveFailures; - await this.attemptRecovery(); - } - - public async getDetailedStatus(): Promise<{ - health: EmpireHealthStatus | null; - logs: string; - containerInfo: any; - }> { - const health = await this.checkHealth(); - const logs = await this.getContainerLogs().catch(() => 'No logs available'); - const containerInfo = await this.getContainerInfo().catch(() => ({ id: 'unknown', status: 'unknown' })); - - return { - health, - logs, - containerInfo - }; - } -} - -export const empireHealthMonitor = new EmpireHealthMonitor(); diff --git a/setup.sh b/setup.sh index 88475ef..660e872 100755 --- a/setup.sh +++ b/setup.sh @@ -156,7 +156,7 @@ if [[ "$response" =~ ^[Yy]$ ]]; then curl -fsSL https://get.docker.com -o get-docker.sh > /dev/null 2>&1 sudo sh get-docker.sh > /dev/null 2>&1 sudo usermod -aG docker $USER - sudo apt install -y docker-compose > /dev/null 2>&1 + sudo apt install -y docker-compose-plugin > /dev/null 2>&1 rm get-docker.sh print_success "Docker installed (logout and login required for group changes)" fi @@ -180,4 +180,4 @@ if [[ "$response" =~ ^[Yy]$ ]]; then echo "Note: Log out and back in for Docker permissions to take effect" fi echo "" -print_success "Happy hacking with Attack Node!" \ No newline at end of file +print_success "Happy hacking with Attack Node!" diff --git a/shared/schema.ts b/shared/schema.ts index bc17443..f7a3a2c 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -71,7 +71,7 @@ export const beacons = pgTable("beacons", { operationId: integer("operation_id").references(() => operations.id).notNull(), systemId: integer("system_id").references(() => systems.id), beaconId: text("beacon_id").notNull().unique(), // Unique beacon identifier - type: text("type").notNull(), // cobalt-strike, metasploit, empire, custom + type: text("type").notNull(), // cobalt-strike, metasploit, custom status: text("status").notNull().default("active"), // active, sleeping, dead, lost hostname: text("hostname"), username: text("username"), diff --git a/test-empire-self-healing.sh b/test-empire-self-healing.sh deleted file mode 100755 index b1ac0be..0000000 --- a/test-empire-self-healing.sh +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/bash - -# Empire Self-Healing Test Script -# This script tests the Empire self-healing solution - -set -e - -echo "🔥 Empire Self-Healing Solution Test Script" -echo "===========================================" -echo "" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Function to print colored output -print_status() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# Function to wait for user input -wait_for_input() { - echo -e "${YELLOW}Press Enter to continue...${NC}" - read -r -} - -# Check if Docker is available -check_docker() { - print_status "Checking Docker availability..." - - if ! command -v docker &> /dev/null; then - print_error "Docker is not installed or not in PATH" - exit 1 - fi - - if ! docker info &> /dev/null; then - print_error "Docker daemon is not running" - exit 1 - fi - - print_success "Docker is available and running" -} - -# Check if Empire directories exist -check_empire_directories() { - print_status "Checking Empire volume directories..." - - if [ ! -d "uploads/empire" ]; then - print_warning "Empire directories don't exist, creating them..." - mkdir -p uploads/empire/data - mkdir -p uploads/empire/downloads - chmod 755 uploads/empire/data - chmod 755 uploads/empire/downloads - print_success "Empire directories created" - else - print_success "Empire directories exist" - fi -} - -# Test Empire image availability -test_empire_image() { - print_status "Testing Empire image availability..." - - if docker pull bcsecurity/empire:latest; then - print_success "Empire image pulled successfully" - else - print_error "Failed to pull Empire image" - exit 1 - fi -} - -# Test Empire container startup -test_empire_startup() { - print_status "Testing Empire container startup..." - - # Stop any existing Empire containers - docker stop attacknode-empire 2>/dev/null || true - docker rm attacknode-empire 2>/dev/null || true - - # Start Empire container with the data container pattern - print_status "Starting Empire container with data container pattern..." - - # Step 1: Create data container - print_status "Creating Empire data container..." - docker create -v /empire --name empire-data bcsecurity/empire:latest - - # Step 2: Start main container - print_status "Starting Empire main container..." - docker run -d -it \ - --name attacknode-empire \ - --restart unless-stopped \ - -p 1337:1337 \ - -p 5000:5000 \ - --volumes-from empire-data \ - bcsecurity/empire:latest - - # Wait for container to start - print_status "Waiting for Empire container to initialize..." - sleep 15 - - # Check if container is running - if docker ps --filter "name=attacknode-empire" --format "table {{.Names}}\t{{.Status}}" | grep -q "attacknode-empire"; then - print_success "Empire container is running" - else - print_error "Empire container failed to start" - print_status "Container logs:" - docker logs attacknode-empire 2>&1 | tail -20 - return 1 - fi -} - -# Test Empire API -test_empire_api() { - print_status "Testing Empire API connectivity..." - - # Wait for Empire to be ready - local max_attempts=30 - local attempt=1 - - while [ $attempt -le $max_attempts ]; do - print_status "Attempt $attempt/$max_attempts: Testing API on port 1337..." - - if curl -s -f --max-time 5 http://localhost:1337/api/version &> /dev/null; then - print_success "Empire API is responding" - return 0 - fi - - sleep 5 - ((attempt++)) - done - - print_warning "Empire API not responding after $max_attempts attempts" - print_status "This may be normal if Empire is still initializing" - return 1 -} - -# Test Starkiller UI -test_starkiller_ui() { - print_status "Testing Starkiller UI connectivity..." - - if curl -s -f --max-time 5 http://localhost:5000 &> /dev/null; then - print_success "Starkiller UI is accessible" - return 0 - else - print_warning "Starkiller UI not accessible" - print_status "This may be normal if Starkiller is not fully initialized" - return 1 - fi -} - -# Test Empire database -test_empire_database() { - print_status "Testing Empire database..." - - if docker exec attacknode-empire ls -la /empire/empire.db &> /dev/null; then - print_success "Empire database exists" - return 0 - else - print_warning "Empire database not found" - return 1 - fi -} - -# Test recovery mechanism -test_recovery_mechanism() { - print_status "Testing Empire recovery mechanism..." - - # Stop the container to simulate failure - print_status "Simulating container failure..." - docker stop attacknode-empire - - print_status "Waiting for health monitor to detect failure and recover..." - print_status "This may take up to 90 seconds..." - - # Wait for potential recovery - sleep 90 - - # Check if container was recovered - if docker ps --filter "name=attacknode-empire" --format "table {{.Names}}\t{{.Status}}" | grep -q "attacknode-empire"; then - print_success "Empire container recovered automatically" - return 0 - else - print_warning "Automatic recovery not detected" - print_status "Manual recovery may be required" - return 1 - fi -} - -# Display Empire information -display_empire_info() { - print_status "Empire Container Information:" - echo "==============================" - - # Container status - echo "Container Status:" - docker ps --filter "name=attacknode-empire" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" || true - echo "" - - # Container logs (last 10 lines) - echo "Recent Logs:" - docker logs attacknode-empire --tail 10 2>&1 || true - echo "" - - # Port status - echo "Port Status:" - netstat -tlnp | grep -E ':1337|:5000' || echo "No ports found" - echo "" - - # Volume status - echo "Volume Status:" - ls -la uploads/empire/ 2>/dev/null || echo "No volumes found" - echo "" -} - -# Main test execution -main() { - echo "Starting Empire self-healing solution tests..." - echo "" - - # Basic checks - check_docker - check_empire_directories - - # Image and startup tests - test_empire_image - - print_status "About to test Empire container startup..." - wait_for_input - - if test_empire_startup; then - print_success "Empire startup test passed" - else - print_error "Empire startup test failed" - display_empire_info - return 1 - fi - - # API tests - print_status "About to test Empire API..." - wait_for_input - - if test_empire_api; then - print_success "Empire API test passed" - else - print_warning "Empire API test failed" - fi - - # UI tests - if test_starkiller_ui; then - print_success "Starkiller UI test passed" - else - print_warning "Starkiller UI test failed" - fi - - # Database tests - if test_empire_database; then - print_success "Empire database test passed" - else - print_warning "Empire database test failed" - fi - - # Recovery tests - print_status "About to test recovery mechanism..." - print_warning "This will stop the Empire container to test auto-recovery" - wait_for_input - - if test_recovery_mechanism; then - print_success "Recovery mechanism test passed" - else - print_warning "Recovery mechanism test failed" - fi - - # Final information - display_empire_info - - echo "" - echo "🎉 Empire Self-Healing Solution Test Complete" - echo "=============================================" - echo "" - print_success "Test execution completed" - print_status "Check the results above for any issues" - print_status "Empire should now be running with self-healing capabilities" - echo "" - print_status "Access Empire:" - echo " - API: http://localhost:1337" - echo " - Starkiller UI: http://localhost:5000" - echo "" - print_status "Monitor Empire health:" - echo " - Container logs: docker logs attacknode-empire" - echo " - Health check: curl http://localhost:1337/api/version" - echo "" -} - -# Run main function -main "$@"