[
  {
    "path": ".cursor/rules/README.md",
    "content": "# Evolution API Cursor Rules\n\nEste diretório contém as regras e configurações do Cursor IDE para o projeto Evolution API.\n\n## Estrutura dos Arquivos\n\n### Arquivos Principais (alwaysApply: true)\n- **`core-development.mdc`** - Princípios fundamentais de desenvolvimento\n- **`project-context.mdc`** - Contexto específico do projeto Evolution API\n- **`cursor.json`** - Configurações do Cursor IDE\n\n### Regras Especializadas (alwaysApply: false)\nEstas regras são ativadas automaticamente quando você trabalha nos arquivos correspondentes:\n\n#### Camadas da Aplicação\n- **`specialized-rules/service-rules.mdc`** - Padrões para services (`src/api/services/`)\n- **`specialized-rules/controller-rules.mdc`** - Padrões para controllers (`src/api/controllers/`)\n- **`specialized-rules/dto-rules.mdc`** - Padrões para DTOs (`src/api/dto/`)\n- **`specialized-rules/guard-rules.mdc`** - Padrões para guards (`src/api/guards/`)\n- **`specialized-rules/route-rules.mdc`** - Padrões para routers (`src/api/routes/`)\n\n#### Tipos e Validação\n- **`specialized-rules/type-rules.mdc`** - Definições TypeScript (`src/api/types/`)\n- **`specialized-rules/validate-rules.mdc`** - Schemas de validação (`src/validate/`)\n\n#### Utilitários\n- **`specialized-rules/util-rules.mdc`** - Funções utilitárias (`src/utils/`)\n\n#### Integrações\n- **`specialized-rules/integration-channel-rules.mdc`** - Integrações de canal (`src/api/integrations/channel/`)\n- **`specialized-rules/integration-chatbot-rules.mdc`** - Integrações de chatbot (`src/api/integrations/chatbot/`)\n- **`specialized-rules/integration-storage-rules.mdc`** - Integrações de storage (`src/api/integrations/storage/`)\n- **`specialized-rules/integration-event-rules.mdc`** - Integrações de eventos (`src/api/integrations/event/`)\n\n## Como Usar\n\n### Referências Cruzadas\nOs arquivos principais fazem referência aos especializados usando a sintaxe `@specialized-rules/nome-do-arquivo.mdc`. Quando você trabalha em um arquivo específico, o Cursor automaticamente carrega as regras relevantes.\n\n### Exemplo de Uso\nQuando você edita um arquivo em `src/api/services/`, o Cursor automaticamente:\n1. Carrega `core-development.mdc` (sempre ativo)\n2. Carrega `project-context.mdc` (sempre ativo)\n3. Carrega `specialized-rules/service-rules.mdc` (ativado pelo glob pattern)\n\n### Padrões de Código\nCada arquivo de regras contém:\n- **Estruturas padrão** - Como organizar o código\n- **Padrões de nomenclatura** - Convenções de nomes\n- **Exemplos práticos** - Código de exemplo\n- **Anti-padrões** - O que evitar\n- **Testes** - Como testar o código\n- **Padrões de Commit** - Conventional Commits com commitlint\n\n## Configuração do Cursor\n\nO arquivo `cursor.json` contém:\n- Configurações de formatação\n- Padrões de código específicos do Evolution API\n- Diretórios principais do projeto\n- Integrações e tecnologias utilizadas\n\n## Manutenção\n\nPara manter as regras atualizadas:\n1. Analise novos padrões no código\n2. Atualize as regras especializadas correspondentes\n3. Mantenha os exemplos sincronizados com o código real\n4. Documente mudanças significativas\n\n## Tecnologias Cobertas\n\n- **Backend**: Node.js 20+ + TypeScript 5+ + Express.js\n- **Database**: Prisma ORM (PostgreSQL/MySQL)\n- **Cache**: Redis + Node-cache\n- **Queue**: RabbitMQ + Amazon SQS\n- **Real-time**: Socket.io\n- **Storage**: AWS S3 + Minio\n- **Validation**: JSONSchema7\n- **Logging**: Pino\n- **WhatsApp**: Baileys + Meta Business API\n- **Integrations**: Chatwoot, Typebot, OpenAI, Dify\n\n## Estrutura do Projeto\n\n```\nsrc/\n├── api/\n│   ├── controllers/     # Controllers (HTTP handlers)\n│   ├── services/        # Business logic\n│   ├── dto/            # Data Transfer Objects\n│   ├── guards/         # Authentication/Authorization\n│   ├── routes/         # Express routers\n│   ├── types/          # TypeScript definitions\n│   └── integrations/   # External integrations\n│       ├── channel/    # WhatsApp channels (Baileys, Business API)\n│       ├── chatbot/    # Chatbot integrations\n│       ├── event/      # Event integrations\n│       └── storage/    # Storage integrations\n├── cache/              # Cache implementations\n├── config/             # Configuration files\n├── utils/              # Utility functions\n├── validate/           # Validation schemas\n└── exceptions/         # Custom exceptions\n```\n\nEste sistema de regras garante consistência no código e facilita o desenvolvimento seguindo os padrões estabelecidos do Evolution API.\n"
  },
  {
    "path": ".cursor/rules/core-development.mdc",
    "content": "---\ndescription: Core development principles and standards for Evolution API development\nglobs:\nalwaysApply: true\n---\n\n# Evolution API Development Standards\n\n## Cross-References\n- **Project Context**: @project-context.mdc for Evolution API-specific patterns\n- **Specialized Rules**: \n  - @specialized-rules/service-rules.mdc for service layer patterns\n  - @specialized-rules/controller-rules.mdc for controller patterns\n  - @specialized-rules/dto-rules.mdc for DTO validation patterns\n  - @specialized-rules/guard-rules.mdc for authentication/authorization\n  - @specialized-rules/route-rules.mdc for router patterns\n  - @specialized-rules/type-rules.mdc for TypeScript definitions\n  - @specialized-rules/util-rules.mdc for utility functions\n  - @specialized-rules/validate-rules.mdc for validation schemas\n  - @specialized-rules/integration-channel-rules.mdc for channel integrations\n  - @specialized-rules/integration-chatbot-rules.mdc for chatbot integrations\n  - @specialized-rules/integration-storage-rules.mdc for storage integrations\n  - @specialized-rules/integration-event-rules.mdc for event integrations\n- **TypeScript/Node.js**: Node.js 20+ + TypeScript 5+ best practices\n- **Express/Prisma**: Express.js + Prisma ORM patterns\n- **WhatsApp Integrations**: Baileys + Meta Business API patterns\n\n## Senior Engineer Context - Evolution API Platform\n- You are a senior software engineer working on a WhatsApp API platform\n- Focus on Node.js + TypeScript + Express.js full-stack development\n- Specialized in real-time messaging, WhatsApp integrations, and event-driven architecture\n- Apply scalable patterns for multi-tenant API platform\n- Consider WhatsApp integration workflow implications and performance at scale\n\n## Fundamental Principles\n\n### Code Quality Standards\n- **Simplicity First**: Always prefer simple solutions over complex ones\n- **DRY Principle**: Avoid code duplication - check for existing similar functionality before implementing\n- **Single Responsibility**: Each function/class should have one clear purpose\n- **Readable Code**: Write code that tells a story - clear naming and structure\n\n### Problem Resolution Approach\n- **Follow Existing Patterns**: Use established Service patterns, DTOs, and Integration patterns\n- **Event-Driven First**: Leverage EventEmitter2 for event publishing when adding new features\n- **Integration Pattern**: Follow existing WhatsApp integration patterns for new channels\n- **Conservative Changes**: Prefer extending existing services over creating new architecture\n- **Clean Migration**: Remove deprecated patterns when introducing new ones\n- **Incremental Changes**: Break large changes into smaller, testable increments with proper migrations\n\n### File and Function Organization - Node.js/TypeScript Structure\n- **Services**: Keep services focused and under 200 lines\n- **Controllers**: Keep controllers thin - only routing and validation\n- **DTOs**: Use JSONSchema7 for all input validation\n- **Integrations**: Follow `src/api/integrations/` structure for new integrations\n- **Utils**: Extract common functionality into well-named utilities\n- **Types**: Define clear TypeScript interfaces and types\n\n### Code Analysis and Reflection\n- After writing code, deeply reflect on scalability and maintainability\n- Provide 1-2 paragraph analysis of code changes\n- Suggest improvements or next steps based on reflection\n- Consider performance, security, and maintenance implications\n\n## Development Standards\n\n### TypeScript Standards\n- **Strict Mode**: Always use TypeScript strict mode\n- **No Any**: Avoid `any` type - use proper typing\n- **Interfaces**: Define clear contracts with interfaces\n- **Enums**: Use enums for constants and status values\n- **Generics**: Use generics for reusable components\n\n### Error Handling Standards\n- **HTTP Exceptions**: Use appropriate HTTP status codes\n- **Logging**: Structured logging with context\n- **Retry Logic**: Implement retry for external services\n- **Graceful Degradation**: Handle service failures gracefully\n\n### Security Standards\n- **Input Validation**: Validate all inputs with JSONSchema7\n- **Authentication**: Use API keys and JWT tokens\n- **Rate Limiting**: Implement rate limiting for APIs\n- **Data Sanitization**: Sanitize sensitive data in logs\n\n### Performance Standards\n- **Caching**: Use Redis for frequently accessed data\n- **Database**: Optimize Prisma queries with proper indexing\n- **Memory**: Monitor memory usage and implement cleanup\n- **Async**: Use async/await properly with error handling\n\n## Communication Standards\n\n### Language Requirements\n- **User Communication**: Always respond in Portuguese (PT-BR)\n- **Code Comments**: English for technical documentation\n- **API Documentation**: English for consistency\n- **Error Messages**: Portuguese for user-facing errors\n\n### Documentation Standards\n- **Code Comments**: Document complex business logic\n- **API Documentation**: Document all public endpoints\n- **README**: Keep project documentation updated\n- **Changelog**: Document breaking changes\n\n## Quality Assurance\n\n### Testing Standards\n- **Unit Tests**: Test business logic in services\n- **Integration Tests**: Test API endpoints\n- **Mocks**: Mock external dependencies\n- **Coverage**: Aim for 70%+ test coverage\n\n### Code Review Standards\n- **Peer Review**: All code must be reviewed\n- **Automated Checks**: ESLint, Prettier, TypeScript\n- **Security Review**: Check for security vulnerabilities\n- **Performance Review**: Check for performance issues\n\n### Commit Standards (Conventional Commits)\n- **Format**: `type(scope): subject` (max 100 characters)\n- **Types**: \n  - `feat` - New feature\n  - `fix` - Bug fix\n  - `docs` - Documentation changes\n  - `style` - Code style changes (formatting, etc)\n  - `refactor` - Code refactoring\n  - `perf` - Performance improvements\n  - `test` - Adding or updating tests\n  - `chore` - Maintenance tasks\n  - `ci` - CI/CD changes\n  - `build` - Build system changes\n  - `revert` - Reverting changes\n  - `security` - Security fixes\n- **Examples**:\n  - `feat(api): add WhatsApp message status endpoint`\n  - `fix(baileys): resolve connection timeout issue`\n  - `docs(readme): update installation instructions`\n  - `refactor(service): extract common message validation logic`\n- **Tools**: Use `npm run commit` (Commitizen) for guided commits\n- **Validation**: Enforced by commitlint on commit-msg hook\n\n## Evolution API Specific Patterns\n\n### WhatsApp Integration Patterns\n- **Connection Management**: One connection per instance\n- **Event Handling**: Proper event listeners for Baileys\n- **Message Processing**: Queue-based message processing\n- **Error Recovery**: Automatic reconnection logic\n\n### Multi-Database Support\n- **Schema Compatibility**: Support PostgreSQL and MySQL\n- **Migration Sync**: Keep migrations synchronized\n- **Type Safety**: Use Prisma generated types\n- **Connection Pooling**: Proper database connection management\n\n### Cache Strategy\n- **Redis Primary**: Use Redis for distributed caching\n- **Local Fallback**: Node-cache for local fallback\n- **TTL Strategy**: Appropriate TTL for different data types\n- **Cache Invalidation**: Proper cache invalidation patterns\n\n### Event System\n- **EventEmitter2**: Use for internal events\n- **WebSocket**: Socket.io for real-time updates\n- **Queue Systems**: RabbitMQ/SQS for async processing\n- **Webhook Processing**: Proper webhook validation and processing"
  },
  {
    "path": ".cursor/rules/cursor.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"description\": \"Cursor IDE configuration for Evolution API project\",\n  \"rules\": {\n    \"general\": {\n      \"max_line_length\": 120,\n      \"indent_size\": 2,\n      \"end_of_line\": \"lf\",\n      \"charset\": \"utf-8\",\n      \"trim_trailing_whitespace\": true,\n      \"insert_final_newline\": true\n    },\n    \"typescript\": {\n      \"quotes\": \"single\",\n      \"semi\": true,\n      \"trailing_comma\": \"es5\",\n      \"bracket_spacing\": true,\n      \"arrow_parens\": \"avoid\",\n      \"print_width\": 120,\n      \"tab_width\": 2,\n      \"use_tabs\": false,\n      \"single_quote\": true,\n      \"end_of_line\": \"lf\",\n      \"strict\": true,\n      \"no_implicit_any\": true,\n      \"strict_null_checks\": true\n    },\n    \"javascript\": {\n      \"quotes\": \"single\",\n      \"semi\": true,\n      \"trailing_comma\": \"es5\",\n      \"bracket_spacing\": true,\n      \"arrow_parens\": \"avoid\",\n      \"print_width\": 120,\n      \"tab_width\": 2,\n      \"use_tabs\": false,\n      \"single_quote\": true,\n      \"end_of_line\": \"lf\",\n      \"style_guide\": \"eslint-airbnb\"\n    },\n    \"json\": {\n      \"tab_width\": 2,\n      \"use_tabs\": false,\n      \"parser\": \"json\"\n    },\n    \"ignore\": {\n      \"files\": [\n        \"node_modules/**\",\n        \"dist/**\",\n        \"build/**\",\n        \".git/**\",\n        \"*.min.js\",\n        \"*.min.css\",\n        \".env\",\n        \".env.*\",\n        \".env.example\",\n        \"coverage/**\",\n        \"*.log\",\n        \"*.lock\",\n        \"pnpm-lock.yaml\",\n        \"package-lock.json\",\n        \"yarn.lock\",\n        \"log/**\",\n        \"tmp/**\",\n        \"instances/**\",\n        \"public/uploads/**\",\n        \"*.dump\",\n        \"*.rdb\",\n        \"*.mmdb\",\n        \".DS_Store\",\n        \"*.swp\",\n        \"*.swo\",\n        \"*.un~\",\n        \".jest-cache\",\n        \".idea/**\",\n        \".vscode/**\",\n        \".yalc/**\",\n        \"yalc.lock\",\n        \"*.local\",\n        \"prisma/migrations/**\",\n        \"prisma/mysql-migrations/**\",\n        \"prisma/postgresql-migrations/**\"\n      ]\n    },\n    \"search\": {\n      \"exclude_patterns\": [\n        \"**/node_modules/**\",\n        \"**/dist/**\",\n        \"**/build/**\",\n        \"**/.git/**\",\n        \"**/coverage/**\",\n        \"**/log/**\",\n        \"**/tmp/**\",\n        \"**/instances/**\",\n        \"**/public/uploads/**\",\n        \"**/*.min.js\",\n        \"**/*.min.css\",\n        \"**/*.log\",\n        \"**/*.lock\",\n        \"**/pnpm-lock.yaml\",\n        \"**/package-lock.json\",\n        \"**/yarn.lock\",\n        \"**/*.dump\",\n        \"**/*.rdb\",\n        \"**/*.mmdb\",\n        \"**/.DS_Store\",\n        \"**/*.swp\",\n        \"**/*.swo\",\n        \"**/*.un~\",\n        \"**/.jest-cache\",\n        \"**/.idea/**\",\n        \"**/.vscode/**\",\n        \"**/.yalc/**\",\n        \"**/yalc.lock\",\n        \"**/*.local\",\n        \"**/prisma/migrations/**\",\n        \"**/prisma/mysql-migrations/**\",\n        \"**/prisma/postgresql-migrations/**\"\n      ]\n    },\n    \"evolution_api\": {\n      \"project_type\": \"nodejs_typescript_api\",\n      \"backend_framework\": \"express_prisma\",\n      \"database\": [\"postgresql\", \"mysql\"],\n      \"cache\": [\"redis\", \"node_cache\"],\n      \"queue\": [\"rabbitmq\", \"sqs\"],\n      \"real_time\": \"socket_io\",\n      \"file_storage\": [\"aws_s3\", \"minio\"],\n      \"validation\": \"class_validator\",\n      \"logging\": \"pino\",\n      \"main_directories\": {\n        \"source\": \"src/\",\n        \"api\": \"src/api/\",\n        \"controllers\": \"src/api/controllers/\",\n        \"services\": \"src/api/services/\",\n        \"integrations\": \"src/api/integrations/\",\n        \"dto\": \"src/api/dto/\",\n        \"types\": \"src/api/types/\",\n        \"guards\": \"src/api/guards/\",\n        \"routes\": \"src/api/routes/\",\n        \"cache\": \"src/cache/\",\n        \"config\": \"src/config/\",\n        \"utils\": \"src/utils/\",\n        \"exceptions\": \"src/exceptions/\",\n        \"validate\": \"src/validate/\",\n        \"prisma\": \"prisma/\",\n        \"tests\": \"test/\",\n        \"docs\": \"docs/\"\n      },\n      \"key_patterns\": [\n        \"whatsapp_integration\",\n        \"multi_database_support\",\n        \"instance_management\",\n        \"event_driven_architecture\",\n        \"service_layer_pattern\",\n        \"dto_validation\",\n        \"webhook_processing\",\n        \"message_queuing\",\n        \"real_time_communication\",\n        \"file_storage_integration\"\n      ],\n      \"whatsapp_integrations\": [\n        \"baileys\",\n        \"meta_business_api\",\n        \"whatsapp_cloud_api\"\n      ],\n      \"external_integrations\": [\n        \"chatwoot\",\n        \"typebot\",\n        \"openai\",\n        \"dify\",\n        \"rabbitmq\",\n        \"sqs\",\n        \"s3\",\n        \"minio\"\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": ".cursor/rules/project-context.mdc",
    "content": "---\ndescription: Evolution API project-specific context and constraints\nglobs:\nalwaysApply: true\n---\n\n# Evolution API Project Context\n\n## Cross-References\n- **Core Development**: @core-development.mdc for fundamental development principles\n- **Specialized Rules**: Reference specific specialized rules when working on:\n  - Services: @specialized-rules/service-rules.mdc\n  - Controllers: @specialized-rules/controller-rules.mdc\n  - DTOs: @specialized-rules/dto-rules.mdc\n  - Guards: @specialized-rules/guard-rules.mdc\n  - Routes: @specialized-rules/route-rules.mdc\n  - Types: @specialized-rules/type-rules.mdc\n  - Utils: @specialized-rules/util-rules.mdc\n  - Validation: @specialized-rules/validate-rules.mdc\n  - Channel Integrations: @specialized-rules/integration-channel-rules.mdc\n  - Chatbot Integrations: @specialized-rules/integration-chatbot-rules.mdc\n  - Storage Integrations: @specialized-rules/integration-storage-rules.mdc\n  - Event Integrations: @specialized-rules/integration-event-rules.mdc\n- **TypeScript/Node.js**: Node.js 20+ + TypeScript 5+ backend standards\n- **Express/Prisma**: Express.js + Prisma ORM patterns\n- **WhatsApp Integrations**: Baileys, Meta Business API, and other messaging platforms\n\n## Technology Stack\n- **Backend**: Node.js 20+ + TypeScript 5+ + Express.js\n- **Database**: Prisma ORM (PostgreSQL/MySQL support)\n- **Cache**: Redis + Node-cache for local fallback\n- **Queue**: RabbitMQ + Amazon SQS for message processing\n- **Real-time**: Socket.io for WebSocket connections\n- **Storage**: AWS S3 + Minio for file storage\n- **Validation**: JSONSchema7 for input validation\n- **Logging**: Pino for structured logging\n- **Architecture**: Multi-tenant API with WhatsApp integrations\n\n## Project-Specific Patterns\n\n### WhatsApp Integration Architecture\n- **MANDATORY**: All WhatsApp integrations must follow established patterns\n- **BAILEYS**: Use `whatsapp.baileys.service.ts` patterns for WhatsApp Web\n- **META BUSINESS**: Use `whatsapp.business.service.ts` for official API\n- **CONNECTION MANAGEMENT**: One connection per instance with proper lifecycle\n- **EVENT HANDLING**: Proper event listeners and error handling\n\n### Multi-Database Architecture\n- **CRITICAL**: Support both PostgreSQL and MySQL\n- **SCHEMAS**: Use appropriate schema files (postgresql-schema.prisma / mysql-schema.prisma)\n- **MIGRATIONS**: Keep migrations synchronized between databases\n- **TYPES**: Use database-specific types (@db.JsonB vs @db.Json)\n- **COMPATIBILITY**: Ensure feature parity between databases\n\n### API Integration Workflow\n- **CORE FEATURE**: REST API for WhatsApp communication\n- **COMPLEXITY**: High - involves webhook processing, message routing, and instance management\n- **COMPONENTS**: Instance management, message handling, media processing\n- **INTEGRATIONS**: Baileys, Meta Business API, Chatwoot, Typebot, OpenAI, Dify\n\n### Multi-Tenant Instance Architecture\n- **CRITICAL**: All operations must be scoped by instance\n- **ISOLATION**: Complete data isolation between instances\n- **SECURITY**: Validate instance ownership before operations\n- **SCALING**: Support thousands of concurrent instances\n- **AUTHENTICATION**: API key-based authentication per instance\n\n## Documentation Requirements\n\n### Implementation Documentation\n- **MANDATORY**: Document complex integration patterns\n- **LOCATION**: Use inline comments for business logic\n- **API DOCS**: Document all public endpoints\n- **WEBHOOK DOCS**: Document webhook payloads and signatures\n\n### Change Documentation\n- **CHANGELOG**: Document breaking changes\n- **MIGRATION GUIDES**: Document database migrations\n- **INTEGRATION GUIDES**: Document new integration patterns\n\n## Environment and Security\n\n### Environment Variables\n- **CRITICAL**: Never hardcode sensitive values\n- **VALIDATION**: Validate required environment variables on startup\n- **SECURITY**: Use secure defaults and proper encryption\n- **DOCUMENTATION**: Document all environment variables\n\n### File Organization - Node.js/TypeScript Structure\n- **CONTROLLERS**: Organized by feature (`api/controllers/`)\n- **SERVICES**: Business logic in service classes (`api/services/`)\n- **INTEGRATIONS**: External integrations (`api/integrations/`)\n- **DTOS**: Data transfer objects (`api/dto/`)\n- **TYPES**: TypeScript types (`api/types/`)\n- **UTILS**: Utility functions (`utils/`)\n\n## Integration Points\n\n### WhatsApp Providers\n- **BAILEYS**: WhatsApp Web integration with QR code\n- **META BUSINESS**: Official WhatsApp Business API\n- **CLOUD API**: WhatsApp Cloud API integration\n- **WEBHOOK PROCESSING**: Proper webhook validation and processing\n\n### External Integrations\n- **CHATWOOT**: Customer support platform integration\n- **TYPEBOT**: Chatbot flow integration\n- **OPENAI**: AI-powered chat integration\n- **DIFY**: AI workflow integration\n- **STORAGE**: S3/Minio for media file storage\n\n### Event-Driven Communication\n- **EVENTEMITTER2**: Internal event system\n- **SOCKET.IO**: Real-time WebSocket communication\n- **RABBITMQ**: Message queue for async processing\n- **SQS**: Amazon SQS for cloud-based queuing\n- **WEBHOOKS**: Outbound webhook system\n\n## Development Constraints\n\n### Language Requirements\n- **USER COMMUNICATION**: Always respond in Portuguese (PT-BR)\n- **CODE/COMMENTS**: English for code and technical documentation\n- **API RESPONSES**: English for consistency\n- **ERROR MESSAGES**: Portuguese for user-facing errors\n\n### Performance Constraints\n- **MEMORY**: Efficient memory usage for multiple instances\n- **DATABASE**: Optimized queries with proper indexing\n- **CACHE**: Strategic caching for frequently accessed data\n- **CONNECTIONS**: Proper connection pooling and management\n\n### Security Constraints\n- **AUTHENTICATION**: API key validation for all endpoints\n- **AUTHORIZATION**: Instance-based access control\n- **INPUT VALIDATION**: Validate all inputs with JSONSchema7\n- **RATE LIMITING**: Prevent abuse with rate limiting\n- **WEBHOOK SECURITY**: Validate webhook signatures\n\n## Quality Standards\n- **TYPE SAFETY**: Full TypeScript coverage with strict mode\n- **ERROR HANDLING**: Comprehensive error scenarios with proper logging\n- **TESTING**: Unit and integration tests for critical paths\n- **MONITORING**: Proper logging and error tracking\n- **DOCUMENTATION**: Clear API documentation and code comments\n- **PERFORMANCE**: Optimized for high-throughput message processing\n- **SECURITY**: Secure by default with proper validation\n- **SCALABILITY**: Design for horizontal scaling\n\n## Evolution API Specific Development Patterns\n\n### Instance Management\n- **LIFECYCLE**: Proper instance creation, connection, and cleanup\n- **STATE MANAGEMENT**: Track connection status and health\n- **RECOVERY**: Automatic reconnection and error recovery\n- **MONITORING**: Health checks and status reporting\n\n### Message Processing\n- **QUEUE-BASED**: Use queues for message processing\n- **RETRY LOGIC**: Implement exponential backoff for failures\n- **MEDIA HANDLING**: Proper media upload and processing\n- **WEBHOOK DELIVERY**: Reliable webhook delivery with retries\n\n### Integration Patterns\n- **SERVICE LAYER**: Business logic in service classes\n- **DTO VALIDATION**: Input validation with JSONSchema7\n- **ERROR HANDLING**: Consistent error responses\n- **LOGGING**: Structured logging with correlation IDs\n\n### Database Patterns\n- **PRISMA**: Use Prisma ORM for all database operations\n- **TRANSACTIONS**: Use transactions for multi-step operations\n- **MIGRATIONS**: Proper migration management\n- **INDEXING**: Optimize queries with appropriate indexes"
  },
  {
    "path": ".cursor/rules/specialized-rules/controller-rules.mdc",
    "content": "---\ndescription: Controller patterns for Evolution API\nglobs:\n  - \"src/api/controllers/**/*.ts\"\n  - \"src/api/integrations/**/controllers/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Controller Rules\n\n## Controller Structure Pattern\n\n### Standard Controller Class\n```typescript\nexport class ExampleController {\n  constructor(private readonly exampleService: ExampleService) {}\n\n  public async createExample(instance: InstanceDto, data: ExampleDto) {\n    return this.exampleService.create(instance, data);\n  }\n\n  public async findExample(instance: InstanceDto) {\n    return this.exampleService.find(instance);\n  }\n}\n```\n\n## Dependency Injection Pattern\n\n### Service Injection\n```typescript\n// CORRECT - Evolution API pattern\nexport class ChatController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) {\n    return await this.waMonitor.waInstances[instanceName].getWhatsAppNumbers(data);\n  }\n}\n\n// INCORRECT - Don't inject multiple services when waMonitor is sufficient\nexport class ChatController {\n  constructor(\n    private readonly waMonitor: WAMonitoringService,\n    private readonly prismaRepository: PrismaRepository, // ❌ Unnecessary if waMonitor has access\n    private readonly configService: ConfigService, // ❌ Unnecessary if waMonitor has access\n  ) {}\n}\n```\n\n## Method Signature Pattern\n\n### Instance Parameter Pattern\n```typescript\n// CORRECT - Evolution API pattern (destructuring instanceName)\npublic async fetchCatalog({ instanceName }: InstanceDto, data: getCatalogDto) {\n  return await this.waMonitor.waInstances[instanceName].fetchCatalog(instanceName, data);\n}\n\n// CORRECT - Alternative pattern for full instance (when using services)\npublic async createTemplate(instance: InstanceDto, data: TemplateDto) {\n  return this.templateService.create(instance, data);\n}\n\n// INCORRECT - Don't use generic method names\npublic async methodName(instance: InstanceDto, data: DataDto) { // ❌ Use specific names\n  return this.service.performAction(instance, data);\n}\n```\n\n## WAMonitor Access Pattern\n\n### Direct WAMonitor Usage\n```typescript\n// CORRECT - Standard pattern in controllers\nexport class CallController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async offerCall({ instanceName }: InstanceDto, data: OfferCallDto) {\n    return await this.waMonitor.waInstances[instanceName].offerCall(data);\n  }\n}\n```\n\n## Controller Registration Pattern\n\n### Server Module Registration\n```typescript\n// In server.module.ts\nexport const templateController = new TemplateController(templateService);\nexport const businessController = new BusinessController(waMonitor);\nexport const chatController = new ChatController(waMonitor);\nexport const callController = new CallController(waMonitor);\n```\n\n## Error Handling in Controllers\n\n### Let Services Handle Errors\n```typescript\n// CORRECT - Let service handle errors\npublic async fetchCatalog(instance: InstanceDto, data: getCatalogDto) {\n  return await this.waMonitor.waInstances[instance.instanceName].fetchCatalog(instance.instanceName, data);\n}\n\n// INCORRECT - Don't add try-catch in controllers unless specific handling needed\npublic async fetchCatalog(instance: InstanceDto, data: getCatalogDto) {\n  try {\n    return await this.waMonitor.waInstances[instance.instanceName].fetchCatalog(instance.instanceName, data);\n  } catch (error) {\n    throw error; // ❌ Unnecessary try-catch\n  }\n}\n```\n\n## Complex Controller Pattern\n\n### Instance Controller Pattern\n```typescript\nexport class InstanceController {\n  constructor(\n    private readonly waMonitor: WAMonitoringService,\n    private readonly configService: ConfigService,\n    private readonly prismaRepository: PrismaRepository,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly chatwootService: ChatwootService,\n    private readonly settingsService: SettingsService,\n    private readonly proxyService: ProxyController,\n    private readonly cache: CacheService,\n    private readonly chatwootCache: CacheService,\n    private readonly baileysCache: CacheService,\n    private readonly providerFiles: ProviderFiles,\n  ) {}\n\n  private readonly logger = new Logger('InstanceController');\n\n  // Multiple methods handling different aspects\n  public async createInstance(data: InstanceDto) {\n    // Complex instance creation logic\n  }\n\n  public async deleteInstance({ instanceName }: InstanceDto) {\n    // Complex instance deletion logic\n  }\n}\n```\n\n## Channel Controller Pattern\n\n### Base Channel Controller\n```typescript\nexport class ChannelController {\n  public prismaRepository: PrismaRepository;\n  public waMonitor: WAMonitoringService;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    this.prisma = prismaRepository;\n    this.monitor = waMonitor;\n  }\n\n  // Getters and setters for dependency access\n  public set prisma(prisma: PrismaRepository) {\n    this.prismaRepository = prisma;\n  }\n\n  public get prisma() {\n    return this.prismaRepository;\n  }\n\n  public set monitor(waMonitor: WAMonitoringService) {\n    this.waMonitor = waMonitor;\n  }\n\n  public get monitor() {\n    return this.waMonitor;\n  }\n}\n```\n\n### Extended Channel Controller\n```typescript\nexport class EvolutionController extends ChannelController implements ChannelControllerInterface {\n  private readonly logger = new Logger('EvolutionController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n  }\n\n  integrationEnabled: boolean;\n\n  public async receiveWebhook(data: any) {\n    const numberId = data.numberId;\n\n    if (!numberId) {\n      this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');\n      return;\n    }\n\n    const instance = await this.prismaRepository.instance.findFirst({\n      where: { number: numberId },\n    });\n\n    if (!instance) {\n      this.logger.error('WebhookService -> receiveWebhook -> instance not found');\n      return;\n    }\n\n    await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);\n\n    return {\n      status: 'success',\n    };\n  }\n}\n```\n\n## Chatbot Controller Pattern\n\n### Base Chatbot Controller\n```typescript\nexport abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto>\n  extends ChatbotController\n  implements ChatbotControllerInterface\n{\n  public readonly logger: Logger;\n  integrationEnabled: boolean;\n  \n  // Abstract methods to be implemented\n  protected abstract readonly integrationName: string;\n  protected abstract processBot(/* parameters */): Promise<void>;\n  protected abstract getFallbackBotId(settings: any): string | undefined;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n  }\n\n  // Base implementation methods\n  public async createBot(instance: InstanceDto, data: BotData) {\n    // Common bot creation logic\n  }\n}\n```\n\n## Method Naming Conventions\n\n### Standard Method Names\n- `create*()` - Create operations\n- `find*()` - Find operations  \n- `fetch*()` - Fetch from external APIs\n- `send*()` - Send operations\n- `receive*()` - Receive webhook/data\n- `handle*()` - Handle specific actions\n- `offer*()` - Offer services (like calls)\n\n## Return Patterns\n\n### Direct Return Pattern\n```typescript\n// CORRECT - Direct return from service\npublic async createTemplate(instance: InstanceDto, data: TemplateDto) {\n  return this.templateService.create(instance, data);\n}\n\n// CORRECT - Direct return from waMonitor\npublic async offerCall({ instanceName }: InstanceDto, data: OfferCallDto) {\n  return await this.waMonitor.waInstances[instanceName].offerCall(data);\n}\n```\n\n## Controller Testing Pattern\n\n### Unit Test Structure\n```typescript\ndescribe('ExampleController', () => {\n  let controller: ExampleController;\n  let service: jest.Mocked<ExampleService>;\n\n  beforeEach(() => {\n    const mockService = {\n      create: jest.fn(),\n      find: jest.fn(),\n    };\n\n    controller = new ExampleController(mockService as any);\n    service = mockService as any;\n  });\n\n  describe('createExample', () => {\n    it('should call service create method', async () => {\n      const instance = { instanceName: 'test' };\n      const data = { test: 'data' };\n      const expectedResult = { success: true };\n\n      service.create.mockResolvedValue(expectedResult);\n\n      const result = await controller.createExample(instance, data);\n\n      expect(service.create).toHaveBeenCalledWith(instance, data);\n      expect(result).toEqual(expectedResult);\n    });\n  });\n});\n```\n\n## Interface Implementation\n\n### Controller Interface Pattern\n```typescript\nexport interface ChannelControllerInterface {\n  integrationEnabled: boolean;\n}\n\nexport interface ChatbotControllerInterface {\n  integrationEnabled: boolean;\n  createBot(instance: InstanceDto, data: any): Promise<any>;\n  findBot(instance: InstanceDto): Promise<any>;\n  // ... other methods\n}\n```\n\n## Controller Organization\n\n### File Naming Convention\n- `*.controller.ts` - Main controllers\n- `*/*.controller.ts` - Integration-specific controllers\n\n### Method Organization\n1. Constructor\n2. Public methods (alphabetical order)\n3. Private methods (if any)\n\n### Import Organization\n```typescript\n// DTOs first\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { ExampleDto } from '@api/dto/example.dto';\n\n// Services\nimport { ExampleService } from '@api/services/example.service';\n\n// Types\nimport { WAMonitoringService } from '@api/services/monitor.service';\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/dto-rules.mdc",
    "content": "---\ndescription: DTO patterns and validation for Evolution API\nglobs:\n  - \"src/api/dto/**/*.ts\"\n  - \"src/api/integrations/**/dto/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API DTO Rules\n\n## DTO Structure Pattern\n\n### Basic DTO Class\n```typescript\nexport class ExampleDto {\n  name: string;\n  category: string;\n  allowCategoryChange: boolean;\n  language: string;\n  components: any;\n  webhookUrl?: string;\n}\n```\n\n## Inheritance Pattern\n\n### DTO Inheritance\n```typescript\n// CORRECT - Evolution API pattern\nexport class InstanceDto extends IntegrationDto {\n  instanceName: string;\n  instanceId?: string;\n  qrcode?: boolean;\n  businessId?: string;\n  number?: string;\n  integration?: string;\n  token?: string;\n  status?: string;\n  ownerJid?: string;\n  profileName?: string;\n  profilePicUrl?: string;\n  \n  // Settings\n  rejectCall?: boolean;\n  msgCall?: string;\n  groupsIgnore?: boolean;\n  alwaysOnline?: boolean;\n  readMessages?: boolean;\n  readStatus?: boolean;\n  syncFullHistory?: boolean;\n  wavoipToken?: string;\n  \n  // Proxy settings\n  proxyHost?: string;\n  proxyPort?: string;\n  proxyProtocol?: string;\n  proxyUsername?: string;\n  proxyPassword?: string;\n  \n  // Webhook configuration\n  webhook?: {\n    enabled?: boolean;\n    events?: string[];\n    headers?: JsonValue;\n    url?: string;\n    byEvents?: boolean;\n    base64?: boolean;\n  };\n  \n  // Chatwoot integration\n  chatwootAccountId?: string;\n  chatwootConversationPending?: boolean;\n  chatwootAutoCreate?: boolean;\n  chatwootDaysLimitImportMessages?: number;\n  chatwootImportContacts?: boolean;\n  chatwootImportMessages?: boolean;\n  chatwootLogo?: string;\n  chatwootMergeBrazilContacts?: boolean;\n  chatwootNameInbox?: string;\n  chatwootOrganization?: string;\n  chatwootReopenConversation?: boolean;\n  chatwootSignMsg?: boolean;\n  chatwootToken?: string;\n  chatwootUrl?: string;\n}\n```\n\n## Base DTO Pattern\n\n### Base Chatbot DTO\n```typescript\n/**\n * Base DTO for all chatbot integrations\n * Contains common properties shared by all chatbot types\n */\nexport class BaseChatbotDto {\n  enabled?: boolean;\n  description: string;\n  expire?: number;\n  keywordFinish?: string;\n  delayMessage?: number;\n  unknownMessage?: string;\n  listeningFromMe?: boolean;\n  stopBotFromMe?: boolean;\n  keepOpen?: boolean;\n  debounceTime?: number;\n  triggerType: TriggerType;\n  triggerOperator?: TriggerOperator;\n  triggerValue?: string;\n  ignoreJids?: string[];\n  splitMessages?: boolean;\n  timePerChar?: number;\n}\n\n/**\n * Base settings DTO for all chatbot integrations\n */\nexport class BaseChatbotSettingDto {\n  expire?: number;\n  keywordFinish?: string;\n  delayMessage?: number;\n  unknownMessage?: string;\n  listeningFromMe?: boolean;\n  stopBotFromMe?: boolean;\n  keepOpen?: boolean;\n  debounceTime?: number;\n  ignoreJids?: string[];\n  splitMessages?: boolean;\n  timePerChar?: number;\n}\n```\n\n## Message DTO Patterns\n\n### Send Message DTOs\n```typescript\nexport class Metadata {\n  number: string;\n  delay?: number;\n}\n\nexport class SendTextDto extends Metadata {\n  text: string;\n  linkPreview?: boolean;\n  mentionsEveryOne?: boolean;\n  mentioned?: string[];\n}\n\nexport class SendListDto extends Metadata {\n  title: string;\n  description: string;\n  buttonText: string;\n  footerText?: string;\n\n  sections: Section[];\n}\n\nexport class ContactMessage {\n  fullName: string;\n  wuid: string;\n  phoneNumber: string;\n  organization?: string;\n  email?: string;\n  url?: string;\n}\n\nexport class SendTemplateDto extends Metadata {\n  name: string;\n  language: string;\n  components: any;\n}\n```\n\n## Simple DTO Patterns\n\n### Basic DTOs\n```typescript\nexport class NumberDto {\n  number: string;\n}\n\nexport class LabelDto {\n  id?: string;\n  name: string;\n  color: string;\n  predefinedId?: string;\n}\n\nexport class HandleLabelDto {\n  number: string;\n  labelId: string;\n}\n\nexport class ProfileNameDto {\n  name: string;\n}\n\nexport class WhatsAppNumberDto {\n  numbers: string[];\n}\n```\n\n## Complex DTO Patterns\n\n### Business DTOs\n```typescript\nexport class getCatalogDto {\n  number?: string;\n  limit?: number;\n  cursor?: string;\n}\n\nexport class getCollectionsDto {\n  number?: string;\n  limit?: number;\n  cursor?: string;\n}\n\nexport class NumberBusiness {\n  number: string;\n  name?: string;\n  description?: string;\n  email?: string;\n  websites?: string[];\n  latitude?: number;\n  longitude?: number;\n  address?: string;\n  profilehandle?: string;\n}\n```\n\n## Settings DTO Pattern\n\n### Settings Configuration\n```typescript\nexport class SettingsDto {\n  rejectCall?: boolean;\n  msgCall?: string;\n  groupsIgnore?: boolean;\n  alwaysOnline?: boolean;\n  readMessages?: boolean;\n  readStatus?: boolean;\n  syncFullHistory?: boolean;\n  wavoipToken?: string;\n}\n\nexport class ProxyDto {\n  host?: string;\n  port?: string;\n  protocol?: string;\n  username?: string;\n  password?: string;\n}\n```\n\n## Presence DTO Pattern\n\n### WhatsApp Presence\n```typescript\nexport class SetPresenceDto {\n  presence: WAPresence;\n}\n\nexport class SendPresenceDto {\n  number: string;\n  presence: WAPresence;\n}\n```\n\n## DTO Structure (No Decorators)\n\n### Simple DTO Classes (Evolution API Pattern)\n```typescript\n// CORRECT - Evolution API pattern (no decorators)\nexport class ExampleDto {\n  name: string;\n  description?: string;\n  enabled: boolean;\n  items?: string[];\n  timeout?: number;\n}\n\n// INCORRECT - Don't use class-validator decorators\nexport class ValidatedDto {\n  @IsString() // ❌ Evolution API doesn't use decorators\n  name: string;\n}\n```\n\n## Type Safety Patterns\n\n### Prisma Type Integration\n```typescript\nimport { JsonValue } from '@prisma/client/runtime/library';\nimport { WAPresence } from 'baileys';\nimport { TriggerOperator, TriggerType } from '@prisma/client';\n\nexport class TypeSafeDto {\n  presence: WAPresence;\n  triggerType: TriggerType;\n  triggerOperator?: TriggerOperator;\n  metadata?: JsonValue;\n}\n```\n\n## DTO Documentation\n\n### JSDoc Comments\n```typescript\n/**\n * DTO for creating WhatsApp templates\n * Used by Meta Business API integration\n */\nexport class TemplateDto {\n  /** Template name - must be unique */\n  name: string;\n  \n  /** Template category (MARKETING, UTILITY, AUTHENTICATION) */\n  category: string;\n  \n  /** Whether category can be changed after creation */\n  allowCategoryChange: boolean;\n  \n  /** Language code (e.g., 'pt_BR', 'en_US') */\n  language: string;\n  \n  /** Template components (header, body, footer, buttons) */\n  components: any;\n  \n  /** Optional webhook URL for template status updates */\n  webhookUrl?: string;\n}\n```\n\n## DTO Naming Conventions\n\n### Standard Naming Patterns\n- `*Dto` - Data transfer objects\n- `Create*Dto` - Creation DTOs\n- `Update*Dto` - Update DTOs\n- `Send*Dto` - Message sending DTOs\n- `Get*Dto` - Query DTOs\n- `Handle*Dto` - Action DTOs\n\n## File Organization\n\n### DTO File Structure\n```\nsrc/api/dto/\n├── instance.dto.ts          # Main instance DTO\n├── template.dto.ts          # Template management\n├── sendMessage.dto.ts       # Message sending DTOs\n├── chat.dto.ts             # Chat operations\n├── business.dto.ts         # Business API DTOs\n├── group.dto.ts            # Group management\n├── label.dto.ts            # Label management\n├── proxy.dto.ts            # Proxy configuration\n├── settings.dto.ts         # Instance settings\n└── call.dto.ts             # Call operations\n```\n\n## Integration DTO Patterns\n\n### Chatbot Integration DTOs\n```typescript\n// Base for all chatbot DTOs\nexport class BaseChatbotDto {\n  enabled?: boolean;\n  description: string;\n  // ... common properties\n}\n\n// Specific chatbot DTOs extend base\nexport class TypebotDto extends BaseChatbotDto {\n  url: string;\n  typebot: string;\n  // ... typebot-specific properties\n}\n\nexport class OpenaiDto extends BaseChatbotDto {\n  apiKey: string;\n  model: string;\n  // ... openai-specific properties\n}\n```\n\n## DTO Testing Pattern\n\n### DTO Validation Tests\n```typescript\ndescribe('ExampleDto', () => {\n  it('should validate required fields', () => {\n    const dto = new ExampleDto();\n    dto.name = 'test';\n    dto.category = 'MARKETING';\n    dto.allowCategoryChange = true;\n    dto.language = 'pt_BR';\n    dto.components = {};\n\n    expect(dto.name).toBe('test');\n    expect(dto.category).toBe('MARKETING');\n  });\n\n  it('should handle optional fields', () => {\n    const dto = new ExampleDto();\n    dto.name = 'test';\n    dto.category = 'MARKETING';\n    dto.allowCategoryChange = true;\n    dto.language = 'pt_BR';\n    dto.components = {};\n    dto.webhookUrl = 'https://example.com/webhook';\n\n    expect(dto.webhookUrl).toBe('https://example.com/webhook');\n  });\n});\n```\n\n## DTO Transformation\n\n### Request to DTO Mapping (Evolution API Pattern)\n```typescript\n// CORRECT - Evolution API uses RouterBroker dataValidate\nconst response = await this.dataValidate<ExampleDto>({\n  request: req,\n  schema: exampleSchema, // JSONSchema7\n  ClassRef: ExampleDto,\n  execute: (instance, data) => controller.method(instance, data),\n});\n\n// INCORRECT - Don't use class-validator\nconst dto = plainToClass(ExampleDto, req.body); // ❌ Not used in Evolution API\nconst errors = await validate(dto); // ❌ Not used in Evolution API\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/guard-rules.mdc",
    "content": "---\ndescription: Guard patterns for authentication and authorization in Evolution API\nglobs:\n  - \"src/api/guards/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Guard Rules\n\n## Guard Structure Pattern\n\n### Standard Guard Function\n```typescript\nimport { NextFunction, Request, Response } from 'express';\nimport { Logger } from '@config/logger.config';\nimport { UnauthorizedException, ForbiddenException } from '@exceptions';\n\nconst logger = new Logger('GUARD');\n\nasync function guardFunction(req: Request, _: Response, next: NextFunction) {\n  // Guard logic here\n  \n  if (validationFails) {\n    throw new UnauthorizedException();\n  }\n  \n  return next();\n}\n\nexport const guardName = { guardFunction };\n```\n\n## Authentication Guard Pattern\n\n### API Key Authentication\n```typescript\nasync function apikey(req: Request, _: Response, next: NextFunction) {\n  const env = configService.get<Auth>('AUTHENTICATION').API_KEY;\n  const key = req.get('apikey');\n  const db = configService.get<Database>('DATABASE');\n\n  if (!key) {\n    throw new UnauthorizedException();\n  }\n\n  // Global API key check\n  if (env.KEY === key) {\n    return next();\n  }\n\n  // Special routes handling\n  if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) {\n    throw new ForbiddenException('Missing global api key', 'The global api key must be set');\n  }\n\n  const param = req.params as unknown as InstanceDto;\n\n  try {\n    if (param?.instanceName) {\n      const instance = await prismaRepository.instance.findUnique({\n        where: { name: param.instanceName },\n      });\n      if (instance.token === key) {\n        return next();\n      }\n    } else {\n      if (req.originalUrl.includes('/instance/fetchInstances') && db.SAVE_DATA.INSTANCE) {\n        const instanceByKey = await prismaRepository.instance.findFirst({\n          where: { token: key },\n        });\n        if (instanceByKey) {\n          return next();\n        }\n      }\n    }\n  } catch (error) {\n    logger.error(error);\n  }\n\n  throw new UnauthorizedException();\n}\n\nexport const authGuard = { apikey };\n```\n\n## Instance Validation Guards\n\n### Instance Exists Guard\n```typescript\nasync function getInstance(instanceName: string) {\n  try {\n    const cacheConf = configService.get<CacheConf>('CACHE');\n\n    const exists = !!waMonitor.waInstances[instanceName];\n\n    if (cacheConf.REDIS.ENABLED && cacheConf.REDIS.SAVE_INSTANCES) {\n      const keyExists = await cache.has(instanceName);\n      return exists || keyExists;\n    }\n\n    return exists || (await prismaRepository.instance.findMany({ where: { name: instanceName } })).length > 0;\n  } catch (error) {\n    throw new InternalServerErrorException(error?.toString());\n  }\n}\n\nexport async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) {\n  if (req.originalUrl.includes('/instance/create')) {\n    return next();\n  }\n\n  const param = req.params as unknown as InstanceDto;\n  if (!param?.instanceName) {\n    throw new BadRequestException('\"instanceName\" not provided.');\n  }\n\n  if (!(await getInstance(param.instanceName))) {\n    throw new NotFoundException(`The \"${param.instanceName}\" instance does not exist`);\n  }\n\n  next();\n}\n```\n\n### Instance Logged Guard\n```typescript\nexport async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) {\n  if (req.originalUrl.includes('/instance/create')) {\n    const instance = req.body as InstanceDto;\n    if (await getInstance(instance.instanceName)) {\n      throw new ForbiddenException(`This name \"${instance.instanceName}\" is already in use.`);\n    }\n\n    if (waMonitor.waInstances[instance.instanceName]) {\n      delete waMonitor.waInstances[instance.instanceName];\n    }\n  }\n\n  next();\n}\n```\n\n## Telemetry Guard Pattern\n\n### Telemetry Collection\n```typescript\nclass Telemetry {\n  public collectTelemetry(req: Request, res: Response, next: NextFunction): void {\n    // Collect telemetry data\n    const telemetryData = {\n      route: req.originalUrl,\n      method: req.method,\n      timestamp: new Date(),\n      userAgent: req.get('User-Agent'),\n    };\n\n    // Send telemetry asynchronously (don't block request)\n    setImmediate(() => {\n      this.sendTelemetry(telemetryData);\n    });\n\n    next();\n  }\n\n  private async sendTelemetry(data: any): Promise<void> {\n    try {\n      // Send telemetry data\n    } catch (error) {\n      // Silently fail - don't affect main request\n    }\n  }\n}\n\nexport default Telemetry;\n```\n\n## Guard Composition Pattern\n\n### Multiple Guards Usage\n```typescript\n// In router setup\nconst guards = [instanceExistsGuard, instanceLoggedGuard, authGuard['apikey']];\n\nrouter\n  .use('/instance', new InstanceRouter(configService, ...guards).router)\n  .use('/message', new MessageRouter(...guards).router)\n  .use('/chat', new ChatRouter(...guards).router);\n```\n\n## Error Handling in Guards\n\n### Proper Exception Throwing\n```typescript\n// CORRECT - Use proper HTTP exceptions\nif (!apiKey) {\n  throw new UnauthorizedException('API key required');\n}\n\nif (instanceExists) {\n  throw new ForbiddenException('Instance already exists');\n}\n\nif (!instanceFound) {\n  throw new NotFoundException('Instance not found');\n}\n\nif (validationFails) {\n  throw new BadRequestException('Invalid request parameters');\n}\n\n// INCORRECT - Don't use generic Error\nif (!apiKey) {\n  throw new Error('API key required'); // ❌ Use specific exceptions\n}\n```\n\n## Configuration Access in Guards\n\n### Config Service Usage\n```typescript\nasync function configAwareGuard(req: Request, _: Response, next: NextFunction) {\n  const authConfig = configService.get<Auth>('AUTHENTICATION');\n  const cacheConfig = configService.get<CacheConf>('CACHE');\n  const dbConfig = configService.get<Database>('DATABASE');\n\n  // Use configuration for guard logic\n  if (authConfig.API_KEY.KEY === providedKey) {\n    return next();\n  }\n\n  throw new UnauthorizedException();\n}\n```\n\n## Database Access in Guards\n\n### Prisma Repository Usage\n```typescript\nasync function databaseGuard(req: Request, _: Response, next: NextFunction) {\n  try {\n    const param = req.params as unknown as InstanceDto;\n    \n    const instance = await prismaRepository.instance.findUnique({\n      where: { name: param.instanceName },\n    });\n\n    if (!instance) {\n      throw new NotFoundException('Instance not found');\n    }\n\n    // Additional validation logic\n    if (instance.status !== 'active') {\n      throw new ForbiddenException('Instance not active');\n    }\n\n    return next();\n  } catch (error) {\n    logger.error('Database guard error:', error);\n    throw new InternalServerErrorException('Database access failed');\n  }\n}\n```\n\n## Cache Integration in Guards\n\n### Cache Service Usage\n```typescript\nasync function cacheAwareGuard(req: Request, _: Response, next: NextFunction) {\n  const cacheConf = configService.get<CacheConf>('CACHE');\n  \n  if (cacheConf.REDIS.ENABLED) {\n    const cached = await cache.get(`guard:${req.params.instanceName}`);\n    if (cached) {\n      // Use cached validation result\n      return next();\n    }\n  }\n\n  // Perform validation and cache result\n  const isValid = await performValidation(req.params.instanceName);\n  \n  if (cacheConf.REDIS.ENABLED) {\n    await cache.set(`guard:${req.params.instanceName}`, isValid, 300); // 5 min TTL\n  }\n\n  if (isValid) {\n    return next();\n  }\n\n  throw new UnauthorizedException();\n}\n```\n\n## Logging in Guards\n\n### Structured Logging\n```typescript\nconst logger = new Logger('GUARD');\n\nasync function loggedGuard(req: Request, _: Response, next: NextFunction) {\n  logger.log(`Guard validation started for ${req.originalUrl}`);\n\n  try {\n    // Guard logic\n    const isValid = await validateRequest(req);\n    \n    if (isValid) {\n      logger.log(`Guard validation successful for ${req.params.instanceName}`);\n      return next();\n    }\n\n    logger.warn(`Guard validation failed for ${req.params.instanceName}`);\n    throw new UnauthorizedException();\n  } catch (error) {\n    logger.error(`Guard validation error: ${error.message}`, error.stack);\n    throw error;\n  }\n}\n```\n\n## Guard Testing Pattern\n\n### Unit Test Structure\n```typescript\ndescribe('authGuard', () => {\n  let req: Partial<Request>;\n  let res: Partial<Response>;\n  let next: NextFunction;\n\n  beforeEach(() => {\n    req = {\n      get: jest.fn(),\n      params: {},\n      originalUrl: '/test',\n    };\n    res = {};\n    next = jest.fn();\n  });\n\n  describe('apikey', () => {\n    it('should pass with valid global API key', async () => {\n      (req.get as jest.Mock).mockReturnValue('valid-global-key');\n      \n      await authGuard.apikey(req as Request, res as Response, next);\n      \n      expect(next).toHaveBeenCalled();\n    });\n\n    it('should throw UnauthorizedException with no API key', async () => {\n      (req.get as jest.Mock).mockReturnValue(undefined);\n      \n      await expect(\n        authGuard.apikey(req as Request, res as Response, next)\n      ).rejects.toThrow(UnauthorizedException);\n    });\n\n    it('should pass with valid instance token', async () => {\n      (req.get as jest.Mock).mockReturnValue('instance-token');\n      req.params = { instanceName: 'test-instance' };\n      \n      // Mock prisma repository\n      jest.spyOn(prismaRepository.instance, 'findUnique').mockResolvedValue({\n        token: 'instance-token',\n      } as any);\n      \n      await authGuard.apikey(req as Request, res as Response, next);\n      \n      expect(next).toHaveBeenCalled();\n    });\n  });\n});\n```\n\n## Guard Performance Considerations\n\n### Efficient Validation\n```typescript\n// CORRECT - Efficient guard with early returns\nasync function efficientGuard(req: Request, _: Response, next: NextFunction) {\n  // Quick checks first\n  if (req.originalUrl.includes('/public')) {\n    return next(); // Skip validation for public routes\n  }\n\n  const apiKey = req.get('apikey');\n  if (!apiKey) {\n    throw new UnauthorizedException(); // Fail fast\n  }\n\n  // More expensive checks only if needed\n  if (apiKey === globalKey) {\n    return next(); // Skip database check\n  }\n\n  // Database check only as last resort\n  const isValid = await validateInDatabase(apiKey);\n  if (isValid) {\n    return next();\n  }\n\n  throw new UnauthorizedException();\n}\n\n// INCORRECT - Inefficient guard\nasync function inefficientGuard(req: Request, _: Response, next: NextFunction) {\n  // Always do expensive database check first\n  const dbResult = await expensiveDatabaseQuery(); // ❌ Expensive operation first\n  \n  const apiKey = req.get('apikey');\n  if (!apiKey && dbResult) { // ❌ Complex logic\n    throw new UnauthorizedException();\n  }\n  \n  next();\n}\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/integration-channel-rules.mdc",
    "content": "---\ndescription: Channel integration patterns for Evolution API\nglobs:\n  - \"src/api/integrations/channel/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Channel Integration Rules\n\n## Channel Controller Pattern\n\n### Base Channel Controller\n```typescript\nexport interface ChannelControllerInterface {\n  integrationEnabled: boolean;\n}\n\nexport class ChannelController {\n  public prismaRepository: PrismaRepository;\n  public waMonitor: WAMonitoringService;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    this.prisma = prismaRepository;\n    this.monitor = waMonitor;\n  }\n\n  public set prisma(prisma: PrismaRepository) {\n    this.prismaRepository = prisma;\n  }\n\n  public get prisma() {\n    return this.prismaRepository;\n  }\n\n  public set monitor(waMonitor: WAMonitoringService) {\n    this.waMonitor = waMonitor;\n  }\n\n  public get monitor() {\n    return this.waMonitor;\n  }\n\n  public init(instanceData: InstanceDto, data: ChannelDataType) {\n    if (!instanceData.token && instanceData.integration === Integration.WHATSAPP_BUSINESS) {\n      throw new BadRequestException('token is required');\n    }\n\n    if (instanceData.integration === Integration.WHATSAPP_BUSINESS) {\n      return new BusinessStartupService(/* dependencies */);\n    }\n\n    if (instanceData.integration === Integration.EVOLUTION) {\n      return new EvolutionStartupService(/* dependencies */);\n    }\n\n    if (instanceData.integration === Integration.WHATSAPP_BAILEYS) {\n      return new BaileysStartupService(/* dependencies */);\n    }\n\n    return null;\n  }\n}\n```\n\n### Extended Channel Controller\n```typescript\nexport class EvolutionController extends ChannelController implements ChannelControllerInterface {\n  private readonly logger = new Logger('EvolutionController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n  }\n\n  integrationEnabled: boolean;\n\n  public async receiveWebhook(data: any) {\n    const numberId = data.numberId;\n\n    if (!numberId) {\n      this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');\n      return;\n    }\n\n    const instance = await this.prismaRepository.instance.findFirst({\n      where: { number: numberId },\n    });\n\n    if (!instance) {\n      this.logger.error('WebhookService -> receiveWebhook -> instance not found');\n      return;\n    }\n\n    await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);\n\n    return {\n      status: 'success',\n    };\n  }\n}\n```\n\n## Channel Service Pattern\n\n### Base Channel Service\n```typescript\nexport class ChannelStartupService {\n  constructor(\n    private readonly configService: ConfigService,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly prismaRepository: PrismaRepository,\n    public readonly cache: CacheService,\n    public readonly chatwootCache: CacheService,\n  ) {}\n\n  public readonly logger = new Logger('ChannelStartupService');\n\n  public client: WASocket;\n  public readonly instance: wa.Instance = {};\n  public readonly localChatwoot: wa.LocalChatwoot = {};\n  public readonly localProxy: wa.LocalProxy = {};\n  public readonly localSettings: wa.LocalSettings = {};\n  public readonly localWebhook: wa.LocalWebHook = {};\n\n  public setInstance(instance: InstanceDto) {\n    this.logger.setInstance(instance.instanceName);\n\n    this.instance.name = instance.instanceName;\n    this.instance.id = instance.instanceId;\n    this.instance.integration = instance.integration;\n    this.instance.number = instance.number;\n    this.instance.token = instance.token;\n    this.instance.businessId = instance.businessId;\n\n    if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n      this.chatwootService.eventWhatsapp(\n        Events.STATUS_INSTANCE,\n        { instanceName: this.instance.name },\n        {\n          instance: this.instance.name,\n          status: 'created',\n        },\n      );\n    }\n  }\n\n  public set instanceName(name: string) {\n    this.logger.setInstance(name);\n    this.instance.name = name;\n  }\n\n  public get instanceName() {\n    return this.instance.name;\n  }\n}\n```\n\n### Extended Channel Service\n```typescript\nexport class EvolutionStartupService extends ChannelStartupService {\n  constructor(\n    configService: ConfigService,\n    eventEmitter: EventEmitter2,\n    prismaRepository: PrismaRepository,\n    cache: CacheService,\n    chatwootCache: CacheService,\n  ) {\n    super(configService, eventEmitter, prismaRepository, cache, chatwootCache);\n  }\n\n  public async sendMessage(data: SendTextDto): Promise<any> {\n    // Evolution-specific message sending logic\n    const response = await this.evolutionApiCall('/send-message', data);\n    return response;\n  }\n\n  public async connectToWhatsapp(data: any): Promise<void> {\n    // Evolution-specific connection logic\n    this.logger.log('Connecting to Evolution API');\n    \n    // Set up webhook listeners\n    this.setupWebhookHandlers();\n    \n    // Initialize connection\n    await this.initializeConnection(data);\n  }\n\n  private async evolutionApiCall(endpoint: string, data: any): Promise<any> {\n    const config = this.configService.get<Evolution>('EVOLUTION');\n    \n    try {\n      const response = await axios.post(`${config.API_URL}${endpoint}`, data, {\n        headers: {\n          'Authorization': `Bearer ${this.instance.token}`,\n          'Content-Type': 'application/json',\n        },\n      });\n      \n      return response.data;\n    } catch (error) {\n      this.logger.error(`Evolution API call failed: ${error.message}`);\n      throw new InternalServerErrorException('Evolution API call failed');\n    }\n  }\n\n  private setupWebhookHandlers(): void {\n    // Set up webhook event handlers\n  }\n\n  private async initializeConnection(data: any): Promise<void> {\n    // Initialize connection with Evolution API\n  }\n}\n```\n\n## Business API Service Pattern\n\n### Meta Business Service\n```typescript\nexport class BusinessStartupService extends ChannelStartupService {\n  constructor(\n    configService: ConfigService,\n    eventEmitter: EventEmitter2,\n    prismaRepository: PrismaRepository,\n    cache: CacheService,\n    chatwootCache: CacheService,\n    baileysCache: CacheService,\n    providerFiles: ProviderFiles,\n  ) {\n    super(configService, eventEmitter, prismaRepository, cache, chatwootCache);\n  }\n\n  public async sendMessage(data: SendTextDto): Promise<any> {\n    const businessConfig = this.configService.get<WaBusiness>('WA_BUSINESS');\n    \n    const payload = {\n      messaging_product: 'whatsapp',\n      to: data.number,\n      type: 'text',\n      text: {\n        body: data.text,\n      },\n    };\n\n    try {\n      const response = await axios.post(\n        `${businessConfig.URL}/${businessConfig.VERSION}/${this.instance.businessId}/messages`,\n        payload,\n        {\n          headers: {\n            'Authorization': `Bearer ${this.instance.token}`,\n            'Content-Type': 'application/json',\n          },\n        }\n      );\n\n      return response.data;\n    } catch (error) {\n      this.logger.error(`Business API call failed: ${error.message}`);\n      throw new BadRequestException('Failed to send message via Business API');\n    }\n  }\n\n  public async receiveWebhook(data: any): Promise<void> {\n    // Process incoming webhook from Meta Business API\n    const { entry } = data;\n    \n    for (const entryItem of entry) {\n      const { changes } = entryItem;\n      \n      for (const change of changes) {\n        if (change.field === 'messages') {\n          await this.processMessage(change.value);\n        }\n      }\n    }\n  }\n\n  private async processMessage(messageData: any): Promise<void> {\n    // Process incoming message from Business API\n    const { messages, contacts } = messageData;\n    \n    if (messages) {\n      for (const message of messages) {\n        await this.handleIncomingMessage(message, contacts);\n      }\n    }\n  }\n\n  private async handleIncomingMessage(message: any, contacts: any[]): Promise<void> {\n    // Handle individual message\n    const contact = contacts?.find(c => c.wa_id === message.from);\n    \n    // Emit event for message processing\n    this.eventEmitter.emit(Events.MESSAGES_UPSERT, {\n      instanceName: this.instance.name,\n      message,\n      contact,\n    });\n  }\n}\n```\n\n## Baileys Service Pattern\n\n### Baileys Integration Service\n```typescript\nexport class BaileysStartupService extends ChannelStartupService {\n  constructor(\n    configService: ConfigService,\n    eventEmitter: EventEmitter2,\n    prismaRepository: PrismaRepository,\n    cache: CacheService,\n    chatwootCache: CacheService,\n    baileysCache: CacheService,\n    providerFiles: ProviderFiles,\n  ) {\n    super(configService, eventEmitter, prismaRepository, cache, chatwootCache);\n  }\n\n  public async connectToWhatsapp(): Promise<void> {\n    const authPath = path.join(INSTANCE_DIR, this.instance.name);\n    const { state, saveCreds } = await useMultiFileAuthState(authPath);\n\n    this.client = makeWASocket({\n      auth: state,\n      logger: P({ level: 'error' }),\n      printQRInTerminal: false,\n      browser: ['Evolution API', 'Chrome', '4.0.0'],\n      defaultQueryTimeoutMs: 60000,\n    });\n\n    this.setupEventHandlers();\n    this.client.ev.on('creds.update', saveCreds);\n  }\n\n  private setupEventHandlers(): void {\n    this.client.ev.on('connection.update', (update) => {\n      this.handleConnectionUpdate(update);\n    });\n\n    this.client.ev.on('messages.upsert', ({ messages, type }) => {\n      this.handleIncomingMessages(messages, type);\n    });\n\n    this.client.ev.on('messages.update', (updates) => {\n      this.handleMessageUpdates(updates);\n    });\n\n    this.client.ev.on('contacts.upsert', (contacts) => {\n      this.handleContactsUpdate(contacts);\n    });\n\n    this.client.ev.on('chats.upsert', (chats) => {\n      this.handleChatsUpdate(chats);\n    });\n  }\n\n  private async handleConnectionUpdate(update: ConnectionUpdate): Promise<void> {\n    const { connection, lastDisconnect, qr } = update;\n\n    if (qr) {\n      this.instance.qrcode = {\n        count: this.instance.qrcode?.count ? this.instance.qrcode.count + 1 : 1,\n        base64: qr,\n      };\n\n      this.eventEmitter.emit(Events.QRCODE_UPDATED, {\n        instanceName: this.instance.name,\n        qrcode: this.instance.qrcode,\n      });\n    }\n\n    if (connection === 'close') {\n      const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut;\n      \n      if (shouldReconnect) {\n        this.logger.log('Connection closed, reconnecting...');\n        await this.connectToWhatsapp();\n      } else {\n        this.logger.log('Connection closed, logged out');\n        this.eventEmitter.emit(Events.LOGOUT_INSTANCE, {\n          instanceName: this.instance.name,\n        });\n      }\n    }\n\n    if (connection === 'open') {\n      this.logger.log('Connection opened successfully');\n      this.instance.wuid = this.client.user?.id;\n      \n      this.eventEmitter.emit(Events.CONNECTION_UPDATE, {\n        instanceName: this.instance.name,\n        state: 'open',\n      });\n    }\n  }\n\n  public async sendMessage(data: SendTextDto): Promise<any> {\n    const jid = createJid(data.number);\n    \n    const message = {\n      text: data.text,\n    };\n\n    if (data.linkPreview !== undefined) {\n      message.linkPreview = data.linkPreview;\n    }\n\n    if (data.mentionsEveryOne) {\n      // Handle mentions\n    }\n\n    try {\n      const response = await this.client.sendMessage(jid, message);\n      return response;\n    } catch (error) {\n      this.logger.error(`Failed to send message: ${error.message}`);\n      throw new BadRequestException('Failed to send message');\n    }\n  }\n}\n```\n\n## Channel Router Pattern\n\n### Channel Router Structure\n```typescript\nexport class ChannelRouter {\n  public readonly router: Router;\n\n  constructor(configService: any, ...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/', new EvolutionRouter(configService).router);\n    this.router.use('/', new MetaRouter(configService).router);\n    this.router.use('/baileys', new BaileysRouter(...guards).router);\n  }\n}\n```\n\n### Specific Channel Router\n```typescript\nexport class EvolutionRouter extends RouterBroker {\n  constructor(private readonly configService: ConfigService) {\n    super();\n    this.router\n      .post(this.routerPath('webhook'), async (req, res) => {\n        const response = await evolutionController.receiveWebhook(req.body);\n        return res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n```\n\n## Integration Types\n\n### Channel Data Types\n```typescript\ntype ChannelDataType = {\n  configService: ConfigService;\n  eventEmitter: EventEmitter2;\n  prismaRepository: PrismaRepository;\n  cache: CacheService;\n  chatwootCache: CacheService;\n  baileysCache: CacheService;\n  providerFiles: ProviderFiles;\n};\n\nexport enum Integration {\n  WHATSAPP_BUSINESS = 'WHATSAPP-BUSINESS',\n  WHATSAPP_BAILEYS = 'WHATSAPP-BAILEYS',\n  EVOLUTION = 'EVOLUTION',\n}\n```\n\n## Error Handling in Channels\n\n### Channel-Specific Error Handling\n```typescript\n// CORRECT - Channel-specific error handling\npublic async sendMessage(data: SendTextDto): Promise<any> {\n  try {\n    const response = await this.channelSpecificSend(data);\n    return response;\n  } catch (error) {\n    this.logger.error(`${this.constructor.name} send failed: ${error.message}`);\n    \n    if (error.response?.status === 401) {\n      throw new UnauthorizedException('Invalid token for channel');\n    }\n    \n    if (error.response?.status === 429) {\n      throw new BadRequestException('Rate limit exceeded');\n    }\n    \n    throw new InternalServerErrorException('Channel communication failed');\n  }\n}\n```\n\n## Channel Testing Pattern\n\n### Channel Service Testing\n```typescript\ndescribe('EvolutionStartupService', () => {\n  let service: EvolutionStartupService;\n  let configService: jest.Mocked<ConfigService>;\n  let eventEmitter: jest.Mocked<EventEmitter2>;\n\n  beforeEach(() => {\n    const mockConfig = {\n      get: jest.fn().mockReturnValue({\n        API_URL: 'https://api.evolution.com',\n      }),\n    };\n\n    service = new EvolutionStartupService(\n      mockConfig as any,\n      eventEmitter,\n      prismaRepository,\n      cache,\n      chatwootCache,\n    );\n  });\n\n  describe('sendMessage', () => {\n    it('should send message successfully', async () => {\n      const data = { number: '5511999999999', text: 'Test message' };\n      \n      // Mock axios response\n      jest.spyOn(axios, 'post').mockResolvedValue({\n        data: { success: true, messageId: '123' },\n      });\n\n      const result = await service.sendMessage(data);\n\n      expect(result.success).toBe(true);\n      expect(axios.post).toHaveBeenCalledWith(\n        expect.stringContaining('/send-message'),\n        data,\n        expect.objectContaining({\n          headers: expect.objectContaining({\n            'Authorization': expect.stringContaining('Bearer'),\n          }),\n        })\n      );\n    });\n  });\n});\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/integration-chatbot-rules.mdc",
    "content": "---\ndescription: Chatbot integration patterns for Evolution API\nglobs:\n  - \"src/api/integrations/chatbot/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Chatbot Integration Rules\n\n## Base Chatbot Pattern\n\n### Base Chatbot DTO\n```typescript\n/**\n * Base DTO for all chatbot integrations\n * Contains common properties shared by all chatbot types\n */\nexport class BaseChatbotDto {\n  enabled?: boolean;\n  description: string;\n  expire?: number;\n  keywordFinish?: string;\n  delayMessage?: number;\n  unknownMessage?: string;\n  listeningFromMe?: boolean;\n  stopBotFromMe?: boolean;\n  keepOpen?: boolean;\n  debounceTime?: number;\n  triggerType: TriggerType;\n  triggerOperator?: TriggerOperator;\n  triggerValue?: string;\n  ignoreJids?: string[];\n  splitMessages?: boolean;\n  timePerChar?: number;\n}\n```\n\n### Base Chatbot Controller\n```typescript\nexport abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto>\n  extends ChatbotController\n  implements ChatbotControllerInterface\n{\n  public readonly logger: Logger;\n  integrationEnabled: boolean;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  // Abstract methods to be implemented by specific chatbots\n  protected abstract readonly integrationName: string;\n  protected abstract processBot(\n    waInstance: any,\n    remoteJid: string,\n    bot: BotType,\n    session: any,\n    settings: ChatbotSettings,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void>;\n  protected abstract getFallbackBotId(settings: any): string | undefined;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  // Base implementation methods\n  public async createBot(instance: InstanceDto, data: BotData) {\n    if (!data.enabled) {\n      throw new BadRequestException(`${this.integrationName} is disabled`);\n    }\n\n    // Common bot creation logic\n    const bot = await this.botRepository.create({\n      data: {\n        ...data,\n        instanceId: instance.instanceId,\n      },\n    });\n\n    return bot;\n  }\n}\n```\n\n### Base Chatbot Service\n```typescript\n/**\n * Base class for all chatbot service implementations\n * Contains common methods shared across different chatbot integrations\n */\nexport abstract class BaseChatbotService<BotType = any, SettingsType = any> {\n  protected readonly logger: Logger;\n  protected readonly waMonitor: WAMonitoringService;\n  protected readonly prismaRepository: PrismaRepository;\n  protected readonly configService?: ConfigService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    loggerName: string,\n    configService?: ConfigService,\n  ) {\n    this.waMonitor = waMonitor;\n    this.prismaRepository = prismaRepository;\n    this.logger = new Logger(loggerName);\n    this.configService = configService;\n  }\n\n  /**\n   * Check if a message contains an image\n   */\n  protected isImageMessage(content: string): boolean {\n    return content.includes('imageMessage');\n  }\n\n  /**\n   * Extract text content from message\n   */\n  protected getMessageContent(msg: any): string {\n    return getConversationMessage(msg);\n  }\n\n  /**\n   * Send typing indicator\n   */\n  protected async sendTyping(instanceName: string, remoteJid: string): Promise<void> {\n    await this.waMonitor.waInstances[instanceName].sendPresence(remoteJid, 'composing');\n  }\n}\n```\n\n## Typebot Integration Pattern\n\n### Typebot Service\n```typescript\nexport class TypebotService extends BaseChatbotService<TypebotModel, any> {\n  constructor(\n    waMonitor: WAMonitoringService,\n    configService: ConfigService,\n    prismaRepository: PrismaRepository,\n    private readonly openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'TypebotService', configService);\n  }\n\n  public async sendTypebotMessage(\n    instanceName: string,\n    remoteJid: string,\n    typebot: TypebotModel,\n    content: string,\n  ): Promise<void> {\n    try {\n      const response = await axios.post(\n        `${typebot.url}/api/v1/typebots/${typebot.typebot}/startChat`,\n        {\n          message: content,\n          sessionId: `${instanceName}-${remoteJid}`,\n        },\n        {\n          headers: {\n            'Content-Type': 'application/json',\n          },\n        }\n      );\n\n      const { messages } = response.data;\n      \n      for (const message of messages) {\n        await this.processTypebotMessage(instanceName, remoteJid, message);\n      }\n    } catch (error) {\n      this.logger.error(`Typebot API error: ${error.message}`);\n      throw new InternalServerErrorException('Typebot communication failed');\n    }\n  }\n\n  private async processTypebotMessage(\n    instanceName: string,\n    remoteJid: string,\n    message: any,\n  ): Promise<void> {\n    const waInstance = this.waMonitor.waInstances[instanceName];\n    \n    if (message.type === 'text') {\n      await waInstance.sendMessage({\n        number: remoteJid.split('@')[0],\n        text: message.content.richText[0].children[0].text,\n      });\n    }\n    \n    if (message.type === 'image') {\n      await waInstance.sendMessage({\n        number: remoteJid.split('@')[0],\n        mediaMessage: {\n          mediatype: 'image',\n          media: message.content.url,\n        },\n      });\n    }\n  }\n}\n```\n\n## OpenAI Integration Pattern\n\n### OpenAI Service\n```typescript\nexport class OpenaiService extends BaseChatbotService<OpenaiModel, any> {\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n  ) {\n    super(waMonitor, prismaRepository, 'OpenaiService', configService);\n  }\n\n  public async sendOpenaiMessage(\n    instanceName: string,\n    remoteJid: string,\n    openai: OpenaiModel,\n    content: string,\n    pushName?: string,\n  ): Promise<void> {\n    try {\n      const openaiConfig = this.configService.get<Openai>('OPENAI');\n      \n      const response = await axios.post(\n        'https://api.openai.com/v1/chat/completions',\n        {\n          model: openai.model || 'gpt-3.5-turbo',\n          messages: [\n            {\n              role: 'system',\n              content: openai.systemMessage || 'You are a helpful assistant.',\n            },\n            {\n              role: 'user',\n              content: content,\n            },\n          ],\n          max_tokens: openai.maxTokens || 1000,\n          temperature: openai.temperature || 0.7,\n        },\n        {\n          headers: {\n            'Authorization': `Bearer ${openai.apiKey || openaiConfig.API_KEY}`,\n            'Content-Type': 'application/json',\n          },\n        }\n      );\n\n      const aiResponse = response.data.choices[0].message.content;\n      \n      await this.waMonitor.waInstances[instanceName].sendMessage({\n        number: remoteJid.split('@')[0],\n        text: aiResponse,\n      });\n    } catch (error) {\n      this.logger.error(`OpenAI API error: ${error.message}`);\n      \n      // Send fallback message\n      await this.waMonitor.waInstances[instanceName].sendMessage({\n        number: remoteJid.split('@')[0],\n        text: openai.unknownMessage || 'Desculpe, não consegui processar sua mensagem.',\n      });\n    }\n  }\n}\n```\n\n## Chatwoot Integration Pattern\n\n### Chatwoot Service\n```typescript\nexport class ChatwootService extends BaseChatbotService<any, any> {\n  constructor(\n    waMonitor: WAMonitoringService,\n    configService: ConfigService,\n    prismaRepository: PrismaRepository,\n    private readonly chatwootCache: CacheService,\n  ) {\n    super(waMonitor, prismaRepository, 'ChatwootService', configService);\n  }\n\n  public async eventWhatsapp(\n    event: Events,\n    instanceName: { instanceName: string },\n    data: any,\n  ): Promise<void> {\n    const chatwootConfig = this.configService.get<Chatwoot>('CHATWOOT');\n    \n    if (!chatwootConfig.ENABLED) {\n      return;\n    }\n\n    try {\n      const instance = await this.prismaRepository.instance.findUnique({\n        where: { name: instanceName.instanceName },\n      });\n\n      if (!instance?.chatwootAccountId) {\n        return;\n      }\n\n      const webhook = {\n        event,\n        instance: instanceName.instanceName,\n        data,\n        timestamp: new Date().toISOString(),\n      };\n\n      await axios.post(\n        `${instance.chatwootUrl}/api/v1/accounts/${instance.chatwootAccountId}/webhooks`,\n        webhook,\n        {\n          headers: {\n            'Authorization': `Bearer ${instance.chatwootToken}`,\n            'Content-Type': 'application/json',\n          },\n        }\n      );\n    } catch (error) {\n      this.logger.error(`Chatwoot webhook error: ${error.message}`);\n    }\n  }\n\n  public async createConversation(\n    instanceName: string,\n    contact: any,\n    message: any,\n  ): Promise<void> {\n    // Create conversation in Chatwoot\n    const instance = await this.prismaRepository.instance.findUnique({\n      where: { name: instanceName },\n    });\n\n    if (!instance?.chatwootAccountId) {\n      return;\n    }\n\n    try {\n      const conversation = await axios.post(\n        `${instance.chatwootUrl}/api/v1/accounts/${instance.chatwootAccountId}/conversations`,\n        {\n          source_id: contact.id,\n          inbox_id: instance.chatwootInboxId,\n          contact_id: contact.chatwootContactId,\n        },\n        {\n          headers: {\n            'Authorization': `Bearer ${instance.chatwootToken}`,\n            'Content-Type': 'application/json',\n          },\n        }\n      );\n\n      // Cache conversation\n      await this.chatwootCache.set(\n        `conversation:${instanceName}:${contact.id}`,\n        conversation.data,\n        3600\n      );\n    } catch (error) {\n      this.logger.error(`Chatwoot conversation creation error: ${error.message}`);\n    }\n  }\n}\n```\n\n## Dify Integration Pattern\n\n### Dify Service\n```typescript\nexport class DifyService extends BaseChatbotService<DifyModel, any> {\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    private readonly openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'DifyService', configService);\n  }\n\n  public async sendDifyMessage(\n    instanceName: string,\n    remoteJid: string,\n    dify: DifyModel,\n    content: string,\n  ): Promise<void> {\n    try {\n      const response = await axios.post(\n        `${dify.apiUrl}/v1/chat-messages`,\n        {\n          inputs: {},\n          query: content,\n          user: remoteJid,\n          conversation_id: `${instanceName}-${remoteJid}`,\n          response_mode: 'blocking',\n        },\n        {\n          headers: {\n            'Authorization': `Bearer ${dify.apiKey}`,\n            'Content-Type': 'application/json',\n          },\n        }\n      );\n\n      const aiResponse = response.data.answer;\n      \n      await this.waMonitor.waInstances[instanceName].sendMessage({\n        number: remoteJid.split('@')[0],\n        text: aiResponse,\n      });\n    } catch (error) {\n      this.logger.error(`Dify API error: ${error.message}`);\n      \n      // Fallback to OpenAI if configured\n      if (dify.fallbackOpenai && this.openaiService) {\n        await this.openaiService.sendOpenaiMessage(instanceName, remoteJid, dify.openaiBot, content);\n      }\n    }\n  }\n}\n```\n\n## Chatbot Router Pattern\n\n### Chatbot Router Structure (Evolution API Real Pattern)\n```typescript\nexport class ChatbotRouter {\n  public readonly router: Router;\n\n  constructor(...guards: any[]) {\n    this.router = Router();\n\n    // Real Evolution API chatbot integrations\n    this.router.use('/evolutionBot', new EvolutionBotRouter(...guards).router);\n    this.router.use('/chatwoot', new ChatwootRouter(...guards).router);\n    this.router.use('/typebot', new TypebotRouter(...guards).router);\n    this.router.use('/openai', new OpenaiRouter(...guards).router);\n    this.router.use('/dify', new DifyRouter(...guards).router);\n    this.router.use('/flowise', new FlowiseRouter(...guards).router);\n    this.router.use('/n8n', new N8nRouter(...guards).router);\n    this.router.use('/evoai', new EvoaiRouter(...guards).router);\n  }\n}\n```\n\n## Chatbot Validation Patterns\n\n### Chatbot Schema Validation (Evolution API Pattern)\n```typescript\nimport { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...fields: string[]) => {\n  const properties = {};\n  fields.forEach((field) => {\n    properties[field] = {\n      if: { properties: { [field]: { type: 'string' } } },\n      then: { properties: { [field]: { minLength: 1 } } },\n    };\n  });\n\n  return {\n    allOf: Object.values(properties),\n  };\n};\n\nexport const evolutionBotSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    apiUrl: { type: 'string' },\n    apiKey: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: ['enabled', 'apiUrl', 'triggerType'],\n  ...isNotEmpty('enabled', 'apiUrl', 'triggerType'),\n};\n\nfunction validateKeywordTrigger(\n  content: string,\n  operator: TriggerOperator,\n  value: string,\n): boolean {\n  const normalizedContent = content.toLowerCase().trim();\n  const normalizedValue = value.toLowerCase().trim();\n\n  switch (operator) {\n    case TriggerOperator.EQUALS:\n      return normalizedContent === normalizedValue;\n    case TriggerOperator.CONTAINS:\n      return normalizedContent.includes(normalizedValue);\n    case TriggerOperator.STARTS_WITH:\n      return normalizedContent.startsWith(normalizedValue);\n    case TriggerOperator.ENDS_WITH:\n      return normalizedContent.endsWith(normalizedValue);\n    default:\n      return false;\n  }\n}\n```\n\n## Session Management Pattern\n\n### Chatbot Session Handling\n```typescript\nexport class ChatbotSessionManager {\n  constructor(\n    private readonly prismaRepository: PrismaRepository,\n    private readonly cache: CacheService,\n  ) {}\n\n  public async getSession(\n    instanceName: string,\n    remoteJid: string,\n    botId: string,\n  ): Promise<IntegrationSession | null> {\n    const cacheKey = `session:${instanceName}:${remoteJid}:${botId}`;\n    \n    // Try cache first\n    let session = await this.cache.get(cacheKey);\n    if (session) {\n      return session;\n    }\n\n    // Query database\n    session = await this.prismaRepository.integrationSession.findFirst({\n      where: {\n        instanceId: instanceName,\n        remoteJid,\n        botId,\n        status: 'opened',\n      },\n    });\n\n    // Cache result\n    if (session) {\n      await this.cache.set(cacheKey, session, 300); // 5 min TTL\n    }\n\n    return session;\n  }\n\n  public async createSession(\n    instanceName: string,\n    remoteJid: string,\n    botId: string,\n  ): Promise<IntegrationSession> {\n    const session = await this.prismaRepository.integrationSession.create({\n      data: {\n        instanceId: instanceName,\n        remoteJid,\n        botId,\n        status: 'opened',\n        createdAt: new Date(),\n      },\n    });\n\n    // Cache new session\n    const cacheKey = `session:${instanceName}:${remoteJid}:${botId}`;\n    await this.cache.set(cacheKey, session, 300);\n\n    return session;\n  }\n\n  public async closeSession(sessionId: string): Promise<void> {\n    await this.prismaRepository.integrationSession.update({\n      where: { id: sessionId },\n      data: { status: 'closed', updatedAt: new Date() },\n    });\n\n    // Invalidate cache\n    // Note: In a real implementation, you'd need to track cache keys by session ID\n  }\n}\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/integration-event-rules.mdc",
    "content": "---\ndescription: Event integration patterns for Evolution API\nglobs:\n  - \"src/api/integrations/event/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Event Integration Rules\n\n## Event Manager Pattern\n\n### Event Manager Structure\n```typescript\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { Server } from 'http';\n\nexport class EventManager {\n  private prismaRepository: PrismaRepository;\n  private configService: ConfigService;\n  private logger = new Logger('EventManager');\n\n  // Event integrations\n  private webhook: WebhookController;\n  private websocket: WebsocketController;\n  private rabbitmq: RabbitmqController;\n  private nats: NatsController;\n  private sqs: SqsController;\n  private pusher: PusherController;\n\n  constructor(\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    server?: Server,\n  ) {\n    this.prismaRepository = prismaRepository;\n    this.configService = configService;\n\n    // Initialize event controllers\n    this.webhook = new WebhookController(prismaRepository, configService);\n    this.websocket = new WebsocketController(prismaRepository, configService, server);\n    this.rabbitmq = new RabbitmqController(prismaRepository, configService);\n    this.nats = new NatsController(prismaRepository, configService);\n    this.sqs = new SqsController(prismaRepository, configService);\n    this.pusher = new PusherController(prismaRepository, configService);\n  }\n\n  public async emit(eventData: {\n    instanceName: string;\n    origin: string;\n    event: string;\n    data: Object;\n    serverUrl: string;\n    dateTime: string;\n    sender: string;\n    apiKey?: string;\n    local?: boolean;\n    integration?: string[];\n  }): Promise<void> {\n    this.logger.log(`Emitting event ${eventData.event} for instance ${eventData.instanceName}`);\n\n    // Emit to all configured integrations\n    await Promise.allSettled([\n      this.webhook.emit(eventData),\n      this.websocket.emit(eventData),\n      this.rabbitmq.emit(eventData),\n      this.nats.emit(eventData),\n      this.sqs.emit(eventData),\n      this.pusher.emit(eventData),\n    ]);\n  }\n\n  public async setInstance(instanceName: string, data: any): Promise<any> {\n    const promises = [];\n\n    if (data.websocket) {\n      promises.push(\n        this.websocket.set(instanceName, {\n          websocket: {\n            enabled: true,\n            events: data.websocket?.events,\n          },\n        })\n      );\n    }\n\n    if (data.rabbitmq) {\n      promises.push(\n        this.rabbitmq.set(instanceName, {\n          rabbitmq: {\n            enabled: true,\n            events: data.rabbitmq?.events,\n          },\n        })\n      );\n    }\n\n    if (data.webhook) {\n      promises.push(\n        this.webhook.set(instanceName, {\n          webhook: {\n            enabled: true,\n            events: data.webhook?.events,\n            url: data.webhook?.url,\n            headers: data.webhook?.headers,\n            base64: data.webhook?.base64,\n            byEvents: data.webhook?.byEvents,\n          },\n        })\n      );\n    }\n\n    // Set other integrations...\n\n    await Promise.allSettled(promises);\n  }\n}\n```\n\n## Base Event Controller Pattern\n\n### Abstract Event Controller\n```typescript\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\n\nexport type EmitData = {\n  instanceName: string;\n  origin: string;\n  event: string;\n  data: Object;\n  serverUrl: string;\n  dateTime: string;\n  sender: string;\n  apiKey?: string;\n  local?: boolean;\n  integration?: string[];\n};\n\nexport interface EventControllerInterface {\n  integrationEnabled: boolean;\n  emit(data: EmitData): Promise<void>;\n  set(instanceName: string, data: any): Promise<any>;\n}\n\nexport abstract class EventController implements EventControllerInterface {\n  protected readonly logger: Logger;\n  protected readonly prismaRepository: PrismaRepository;\n  protected readonly configService: ConfigService;\n\n  public integrationEnabled: boolean = false;\n\n  // Available events for all integrations\n  public static readonly events = [\n    'APPLICATION_STARTUP',\n    'INSTANCE_CREATE',\n    'INSTANCE_DELETE',\n    'QRCODE_UPDATED',\n    'CONNECTION_UPDATE',\n    'STATUS_INSTANCE',\n    'MESSAGES_SET',\n    'MESSAGES_UPSERT',\n    'MESSAGES_EDITED',\n    'MESSAGES_UPDATE',\n    'MESSAGES_DELETE',\n    'SEND_MESSAGE',\n    'CONTACTS_SET',\n    'CONTACTS_UPSERT',\n    'CONTACTS_UPDATE',\n    'PRESENCE_UPDATE',\n    'CHATS_SET',\n    'CHATS_UPDATE',\n    'CHATS_UPSERT',\n    'CHATS_DELETE',\n    'GROUPS_UPSERT',\n    'GROUPS_UPDATE',\n    'GROUP_PARTICIPANTS_UPDATE',\n    'CALL',\n    'TYPEBOT_START',\n    'TYPEBOT_CHANGE_STATUS',\n    'LABELS_EDIT',\n    'LABELS_ASSOCIATION',\n    'CREDS_UPDATE',\n    'MESSAGING_HISTORY_SET',\n    'REMOVE_INSTANCE',\n    'LOGOUT_INSTANCE',\n  ];\n\n  constructor(\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    loggerName: string,\n  ) {\n    this.prismaRepository = prismaRepository;\n    this.configService = configService;\n    this.logger = new Logger(loggerName);\n  }\n\n  // Abstract methods to be implemented by specific integrations\n  public abstract emit(data: EmitData): Promise<void>;\n  public abstract set(instanceName: string, data: any): Promise<any>;\n\n  // Helper method to check if event should be processed\n  protected shouldProcessEvent(eventName: string, configuredEvents?: string[]): boolean {\n    if (!configuredEvents || configuredEvents.length === 0) {\n      return true; // Process all events if none specified\n    }\n    return configuredEvents.includes(eventName);\n  }\n\n  // Helper method to get instance configuration\n  protected async getInstanceConfig(instanceName: string): Promise<any> {\n    try {\n      const instance = await this.prismaRepository.instance.findUnique({\n        where: { name: instanceName },\n      });\n      return instance;\n    } catch (error) {\n      this.logger.error(`Failed to get instance config for ${instanceName}:`, error);\n      return null;\n    }\n  }\n}\n```\n\n## Webhook Integration Pattern\n\n### Webhook Controller Implementation\n```typescript\nexport class WebhookController extends EventController {\n  constructor(\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n  ) {\n    super(prismaRepository, configService, 'WebhookController');\n  }\n\n  public async emit(data: EmitData): Promise<void> {\n    try {\n      const instance = await this.getInstanceConfig(data.instanceName);\n      if (!instance?.webhook?.enabled) {\n        return;\n      }\n\n      const webhookConfig = instance.webhook;\n      \n      if (!this.shouldProcessEvent(data.event, webhookConfig.events)) {\n        return;\n      }\n\n      const payload = {\n        event: data.event,\n        instance: data.instanceName,\n        data: data.data,\n        timestamp: data.dateTime,\n        sender: data.sender,\n        server: {\n          version: process.env.npm_package_version,\n          url: data.serverUrl,\n        },\n      };\n\n      // Encode data as base64 if configured\n      if (webhookConfig.base64) {\n        payload.data = Buffer.from(JSON.stringify(payload.data)).toString('base64');\n      }\n\n      const headers = {\n        'Content-Type': 'application/json',\n        'User-Agent': 'Evolution-API-Webhook',\n        ...webhookConfig.headers,\n      };\n\n      if (webhookConfig.byEvents) {\n        // Send to event-specific endpoint\n        const eventUrl = `${webhookConfig.url}/${data.event.toLowerCase()}`;\n        await this.sendWebhook(eventUrl, payload, headers);\n      } else {\n        // Send to main webhook URL\n        await this.sendWebhook(webhookConfig.url, payload, headers);\n      }\n\n      this.logger.log(`Webhook sent for event ${data.event} to instance ${data.instanceName}`);\n    } catch (error) {\n      this.logger.error(`Webhook emission failed for ${data.instanceName}:`, error);\n    }\n  }\n\n  public async set(instanceName: string, data: any): Promise<any> {\n    try {\n      const webhookData = data.webhook;\n      \n      await this.prismaRepository.instance.update({\n        where: { name: instanceName },\n        data: {\n          webhook: webhookData,\n        },\n      });\n\n      this.logger.log(`Webhook configuration set for instance ${instanceName}`);\n      return { webhook: webhookData };\n    } catch (error) {\n      this.logger.error(`Failed to set webhook config for ${instanceName}:`, error);\n      throw error;\n    }\n  }\n\n  private async sendWebhook(url: string, payload: any, headers: any): Promise<void> {\n    try {\n      const response = await axios.post(url, payload, {\n        headers,\n        timeout: 30000,\n        maxRedirects: 3,\n      });\n\n      if (response.status >= 200 && response.status < 300) {\n        this.logger.log(`Webhook delivered successfully to ${url}`);\n      } else {\n        this.logger.warn(`Webhook returned status ${response.status} for ${url}`);\n      }\n    } catch (error) {\n      this.logger.error(`Webhook delivery failed to ${url}:`, error.message);\n      \n      // Implement retry logic here if needed\n      if (error.response?.status >= 500) {\n        // Server error - might be worth retrying\n        this.logger.log(`Server error detected, webhook might be retried later`);\n      }\n    }\n  }\n}\n```\n\n## WebSocket Integration Pattern\n\n### WebSocket Controller Implementation\n```typescript\nimport { Server as SocketIOServer } from 'socket.io';\nimport { Server } from 'http';\n\nexport class WebsocketController extends EventController {\n  private io: SocketIOServer;\n\n  constructor(\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    server?: Server,\n  ) {\n    super(prismaRepository, configService, 'WebsocketController');\n    \n    if (server) {\n      this.io = new SocketIOServer(server, {\n        cors: {\n          origin: \"*\",\n          methods: [\"GET\", \"POST\"],\n        },\n      });\n\n      this.setupSocketHandlers();\n    }\n  }\n\n  private setupSocketHandlers(): void {\n    this.io.on('connection', (socket) => {\n      this.logger.log(`WebSocket client connected: ${socket.id}`);\n\n      socket.on('join-instance', (instanceName: string) => {\n        socket.join(`instance:${instanceName}`);\n        this.logger.log(`Client ${socket.id} joined instance ${instanceName}`);\n      });\n\n      socket.on('leave-instance', (instanceName: string) => {\n        socket.leave(`instance:${instanceName}`);\n        this.logger.log(`Client ${socket.id} left instance ${instanceName}`);\n      });\n\n      socket.on('disconnect', () => {\n        this.logger.log(`WebSocket client disconnected: ${socket.id}`);\n      });\n    });\n  }\n\n  public async emit(data: EmitData): Promise<void> {\n    if (!this.io) {\n      return;\n    }\n\n    try {\n      const instance = await this.getInstanceConfig(data.instanceName);\n      if (!instance?.websocket?.enabled) {\n        return;\n      }\n\n      const websocketConfig = instance.websocket;\n      \n      if (!this.shouldProcessEvent(data.event, websocketConfig.events)) {\n        return;\n      }\n\n      const payload = {\n        event: data.event,\n        instance: data.instanceName,\n        data: data.data,\n        timestamp: data.dateTime,\n        sender: data.sender,\n      };\n\n      // Emit to specific instance room\n      this.io.to(`instance:${data.instanceName}`).emit('evolution-event', payload);\n      \n      // Also emit to global room for monitoring\n      this.io.emit('global-event', payload);\n\n      this.logger.log(`WebSocket event ${data.event} emitted for instance ${data.instanceName}`);\n    } catch (error) {\n      this.logger.error(`WebSocket emission failed for ${data.instanceName}:`, error);\n    }\n  }\n\n  public async set(instanceName: string, data: any): Promise<any> {\n    try {\n      const websocketData = data.websocket;\n      \n      await this.prismaRepository.instance.update({\n        where: { name: instanceName },\n        data: {\n          websocket: websocketData,\n        },\n      });\n\n      this.logger.log(`WebSocket configuration set for instance ${instanceName}`);\n      return { websocket: websocketData };\n    } catch (error) {\n      this.logger.error(`Failed to set WebSocket config for ${instanceName}:`, error);\n      throw error;\n    }\n  }\n}\n```\n\n## Queue Integration Patterns\n\n### RabbitMQ Controller Implementation\n```typescript\nimport amqp from 'amqplib';\n\nexport class RabbitmqController extends EventController {\n  private connection: amqp.Connection | null = null;\n  private channel: amqp.Channel | null = null;\n\n  constructor(\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n  ) {\n    super(prismaRepository, configService, 'RabbitmqController');\n    this.initializeConnection();\n  }\n\n  private async initializeConnection(): Promise<void> {\n    try {\n      const rabbitmqConfig = this.configService.get('RABBITMQ');\n      if (!rabbitmqConfig?.ENABLED) {\n        return;\n      }\n\n      this.connection = await amqp.connect(rabbitmqConfig.URI);\n      this.channel = await this.connection.createChannel();\n\n      // Declare exchange for Evolution API events\n      await this.channel.assertExchange('evolution-events', 'topic', { durable: true });\n\n      this.logger.log('RabbitMQ connection established');\n    } catch (error) {\n      this.logger.error('Failed to initialize RabbitMQ connection:', error);\n    }\n  }\n\n  public async emit(data: EmitData): Promise<void> {\n    if (!this.channel) {\n      return;\n    }\n\n    try {\n      const instance = await this.getInstanceConfig(data.instanceName);\n      if (!instance?.rabbitmq?.enabled) {\n        return;\n      }\n\n      const rabbitmqConfig = instance.rabbitmq;\n      \n      if (!this.shouldProcessEvent(data.event, rabbitmqConfig.events)) {\n        return;\n      }\n\n      const payload = {\n        event: data.event,\n        instance: data.instanceName,\n        data: data.data,\n        timestamp: data.dateTime,\n        sender: data.sender,\n      };\n\n      const routingKey = `evolution.${data.instanceName}.${data.event.toLowerCase()}`;\n      \n      await this.channel.publish(\n        'evolution-events',\n        routingKey,\n        Buffer.from(JSON.stringify(payload)),\n        {\n          persistent: true,\n          timestamp: Date.now(),\n          messageId: `${data.instanceName}-${Date.now()}`,\n        }\n      );\n\n      this.logger.log(`RabbitMQ message published for event ${data.event} to instance ${data.instanceName}`);\n    } catch (error) {\n      this.logger.error(`RabbitMQ emission failed for ${data.instanceName}:`, error);\n    }\n  }\n\n  public async set(instanceName: string, data: any): Promise<any> {\n    try {\n      const rabbitmqData = data.rabbitmq;\n      \n      await this.prismaRepository.instance.update({\n        where: { name: instanceName },\n        data: {\n          rabbitmq: rabbitmqData,\n        },\n      });\n\n      this.logger.log(`RabbitMQ configuration set for instance ${instanceName}`);\n      return { rabbitmq: rabbitmqData };\n    } catch (error) {\n      this.logger.error(`Failed to set RabbitMQ config for ${instanceName}:`, error);\n      throw error;\n    }\n  }\n}\n```\n\n### SQS Controller Implementation\n```typescript\nimport { SQSClient, SendMessageCommand } from '@aws-sdk/client-sqs';\n\nexport class SqsController extends EventController {\n  private sqsClient: SQSClient | null = null;\n\n  constructor(\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n  ) {\n    super(prismaRepository, configService, 'SqsController');\n    this.initializeSQSClient();\n  }\n\n  private initializeSQSClient(): void {\n    try {\n      const sqsConfig = this.configService.get('SQS');\n      if (!sqsConfig?.ENABLED) {\n        return;\n      }\n\n      this.sqsClient = new SQSClient({\n        region: sqsConfig.REGION,\n        credentials: {\n          accessKeyId: sqsConfig.ACCESS_KEY_ID,\n          secretAccessKey: sqsConfig.SECRET_ACCESS_KEY,\n        },\n      });\n\n      this.logger.log('SQS client initialized');\n    } catch (error) {\n      this.logger.error('Failed to initialize SQS client:', error);\n    }\n  }\n\n  public async emit(data: EmitData): Promise<void> {\n    if (!this.sqsClient) {\n      return;\n    }\n\n    try {\n      const instance = await this.getInstanceConfig(data.instanceName);\n      if (!instance?.sqs?.enabled) {\n        return;\n      }\n\n      const sqsConfig = instance.sqs;\n      \n      if (!this.shouldProcessEvent(data.event, sqsConfig.events)) {\n        return;\n      }\n\n      const payload = {\n        event: data.event,\n        instance: data.instanceName,\n        data: data.data,\n        timestamp: data.dateTime,\n        sender: data.sender,\n      };\n\n      const command = new SendMessageCommand({\n        QueueUrl: sqsConfig.queueUrl,\n        MessageBody: JSON.stringify(payload),\n        MessageAttributes: {\n          event: {\n            DataType: 'String',\n            StringValue: data.event,\n          },\n          instance: {\n            DataType: 'String',\n            StringValue: data.instanceName,\n          },\n        },\n        MessageGroupId: data.instanceName, // For FIFO queues\n        MessageDeduplicationId: `${data.instanceName}-${Date.now()}`, // For FIFO queues\n      });\n\n      await this.sqsClient.send(command);\n\n      this.logger.log(`SQS message sent for event ${data.event} to instance ${data.instanceName}`);\n    } catch (error) {\n      this.logger.error(`SQS emission failed for ${data.instanceName}:`, error);\n    }\n  }\n\n  public async set(instanceName: string, data: any): Promise<any> {\n    try {\n      const sqsData = data.sqs;\n      \n      await this.prismaRepository.instance.update({\n        where: { name: instanceName },\n        data: {\n          sqs: sqsData,\n        },\n      });\n\n      this.logger.log(`SQS configuration set for instance ${instanceName}`);\n      return { sqs: sqsData };\n    } catch (error) {\n      this.logger.error(`Failed to set SQS config for ${instanceName}:`, error);\n      throw error;\n    }\n  }\n}\n```\n\n## Event DTO Pattern\n\n### Event Configuration DTO\n```typescript\nimport { JsonValue } from '@prisma/client/runtime/library';\n\nexport class EventDto {\n  webhook?: {\n    enabled?: boolean;\n    events?: string[];\n    url?: string;\n    headers?: JsonValue;\n    byEvents?: boolean;\n    base64?: boolean;\n  };\n\n  websocket?: {\n    enabled?: boolean;\n    events?: string[];\n  };\n\n  sqs?: {\n    enabled?: boolean;\n    events?: string[];\n    queueUrl?: string;\n  };\n\n  rabbitmq?: {\n    enabled?: boolean;\n    events?: string[];\n    exchange?: string;\n  };\n\n  nats?: {\n    enabled?: boolean;\n    events?: string[];\n    subject?: string;\n  };\n\n  pusher?: {\n    enabled?: boolean;\n    appId?: string;\n    key?: string;\n    secret?: string;\n    cluster?: string;\n    useTLS?: boolean;\n    events?: string[];\n  };\n}\n```\n\n## Event Router Pattern\n\n### Event Router Structure\n```typescript\nimport { NatsRouter } from '@api/integrations/event/nats/nats.router';\nimport { PusherRouter } from '@api/integrations/event/pusher/pusher.router';\nimport { RabbitmqRouter } from '@api/integrations/event/rabbitmq/rabbitmq.router';\nimport { SqsRouter } from '@api/integrations/event/sqs/sqs.router';\nimport { WebhookRouter } from '@api/integrations/event/webhook/webhook.router';\nimport { WebsocketRouter } from '@api/integrations/event/websocket/websocket.router';\nimport { Router } from 'express';\n\nexport class EventRouter {\n  public readonly router: Router;\n\n  constructor(configService: any, ...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/webhook', new WebhookRouter(configService, ...guards).router);\n    this.router.use('/websocket', new WebsocketRouter(...guards).router);\n    this.router.use('/rabbitmq', new RabbitmqRouter(...guards).router);\n    this.router.use('/nats', new NatsRouter(...guards).router);\n    this.router.use('/pusher', new PusherRouter(...guards).router);\n    this.router.use('/sqs', new SqsRouter(...guards).router);\n  }\n}\n```\n\n## Event Validation Schema\n\n### Event Configuration Validation\n```typescript\nimport Joi from 'joi';\nimport { EventController } from '@api/integrations/event/event.controller';\n\nconst eventListSchema = Joi.array().items(\n  Joi.string().valid(...EventController.events)\n).optional();\n\nexport const webhookSchema = Joi.object({\n  enabled: Joi.boolean().required(),\n  url: Joi.string().when('enabled', {\n    is: true,\n    then: Joi.required().uri({ scheme: ['http', 'https'] }),\n    otherwise: Joi.optional(),\n  }),\n  events: eventListSchema,\n  headers: Joi.object().pattern(Joi.string(), Joi.string()).optional(),\n  byEvents: Joi.boolean().optional().default(false),\n  base64: Joi.boolean().optional().default(false),\n}).required();\n\nexport const websocketSchema = Joi.object({\n  enabled: Joi.boolean().required(),\n  events: eventListSchema,\n}).required();\n\nexport const rabbitmqSchema = Joi.object({\n  enabled: Joi.boolean().required(),\n  events: eventListSchema,\n  exchange: Joi.string().optional().default('evolution-events'),\n}).required();\n\nexport const sqsSchema = Joi.object({\n  enabled: Joi.boolean().required(),\n  events: eventListSchema,\n  queueUrl: Joi.string().when('enabled', {\n    is: true,\n    then: Joi.required().uri(),\n    otherwise: Joi.optional(),\n  }),\n}).required();\n\nexport const eventSchema = Joi.object({\n  webhook: webhookSchema.optional(),\n  websocket: websocketSchema.optional(),\n  rabbitmq: rabbitmqSchema.optional(),\n  sqs: sqsSchema.optional(),\n  nats: Joi.object({\n    enabled: Joi.boolean().required(),\n    events: eventListSchema,\n    subject: Joi.string().optional().default('evolution.events'),\n  }).optional(),\n  pusher: Joi.object({\n    enabled: Joi.boolean().required(),\n    appId: Joi.string().when('enabled', { is: true, then: Joi.required() }),\n    key: Joi.string().when('enabled', { is: true, then: Joi.required() }),\n    secret: Joi.string().when('enabled', { is: true, then: Joi.required() }),\n    cluster: Joi.string().when('enabled', { is: true, then: Joi.required() }),\n    useTLS: Joi.boolean().optional().default(true),\n    events: eventListSchema,\n  }).optional(),\n}).min(1).required();\n```\n\n## Event Testing Pattern\n\n### Event Controller Testing\n```typescript\ndescribe('WebhookController', () => {\n  let controller: WebhookController;\n  let prismaRepository: jest.Mocked<PrismaRepository>;\n  let configService: jest.Mocked<ConfigService>;\n\n  beforeEach(() => {\n    controller = new WebhookController(prismaRepository, configService);\n  });\n\n  describe('emit', () => {\n    it('should send webhook when enabled', async () => {\n      const mockInstance = {\n        webhook: {\n          enabled: true,\n          url: 'https://example.com/webhook',\n          events: ['MESSAGES_UPSERT'],\n        },\n      };\n\n      prismaRepository.instance.findUnique.mockResolvedValue(mockInstance);\n      jest.spyOn(axios, 'post').mockResolvedValue({ status: 200 });\n\n      const eventData = {\n        instanceName: 'test-instance',\n        event: 'MESSAGES_UPSERT',\n        data: { message: 'test' },\n        origin: 'test',\n        serverUrl: 'http://localhost',\n        dateTime: new Date().toISOString(),\n        sender: 'test',\n      };\n\n      await controller.emit(eventData);\n\n      expect(axios.post).toHaveBeenCalledWith(\n        'https://example.com/webhook',\n        expect.objectContaining({\n          event: 'MESSAGES_UPSERT',\n          instance: 'test-instance',\n        }),\n        expect.objectContaining({\n          headers: expect.objectContaining({\n            'Content-Type': 'application/json',\n          }),\n        })\n      );\n    });\n  });\n});\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/integration-storage-rules.mdc",
    "content": "---\ndescription: Storage integration patterns for Evolution API\nglobs:\n  - \"src/api/integrations/storage/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Storage Integration Rules\n\n## Storage Service Pattern\n\n### Base Storage Service Structure\n```typescript\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\n\nexport class StorageService {\n  constructor(private readonly prismaRepository: PrismaRepository) {}\n\n  private readonly logger = new Logger('StorageService');\n\n  public async getMedia(instance: InstanceDto, query?: MediaDto) {\n    try {\n      const where: any = {\n        instanceId: instance.instanceId,\n        ...query,\n      };\n\n      const media = await this.prismaRepository.media.findMany({\n        where,\n        select: {\n          id: true,\n          fileName: true,\n          type: true,\n          mimetype: true,\n          createdAt: true,\n          Message: true,\n        },\n      });\n\n      if (!media || media.length === 0) {\n        throw 'Media not found';\n      }\n\n      return media;\n    } catch (error) {\n      throw new BadRequestException(error);\n    }\n  }\n\n  public async getMediaUrl(instance: InstanceDto, data: MediaDto) {\n    const media = (await this.getMedia(instance, { id: data.id }))[0];\n    const mediaUrl = await this.generateUrl(media.fileName, data.expiry);\n    return {\n      mediaUrl,\n      ...media,\n    };\n  }\n\n  protected abstract generateUrl(fileName: string, expiry?: number): Promise<string>;\n}\n```\n\n## S3/MinIO Integration Pattern\n\n### MinIO Client Setup\n```typescript\nimport { ConfigService, S3 } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport * as MinIo from 'minio';\nimport { join } from 'path';\nimport { Readable, Transform } from 'stream';\n\nconst logger = new Logger('S3 Service');\nconst BUCKET = new ConfigService().get<S3>('S3');\n\ninterface Metadata extends MinIo.ItemBucketMetadata {\n  instanceId: string;\n  messageId?: string;\n}\n\nconst minioClient = (() => {\n  if (BUCKET?.ENABLE) {\n    return new MinIo.Client({\n      endPoint: BUCKET.ENDPOINT,\n      port: BUCKET.PORT,\n      useSSL: BUCKET.USE_SSL,\n      accessKey: BUCKET.ACCESS_KEY,\n      secretKey: BUCKET.SECRET_KEY,\n      region: BUCKET.REGION,\n    });\n  }\n})();\n\nconst bucketName = process.env.S3_BUCKET;\n```\n\n### Bucket Management Functions\n```typescript\nconst bucketExists = async (): Promise<boolean> => {\n  if (minioClient) {\n    try {\n      const list = await minioClient.listBuckets();\n      return !!list.find((bucket) => bucket.name === bucketName);\n    } catch (error) {\n      logger.error('Error checking bucket existence:', error);\n      return false;\n    }\n  }\n  return false;\n};\n\nconst setBucketPolicy = async (): Promise<void> => {\n  if (minioClient && bucketName) {\n    try {\n      const policy = {\n        Version: '2012-10-17',\n        Statement: [\n          {\n            Effect: 'Allow',\n            Principal: { AWS: ['*'] },\n            Action: ['s3:GetObject'],\n            Resource: [`arn:aws:s3:::${bucketName}/*`],\n          },\n        ],\n      };\n\n      await minioClient.setBucketPolicy(bucketName, JSON.stringify(policy));\n      logger.log('Bucket policy set successfully');\n    } catch (error) {\n      logger.error('Error setting bucket policy:', error);\n    }\n  }\n};\n\nconst createBucket = async (): Promise<void> => {\n  if (minioClient && bucketName) {\n    try {\n      const exists = await bucketExists();\n      if (!exists) {\n        await minioClient.makeBucket(bucketName, BUCKET.REGION || 'us-east-1');\n        await setBucketPolicy();\n        logger.log(`Bucket ${bucketName} created successfully`);\n      }\n    } catch (error) {\n      logger.error('Error creating bucket:', error);\n    }\n  }\n};\n```\n\n### File Upload Functions\n```typescript\nexport const uploadFile = async (\n  fileName: string,\n  buffer: Buffer,\n  mimetype: string,\n  metadata?: Metadata,\n): Promise<string> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    await createBucket();\n\n    const uploadMetadata = {\n      'Content-Type': mimetype,\n      ...metadata,\n    };\n\n    await minioClient.putObject(bucketName, fileName, buffer, buffer.length, uploadMetadata);\n    \n    logger.log(`File ${fileName} uploaded successfully`);\n    return fileName;\n  } catch (error) {\n    logger.error(`Error uploading file ${fileName}:`, error);\n    throw new BadRequestException(`Failed to upload file: ${error.message}`);\n  }\n};\n\nexport const uploadStream = async (\n  fileName: string,\n  stream: Readable,\n  size: number,\n  mimetype: string,\n  metadata?: Metadata,\n): Promise<string> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    await createBucket();\n\n    const uploadMetadata = {\n      'Content-Type': mimetype,\n      ...metadata,\n    };\n\n    await minioClient.putObject(bucketName, fileName, stream, size, uploadMetadata);\n    \n    logger.log(`Stream ${fileName} uploaded successfully`);\n    return fileName;\n  } catch (error) {\n    logger.error(`Error uploading stream ${fileName}:`, error);\n    throw new BadRequestException(`Failed to upload stream: ${error.message}`);\n  }\n};\n```\n\n### File Download Functions\n```typescript\nexport const getObject = async (fileName: string): Promise<Buffer> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    const stream = await minioClient.getObject(bucketName, fileName);\n    const chunks: Buffer[] = [];\n\n    return new Promise((resolve, reject) => {\n      stream.on('data', (chunk) => chunks.push(chunk));\n      stream.on('end', () => resolve(Buffer.concat(chunks)));\n      stream.on('error', reject);\n    });\n  } catch (error) {\n    logger.error(`Error getting object ${fileName}:`, error);\n    throw new BadRequestException(`Failed to get object: ${error.message}`);\n  }\n};\n\nexport const getObjectUrl = async (fileName: string, expiry: number = 3600): Promise<string> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    const url = await minioClient.presignedGetObject(bucketName, fileName, expiry);\n    logger.log(`Generated URL for ${fileName} with expiry ${expiry}s`);\n    return url;\n  } catch (error) {\n    logger.error(`Error generating URL for ${fileName}:`, error);\n    throw new BadRequestException(`Failed to generate URL: ${error.message}`);\n  }\n};\n\nexport const getObjectStream = async (fileName: string): Promise<Readable> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    const stream = await minioClient.getObject(bucketName, fileName);\n    return stream;\n  } catch (error) {\n    logger.error(`Error getting object stream ${fileName}:`, error);\n    throw new BadRequestException(`Failed to get object stream: ${error.message}`);\n  }\n};\n```\n\n### File Management Functions\n```typescript\nexport const deleteObject = async (fileName: string): Promise<void> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    await minioClient.removeObject(bucketName, fileName);\n    logger.log(`File ${fileName} deleted successfully`);\n  } catch (error) {\n    logger.error(`Error deleting file ${fileName}:`, error);\n    throw new BadRequestException(`Failed to delete file: ${error.message}`);\n  }\n};\n\nexport const listObjects = async (prefix?: string): Promise<MinIo.BucketItem[]> => {\n  if (!minioClient || !bucketName) {\n    throw new BadRequestException('S3 storage not configured');\n  }\n\n  try {\n    const objects: MinIo.BucketItem[] = [];\n    const stream = minioClient.listObjects(bucketName, prefix, true);\n\n    return new Promise((resolve, reject) => {\n      stream.on('data', (obj) => objects.push(obj));\n      stream.on('end', () => resolve(objects));\n      stream.on('error', reject);\n    });\n  } catch (error) {\n    logger.error('Error listing objects:', error);\n    throw new BadRequestException(`Failed to list objects: ${error.message}`);\n  }\n};\n\nexport const objectExists = async (fileName: string): Promise<boolean> => {\n  if (!minioClient || !bucketName) {\n    return false;\n  }\n\n  try {\n    await minioClient.statObject(bucketName, fileName);\n    return true;\n  } catch (error) {\n    return false;\n  }\n};\n```\n\n## Storage Controller Pattern\n\n### S3 Controller Implementation\n```typescript\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';\nimport { S3Service } from '@api/integrations/storage/s3/services/s3.service';\n\nexport class S3Controller {\n  constructor(private readonly s3Service: S3Service) {}\n\n  public async getMedia(instance: InstanceDto, data: MediaDto) {\n    return this.s3Service.getMedia(instance, data);\n  }\n\n  public async getMediaUrl(instance: InstanceDto, data: MediaDto) {\n    return this.s3Service.getMediaUrl(instance, data);\n  }\n\n  public async uploadMedia(instance: InstanceDto, data: UploadMediaDto) {\n    return this.s3Service.uploadMedia(instance, data);\n  }\n\n  public async deleteMedia(instance: InstanceDto, data: MediaDto) {\n    return this.s3Service.deleteMedia(instance, data);\n  }\n}\n```\n\n## Storage Router Pattern\n\n### Storage Router Structure\n```typescript\nimport { S3Router } from '@api/integrations/storage/s3/routes/s3.router';\nimport { Router } from 'express';\n\nexport class StorageRouter {\n  public readonly router: Router;\n\n  constructor(...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/s3', new S3Router(...guards).router);\n    // Add other storage providers here\n    // this.router.use('/gcs', new GCSRouter(...guards).router);\n    // this.router.use('/azure', new AzureRouter(...guards).router);\n  }\n}\n```\n\n### S3 Specific Router\n```typescript\nimport { RouterBroker } from '@api/abstract/abstract.router';\nimport { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';\nimport { s3Schema, s3UrlSchema } from '@api/integrations/storage/s3/validate/s3.schema';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { s3Controller } from '@api/server.module';\nimport { RequestHandler, Router } from 'express';\n\nexport class S3Router extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('getMedia'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<MediaDto>({\n          request: req,\n          schema: s3Schema,\n          ClassRef: MediaDto,\n          execute: (instance, data) => s3Controller.getMedia(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('getMediaUrl'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<MediaDto>({\n          request: req,\n          schema: s3UrlSchema,\n          ClassRef: MediaDto,\n          execute: (instance, data) => s3Controller.getMediaUrl(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('uploadMedia'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<UploadMediaDto>({\n          request: req,\n          schema: uploadSchema,\n          ClassRef: UploadMediaDto,\n          execute: (instance, data) => s3Controller.uploadMedia(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .delete(this.routerPath('deleteMedia'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<MediaDto>({\n          request: req,\n          schema: s3Schema,\n          ClassRef: MediaDto,\n          execute: (instance, data) => s3Controller.deleteMedia(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n```\n\n## Storage DTO Pattern\n\n### Media DTO\n```typescript\nexport class MediaDto {\n  id?: string;\n  fileName?: string;\n  type?: string;\n  mimetype?: string;\n  expiry?: number;\n}\n\nexport class UploadMediaDto {\n  fileName: string;\n  mimetype: string;\n  buffer?: Buffer;\n  base64?: string;\n  url?: string;\n  metadata?: {\n    instanceId: string;\n    messageId?: string;\n    contactId?: string;\n    [key: string]: any;\n  };\n}\n```\n\n## Storage Validation Schema\n\n### S3 Validation Schemas\n```typescript\nimport Joi from 'joi';\n\nexport const s3Schema = Joi.object({\n  id: Joi.string().optional(),\n  fileName: Joi.string().optional(),\n  type: Joi.string().optional().valid('image', 'video', 'audio', 'document'),\n  mimetype: Joi.string().optional(),\n  expiry: Joi.number().optional().min(60).max(604800).default(3600), // 1 min to 7 days\n}).min(1).required();\n\nexport const s3UrlSchema = Joi.object({\n  id: Joi.string().required(),\n  expiry: Joi.number().optional().min(60).max(604800).default(3600),\n}).required();\n\nexport const uploadSchema = Joi.object({\n  fileName: Joi.string().required().max(255),\n  mimetype: Joi.string().required(),\n  buffer: Joi.binary().optional(),\n  base64: Joi.string().base64().optional(),\n  url: Joi.string().uri().optional(),\n  metadata: Joi.object({\n    instanceId: Joi.string().required(),\n    messageId: Joi.string().optional(),\n    contactId: Joi.string().optional(),\n  }).optional(),\n}).xor('buffer', 'base64', 'url').required(); // Exactly one of these must be present\n```\n\n## Error Handling in Storage\n\n### Storage-Specific Error Handling\n```typescript\n// CORRECT - Storage-specific error handling\npublic async uploadFile(fileName: string, buffer: Buffer): Promise<string> {\n  try {\n    const result = await this.storageClient.upload(fileName, buffer);\n    return result;\n  } catch (error) {\n    this.logger.error(`Storage upload failed: ${error.message}`);\n    \n    if (error.code === 'NoSuchBucket') {\n      throw new BadRequestException('Storage bucket not found');\n    }\n    \n    if (error.code === 'AccessDenied') {\n      throw new UnauthorizedException('Storage access denied');\n    }\n    \n    if (error.code === 'EntityTooLarge') {\n      throw new BadRequestException('File too large');\n    }\n    \n    throw new InternalServerErrorException('Storage operation failed');\n  }\n}\n```\n\n## Storage Configuration Pattern\n\n### Environment Configuration\n```typescript\nexport interface S3Config {\n  ENABLE: boolean;\n  ENDPOINT: string;\n  PORT: number;\n  USE_SSL: boolean;\n  ACCESS_KEY: string;\n  SECRET_KEY: string;\n  REGION: string;\n  BUCKET: string;\n}\n\n// Usage in service\nconst s3Config = this.configService.get<S3Config>('S3');\nif (!s3Config.ENABLE) {\n  throw new BadRequestException('S3 storage is disabled');\n}\n```\n\n## Storage Testing Pattern\n\n### Storage Service Testing\n```typescript\ndescribe('S3Service', () => {\n  let service: S3Service;\n  let prismaRepository: jest.Mocked<PrismaRepository>;\n\n  beforeEach(() => {\n    service = new S3Service(prismaRepository);\n  });\n\n  describe('getMedia', () => {\n    it('should return media list', async () => {\n      const instance = { instanceId: 'test-instance' };\n      const mockMedia = [\n        { id: '1', fileName: 'test.jpg', type: 'image', mimetype: 'image/jpeg' },\n      ];\n\n      prismaRepository.media.findMany.mockResolvedValue(mockMedia);\n\n      const result = await service.getMedia(instance);\n\n      expect(result).toEqual(mockMedia);\n      expect(prismaRepository.media.findMany).toHaveBeenCalledWith({\n        where: { instanceId: 'test-instance' },\n        select: expect.objectContaining({\n          id: true,\n          fileName: true,\n          type: true,\n          mimetype: true,\n        }),\n      });\n    });\n\n    it('should throw error when no media found', async () => {\n      const instance = { instanceId: 'test-instance' };\n      prismaRepository.media.findMany.mockResolvedValue([]);\n\n      await expect(service.getMedia(instance)).rejects.toThrow(BadRequestException);\n    });\n  });\n});\n```\n\n## Storage Performance Considerations\n\n### Efficient File Handling\n```typescript\n// CORRECT - Stream-based upload for large files\npublic async uploadLargeFile(fileName: string, stream: Readable, size: number): Promise<string> {\n  const uploadStream = new Transform({\n    transform(chunk, encoding, callback) {\n      // Optional: Add compression, encryption, etc.\n      callback(null, chunk);\n    },\n  });\n\n  return new Promise((resolve, reject) => {\n    stream\n      .pipe(uploadStream)\n      .on('error', reject)\n      .on('finish', () => resolve(fileName));\n  });\n}\n\n// INCORRECT - Loading entire file into memory\npublic async uploadLargeFile(fileName: string, filePath: string): Promise<string> {\n  const buffer = fs.readFileSync(filePath); // ❌ Memory intensive for large files\n  return await this.uploadFile(fileName, buffer);\n}\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/route-rules.mdc",
    "content": "---\ndescription: Router patterns for Evolution API\nglobs:\n  - \"src/api/routes/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Route Rules\n\n## Router Base Pattern\n\n### RouterBroker Extension\n```typescript\nimport { RouterBroker } from '@api/abstract/abstract.router';\nimport { RequestHandler, Router } from 'express';\nimport { HttpStatus } from './index.router';\n\nexport class ExampleRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .get(this.routerPath('findExample'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ExampleDto>({\n          request: req,\n          schema: null,\n          ClassRef: ExampleDto,\n          execute: (instance) => exampleController.find(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('createExample'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ExampleDto>({\n          request: req,\n          schema: exampleSchema,\n          ClassRef: ExampleDto,\n          execute: (instance, data) => exampleController.create(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n```\n\n## Main Router Pattern\n\n### Index Router Structure\n```typescript\nimport { Router } from 'express';\nimport { authGuard } from '@api/guards/auth.guard';\nimport { instanceExistsGuard, instanceLoggedGuard } from '@api/guards/instance.guard';\nimport Telemetry from '@api/guards/telemetry.guard';\n\nenum HttpStatus {\n  OK = 200,\n  CREATED = 201,\n  NOT_FOUND = 404,\n  FORBIDDEN = 403,\n  BAD_REQUEST = 400,\n  UNAUTHORIZED = 401,\n  INTERNAL_SERVER_ERROR = 500,\n}\n\nconst router: Router = Router();\nconst guards = [instanceExistsGuard, instanceLoggedGuard, authGuard['apikey']];\nconst telemetry = new Telemetry();\n\nrouter\n  .use((req, res, next) => telemetry.collectTelemetry(req, res, next))\n  .get('/', async (req, res) => {\n    res.status(HttpStatus.OK).json({\n      status: HttpStatus.OK,\n      message: 'Welcome to the Evolution API, it is working!',\n      version: packageJson.version,\n      clientName: process.env.DATABASE_CONNECTION_CLIENT_NAME,\n      manager: !serverConfig.DISABLE_MANAGER ? `${req.protocol}://${req.get('host')}/manager` : undefined,\n      documentation: `https://doc.evolution-api.com`,\n      whatsappWebVersion: (await fetchLatestWaWebVersion({})).version.join('.'),\n    });\n  })\n  .use('/instance', new InstanceRouter(configService, ...guards).router)\n  .use('/message', new MessageRouter(...guards).router)\n  .use('/chat', new ChatRouter(...guards).router)\n  .use('/business', new BusinessRouter(...guards).router);\n\nexport { HttpStatus, router };\n```\n\n## Data Validation Pattern\n\n### RouterBroker dataValidate Usage\n```typescript\n// CORRECT - Standard validation pattern\n.post(this.routerPath('createTemplate'), ...guards, async (req, res) => {\n  const response = await this.dataValidate<TemplateDto>({\n    request: req,\n    schema: templateSchema,\n    ClassRef: TemplateDto,\n    execute: (instance, data) => templateController.create(instance, data),\n  });\n\n  return res.status(HttpStatus.CREATED).json(response);\n})\n\n// CORRECT - No schema validation (for simple DTOs)\n.get(this.routerPath('findTemplate'), ...guards, async (req, res) => {\n  const response = await this.dataValidate<InstanceDto>({\n    request: req,\n    schema: null,\n    ClassRef: InstanceDto,\n    execute: (instance) => templateController.find(instance),\n  });\n\n  return res.status(HttpStatus.OK).json(response);\n})\n```\n\n## Error Handling in Routes\n\n### Try-Catch Pattern\n```typescript\n// CORRECT - Error handling with utility function\n.post(this.routerPath('getCatalog'), ...guards, async (req, res) => {\n  try {\n    const response = await this.dataValidate<NumberDto>({\n      request: req,\n      schema: catalogSchema,\n      ClassRef: NumberDto,\n      execute: (instance, data) => businessController.fetchCatalog(instance, data),\n    });\n\n    return res.status(HttpStatus.OK).json(response);\n  } catch (error) {\n    // Log error for debugging\n    console.error('Business catalog error:', error);\n\n    // Use utility function to create standardized error response\n    const errorResponse = createMetaErrorResponse(error, 'business_catalog');\n    return res.status(errorResponse.status).json(errorResponse);\n  }\n})\n\n// INCORRECT - Let RouterBroker handle errors (when possible)\n.post(this.routerPath('simpleOperation'), ...guards, async (req, res) => {\n  try {\n    const response = await this.dataValidate<SimpleDto>({\n      request: req,\n      schema: simpleSchema,\n      ClassRef: SimpleDto,\n      execute: (instance, data) => controller.simpleOperation(instance, data),\n    });\n\n    return res.status(HttpStatus.OK).json(response);\n  } catch (error) {\n    throw error; // ❌ Unnecessary - RouterBroker handles this\n  }\n})\n```\n\n## Route Path Pattern\n\n### routerPath Usage\n```typescript\n// CORRECT - Use routerPath for consistent naming\n.get(this.routerPath('findLabels'), ...guards, async (req, res) => {\n  // Implementation\n})\n.post(this.routerPath('handleLabel'), ...guards, async (req, res) => {\n  // Implementation\n})\n\n// INCORRECT - Hardcoded paths\n.get('/labels', ...guards, async (req, res) => { // ❌ Use routerPath\n  // Implementation\n})\n```\n\n## Guard Application Pattern\n\n### Guards Usage\n```typescript\n// CORRECT - Apply guards to protected routes\nexport class ProtectedRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .get(this.routerPath('protectedAction'), ...guards, async (req, res) => {\n        // Protected action\n      })\n      .post(this.routerPath('anotherAction'), ...guards, async (req, res) => {\n        // Another protected action\n      });\n  }\n}\n\n// CORRECT - No guards for public routes\nexport class PublicRouter extends RouterBroker {\n  constructor() {\n    super();\n    this.router\n      .get('/health', async (req, res) => {\n        res.status(HttpStatus.OK).json({ status: 'healthy' });\n      })\n      .get('/version', async (req, res) => {\n        res.status(HttpStatus.OK).json({ version: packageJson.version });\n      });\n  }\n}\n```\n\n## Static File Serving Pattern\n\n### Static Assets Route\n```typescript\n// CORRECT - Secure static file serving\nrouter.get('/assets/*', (req, res) => {\n  const fileName = req.params[0];\n  \n  // Security: Reject paths containing traversal patterns\n  if (!fileName || fileName.includes('..') || fileName.includes('\\\\') || path.isAbsolute(fileName)) {\n    return res.status(403).send('Forbidden');\n  }\n  \n  const basePath = path.join(process.cwd(), 'manager', 'dist');\n  const assetsPath = path.join(basePath, 'assets');\n  const filePath = path.join(assetsPath, fileName);\n  \n  // Security: Ensure the resolved path is within the assets directory\n  const resolvedPath = path.resolve(filePath);\n  const resolvedAssetsPath = path.resolve(assetsPath);\n  \n  if (!resolvedPath.startsWith(resolvedAssetsPath + path.sep) && resolvedPath !== resolvedAssetsPath) {\n    return res.status(403).send('Forbidden');\n  }\n\n  if (fs.existsSync(resolvedPath)) {\n    res.set('Content-Type', mimeTypes.lookup(resolvedPath) || 'text/css');\n    res.send(fs.readFileSync(resolvedPath));\n  } else {\n    res.status(404).send('File not found');\n  }\n});\n```\n\n## Special Route Patterns\n\n### Manager Route Pattern\n```typescript\nexport class ViewsRouter extends RouterBroker {\n  public readonly router: Router;\n\n  constructor() {\n    super();\n    this.router = Router();\n\n    const basePath = path.join(process.cwd(), 'manager', 'dist');\n    const indexPath = path.join(basePath, 'index.html');\n\n    this.router.use(express.static(basePath));\n\n    this.router.get('*', (req, res) => {\n      res.sendFile(indexPath);\n    });\n  }\n}\n```\n\n### Webhook Route Pattern\n```typescript\n// CORRECT - Webhook without guards\n.post('/webhook/evolution', async (req, res) => {\n  const response = await evolutionController.receiveWebhook(req.body);\n  return res.status(HttpStatus.OK).json(response);\n})\n\n// CORRECT - Webhook with signature validation\n.post('/webhook/meta', validateWebhookSignature, async (req, res) => {\n  const response = await metaController.receiveWebhook(req.body);\n  return res.status(HttpStatus.OK).json(response);\n})\n```\n\n## Response Pattern\n\n### Standard Response Format\n```typescript\n// CORRECT - Standard success response\nreturn res.status(HttpStatus.OK).json(response);\n\n// CORRECT - Created response\nreturn res.status(HttpStatus.CREATED).json(response);\n\n// CORRECT - Custom response with additional data\nreturn res.status(HttpStatus.OK).json({\n  ...response,\n  timestamp: new Date().toISOString(),\n  instanceName: req.params.instanceName,\n});\n```\n\n## Route Organization\n\n### File Structure\n```\nsrc/api/routes/\n├── index.router.ts          # Main router with all route registrations\n├── instance.router.ts       # Instance management routes\n├── sendMessage.router.ts    # Message sending routes\n├── chat.router.ts          # Chat operations routes\n├── business.router.ts      # Business API routes\n├── group.router.ts         # Group management routes\n├── label.router.ts         # Label management routes\n├── proxy.router.ts         # Proxy configuration routes\n├── settings.router.ts      # Instance settings routes\n├── template.router.ts      # Template management routes\n├── call.router.ts          # Call operations routes\n└── view.router.ts          # Frontend views routes\n```\n\n## Route Testing Pattern\n\n### Router Testing\n```typescript\ndescribe('ExampleRouter', () => {\n  let app: express.Application;\n  let router: ExampleRouter;\n\n  beforeEach(() => {\n    app = express();\n    router = new ExampleRouter();\n    app.use('/api', router.router);\n    app.use(express.json());\n  });\n\n  describe('GET /findExample', () => {\n    it('should return example data', async () => {\n      const response = await request(app)\n        .get('/api/findExample/test-instance')\n        .set('apikey', 'test-key')\n        .expect(200);\n\n      expect(response.body).toBeDefined();\n      expect(response.body.instanceName).toBe('test-instance');\n    });\n\n    it('should return 401 without API key', async () => {\n      await request(app)\n        .get('/api/findExample/test-instance')\n        .expect(401);\n    });\n  });\n\n  describe('POST /createExample', () => {\n    it('should create example successfully', async () => {\n      const data = {\n        name: 'Test Example',\n        description: 'Test Description',\n      };\n\n      const response = await request(app)\n        .post('/api/createExample/test-instance')\n        .set('apikey', 'test-key')\n        .send(data)\n        .expect(201);\n\n      expect(response.body.name).toBe(data.name);\n    });\n\n    it('should validate required fields', async () => {\n      const data = {\n        description: 'Test Description',\n        // Missing required 'name' field\n      };\n\n      await request(app)\n        .post('/api/createExample/test-instance')\n        .set('apikey', 'test-key')\n        .send(data)\n        .expect(400);\n    });\n  });\n});\n```\n\n## Route Documentation\n\n### JSDoc for Routes\n```typescript\n/**\n * @route GET /api/template/findTemplate/:instanceName\n * @description Find template for instance\n * @param {string} instanceName - Instance name\n * @returns {TemplateDto} Template data\n * @throws {404} Template not found\n * @throws {401} Unauthorized\n */\n.get(this.routerPath('findTemplate'), ...guards, async (req, res) => {\n  // Implementation\n})\n\n/**\n * @route POST /api/template/createTemplate/:instanceName\n * @description Create new template\n * @param {string} instanceName - Instance name\n * @body {TemplateDto} Template data\n * @returns {TemplateDto} Created template\n * @throws {400} Validation error\n * @throws {401} Unauthorized\n */\n.post(this.routerPath('createTemplate'), ...guards, async (req, res) => {\n  // Implementation\n})\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/service-rules.mdc",
    "content": "---\ndescription: Service layer patterns for Evolution API\nglobs:\n  - \"src/api/services/**/*.ts\"\n  - \"src/api/integrations/**/services/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Service Rules\n\n## Service Structure Pattern\n\n### Standard Service Class\n```typescript\nexport class ExampleService {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  private readonly logger = new Logger('ExampleService');\n\n  public async create(instance: InstanceDto, data: ExampleDto) {\n    await this.waMonitor.waInstances[instance.instanceName].setData(data);\n    return { example: { ...instance, data } };\n  }\n\n  public async find(instance: InstanceDto): Promise<ExampleDto> {\n    try {\n      const result = await this.waMonitor.waInstances[instance.instanceName].findData();\n\n      if (Object.keys(result).length === 0) {\n        throw new Error('Data not found');\n      }\n\n      return result;\n    } catch (error) {\n      return null; // Evolution pattern - return null on error\n    }\n  }\n}\n```\n\n## Dependency Injection Pattern\n\n### Constructor Pattern\n```typescript\n// CORRECT - Evolution API pattern\nconstructor(\n  private readonly waMonitor: WAMonitoringService,\n  private readonly prismaRepository: PrismaRepository,\n  private readonly configService: ConfigService,\n) {}\n\n// INCORRECT - Don't use\nconstructor(waMonitor, prismaRepository, configService) {} // ❌ No types\n```\n\n## Logger Pattern\n\n### Standard Logger Usage\n```typescript\n// CORRECT - Evolution API pattern\nprivate readonly logger = new Logger('ServiceName');\n\n// Usage\nthis.logger.log('Operation started');\nthis.logger.error('Operation failed', error);\n\n// INCORRECT\nconsole.log('Operation started'); // ❌ Use Logger\n```\n\n## WAMonitor Integration Pattern\n\n### Instance Access Pattern\n```typescript\n// CORRECT - Standard pattern\npublic async operation(instance: InstanceDto, data: DataDto) {\n  await this.waMonitor.waInstances[instance.instanceName].performAction(data);\n  return { result: { ...instance, data } };\n}\n\n// Instance validation\nconst waInstance = this.waMonitor.waInstances[instance.instanceName];\nif (!waInstance) {\n  throw new NotFoundException('Instance not found');\n}\n```\n\n## Error Handling Pattern\n\n### Try-Catch Pattern\n```typescript\n// CORRECT - Evolution API pattern\npublic async find(instance: InstanceDto): Promise<DataDto> {\n  try {\n    const result = await this.waMonitor.waInstances[instance.instanceName].findData();\n    \n    if (Object.keys(result).length === 0) {\n      throw new Error('Data not found');\n    }\n\n    return result;\n  } catch (error) {\n    this.logger.error('Find operation failed', error);\n    return null; // Return null on error (Evolution pattern)\n  }\n}\n```\n\n## Cache Integration Pattern\n\n### Cache Service Usage\n```typescript\nexport class CacheAwareService {\n  constructor(\n    private readonly cache: CacheService,\n    private readonly chatwootCache: CacheService,\n    private readonly baileysCache: CacheService,\n  ) {}\n\n  public async getCachedData(key: string): Promise<any> {\n    const cached = await this.cache.get(key);\n    if (cached) return cached;\n\n    const data = await this.fetchFromSource(key);\n    await this.cache.set(key, data, 300); // 5 min TTL\n    return data;\n  }\n}\n```\n\n## Integration Service Patterns\n\n### Chatbot Service Base Pattern\n```typescript\nexport class ChatbotService extends BaseChatbotService<BotType, SettingsType> {\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n  ) {\n    super(waMonitor, prismaRepository, 'ChatbotService', configService);\n  }\n\n  protected async processBot(\n    waInstance: any,\n    remoteJid: string,\n    bot: BotType,\n    session: any,\n    settings: any,\n    content: string,\n  ): Promise<void> {\n    // Implementation\n  }\n}\n```\n\n### Channel Service Pattern\n```typescript\nexport class ChannelService extends ChannelStartupService {\n  constructor(\n    configService: ConfigService,\n    eventEmitter: EventEmitter2,\n    prismaRepository: PrismaRepository,\n    cache: CacheService,\n    chatwootCache: CacheService,\n    baileysCache: CacheService,\n  ) {\n    super(configService, eventEmitter, prismaRepository, cache, chatwootCache, baileysCache);\n  }\n\n  public readonly logger = new Logger('ChannelService');\n  public client: WASocket;\n  public readonly instance: wa.Instance = {};\n}\n```\n\n## Service Initialization Pattern\n\n### Service Registration\n```typescript\n// In server.module.ts pattern\nexport const templateService = new TemplateService(\n  waMonitor,\n  prismaRepository,\n  configService,\n);\n\nexport const settingsService = new SettingsService(waMonitor);\n```\n\n## Async Operation Patterns\n\n### Promise Handling\n```typescript\n// CORRECT - Evolution API pattern\npublic async sendMessage(instance: InstanceDto, data: MessageDto) {\n  const waInstance = this.waMonitor.waInstances[instance.instanceName];\n  return await waInstance.sendMessage(data);\n}\n\n// INCORRECT - Don't use .then()\npublic sendMessage(instance: InstanceDto, data: MessageDto) {\n  return this.waMonitor.waInstances[instance.instanceName]\n    .sendMessage(data)\n    .then(result => result); // ❌ Use async/await\n}\n```\n\n## Configuration Access Pattern\n\n### Config Service Usage\n```typescript\n// CORRECT - Evolution API pattern\nconst serverConfig = this.configService.get<HttpServer>('SERVER');\nconst authConfig = this.configService.get<Auth>('AUTHENTICATION');\nconst dbConfig = this.configService.get<Database>('DATABASE');\n\n// Type-safe configuration access\nif (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n  // Chatwoot logic\n}\n```\n\n## Event Emission Pattern\n\n### EventEmitter2 Usage\n```typescript\n// CORRECT - Evolution API pattern\nthis.eventEmitter.emit(Events.INSTANCE_CREATE, {\n  instanceName: instance.name,\n  status: 'created',\n});\n\n// Chatwoot event pattern\nif (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n  this.chatwootService.eventWhatsapp(\n    Events.STATUS_INSTANCE,\n    { instanceName: this.instance.name },\n    {\n      instance: this.instance.name,\n      status: 'created',\n    },\n  );\n}\n```\n\n## Service Method Naming\n\n### Standard Method Names\n- `create()` - Create new resource\n- `find()` - Find single resource\n- `findAll()` - Find multiple resources\n- `update()` - Update resource\n- `delete()` - Delete resource\n- `fetch*()` - Fetch from external API\n- `send*()` - Send data/messages\n- `process*()` - Process data\n\n## Service Testing Pattern\n\n### Unit Test Structure\n```typescript\ndescribe('ExampleService', () => {\n  let service: ExampleService;\n  let waMonitor: jest.Mocked<WAMonitoringService>;\n  let prismaRepository: jest.Mocked<PrismaRepository>;\n\n  beforeEach(() => {\n    const mockWaMonitor = {\n      waInstances: {\n        'test-instance': {\n          performAction: jest.fn(),\n        },\n      },\n    };\n\n    service = new ExampleService(\n      mockWaMonitor as any,\n      prismaRepository,\n      configService,\n    );\n  });\n\n  it('should perform action successfully', async () => {\n    const instance = { instanceName: 'test-instance' };\n    const data = { test: 'data' };\n\n    const result = await service.create(instance, data);\n\n    expect(result).toBeDefined();\n    expect(waMonitor.waInstances['test-instance'].performAction).toHaveBeenCalledWith(data);\n  });\n});\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/type-rules.mdc",
    "content": "---\ndescription: Type definitions and interfaces for Evolution API\nglobs:\n  - \"src/api/types/**/*.ts\"\n  - \"src/@types/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Type Rules\n\n## Namespace Pattern\n\n### WhatsApp Types Namespace\n```typescript\n/* eslint-disable @typescript-eslint/no-namespace */\nimport { JsonValue } from '@prisma/client/runtime/library';\nimport { AuthenticationState, WAConnectionState } from 'baileys';\n\nexport declare namespace wa {\n  export type QrCode = {\n    count?: number;\n    pairingCode?: string;\n    base64?: string;\n    code?: string;\n  };\n\n  export type Instance = {\n    id?: string;\n    qrcode?: QrCode;\n    pairingCode?: string;\n    authState?: { state: AuthenticationState; saveCreds: () => void };\n    name?: string;\n    wuid?: string;\n    profileName?: string;\n    profilePictureUrl?: string;\n    token?: string;\n    number?: string;\n    integration?: string;\n    businessId?: string;\n  };\n\n  export type LocalChatwoot = {\n    enabled?: boolean;\n    accountId?: string;\n    token?: string;\n    url?: string;\n    nameInbox?: string;\n    mergeBrazilContacts?: boolean;\n    importContacts?: boolean;\n    importMessages?: boolean;\n    daysLimitImportMessages?: number;\n    organization?: string;\n    logo?: string;\n  };\n\n  export type LocalProxy = {\n    enabled?: boolean;\n    host?: string;\n    port?: string;\n    protocol?: string;\n    username?: string;\n    password?: string;\n  };\n\n  export type LocalSettings = {\n    rejectCall?: boolean;\n    msgCall?: string;\n    groupsIgnore?: boolean;\n    alwaysOnline?: boolean;\n    readMessages?: boolean;\n    readStatus?: boolean;\n    syncFullHistory?: boolean;\n  };\n\n  export type LocalWebHook = {\n    enabled?: boolean;\n    url?: string;\n    events?: string[];\n    headers?: JsonValue;\n    byEvents?: boolean;\n    base64?: boolean;\n  };\n\n  export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED';\n}\n```\n\n## Enum Definitions\n\n### Events Enum\n```typescript\nexport enum Events {\n  APPLICATION_STARTUP = 'application.startup',\n  INSTANCE_CREATE = 'instance.create',\n  INSTANCE_DELETE = 'instance.delete',\n  QRCODE_UPDATED = 'qrcode.updated',\n  CONNECTION_UPDATE = 'connection.update',\n  STATUS_INSTANCE = 'status.instance',\n  MESSAGES_SET = 'messages.set',\n  MESSAGES_UPSERT = 'messages.upsert',\n  MESSAGES_EDITED = 'messages.edited',\n  MESSAGES_UPDATE = 'messages.update',\n  MESSAGES_DELETE = 'messages.delete',\n  SEND_MESSAGE = 'send.message',\n  SEND_MESSAGE_UPDATE = 'send.message.update',\n  CONTACTS_SET = 'contacts.set',\n  CONTACTS_UPSERT = 'contacts.upsert',\n  CONTACTS_UPDATE = 'contacts.update',\n  PRESENCE_UPDATE = 'presence.update',\n  CHATS_SET = 'chats.set',\n  CHATS_UPDATE = 'chats.update',\n  CHATS_UPSERT = 'chats.upsert',\n  CHATS_DELETE = 'chats.delete',\n  GROUPS_UPSERT = 'groups.upsert',\n  GROUPS_UPDATE = 'groups.update',\n  GROUP_PARTICIPANTS_UPDATE = 'group-participants.update',\n  CALL = 'call',\n  TYPEBOT_START = 'typebot.start',\n  TYPEBOT_CHANGE_STATUS = 'typebot.change-status',\n  LABELS_EDIT = 'labels.edit',\n  LABELS_ASSOCIATION = 'labels.association',\n  CREDS_UPDATE = 'creds.update',\n  MESSAGING_HISTORY_SET = 'messaging-history.set',\n  REMOVE_INSTANCE = 'remove.instance',\n  LOGOUT_INSTANCE = 'logout.instance',\n}\n```\n\n### Integration Types\n```typescript\nexport const Integration = {\n  WHATSAPP_BUSINESS: 'WHATSAPP-BUSINESS',\n  WHATSAPP_BAILEYS: 'WHATSAPP-BAILEYS',\n  EVOLUTION: 'EVOLUTION',\n} as const;\n\nexport type IntegrationType = typeof Integration[keyof typeof Integration];\n```\n\n## Constant Arrays\n\n### Message Type Constants\n```typescript\nexport const TypeMediaMessage = [\n  'imageMessage',\n  'documentMessage',\n  'audioMessage',\n  'videoMessage',\n  'stickerMessage',\n  'ptvMessage', // Evolution API includes this\n];\n\nexport const MessageSubtype = [\n  'ephemeralMessage',\n  'documentWithCaptionMessage',\n  'viewOnceMessage',\n  'viewOnceMessageV2',\n];\n\nexport type MediaMessageType = typeof TypeMediaMessage[number];\nexport type MessageSubtypeType = typeof MessageSubtype[number];\n```\n\n## Interface Definitions\n\n### Service Interfaces\n```typescript\nexport interface ServiceInterface {\n  create(instance: InstanceDto, data: any): Promise<any>;\n  find(instance: InstanceDto): Promise<any>;\n  update?(instance: InstanceDto, data: any): Promise<any>;\n  delete?(instance: InstanceDto): Promise<any>;\n}\n\nexport interface ChannelServiceInterface extends ServiceInterface {\n  sendMessage(data: SendMessageDto): Promise<any>;\n  connectToWhatsapp(data?: any): Promise<void>;\n  receiveWebhook?(data: any): Promise<void>;\n}\n\nexport interface ChatbotServiceInterface extends ServiceInterface {\n  processMessage(\n    instanceName: string,\n    remoteJid: string,\n    message: any,\n    pushName?: string,\n  ): Promise<void>;\n}\n```\n\n## Configuration Types\n\n### Environment Configuration Types\n```typescript\nexport interface DatabaseConfig {\n  CONNECTION: {\n    URI: string;\n    DB_PREFIX_NAME: string;\n    CLIENT_NAME?: string;\n  };\n  ENABLED: boolean;\n  SAVE_DATA: {\n    INSTANCE: boolean;\n    NEW_MESSAGE: boolean;\n    MESSAGE_UPDATE: boolean;\n    CONTACTS: boolean;\n    CHATS: boolean;\n  };\n}\n\nexport interface AuthConfig {\n  TYPE: 'apikey' | 'jwt';\n  API_KEY: {\n    KEY: string;\n  };\n  JWT?: {\n    EXPIRIN_IN: number;\n    SECRET: string;\n  };\n}\n\nexport interface CacheConfig {\n  REDIS: {\n    ENABLED: boolean;\n    URI: string;\n    PREFIX_KEY: string;\n    SAVE_INSTANCES: boolean;\n  };\n  LOCAL: {\n    ENABLED: boolean;\n    TTL: number;\n  };\n}\n```\n\n## Message Types\n\n### Message Structure Types\n```typescript\nexport interface MessageContent {\n  text?: string;\n  caption?: string;\n  media?: Buffer | string;\n  mediatype?: 'image' | 'video' | 'audio' | 'document' | 'sticker';\n  fileName?: string;\n  mimetype?: string;\n}\n\nexport interface MessageOptions {\n  delay?: number;\n  presence?: 'unavailable' | 'available' | 'composing' | 'recording' | 'paused';\n  linkPreview?: boolean;\n  mentionsEveryOne?: boolean;\n  mentioned?: string[];\n  quoted?: {\n    key: {\n      remoteJid: string;\n      fromMe: boolean;\n      id: string;\n    };\n    message: any;\n  };\n}\n\nexport interface SendMessageRequest {\n  number: string;\n  content: MessageContent;\n  options?: MessageOptions;\n}\n```\n\n## Webhook Types\n\n### Webhook Payload Types\n```typescript\nexport interface WebhookPayload {\n  event: Events;\n  instance: string;\n  data: any;\n  timestamp: string;\n  server?: {\n    version: string;\n    host: string;\n  };\n}\n\nexport interface WebhookConfig {\n  enabled: boolean;\n  url: string;\n  events: Events[];\n  headers?: Record<string, string>;\n  byEvents?: boolean;\n  base64?: boolean;\n}\n```\n\n## Error Types\n\n### Custom Error Types\n```typescript\nexport interface ApiError {\n  status: number;\n  message: string;\n  error?: string;\n  details?: any;\n  timestamp: string;\n  path: string;\n}\n\nexport interface ValidationError extends ApiError {\n  status: 400;\n  validationErrors: Array<{\n    field: string;\n    message: string;\n    value?: any;\n  }>;\n}\n\nexport interface AuthenticationError extends ApiError {\n  status: 401;\n  message: 'Unauthorized' | 'Invalid API Key' | 'Token Expired';\n}\n```\n\n## Utility Types\n\n### Generic Utility Types\n```typescript\nexport type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nexport type RequiredFields<T, K extends keyof T> = T & Required<Pick<T, K>>;\n\nexport type DeepPartial<T> = {\n  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\nexport type NonEmptyArray<T> = [T, ...T[]];\n\nexport type StringKeys<T> = {\n  [K in keyof T]: T[K] extends string ? K : never;\n}[keyof T];\n```\n\n## Response Types\n\n### API Response Types\n```typescript\nexport interface ApiResponse<T = any> {\n  success: boolean;\n  data?: T;\n  message?: string;\n  error?: string;\n  timestamp: string;\n}\n\nexport interface PaginatedResponse<T> extends ApiResponse<T[]> {\n  pagination: {\n    page: number;\n    limit: number;\n    total: number;\n    totalPages: number;\n    hasNext: boolean;\n    hasPrev: boolean;\n  };\n}\n\nexport interface InstanceResponse extends ApiResponse {\n  instance: {\n    instanceName: string;\n    status: 'connecting' | 'open' | 'close' | 'qr';\n    qrcode?: string;\n    profileName?: string;\n    profilePicUrl?: string;\n  };\n}\n```\n\n## Integration-Specific Types\n\n### Baileys Types Extension\n```typescript\nimport { WASocket, ConnectionState, DisconnectReason } from 'baileys';\n\nexport interface BaileysInstance {\n  client: WASocket;\n  state: ConnectionState;\n  qrRetry: number;\n  authPath: string;\n}\n\nexport interface BaileysConfig {\n  qrTimeout: number;\n  maxQrRetries: number;\n  authTimeout: number;\n  reconnectInterval: number;\n}\n```\n\n### Business API Types\n```typescript\nexport interface BusinessApiConfig {\n  version: string;\n  baseUrl: string;\n  timeout: number;\n  retries: number;\n}\n\nexport interface BusinessApiMessage {\n  messaging_product: 'whatsapp';\n  to: string;\n  type: 'text' | 'image' | 'document' | 'audio' | 'video' | 'template';\n  text?: {\n    body: string;\n    preview_url?: boolean;\n  };\n  image?: {\n    link?: string;\n    id?: string;\n    caption?: string;\n  };\n  template?: {\n    name: string;\n    language: {\n      code: string;\n    };\n    components?: any[];\n  };\n}\n```\n\n## Type Guards\n\n### Type Guard Functions\n```typescript\nexport function isMediaMessage(message: any): message is MediaMessage {\n  return message && TypeMediaMessage.some(type => message[type]);\n}\n\nexport function isTextMessage(message: any): message is TextMessage {\n  return message && message.conversation;\n}\n\nexport function isValidIntegration(integration: string): integration is IntegrationType {\n  return Object.values(Integration).includes(integration as IntegrationType);\n}\n\nexport function isValidEvent(event: string): event is Events {\n  return Object.values(Events).includes(event as Events);\n}\n```\n\n## Module Augmentation\n\n### Express Request Extension\n```typescript\ndeclare global {\n  namespace Express {\n    interface Request {\n      instanceName?: string;\n      instanceData?: InstanceDto;\n      user?: {\n        id: string;\n        apiKey: string;\n      };\n    }\n  }\n}\n```\n\n## Type Documentation\n\n### JSDoc Type Documentation\n```typescript\n/**\n * WhatsApp instance configuration\n * @interface InstanceConfig\n * @property {string} name - Unique instance name\n * @property {IntegrationType} integration - Integration type\n * @property {string} [token] - API token for business integrations\n * @property {WebhookConfig} [webhook] - Webhook configuration\n * @property {ProxyConfig} [proxy] - Proxy configuration\n */\nexport interface InstanceConfig {\n  name: string;\n  integration: IntegrationType;\n  token?: string;\n  webhook?: WebhookConfig;\n  proxy?: ProxyConfig;\n}\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/util-rules.mdc",
    "content": "---\ndescription: Utility functions and helpers for Evolution API\nglobs:\n  - \"src/utils/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Utility Rules\n\n## Utility Function Structure\n\n### Standard Utility Pattern\n```typescript\nimport { Logger } from '@config/logger.config';\n\nconst logger = new Logger('UtilityName');\n\nexport function utilityFunction(param: ParamType): ReturnType {\n  try {\n    // Utility logic\n    return result;\n  } catch (error) {\n    logger.error(`Utility function failed: ${error.message}`);\n    throw error;\n  }\n}\n\nexport default utilityFunction;\n```\n\n## Authentication Utilities\n\n### Multi-File Auth State Pattern\n```typescript\nimport { AuthenticationState } from 'baileys';\nimport { CacheService } from '@api/services/cache.service';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nexport default async function useMultiFileAuthStatePrisma(\n  sessionId: string,\n  cache: CacheService,\n): Promise<{\n  state: AuthenticationState;\n  saveCreds: () => Promise<void>;\n}> {\n  const localFolder = path.join(INSTANCE_DIR, sessionId);\n  const localFile = (key: string) => path.join(localFolder, fixFileName(key) + '.json');\n  await fs.mkdir(localFolder, { recursive: true });\n\n  async function writeData(data: any, key: string): Promise<any> {\n    const dataString = JSON.stringify(data, BufferJSON.replacer);\n\n    if (key !== 'creds') {\n      if (process.env.CACHE_REDIS_ENABLED === 'true') {\n        return await cache.hSet(sessionId, key, data);\n      } else {\n        await fs.writeFile(localFile(key), dataString);\n        return;\n      }\n    }\n    await saveKey(sessionId, dataString);\n    return;\n  }\n\n  async function readData(key: string): Promise<any> {\n    try {\n      let rawData;\n\n      if (key !== 'creds') {\n        if (process.env.CACHE_REDIS_ENABLED === 'true') {\n          return await cache.hGet(sessionId, key);\n        } else {\n          if (!(await fileExists(localFile(key)))) return null;\n          rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' });\n          return JSON.parse(rawData, BufferJSON.reviver);\n        }\n      } else {\n        rawData = await getAuthKey(sessionId);\n      }\n\n      const parsedData = JSON.parse(rawData, BufferJSON.reviver);\n      return parsedData;\n    } catch (error) {\n      return null;\n    }\n  }\n\n  async function removeData(key: string): Promise<any> {\n    try {\n      if (key !== 'creds') {\n        if (process.env.CACHE_REDIS_ENABLED === 'true') {\n          return await cache.hDelete(sessionId, key);\n        } else {\n          await fs.unlink(localFile(key));\n        }\n      } else {\n        await deleteAuthKey(sessionId);\n      }\n    } catch (error) {\n      return;\n    }\n  }\n\n  let creds = await readData('creds');\n  if (!creds) {\n    creds = initAuthCreds();\n    await writeData(creds, 'creds');\n  }\n\n  return {\n    state: {\n      creds,\n      keys: {\n        get: async (type, ids) => {\n          const data = {};\n          await Promise.all(\n            ids.map(async (id) => {\n              let value = await readData(`${type}-${id}`);\n              if (type === 'app-state-sync-key' && value) {\n                value = proto.Message.AppStateSyncKeyData.fromObject(value);\n              }\n              data[id] = value;\n            })\n          );\n          return data;\n        },\n        set: async (data) => {\n          const tasks = [];\n          for (const category in data) {\n            for (const id in data[category]) {\n              const value = data[category][id];\n              const key = `${category}-${id}`;\n              tasks.push(value ? writeData(value, key) : removeData(key));\n            }\n          }\n          await Promise.all(tasks);\n        },\n      },\n    },\n    saveCreds: () => writeData(creds, 'creds'),\n  };\n}\n```\n\n## Message Processing Utilities\n\n### Message Content Extraction\n```typescript\nexport const getConversationMessage = (msg: any): string => {\n  const types = getTypeMessage(msg);\n  const messageContent = getMessageContent(types);\n  return messageContent;\n};\n\nconst getTypeMessage = (msg: any): any => {\n  return Object.keys(msg?.message || msg || {})[0];\n};\n\nconst getMessageContent = (type: string, msg?: any): string => {\n  const typeKey = type?.replace('Message', '');\n  \n  const types = {\n    conversation: msg?.message?.conversation,\n    extendedTextMessage: msg?.message?.extendedTextMessage?.text,\n    imageMessage: msg?.message?.imageMessage?.caption || 'Image',\n    videoMessage: msg?.message?.videoMessage?.caption || 'Video',\n    audioMessage: 'Audio',\n    documentMessage: msg?.message?.documentMessage?.caption || 'Document',\n    stickerMessage: 'Sticker',\n    contactMessage: 'Contact',\n    locationMessage: 'Location',\n    liveLocationMessage: 'Live Location',\n    viewOnceMessage: 'View Once',\n    reactionMessage: 'Reaction',\n    pollCreationMessage: 'Poll',\n    pollUpdateMessage: 'Poll Update',\n  };\n\n  let result = types[typeKey] || types[type] || 'Unknown';\n  \n  if (!result || result === 'Unknown') {\n    result = JSON.stringify(msg);\n  }\n\n  return result;\n};\n```\n\n### JID Creation Utility\n```typescript\nexport const createJid = (number: string): string => {\n  if (number.includes('@')) {\n    return number;\n  }\n\n  // Remove any non-numeric characters except +\n  let cleanNumber = number.replace(/[^\\d+]/g, '');\n  \n  // Remove + if present\n  if (cleanNumber.startsWith('+')) {\n    cleanNumber = cleanNumber.substring(1);\n  }\n\n  // Add country code if missing (assuming Brazil as default)\n  if (cleanNumber.length === 11 && cleanNumber.startsWith('11')) {\n    cleanNumber = '55' + cleanNumber;\n  } else if (cleanNumber.length === 10) {\n    cleanNumber = '5511' + cleanNumber;\n  }\n\n  // Determine if it's a group or individual\n  const isGroup = cleanNumber.includes('-');\n  const domain = isGroup ? 'g.us' : 's.whatsapp.net';\n\n  return `${cleanNumber}@${domain}`;\n};\n```\n\n## Cache Utilities\n\n### WhatsApp Number Cache\n```typescript\ninterface ISaveOnWhatsappCacheParams {\n  remoteJid: string;\n  lid?: string;\n}\n\nfunction getAvailableNumbers(remoteJid: string): string[] {\n  const numbersAvailable: string[] = [];\n\n  if (remoteJid.startsWith('+')) {\n    remoteJid = remoteJid.slice(1);\n  }\n\n  const [number, domain] = remoteJid.split('@');\n\n  // Brazilian numbers\n  if (remoteJid.startsWith('55')) {\n    const numberWithDigit =\n      number.slice(4, 5) === '9' && number.length === 13 ? number : `${number.slice(0, 4)}9${number.slice(4)}`;\n    const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 4) + number.slice(5);\n\n    numbersAvailable.push(numberWithDigit);\n    numbersAvailable.push(numberWithoutDigit);\n  }\n  // Mexican/Argentina numbers\n  else if (number.startsWith('52') || number.startsWith('54')) {\n    let prefix = '';\n    if (number.startsWith('52')) {\n      prefix = '1';\n    }\n    if (number.startsWith('54')) {\n      prefix = '9';\n    }\n\n    const numberWithDigit =\n      number.slice(2, 3) === prefix && number.length === 13\n        ? number\n        : `${number.slice(0, 2)}${prefix}${number.slice(2)}`;\n    const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 2) + number.slice(3);\n\n    numbersAvailable.push(numberWithDigit);\n    numbersAvailable.push(numberWithoutDigit);\n  }\n  // Other countries\n  else {\n    numbersAvailable.push(remoteJid);\n  }\n\n  return numbersAvailable.map((number) => `${number}@${domain}`);\n}\n\nexport async function saveOnWhatsappCache(params: ISaveOnWhatsappCacheParams): Promise<void> {\n  const { remoteJid, lid } = params;\n  const db = configService.get<Database>('DATABASE');\n\n  if (!db.SAVE_DATA.CONTACTS) {\n    return;\n  }\n\n  try {\n    const numbersAvailable = getAvailableNumbers(remoteJid);\n    \n    const existingContact = await prismaRepository.contact.findFirst({\n      where: {\n        OR: numbersAvailable.map(number => ({ id: number })),\n      },\n    });\n\n    if (!existingContact) {\n      await prismaRepository.contact.create({\n        data: {\n          id: remoteJid,\n          pushName: '',\n          profilePicUrl: '',\n          isOnWhatsapp: true,\n          lid: lid || null,\n          createdAt: new Date(),\n          updatedAt: new Date(),\n        },\n      });\n    } else {\n      await prismaRepository.contact.update({\n        where: { id: existingContact.id },\n        data: {\n          isOnWhatsapp: true,\n          lid: lid || existingContact.lid,\n          updatedAt: new Date(),\n        },\n      });\n    }\n  } catch (error) {\n    console.error('Error saving WhatsApp cache:', error);\n  }\n}\n```\n\n## Search Utilities\n\n### Advanced Search Operators\n```typescript\nfunction normalizeString(str: string): string {\n  return str\n    .toLowerCase()\n    .normalize('NFD')\n    .replace(/[\\u0300-\\u036f]/g, '');\n}\n\nexport function advancedOperatorsSearch(data: string, query: string): boolean {\n  const normalizedData = normalizeString(data);\n  const normalizedQuery = normalizeString(query);\n\n  // Exact phrase search with quotes\n  if (normalizedQuery.startsWith('\"') && normalizedQuery.endsWith('\"')) {\n    const phrase = normalizedQuery.slice(1, -1);\n    return normalizedData.includes(phrase);\n  }\n\n  // OR operator\n  if (normalizedQuery.includes(' OR ')) {\n    const terms = normalizedQuery.split(' OR ');\n    return terms.some(term => normalizedData.includes(term.trim()));\n  }\n\n  // AND operator (default behavior)\n  if (normalizedQuery.includes(' AND ')) {\n    const terms = normalizedQuery.split(' AND ');\n    return terms.every(term => normalizedData.includes(term.trim()));\n  }\n\n  // NOT operator\n  if (normalizedQuery.startsWith('NOT ')) {\n    const term = normalizedQuery.slice(4);\n    return !normalizedData.includes(term);\n  }\n\n  // Wildcard search\n  if (normalizedQuery.includes('*')) {\n    const regex = new RegExp(normalizedQuery.replace(/\\*/g, '.*'), 'i');\n    return regex.test(normalizedData);\n  }\n\n  // Default: simple contains search\n  return normalizedData.includes(normalizedQuery);\n}\n```\n\n## Proxy Utilities\n\n### Proxy Agent Creation\n```typescript\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { SocksProxyAgent } from 'socks-proxy-agent';\n\ntype Proxy = {\n  host: string;\n  port: string;\n  protocol: 'http' | 'https' | 'socks4' | 'socks5';\n  username?: string;\n  password?: string;\n};\n\nfunction selectProxyAgent(proxyUrl: string): HttpsProxyAgent<string> | SocksProxyAgent {\n  const url = new URL(proxyUrl);\n  \n  if (url.protocol === 'socks4:' || url.protocol === 'socks5:') {\n    return new SocksProxyAgent(proxyUrl);\n  } else {\n    return new HttpsProxyAgent(proxyUrl);\n  }\n}\n\nexport function makeProxyAgent(proxy: Proxy): HttpsProxyAgent<string> | SocksProxyAgent | null {\n  if (!proxy.host || !proxy.port) {\n    return null;\n  }\n\n  let proxyUrl = `${proxy.protocol}://`;\n  \n  if (proxy.username && proxy.password) {\n    proxyUrl += `${proxy.username}:${proxy.password}@`;\n  }\n  \n  proxyUrl += `${proxy.host}:${proxy.port}`;\n\n  try {\n    return selectProxyAgent(proxyUrl);\n  } catch (error) {\n    console.error('Failed to create proxy agent:', error);\n    return null;\n  }\n}\n```\n\n## Telemetry Utilities\n\n### Telemetry Data Collection\n```typescript\nexport interface TelemetryData {\n  route: string;\n  apiVersion: string;\n  timestamp: Date;\n  method?: string;\n  statusCode?: number;\n  responseTime?: number;\n  userAgent?: string;\n  instanceName?: string;\n}\n\nexport const sendTelemetry = async (route: string): Promise<void> => {\n  try {\n    const telemetryData: TelemetryData = {\n      route,\n      apiVersion: packageJson.version,\n      timestamp: new Date(),\n    };\n\n    // Only send telemetry if enabled\n    if (process.env.DISABLE_TELEMETRY === 'true') {\n      return;\n    }\n\n    // Send to telemetry service (implement as needed)\n    await axios.post('https://telemetry.evolution-api.com/collect', telemetryData, {\n      timeout: 5000,\n    });\n  } catch (error) {\n    // Silently fail - don't affect main application\n    console.debug('Telemetry failed:', error.message);\n  }\n};\n```\n\n## Internationalization Utilities\n\n### i18n Setup\n```typescript\nimport { ConfigService, Language } from '@config/env.config';\nimport fs from 'fs';\nimport i18next from 'i18next';\nimport path from 'path';\n\nconst __dirname = path.resolve(process.cwd(), 'src', 'utils');\nconst languages = ['en', 'pt-BR', 'es'];\nconst translationsPath = path.join(__dirname, 'translations');\nconst configService: ConfigService = new ConfigService();\n\nconst resources: any = {};\n\nlanguages.forEach((language) => {\n  const languagePath = path.join(translationsPath, `${language}.json`);\n  if (fs.existsSync(languagePath)) {\n    const translationContent = fs.readFileSync(languagePath, 'utf8');\n    resources[language] = {\n      translation: JSON.parse(translationContent),\n    };\n  }\n});\n\ni18next.init({\n  resources,\n  fallbackLng: 'en',\n  lng: configService.get<Language>('LANGUAGE') || 'pt-BR',\n  interpolation: {\n    escapeValue: false,\n  },\n});\n\nexport const t = i18next.t.bind(i18next);\nexport default i18next;\n```\n\n## Bot Trigger Utilities\n\n### Bot Trigger Matching\n```typescript\nimport { TriggerOperator, TriggerType } from '@prisma/client';\n\nexport function findBotByTrigger(\n  bots: any[],\n  content: string,\n  remoteJid: string,\n): any | null {\n  for (const bot of bots) {\n    if (!bot.enabled) continue;\n    \n    // Check ignore list\n    if (bot.ignoreJids && bot.ignoreJids.includes(remoteJid)) {\n      continue;\n    }\n\n    // Check trigger\n    if (matchesTrigger(content, bot.triggerType, bot.triggerOperator, bot.triggerValue)) {\n      return bot;\n    }\n  }\n\n  return null;\n}\n\nfunction matchesTrigger(\n  content: string,\n  triggerType: TriggerType,\n  triggerOperator: TriggerOperator,\n  triggerValue: string,\n): boolean {\n  const normalizedContent = content.toLowerCase().trim();\n  const normalizedValue = triggerValue.toLowerCase().trim();\n\n  switch (triggerType) {\n    case TriggerType.ALL:\n      return true;\n\n    case TriggerType.KEYWORD:\n      return matchesKeyword(normalizedContent, triggerOperator, normalizedValue);\n\n    case TriggerType.REGEX:\n      try {\n        const regex = new RegExp(triggerValue, 'i');\n        return regex.test(content);\n      } catch {\n        return false;\n      }\n\n    default:\n      return false;\n  }\n}\n\nfunction matchesKeyword(\n  content: string,\n  operator: TriggerOperator,\n  value: string,\n): boolean {\n  switch (operator) {\n    case TriggerOperator.EQUALS:\n      return content === value;\n    case TriggerOperator.CONTAINS:\n      return content.includes(value);\n    case TriggerOperator.STARTS_WITH:\n      return content.startsWith(value);\n    case TriggerOperator.ENDS_WITH:\n      return content.endsWith(value);\n    default:\n      return false;\n  }\n}\n```\n\n## Server Utilities\n\n### Server Status Check\n```typescript\nexport class ServerUP {\n  private static instance: ServerUP;\n  private isServerUp: boolean = false;\n\n  private constructor() {}\n\n  public static getInstance(): ServerUP {\n    if (!ServerUP.instance) {\n      ServerUP.instance = new ServerUP();\n    }\n    return ServerUP.instance;\n  }\n\n  public setServerStatus(status: boolean): void {\n    this.isServerUp = status;\n  }\n\n  public getServerStatus(): boolean {\n    return this.isServerUp;\n  }\n\n  public async waitForServer(timeout: number = 30000): Promise<boolean> {\n    const startTime = Date.now();\n    \n    while (!this.isServerUp && (Date.now() - startTime) < timeout) {\n      await new Promise(resolve => setTimeout(resolve, 100));\n    }\n    \n    return this.isServerUp;\n  }\n}\n```\n\n## Error Response Utilities\n\n### Standardized Error Responses\n```typescript\nexport function createMetaErrorResponse(error: any, context: string) {\n  const timestamp = new Date().toISOString();\n  \n  if (error.response?.data) {\n    return {\n      status: error.response.status || 500,\n      error: {\n        message: error.response.data.error?.message || 'External API error',\n        type: error.response.data.error?.type || 'api_error',\n        code: error.response.data.error?.code || 'unknown_error',\n        context,\n        timestamp,\n      },\n    };\n  }\n\n  return {\n    status: 500,\n    error: {\n      message: error.message || 'Internal server error',\n      type: 'internal_error',\n      code: 'server_error',\n      context,\n      timestamp,\n    },\n  };\n}\n\nexport function createValidationErrorResponse(errors: any[], context: string) {\n  return {\n    status: 400,\n    error: {\n      message: 'Validation failed',\n      type: 'validation_error',\n      code: 'invalid_input',\n      context,\n      details: errors,\n      timestamp: new Date().toISOString(),\n    },\n  };\n}\n```"
  },
  {
    "path": ".cursor/rules/specialized-rules/validate-rules.mdc",
    "content": "---\ndescription: Validation schemas and patterns for Evolution API\nglobs:\n  - \"src/validate/**/*.ts\"\nalwaysApply: false\n---\n\n# Evolution API Validation Rules\n\n## Validation Schema Structure\n\n### JSONSchema7 Pattern (Evolution API Standard)\n```typescript\nimport { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...fields: string[]) => {\n  const properties = {};\n  fields.forEach((field) => {\n    properties[field] = {\n      if: { properties: { [field]: { type: 'string' } } },\n      then: { properties: { [field]: { minLength: 1 } } },\n    };\n  });\n\n  return {\n    allOf: Object.values(properties),\n  };\n};\n\nexport const exampleSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    name: { type: 'string' },\n    description: { type: 'string' },\n    enabled: { type: 'boolean' },\n    settings: {\n      type: 'object',\n      properties: {\n        timeout: { type: 'number', minimum: 1000, maximum: 60000 },\n        retries: { type: 'number', minimum: 0, maximum: 5 },\n      },\n    },\n    tags: {\n      type: 'array',\n      items: { type: 'string' },\n    },\n  },\n  required: ['name', 'enabled'],\n  ...isNotEmpty('name'),\n};\n```\n\n## Message Validation Schemas\n\n### Send Message Validation\n```typescript\nconst numberDefinition = {\n  type: 'string',\n  pattern: '^\\\\d+[\\\\.@\\\\w-]+',\n  description: 'Invalid number',\n};\n\nexport const sendTextSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: numberDefinition,\n    text: { type: 'string', minLength: 1, maxLength: 4096 },\n    delay: { type: 'number', minimum: 0, maximum: 60000 },\n    linkPreview: { type: 'boolean' },\n    mentionsEveryOne: { type: 'boolean' },\n    mentioned: {\n      type: 'array',\n      items: { type: 'string' },\n    },\n  },\n  required: ['number', 'text'],\n  ...isNotEmpty('number', 'text'),\n};\n\nexport const sendMediaSchema = Joi.object({\n  number: Joi.string().required().pattern(/^\\d+$/),\n  mediatype: Joi.string().required().valid('image', 'video', 'audio', 'document'),\n  media: Joi.alternatives().try(\n    Joi.string().uri(),\n    Joi.string().base64(),\n  ).required(),\n  caption: Joi.string().optional().max(1024),\n  fileName: Joi.string().optional().max(255),\n  delay: Joi.number().optional().min(0).max(60000),\n}).required();\n\nexport const sendButtonsSchema = Joi.object({\n  number: Joi.string().required().pattern(/^\\d+$/),\n  title: Joi.string().required().max(1024),\n  description: Joi.string().optional().max(1024),\n  footer: Joi.string().optional().max(60),\n  buttons: Joi.array().items(\n    Joi.object({\n      type: Joi.string().required().valid('replyButton', 'urlButton', 'callButton'),\n      displayText: Joi.string().required().max(20),\n      id: Joi.string().when('type', {\n        is: 'replyButton',\n        then: Joi.required().max(256),\n        otherwise: Joi.optional(),\n      }),\n      url: Joi.string().when('type', {\n        is: 'urlButton',\n        then: Joi.required().uri(),\n        otherwise: Joi.optional(),\n      }),\n      phoneNumber: Joi.string().when('type', {\n        is: 'callButton',\n        then: Joi.required().pattern(/^\\+?\\d+$/),\n        otherwise: Joi.optional(),\n      }),\n    })\n  ).min(1).max(3).required(),\n}).required();\n```\n\n## Instance Validation Schemas\n\n### Instance Creation Validation\n```typescript\nexport const instanceSchema = Joi.object({\n  instanceName: Joi.string().required().min(1).max(100).pattern(/^[a-zA-Z0-9_-]+$/),\n  integration: Joi.string().required().valid('WHATSAPP-BAILEYS', 'WHATSAPP-BUSINESS', 'EVOLUTION'),\n  token: Joi.string().when('integration', {\n    is: Joi.valid('WHATSAPP-BUSINESS', 'EVOLUTION'),\n    then: Joi.required().min(10),\n    otherwise: Joi.optional(),\n  }),\n  qrcode: Joi.boolean().optional().default(false),\n  number: Joi.string().optional().pattern(/^\\d+$/),\n  businessId: Joi.string().when('integration', {\n    is: 'WHATSAPP-BUSINESS',\n    then: Joi.required(),\n    otherwise: Joi.optional(),\n  }),\n}).required();\n\nexport const settingsSchema = Joi.object({\n  rejectCall: Joi.boolean().optional(),\n  msgCall: Joi.string().optional().max(500),\n  groupsIgnore: Joi.boolean().optional(),\n  alwaysOnline: Joi.boolean().optional(),\n  readMessages: Joi.boolean().optional(),\n  readStatus: Joi.boolean().optional(),\n  syncFullHistory: Joi.boolean().optional(),\n  wavoipToken: Joi.string().optional(),\n}).optional();\n\nexport const proxySchema = Joi.object({\n  host: Joi.string().required().hostname(),\n  port: Joi.string().required().pattern(/^\\d+$/).custom((value) => {\n    const port = parseInt(value);\n    if (port < 1 || port > 65535) {\n      throw new Error('Port must be between 1 and 65535');\n    }\n    return value;\n  }),\n  protocol: Joi.string().required().valid('http', 'https', 'socks4', 'socks5'),\n  username: Joi.string().optional(),\n  password: Joi.string().optional(),\n}).optional();\n```\n\n## Webhook Validation Schemas\n\n### Webhook Configuration Validation\n```typescript\nexport const webhookSchema = Joi.object({\n  enabled: Joi.boolean().required(),\n  url: Joi.string().when('enabled', {\n    is: true,\n    then: Joi.required().uri({ scheme: ['http', 'https'] }),\n    otherwise: Joi.optional(),\n  }),\n  events: Joi.array().items(\n    Joi.string().valid(\n      'APPLICATION_STARTUP',\n      'INSTANCE_CREATE',\n      'INSTANCE_DELETE',\n      'QRCODE_UPDATED',\n      'CONNECTION_UPDATE',\n      'STATUS_INSTANCE',\n      'MESSAGES_SET',\n      'MESSAGES_UPSERT',\n      'MESSAGES_UPDATE',\n      'MESSAGES_DELETE',\n      'CONTACTS_SET',\n      'CONTACTS_UPSERT',\n      'CONTACTS_UPDATE',\n      'CHATS_SET',\n      'CHATS_UPDATE',\n      'CHATS_UPSERT',\n      'CHATS_DELETE',\n      'GROUPS_UPSERT',\n      'GROUPS_UPDATE',\n      'GROUP_PARTICIPANTS_UPDATE',\n      'CALL'\n    )\n  ).min(1).when('enabled', {\n    is: true,\n    then: Joi.required(),\n    otherwise: Joi.optional(),\n  }),\n  headers: Joi.object().pattern(\n    Joi.string(),\n    Joi.string()\n  ).optional(),\n  byEvents: Joi.boolean().optional().default(false),\n  base64: Joi.boolean().optional().default(false),\n}).required();\n```\n\n## Chatbot Validation Schemas\n\n### Base Chatbot Validation\n```typescript\nexport const baseChatbotSchema = Joi.object({\n  enabled: Joi.boolean().required(),\n  description: Joi.string().required().min(1).max(500),\n  expire: Joi.number().optional().min(0).max(86400), // 24 hours in seconds\n  keywordFinish: Joi.string().optional().max(100),\n  delayMessage: Joi.number().optional().min(0).max(10000),\n  unknownMessage: Joi.string().optional().max(1000),\n  listeningFromMe: Joi.boolean().optional().default(false),\n  stopBotFromMe: Joi.boolean().optional().default(false),\n  keepOpen: Joi.boolean().optional().default(false),\n  debounceTime: Joi.number().optional().min(0).max(60000),\n  triggerType: Joi.string().required().valid('ALL', 'KEYWORD', 'REGEX'),\n  triggerOperator: Joi.string().when('triggerType', {\n    is: 'KEYWORD',\n    then: Joi.required().valid('EQUALS', 'CONTAINS', 'STARTS_WITH', 'ENDS_WITH'),\n    otherwise: Joi.optional(),\n  }),\n  triggerValue: Joi.string().when('triggerType', {\n    is: Joi.valid('KEYWORD', 'REGEX'),\n    then: Joi.required().min(1).max(500),\n    otherwise: Joi.optional(),\n  }),\n  ignoreJids: Joi.array().items(Joi.string()).optional(),\n  splitMessages: Joi.boolean().optional().default(false),\n  timePerChar: Joi.number().optional().min(10).max(1000).default(100),\n}).required();\n\nexport const typebotSchema = baseChatbotSchema.keys({\n  url: Joi.string().required().uri({ scheme: ['http', 'https'] }),\n  typebot: Joi.string().required().min(1).max(100),\n  apiVersion: Joi.string().optional().valid('v1', 'v2').default('v1'),\n}).required();\n\nexport const openaiSchema = baseChatbotSchema.keys({\n  apiKey: Joi.string().required().min(10),\n  model: Joi.string().optional().valid(\n    'gpt-3.5-turbo',\n    'gpt-3.5-turbo-16k',\n    'gpt-4',\n    'gpt-4-32k',\n    'gpt-4-turbo-preview'\n  ).default('gpt-3.5-turbo'),\n  systemMessage: Joi.string().optional().max(2000),\n  maxTokens: Joi.number().optional().min(1).max(4000).default(1000),\n  temperature: Joi.number().optional().min(0).max(2).default(0.7),\n}).required();\n```\n\n## Business API Validation Schemas\n\n### Template Validation\n```typescript\nexport const templateSchema = Joi.object({\n  name: Joi.string().required().min(1).max(512).pattern(/^[a-z0-9_]+$/),\n  category: Joi.string().required().valid('MARKETING', 'UTILITY', 'AUTHENTICATION'),\n  allowCategoryChange: Joi.boolean().required(),\n  language: Joi.string().required().pattern(/^[a-z]{2}_[A-Z]{2}$/), // e.g., pt_BR, en_US\n  components: Joi.array().items(\n    Joi.object({\n      type: Joi.string().required().valid('HEADER', 'BODY', 'FOOTER', 'BUTTONS'),\n      format: Joi.string().when('type', {\n        is: 'HEADER',\n        then: Joi.valid('TEXT', 'IMAGE', 'VIDEO', 'DOCUMENT'),\n        otherwise: Joi.optional(),\n      }),\n      text: Joi.string().when('type', {\n        is: Joi.valid('HEADER', 'BODY', 'FOOTER'),\n        then: Joi.required().min(1).max(1024),\n        otherwise: Joi.optional(),\n      }),\n      buttons: Joi.array().when('type', {\n        is: 'BUTTONS',\n        then: Joi.items(\n          Joi.object({\n            type: Joi.string().required().valid('QUICK_REPLY', 'URL', 'PHONE_NUMBER'),\n            text: Joi.string().required().min(1).max(25),\n            url: Joi.string().when('type', {\n              is: 'URL',\n              then: Joi.required().uri(),\n              otherwise: Joi.optional(),\n            }),\n            phone_number: Joi.string().when('type', {\n              is: 'PHONE_NUMBER',\n              then: Joi.required().pattern(/^\\+?\\d+$/),\n              otherwise: Joi.optional(),\n            }),\n          })\n        ).min(1).max(10),\n        otherwise: Joi.optional(),\n      }),\n    })\n  ).min(1).required(),\n  webhookUrl: Joi.string().optional().uri({ scheme: ['http', 'https'] }),\n}).required();\n\nexport const catalogSchema = Joi.object({\n  number: Joi.string().optional().pattern(/^\\d+$/),\n  limit: Joi.number().optional().min(1).max(1000).default(10),\n  cursor: Joi.string().optional(),\n}).optional();\n```\n\n## Group Validation Schemas\n\n### Group Management Validation\n```typescript\nexport const createGroupSchema = Joi.object({\n  subject: Joi.string().required().min(1).max(100),\n  description: Joi.string().optional().max(500),\n  participants: Joi.array().items(\n    Joi.string().pattern(/^\\d+$/)\n  ).min(1).max(256).required(),\n  promoteParticipants: Joi.boolean().optional().default(false),\n}).required();\n\nexport const updateGroupSchema = Joi.object({\n  subject: Joi.string().optional().min(1).max(100),\n  description: Joi.string().optional().max(500),\n}).min(1).required();\n\nexport const groupParticipantsSchema = Joi.object({\n  participants: Joi.array().items(\n    Joi.string().pattern(/^\\d+$/)\n  ).min(1).max(50).required(),\n  action: Joi.string().required().valid('add', 'remove', 'promote', 'demote'),\n}).required();\n```\n\n## Label Validation Schemas\n\n### Label Management Validation\n```typescript\nexport const labelSchema = Joi.object({\n  name: Joi.string().required().min(1).max(100),\n  color: Joi.string().required().pattern(/^#[0-9A-Fa-f]{6}$/), // Hex color\n  predefinedId: Joi.string().optional(),\n}).required();\n\nexport const handleLabelSchema = Joi.object({\n  number: Joi.string().required().pattern(/^\\d+$/),\n  labelId: Joi.string().required(),\n  action: Joi.string().required().valid('add', 'remove'),\n}).required();\n```\n\n## Custom Validation Functions\n\n### Phone Number Validation\n```typescript\nexport function validatePhoneNumber(number: string): boolean {\n  // Remove any non-digit characters\n  const cleaned = number.replace(/\\D/g, '');\n  \n  // Check minimum and maximum length\n  if (cleaned.length < 10 || cleaned.length > 15) {\n    return false;\n  }\n  \n  // Check for valid country codes (basic validation)\n  const validCountryCodes = ['1', '7', '20', '27', '30', '31', '32', '33', '34', '36', '39', '40', '41', '43', '44', '45', '46', '47', '48', '49', '51', '52', '53', '54', '55', '56', '57', '58', '60', '61', '62', '63', '64', '65', '66', '81', '82', '84', '86', '90', '91', '92', '93', '94', '95', '98'];\n  \n  // Check if starts with valid country code\n  const startsWithValidCode = validCountryCodes.some(code => cleaned.startsWith(code));\n  \n  return startsWithValidCode;\n}\n\nexport const phoneNumberValidator = Joi.string().custom((value, helpers) => {\n  if (!validatePhoneNumber(value)) {\n    return helpers.error('any.invalid');\n  }\n  return value;\n}, 'Phone number validation');\n```\n\n### Base64 Validation\n```typescript\nexport function validateBase64(base64: string): boolean {\n  try {\n    // Check if it's a valid base64 string\n    const decoded = Buffer.from(base64, 'base64').toString('base64');\n    return decoded === base64;\n  } catch {\n    return false;\n  }\n}\n\nexport const base64Validator = Joi.string().custom((value, helpers) => {\n  if (!validateBase64(value)) {\n    return helpers.error('any.invalid');\n  }\n  return value;\n}, 'Base64 validation');\n```\n\n### URL Validation with Protocol Check\n```typescript\nexport function validateWebhookUrl(url: string): boolean {\n  try {\n    const parsed = new URL(url);\n    return ['http:', 'https:'].includes(parsed.protocol);\n  } catch {\n    return false;\n  }\n}\n\nexport const webhookUrlValidator = Joi.string().custom((value, helpers) => {\n  if (!validateWebhookUrl(value)) {\n    return helpers.error('any.invalid');\n  }\n  return value;\n}, 'Webhook URL validation');\n```\n\n## Validation Error Handling\n\n### Error Message Customization\n```typescript\nexport const validationMessages = {\n  'any.required': 'O campo {#label} é obrigatório',\n  'string.empty': 'O campo {#label} não pode estar vazio',\n  'string.min': 'O campo {#label} deve ter pelo menos {#limit} caracteres',\n  'string.max': 'O campo {#label} deve ter no máximo {#limit} caracteres',\n  'string.pattern.base': 'O campo {#label} possui formato inválido',\n  'number.min': 'O campo {#label} deve ser maior ou igual a {#limit}',\n  'number.max': 'O campo {#label} deve ser menor ou igual a {#limit}',\n  'array.min': 'O campo {#label} deve ter pelo menos {#limit} itens',\n  'array.max': 'O campo {#label} deve ter no máximo {#limit} itens',\n  'any.only': 'O campo {#label} deve ser um dos valores: {#valids}',\n};\n\nexport function formatValidationError(error: Joi.ValidationError): any {\n  return {\n    message: 'Dados de entrada inválidos',\n    details: error.details.map(detail => ({\n      field: detail.path.join('.'),\n      message: detail.message,\n      value: detail.context?.value,\n    })),\n  };\n}\n```\n\n## Schema Composition\n\n### Reusable Schema Components\n```typescript\nexport const commonFields = {\n  instanceName: Joi.string().required().min(1).max(100).pattern(/^[a-zA-Z0-9_-]+$/),\n  number: phoneNumberValidator.required(),\n  delay: Joi.number().optional().min(0).max(60000),\n  enabled: Joi.boolean().optional().default(true),\n};\n\nexport const mediaFields = {\n  mediatype: Joi.string().required().valid('image', 'video', 'audio', 'document'),\n  media: Joi.alternatives().try(\n    Joi.string().uri(),\n    base64Validator,\n  ).required(),\n  caption: Joi.string().optional().max(1024),\n  fileName: Joi.string().optional().max(255),\n};\n\n// Compose schemas using common fields\nexport const quickMessageSchema = Joi.object({\n  ...commonFields,\n  text: Joi.string().required().min(1).max(4096),\n}).required();\n\nexport const quickMediaSchema = Joi.object({\n  ...commonFields,\n  ...mediaFields,\n}).required();\n```"
  },
  {
    "path": ".dockerignore",
    "content": ".git\n*Dockerfile*\n*docker-compose*\n.env\nnode_modules\ndist"
  },
  {
    "path": ".eslintignore",
    "content": "/node-modules\n/dist"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    project: 'tsconfig.json',\n    tsconfigRootDir: __dirname,\n    sourceType: 'module',\n    warnOnUnsupportedTypeScriptVersion: false,\n    EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true,\n  },\n  plugins: ['@typescript-eslint', 'simple-import-sort', 'import'],\n  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],\n  globals: {\n    Atomics: 'readonly',\n    SharedArrayBuffer: 'readonly',\n  },\n  root: true,\n  env: {\n    node: true,\n    jest: true,\n  },\n  ignorePatterns: ['.eslintrc.js'],\n  rules: {\n    '@typescript-eslint/interface-name-prefix': 'off',\n    '@typescript-eslint/explicit-function-return-type': 'off',\n    '@typescript-eslint/explicit-module-boundary-types': 'off',\n    '@typescript-eslint/no-explicit-any': 'off',\n    '@typescript-eslint/no-empty-function': 'off',\n    '@typescript-eslint/no-non-null-assertion': 'off',\n    '@typescript-eslint/no-unused-vars': 'error',\n    'import/first': 'error',\n    'import/no-duplicates': 'error',\n    'simple-import-sort/imports': 'error',\n    'simple-import-sort/exports': 'error',\n    '@typescript-eslint/no-empty-object-type': 'off',\n    '@typescript-eslint/no-wrapper-object-types': 'off',\n    '@typescript-eslint/no-unused-expressions': 'off',\n    'prettier/prettier': ['error', { endOfLine: 'auto' }],\n  },\n};\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/-en--bug-report.yaml",
    "content": "name: Bug Report\ndescription: Create a report to help us improve.\nlabels:\n  - bug\n  - en\n  # - help wanted\n# Automatically assign the issue to:\n# assignees: DavidsonGomes\nbody:\n  - type: checkboxes\n    id: terms\n    attributes:\n      label: Welcome!\n      description: |\n        The issue tracker is only for reporting bugs and feature requests.\n        For user-related support questions, please visit:\n          - [Discord](https://evolution-api.com/discord)\n          - [WhatsApp Group](https://evolution-api.com/whatsapp)\n          <br/>\n\n        **DO NOT OPEN AN ISSUE FOR GENERAL SUPPORT QUESTIONS.**\n\n      options:\n        - label: Yes, I have searched for similar issues on [GitHub](https://github.com/EvolutionAPI/evolution-api/issues) and found none.\n          required: true\n\n  - type: textarea\n    attributes:\n      label: What did you do?\n      description: |\n        How to write a good bug report?\n\n        - Respect the issue template as much as possible.\n        - The title should be short and descriptive.\n        - Explain the conditions that led you to report this issue: the context.\n        - The context should lead to something, an idea or problem you are facing.\n        - Be clear and concise.\n        - Format your messages to help the reader focus on what matters and understand the structure of your message, use [Markdown syntax](https://help.github.com/articles/github-flavored-markdown)\n      placeholder: Describe the problem you encountered in detail.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: What did you expect?\n      placeholder: Describe what you expected to happen.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: What did you observe instead of what you expected?\n      placeholder: Explain what actually happens when you follow the steps above.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Screenshots/Videos\n      placeholder: |\n        If possible, add screenshots or videos that illustrate the problem. This can be extremely helpful in understanding the issue better.\n\n  - type: textarea\n    attributes:\n      label: Which version of the API are you using?\n      description: |\n        Enter the version number found in the `version` property of the **package.json**.\n      placeholder: Paste the version here.\n    validations:\n      required: true\n\n  - type: dropdown\n    id: select\n    attributes:\n      label: What is your environment?\n      options:\n        - Windows\n        - Linux\n        - Mac\n        - Docker\n        - Other\n    validations:\n      required: true\n  \n  - type: textarea\n    attributes:\n      label: Other environment specifications\n      placeholder: 'Hardware/Software: [e.g., CPU, GPU]'\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: If applicable, paste the log output\n      description: |\n        Please attach any logs that might be related to the issue.\n        If the logs contain sensitive information, consider sending them privately to one of the project maintainers.\n      placeholder: Paste the application log here.\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: Additional Notes\n      description: Include any other information you think might be useful to understand or resolve the bug.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/-en--feature-request.yaml",
    "content": "name: Feature Request\ndescription: Suggest ideas for the project.\nlabels:\n  - enhancement\n  - en\n# Automatically assign the issue to:\n# assignees: DavidsonGomes\nbody:\n  - type: checkboxes\n    id: terms\n    attributes:\n      label: Welcome!\n      description: '**DO NOT OPEN FOR GENERAL SUPPORT QUESTIONS.**'\n\n      options:\n        - label: Yes, I have searched for similar requests on [GitHub](https://github.com/code-chat-br/whatsapp-api/issues) and found none.\n          required: true\n\n  - type: dropdown\n    attributes:\n      label: What type of feature?\n      description: |\n        How to write a good feature request?\n\n        - Respect the issue template as much as possible.\n        - The title should be short and descriptive.\n        - Explain the conditions that led you to suggest this feature: the context.\n        - The context should lead to something, an idea or problem you are facing.\n        - Be clear and concise.\n        - Format your messages to help the reader focus on what matters and understand the structure of your message, use [Markdown syntax](https://help.github.com/articles/github-flavored-markdown)\n      options:\n        - Integration\n        - Functionality\n        - Endpoint\n        - Database adjustment\n        - Other\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: What is the motivation for the request?\n      description: |\n        What problem does the feature seek to solve?\n        Clearly and in detail describe the functionality you want to be implemented.\n        Explain how it fits into the context of the project.\n      placeholder: Detailed description\n    validations:\n      required: true\n  \n  - type: textarea\n    attributes:\n      label: Usage Examples\n      description: |\n        Provide specific examples of how this functionality could be used.\n        This can include scenarios or use cases where the feature would be particularly beneficial.\n      placeholder: text - image - video - flowcharts\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: How should the feature be developed?\n      description: |\n        Should it be inserted directly into the code?\n        Should it be built as a different application that acts as an extension of the API? \n        For example: a `worker`?\n        \n        Discuss how this new functionality could impact other parts of the project, if applicable.\n\n        ---\n\n        If you have ideas on how this functionality could be implemented, please share them here.\n        This is not mandatory, but it can be helpful for the development team.\n\n      placeholder: Insert feature ideas here\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: Additional Notes\n      description: Any other information you believe is relevant to your request.\n      placeholder: Insert your observations here.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/-pt--reportar-bug.yaml",
    "content": "name: Relatório de bug\ndescription: Crie um relatório para nos ajudar a melhorar.\nlabels:\n  - bug\n  - pt-br\n  # - help wanted\n# Atrubuir automaticamente a issue a:\n# assignees: DavidsonGomes\nbody:\n  - type: checkboxes\n    id: termos\n    attributes:\n      label: Bem-vido!\n      description: |\n        O rastreador de problemas é apenas para relatar bugs e solicitações de recursos.\n        Para perguntas de suporte relacionadas ao usuário final, acesse:\n          - [Discord](https://evolution-api.com/discord)\n          - [Grupo do WhatsApp](https://evolution-api.com/whatsapp)\n          <br/>\n\n        **NÃO ABRA UM PROBLEMA PARA PERGUNTAS GERAIS DE SUPORTE.**\n\n      options:\n        - label: Sim, pesquisei problemas semelhantes no [GitHub](https://github.com/EvolutionAPI/evolution-api/issues) e não encontrei nenhum.\n          required: true\n\n  - type: textarea\n    attributes:\n      label: O que você fez?\n      description: |\n        Como escrever um bom relatório de bug?\n\n        - Respeite o modelo de problema tanto quanto possível.\n        - O título deve ser curto e descritivo.\n        - Explique as condições que o levaram a reportar este problema: o contexto.\n        - O contexto deve levar a algo, ideia ou problema que você está enfrentando.\n        - Seja claro e conciso.\n        - Formate suas mensagens para ajudar o leitor a se concentrar no que importa e entender a estrutura da sua mensagem, use [sintaxe Markdown](https://help.github.com/articles/github-flavored-markdown)\n      placeholder: Descreva detalhadamente o problema que você encontrou.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: O que você esperava?\n      placeholder: Descreva o que você esperava que acontecesse.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: O que vc observou ao invés do que esperava?\n      placeholder: Explique o que realmente acontece quando você segue os passos acima.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Capturas de Tela/Vídeos\n      placeholder: |\n        Se possível, adicione capturas de tela ou vídeos que ilustrem o problema. Isso pode ser extremamente útil para entender melhor o problema.\n\n  - type: textarea\n    attributes:\n      label: Qual versão da API você está usando?\n      description: |\n        Insira o número da sua versão que está na propriedade `version` do **package.json**.\n      placeholder: Cole aqui a versão.\n    validations:\n      required: true\n\n  - type: dropdown\n    id: select\n    attributes:\n      label: Qual é o seu ambiente?\n      options:\n        - Windows\n        - Linux\n        - Mac\n        - Docker\n        - Outro\n    validations:\n      required: true\n  \n  - type: textarea\n    attributes:\n      label: Outras expecificações do ambiente\n      placeholder: 'Hardware/Software: [ex: CPU, GPU]'\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: Se aplicável, cole a saída do log\n      description: |\n        Por favor, anexe os logs que possam estar relacionados ao problema.\n        Se os logs contiverem informações sensíveis, considere enviá-los de forma privada para um dos mantenedores do projeto.\n      placeholder: Cole aqui o log da aplicação\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: Notas Adicionais\n      description: Inclua aqui qualquer outra informação que você ache que possa ser útil para entender ou resolver o bug.\n    validations:\n      required: false\n    \n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/-pt--solicitar-recurso.yaml",
    "content": "name: Solicitação de recursos\ndescription: Sugira ideias para o projeto.\nlabels:\n  - enhancement\n  - pt-br\n# Automatically assign the issue to:\n# assignees: DavidsonGomes\nbody:\n  - type: checkboxes\n    id: termos\n    attributes:\n      label: Bem-vindo!\n      description: '**NÃO ABRA PARA PERGUNTAS GERAIS DE SUPORTE.**'\n\n      options:\n        - label: Sim, pesquisei solicitações semelhantes no [GitHub](https://github.com/code-chat-br/whatsapp-api/issues) e não encontrei nenhum.\n          required: true\n\n  - type: dropdown\n    attributes:\n      label: Qual tipo de recurso?\n      description: |\n        Como escrever uma boa solicitação de bug?\n\n        - Respeite o modelo de problema tanto quanto possível.\n        - O título deve ser curto e descritivo.\n        - Explique as condições que o levaram a reportar este problema: o contexto.\n        - O contexto deve levar a algo, ideia ou problema que você está enfrentando.\n        - Seja claro e conciso.\n        - Formate suas mensagens para ajudar o leitor a se concentrar no que importa e entender a estrutura da sua mensagem, use [sintaxe Markdown](https://help.github.com/articles/github-flavored-markdown)\n      options:\n        - Integração\n        - Funcionalidade\n        - Endpoint\n        - Ajuste de banco de dados\n        - Outro\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Qual a motivação para a solicitação?\n      description: |\n        Qual problema o recurso busca resolver?\n        Descreva claramente e em detalhes a funcionalidade que você deseja que seja implementada.\n        Explique como isso se encaixa no contexto do projeto.\n      placeholder: Descrição detalhada\n    validations:\n      required: true\n  \n  - type: textarea\n    attributes:\n      label: Exemplos de Uso\n      description: |\n        Forneça exemplos específicos de como essa funcionalidade poderia ser utilizada.\n        Isso pode incluir cenários ou casos de uso onde a funcionalidade seria particularmente benéfica.\n      placeholder: texto - imagem - video - fluxogramas\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: Como o recurso deve ser desenvolvido?\n      description: |\n        Deve ser inserido diretamente no código?\n        Deve ser construído uma aplicação diferente que atuará como uma extenção da api? \n        Por exemplo: um `worker`?\n        \n        Discuta como essa nova funcionalidade poderia impactar outras partes do projeto, se aplicável.\n\n        ---\n\n        Se você tem ideias sobre como essa funcionalidade pode ser implementada, por favor, compartilhe-as aqui.\n        Isso não é obrigatório, mas pode ser útil para a equipe de desenvolvimento.\n\n      placeholder: Insira ideias para o recurso\n    validations:\n      required: false\n\n  - type: textarea\n    attributes:\n      label: Notas Adicionais\n      description: Qualquer outra informação que você acredita ser relevante para a sua solicitação.\n      placeholder: Insira aqui as sua observções.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: 🐛 Bug Report\ndescription: Report a bug or unexpected behavior\ntitle: \"[BUG] \"\nlabels: [\"bug\", \"needs-triage\"]\nassignees: []\n\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report! \n        Please search existing issues before creating a new one.\n\n  - type: textarea\n    id: description\n    attributes:\n      label: 📋 Bug Description\n      description: A clear and concise description of what the bug is.\n      placeholder: Describe the bug...\n    validations:\n      required: true\n\n  - type: textarea\n    id: reproduction\n    attributes:\n      label: 🔄 Steps to Reproduce\n      description: Steps to reproduce the behavior\n      placeholder: |\n        1. Go to '...'\n        2. Click on '....'\n        3. Scroll down to '....'\n        4. See error\n    validations:\n      required: true\n\n  - type: textarea\n    id: expected\n    attributes:\n      label: ✅ Expected Behavior\n      description: A clear and concise description of what you expected to happen.\n      placeholder: What should happen?\n    validations:\n      required: true\n\n  - type: textarea\n    id: actual\n    attributes:\n      label: ❌ Actual Behavior\n      description: A clear and concise description of what actually happened.\n      placeholder: What actually happened?\n    validations:\n      required: true\n\n  - type: textarea\n    id: environment\n    attributes:\n      label: 🌍 Environment\n      description: Please provide information about your environment\n      value: |\n        - OS: [e.g. Ubuntu 20.04, Windows 10, macOS 12.0]\n        - Node.js version: [e.g. 18.17.0]\n        - Evolution API version: [e.g. 2.3.7]\n        - Database: [e.g. PostgreSQL 14, MySQL 8.0]\n        - Connection type: [e.g. Baileys, WhatsApp Business API]\n    validations:\n      required: true\n\n  - type: textarea\n    id: logs\n    attributes:\n      label: 📋 Logs\n      description: If applicable, add logs to help explain your problem.\n      placeholder: Paste relevant logs here...\n      render: shell\n\n  - type: textarea\n    id: additional\n    attributes:\n      label: 📝 Additional Context\n      description: Add any other context about the problem here.\n      placeholder: Any additional information...\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "content": "name: ✨ Feature Request\ndescription: Suggest a new feature or enhancement\ntitle: \"[FEATURE] \"\nlabels: [\"enhancement\", \"needs-triage\"]\nassignees: []\n\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for suggesting a new feature! \n        Please check our [Feature Requests on Canny](https://evolutionapi.canny.io/feature-requests) first.\n\n  - type: textarea\n    id: problem\n    attributes:\n      label: 🎯 Problem Statement\n      description: Is your feature request related to a problem? Please describe.\n      placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n    validations:\n      required: true\n\n  - type: textarea\n    id: solution\n    attributes:\n      label: 💡 Proposed Solution\n      description: Describe the solution you'd like\n      placeholder: A clear and concise description of what you want to happen.\n    validations:\n      required: true\n\n  - type: textarea\n    id: alternatives\n    attributes:\n      label: 🔄 Alternatives Considered\n      description: Describe alternatives you've considered\n      placeholder: A clear and concise description of any alternative solutions or features you've considered.\n\n  - type: dropdown\n    id: priority\n    attributes:\n      label: 📊 Priority\n      description: How important is this feature to you?\n      options:\n        - Low - Nice to have\n        - Medium - Would be helpful\n        - High - Important for my use case\n        - Critical - Blocking my work\n    validations:\n      required: true\n\n  - type: dropdown\n    id: component\n    attributes:\n      label: 🧩 Component\n      description: Which component does this feature relate to?\n      options:\n        - WhatsApp Integration (Baileys)\n        - WhatsApp Business API\n        - Chatwoot Integration\n        - Typebot Integration\n        - OpenAI Integration\n        - Dify Integration\n        - API Endpoints\n        - Database\n        - Authentication\n        - Webhooks\n        - File Storage\n        - Other\n\n  - type: textarea\n    id: use_case\n    attributes:\n      label: 🎯 Use Case\n      description: Describe your specific use case for this feature\n      placeholder: How would you use this feature? What problem does it solve for you?\n    validations:\n      required: true\n\n  - type: textarea\n    id: additional\n    attributes:\n      label: 📝 Additional Context\n      description: Add any other context, screenshots, or examples about the feature request here.\n      placeholder: Any additional information, mockups, or examples...\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "## 📋 Description\n<!-- Describe your changes in detail -->\n\n## 🔗 Related Issue\n<!-- Link to the issue this PR addresses -->\nCloses #(issue_number)\n\n## 🧪 Type of Change\n<!-- Mark with an `x` all the checkboxes that apply -->\n- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)\n- [ ] ✨ New feature (non-breaking change which adds functionality)\n- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)\n- [ ] 📚 Documentation update\n- [ ] 🔧 Refactoring (no functional changes)\n- [ ] ⚡ Performance improvement\n- [ ] 🧹 Code cleanup\n- [ ] 🔒 Security fix\n\n## 🧪 Testing\n<!-- Describe the testing you performed to verify your changes -->\n- [ ] Manual testing completed\n- [ ] Functionality verified in development environment\n- [ ] No breaking changes introduced\n- [ ] Tested with different connection types (if applicable)\n\n## 📸 Screenshots (if applicable)\n<!-- Add screenshots to help explain your changes -->\n\n## ✅ Checklist\n<!-- Mark with an `x` all the checkboxes that apply -->\n- [ ] My code follows the project's style guidelines\n- [ ] I have performed a self-review of my code\n- [ ] I have commented my code, particularly in hard-to-understand areas\n- [ ] I have made corresponding changes to the documentation\n- [ ] My changes generate no new warnings\n- [ ] I have manually tested my changes thoroughly\n- [ ] I have verified the changes work with different scenarios\n- [ ] Any dependent changes have been merged and published\n\n## 📝 Additional Notes\n<!-- Any additional information, concerns, or questions -->\n"
  },
  {
    "path": ".github/workflows/check_code_quality.yml",
    "content": "name: Check Code Quality\n\non: \n  pull_request:\n    branches: [ main, develop ]\n  push:\n    branches: [ main, develop ]\n\njobs:\n  check-lint-and-build:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    steps:\n    - uses: actions/checkout@v5\n      with:\n        submodules: recursive\n\n    - name: Install Node\n      uses: actions/setup-node@v5\n      with:\n        node-version: 20.x\n\n    - name: Cache node modules\n      uses: actions/cache@v4\n      with:\n        path: ~/.npm\n        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}\n        restore-keys: |\n          ${{ runner.os }}-node-\n\n    - name: Install packages\n      run: npm ci\n    \n    - name: Check linting\n      run: npm run lint:check\n\n    - name: Generate Prisma client\n      run: npm run db:generate\n\n    - name: Check build\n      run: npm run build"
  },
  {
    "path": ".github/workflows/publish_docker_image.yml",
    "content": "name: Build Docker image\n\non:\n  push:\n    tags:\n      - \"*.*.*\"\n\njobs:\n  build_deploy:\n    name: Build and Deploy\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n        with:\n          submodules: recursive\n\n      - name: Docker meta\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: evoapicloud/evolution-api\n          tags: type=semver,pattern=v{{version}}\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Login to GitHub Container Registry\n        uses: docker/login-action@v3\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n\n      - name: Build and push\n        id: docker_build\n        uses: docker/build-push-action@v6\n        with:\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}"
  },
  {
    "path": ".github/workflows/publish_docker_image_homolog.yml",
    "content": "name: Build Docker image\n\non:\n  push:\n    branches:\n      - develop\n\njobs:\n  build_deploy:\n    name: Build and Deploy\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n        with:\n          submodules: recursive\n\n      - name: Docker meta\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: evoapicloud/evolution-api\n          tags: homolog\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Login to Docker Hub\n        uses: docker/login-action@v3\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n\n      - name: Build and push\n        id: docker_build\n        uses: docker/build-push-action@v6\n        with:\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n"
  },
  {
    "path": ".github/workflows/publish_docker_image_latest.yml",
    "content": "name: Build Docker image\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  build_deploy:\n    name: Build and Deploy\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n        with:\n          submodules: recursive\n\n      - name: Docker meta\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: evoapicloud/evolution-api\n          tags: latest\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Login to Docker Hub\n        uses: docker/login-action@v3\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n\n      - name: Build and push\n        id: docker_build\n        uses: docker/build-push-action@v6\n        with:\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n\n      - name: Image digest\n        run: echo ${{ steps.docker_build.outputs.digest }}\n"
  },
  {
    "path": ".github/workflows/security.yml",
    "content": "name: Security Scan\n\non:\n  push:\n    branches: [ main, develop ]\n  pull_request:\n    branches: [ main, develop ]\n  schedule:\n    - cron: '0 0 * * 1' # Weekly on Mondays\n\njobs:\n  codeql:\n    name: CodeQL Analysis\n    runs-on: ubuntu-latest\n    timeout-minutes: 15\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'javascript' ]\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v5\n      with:\n        submodules: recursive\n\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v3\n      with:\n        languages: ${{ matrix.language }}\n\n    - name: Autobuild\n      uses: github/codeql-action/autobuild@v3\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v3\n      with:\n        category: \"/language:${{matrix.language}}\"\n\n  dependency-review:\n    name: Dependency Review\n    runs-on: ubuntu-latest\n    if: github.event_name == 'pull_request'\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v5\n        with:\n          submodules: recursive\n      - name: Dependency Review\n        uses: actions/dependency-review-action@v4\n"
  },
  {
    "path": ".gitignore",
    "content": "# Repo\nBaileys\n# compiled output\n/dist\n/node_modules\n\n/Docker/.env\n\n# Logs\nlogs/**.json\n*.log\nnpm-debug.log*\npnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n/docker-compose-data\n/docker-data\n\n# Package\n/yarn.lock\n/pnpm-lock.yaml\n\n# IDEs\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n.nova/*\n.idea/*\n\n# Project related\n/instances/*\n!/instances/.gitkeep\n/test/\n/src/env.yml\n/store\n*.env\n\n/temp/*\n\n.DS_Store\n*.DS_Store\n.tool-versions\n\n/prisma/migrations/*\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"evolution-manager-v2\"]\n\tpath = evolution-manager-v2\n\turl = https://github.com/EvolutionAPI/evolution-manager-v2.git\n"
  },
  {
    "path": ".husky/README.md",
    "content": "# Git Hooks Configuration\n\nEste projeto usa [Husky](https://typicode.github.io/husky/) para automatizar verificações de qualidade de código.\n\n## Hooks Configurados\n\n### Pre-commit\n- **Arquivo**: `.husky/pre-commit`\n- **Executa**: `npx lint-staged`\n- **Função**: Executa lint e correções automáticas apenas nos arquivos modificados\n\n### Pre-push  \n- **Arquivo**: `.husky/pre-push`\n- **Executa**: `npm run build` + `npm run lint:check`\n- **Função**: Verifica se o projeto compila e não tem erros de lint antes do push\n\n## Lint-staged Configuration\n\nConfigurado no `package.json`:\n\n```json\n\"lint-staged\": {\n  \"src/**/*.{ts,js}\": [\n    \"eslint --fix\",\n    \"git add\"\n  ],\n  \"src/**/*.ts\": [\n    \"npm run build\"\n  ]\n}\n```\n\n## Como funciona\n\n1. **Ao fazer commit**: Executa lint apenas nos arquivos modificados\n2. **Ao fazer push**: Executa build completo e verificação de lint\n3. **Se houver erros**: O commit/push é bloqueado até correção\n\n## Comandos úteis\n\n```bash\n# Pular hooks (não recomendado)\ngit commit --no-verify\ngit push --no-verify\n\n# Executar lint manualmente\nnpm run lint\n\n# Executar build manualmente  \nnpm run build\n```\n"
  },
  {
    "path": ".husky/commit-msg",
    "content": "npx --no -- commitlint --edit $1\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "npx lint-staged\n"
  },
  {
    "path": ".husky/pre-push",
    "content": "npm run build\nnpm run lint:check\n"
  },
  {
    "path": ".prettierrc.js",
    "content": "module.exports = {\n  semi: true,\n  trailingComma: 'all',\n  singleQuote: true,\n  printWidth: 120,\n  arrowParens: 'always',\n  tabWidth: 2,\n  useTabs: false,\n  bracketSameLine: false,\n  bracketSpacing: true,\n  parser: 'typescript'\n}"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"editor.fontSize\": 13,\n  \"editor.fontLigatures\": true,\n  \"editor.letterSpacing\": 0.5,\n  \"editor.smoothScrolling\": true,\n  \"editor.tabSize\": 2,\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": \"explicit\",\n    \"source.fixAll\": \"explicit\"\n  },\n  \"prisma-smart-formatter.typescript.defaultFormatter\": \"esbenp.prettier-vscode\",\n  \"prisma-smart-formatter.prisma.defaultFormatter\": \"Prisma.prisma\",\n  \"i18n-ally.localesPaths\": [\n    \"store/messages\"\n  ]\n}"
  },
  {
    "path": "AGENTS.md",
    "content": "# Evolution API - AI Agent Guidelines\n\nThis document provides comprehensive guidelines for AI agents (Claude, GPT, Cursor, etc.) working with the Evolution API codebase.\n\n## Project Overview\n\n**Evolution API** is a production-ready, multi-tenant WhatsApp API platform built with Node.js, TypeScript, and Express.js. It supports multiple WhatsApp providers and extensive integrations with chatbots, CRM systems, and messaging platforms.\n\n## Project Structure & Module Organization\n\n### Core Directories\n- **`src/`** – TypeScript source code with modular architecture\n  - `api/controllers/` – HTTP route handlers (thin layer)\n  - `api/services/` – Business logic (core functionality)\n  - `api/routes/` – Express route definitions (RouterBroker pattern)\n  - `api/integrations/` – External service integrations\n    - `channel/` – WhatsApp providers (Baileys, Business API, Evolution)\n    - `chatbot/` – AI/Bot integrations (OpenAI, Dify, Typebot, Chatwoot)\n    - `event/` – Event systems (WebSocket, RabbitMQ, SQS, NATS, Pusher)\n    - `storage/` – File storage (S3, MinIO)\n  - `dto/` – Data Transfer Objects (simple classes, no decorators)\n  - `guards/` – Authentication/authorization middleware\n  - `types/` – TypeScript type definitions\n  - `repository/` – Data access layer (Prisma)\n- **`prisma/`** – Database schemas and migrations\n  - `postgresql-schema.prisma` / `mysql-schema.prisma` – Provider-specific schemas\n  - `postgresql-migrations/` / `mysql-migrations/` – Provider-specific migrations\n- **`config/`** – Environment and application configuration\n- **`utils/`** – Shared utilities and helper functions\n- **`validate/`** – JSONSchema7 validation schemas\n- **`exceptions/`** – Custom HTTP exception classes\n- **`cache/`** – Redis and local cache implementations\n\n### Build & Deployment\n- **`dist/`** – Build output (do not edit directly)\n- **`public/`** – Static assets and media files\n- **`Docker*`**, **`docker-compose*.yaml`** – Containerization and local development stack\n\n## Build, Test, and Development Commands\n\n### Development Workflow\n```bash\n# Development server with hot reload\nnpm run dev:server\n\n# Direct execution for testing\nnpm start\n\n# Production build and run\nnpm run build\nnpm run start:prod\n```\n\n### Code Quality\n```bash\n# Linting and formatting\nnpm run lint        # ESLint with auto-fix\nnpm run lint:check  # ESLint check only\n\n# Commit with conventional commits\nnpm run commit      # Interactive commit with Commitizen\n```\n\n### Database Management\n```bash\n# Set database provider first (CRITICAL)\nexport DATABASE_PROVIDER=postgresql  # or mysql\n\n# Generate Prisma client\nnpm run db:generate\n\n# Development migrations (with provider sync)\nnpm run db:migrate:dev      # Unix/Mac\nnpm run db:migrate:dev:win  # Windows\n\n# Production deployment\nnpm run db:deploy      # Unix/Mac\nnpm run db:deploy:win  # Windows\n\n# Database tools\nnpm run db:studio      # Open Prisma Studio\n```\n\n### Docker Development\n```bash\n# Start local services (Redis, PostgreSQL, etc.)\ndocker-compose up -d\n\n# Full development stack\ndocker-compose -f docker-compose.dev.yaml up -d\n```\n\n## Coding Standards & Architecture Patterns\n\n### Code Style (Enforced by ESLint + Prettier)\n- **TypeScript strict mode** with full type coverage\n- **2-space indentation**, single quotes, trailing commas\n- **120-character line limit**\n- **Import order** via `simple-import-sort`\n- **File naming**: `feature.kind.ts` (e.g., `whatsapp.baileys.service.ts`)\n- **Naming conventions**:\n  - Classes: `PascalCase`\n  - Functions/variables: `camelCase`\n  - Constants: `UPPER_SNAKE_CASE`\n  - Files: `kebab-case.type.ts`\n\n### Architecture Patterns\n\n#### Service Layer Pattern\n```typescript\nexport class ExampleService {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n  \n  private readonly logger = new Logger('ExampleService');\n  \n  public async create(instance: InstanceDto, data: ExampleDto) {\n    // Business logic here\n    return { example: { ...instance, data } };\n  }\n  \n  public async find(instance: InstanceDto): Promise<ExampleDto | null> {\n    try {\n      const result = await this.waMonitor.waInstances[instance.instanceName].findData();\n      return result || null; // Return null on not found (Evolution pattern)\n    } catch (error) {\n      this.logger.error('Error finding data:', error);\n      return null; // Return null on error (Evolution pattern)\n    }\n  }\n}\n```\n\n#### Controller Pattern (Thin Layer)\n```typescript\nexport class ExampleController {\n  constructor(private readonly exampleService: ExampleService) {}\n  \n  public async createExample(instance: InstanceDto, data: ExampleDto) {\n    return this.exampleService.create(instance, data);\n  }\n}\n```\n\n#### RouterBroker Pattern\n```typescript\nexport class ExampleRouter extends RouterBroker {\n  constructor(...guards: any[]) {\n    super();\n    this.router.post(this.routerPath('create'), ...guards, async (req, res) => {\n      const response = await this.dataValidate<ExampleDto>({\n        request: req,\n        schema: exampleSchema, // JSONSchema7\n        ClassRef: ExampleDto,\n        execute: (instance, data) => controller.createExample(instance, data),\n      });\n      res.status(201).json(response);\n    });\n  }\n}\n```\n\n#### DTO Pattern (Simple Classes)\n```typescript\n// CORRECT - Evolution API pattern (no decorators)\nexport class ExampleDto {\n  name: string;\n  description?: string;\n  enabled: boolean;\n}\n\n// INCORRECT - Don't use class-validator decorators\nexport class BadExampleDto {\n  @IsString() // ❌ Evolution API doesn't use decorators\n  name: string;\n}\n```\n\n#### Validation Pattern (JSONSchema7)\n```typescript\nimport { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nexport const exampleSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    name: { type: 'string' },\n    description: { type: 'string' },\n    enabled: { type: 'boolean' },\n  },\n  required: ['name', 'enabled'],\n};\n```\n\n## Multi-Tenant Architecture\n\n### Instance Isolation\n- **CRITICAL**: All operations must be scoped by `instanceName` or `instanceId`\n- **Database queries**: Always include `where: { instanceId: ... }`\n- **Authentication**: Validate instance ownership before operations\n- **Data isolation**: Complete separation between tenant instances\n\n### WhatsApp Instance Management\n```typescript\n// Access instance via WAMonitoringService\nconst waInstance = this.waMonitor.waInstances[instance.instanceName];\nif (!waInstance) {\n  throw new NotFoundException(`Instance ${instance.instanceName} not found`);\n}\n```\n\n## Database Patterns\n\n### Multi-Provider Support\n- **PostgreSQL**: Uses `@db.Integer`, `@db.JsonB`, `@default(now())`\n- **MySQL**: Uses `@db.Int`, `@db.Json`, `@default(now())`\n- **Environment**: Set `DATABASE_PROVIDER=postgresql` or `mysql`\n- **Migrations**: Provider-specific folders auto-selected\n\n### Prisma Repository Pattern\n```typescript\n// Always use PrismaRepository for database operations\nconst result = await this.prismaRepository.instance.findUnique({\n  where: { name: instanceName },\n});\n```\n\n## Integration Patterns\n\n### Channel Integration (WhatsApp Providers)\n- **Baileys**: WhatsApp Web with QR code authentication\n- **Business API**: Official Meta WhatsApp Business API  \n- **Evolution API**: Custom WhatsApp integration\n- **Pattern**: Extend base channel service classes\n\n### Chatbot Integration\n- **Base classes**: Extend `BaseChatbotService` and `BaseChatbotController`\n- **Trigger system**: Support keyword, regex, and advanced triggers\n- **Session management**: Handle conversation state per user\n- **Available integrations**: EvolutionBot, OpenAI, Dify, Typebot, Chatwoot, Flowise, N8N, EvoAI\n\n### Event Integration\n- **Internal events**: EventEmitter2 for application events\n- **External events**: WebSocket, RabbitMQ, SQS, NATS, Pusher\n- **Webhook delivery**: Reliable delivery with retry logic\n\n## Testing Guidelines\n\n### Current State\n- **No formal test suite** currently implemented\n- **Manual testing** is the primary approach\n- **Integration testing** in development environment\n\n### Testing Strategy\n```typescript\n// Place tests in test/ directory as *.test.ts\n// Run: npm test (watches test/all.test.ts)\n\ndescribe('ExampleService', () => {\n  it('should create example', async () => {\n    // Mock external dependencies\n    // Test business logic\n    // Assert expected behavior\n  });\n});\n```\n\n### Recommended Approach\n- Focus on **critical business logic** in services\n- **Mock external dependencies** (WhatsApp APIs, databases)\n- **Integration tests** for API endpoints\n- **Manual testing** for WhatsApp connection flows\n\n## Commit & Pull Request Guidelines\n\n### Conventional Commits (Enforced by commitlint)\n```bash\n# Use interactive commit tool\nnpm run commit\n\n# Commit format: type(scope): subject (max 100 chars)\n# Types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert, security\n```\n\n### Examples\n- `feat(api): add WhatsApp message status endpoint`\n- `fix(baileys): resolve connection timeout issue`\n- `docs(readme): update installation instructions`\n- `refactor(service): extract common message validation logic`\n\n### Pull Request Requirements\n- **Clear description** of changes and motivation\n- **Linked issues** if applicable\n- **Migration impact** (specify database provider)\n- **Local testing steps** with screenshots/logs\n- **Breaking changes** clearly documented\n\n## Security & Configuration\n\n### Environment Setup\n```bash\n# Copy example environment file\ncp .env.example .env\n\n# NEVER commit secrets to version control\n# Set DATABASE_PROVIDER before database commands\nexport DATABASE_PROVIDER=postgresql  # or mysql\n```\n\n### Security Best Practices\n- **API key authentication** via `apikey` header\n- **Input validation** with JSONSchema7\n- **Rate limiting** on all endpoints\n- **Webhook signature validation**\n- **Instance-based access control**\n- **Secure defaults** for all configurations\n\n### Vulnerability Reporting\n- See `SECURITY.md` for security vulnerability reporting process\n- Contact: `contato@evolution-api.com`\n\n## Communication Standards\n\n### Language Requirements\n- **User communication**: Always respond in Portuguese (PT-BR)\n- **Code/comments**: English for technical documentation\n- **API responses**: English for consistency\n- **Error messages**: Portuguese for user-facing errors\n\n### Documentation Standards\n- **Inline comments**: Document complex business logic\n- **API documentation**: Document all public endpoints\n- **Integration guides**: Document new integration patterns\n- **Migration guides**: Document database schema changes\n\n## Performance & Scalability\n\n### Caching Strategy\n- **Redis primary**: Distributed caching for production\n- **Node-cache fallback**: Local caching when Redis unavailable\n- **TTL strategy**: Appropriate cache expiration per data type\n- **Cache invalidation**: Proper invalidation on data changes\n\n### Connection Management\n- **Database**: Prisma connection pooling\n- **WhatsApp**: One connection per instance with lifecycle management\n- **Redis**: Connection pooling and retry logic\n- **External APIs**: Rate limiting and retry with exponential backoff\n\n### Monitoring & Observability\n- **Structured logging**: Pino logger with correlation IDs\n- **Error tracking**: Comprehensive error scenarios\n- **Health checks**: Instance status and connection monitoring\n- **Telemetry**: Usage analytics (non-sensitive data only)\n\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# 2.3.7 (2025-12-05)\n\n### Features\n\n* **WhatsApp Business Meta Templates**: Add update and delete endpoints for Meta templates\n  - New endpoints to edit and delete WhatsApp Business templates\n  - Added DTOs and validation schemas for template management\n  - Enhanced template lifecycle management capabilities\n\n* **Events API**: Add isLatest and progress to messages.set event\n  - Allows consumers to know when history sync is complete (isLatest=true)\n  - Track sync progress percentage through webhooks\n  - Added extra field to EmitData type for additional payload properties\n  - Updated all event controllers (webhook, rabbitmq, sqs, websocket, pusher, kafka, nats)\n\n* **N8N Integration**: Add quotedMessage to payload in sendMessageToBot\n  - Support for quoted messages in N8N chatbot integration\n  - Enhanced message context information\n\n* **WebSocket**: Add wildcard \"*\" to allow all hosts to connect via websocket\n  - More flexible host configuration for WebSocket connections\n  - Improved host validation logic in WebsocketController\n\n* **Pix Support**: Handle interactive button message for pix\n  - Support for interactive Pix button messages\n  - Enhanced payment flow integration\n\n### Fixed\n\n* **Baileys Message Processor**: Fix incoming message events not working after reconnection\n  - Added cleanup logic in mount() to prevent memory leaks from multiple subscriptions\n  - Recreate messageSubject if it was completed during logout\n  - Remount messageProcessor in connectToWhatsapp() to ensure subscription is active\n  - Fixed issue where onDestroy() calls complete() on RxJS Subject, making it permanently closed\n  - Ensures old subscriptions are properly cleaned up before creating new ones\n\n* **Baileys Authentication**: Resolve \"waiting for message\" state after reconnection\n  - Fixed Redis keys not being properly removed during instance logout\n  - Prevented loading of old/invalid cryptographic keys on reconnection\n  - Fixed blocking state where instances authenticate but cannot send messages\n  - Ensures new credentials (creds) are properly used after reconnection\n\n* **OnWhatsapp Cache**: Prevent unique constraint errors and optimize database writes\n  - Fixed `Unique constraint failed on the fields: (remoteJid)` error when sending to groups\n  - Refactored query to use OR condition finding by jidOptions or remoteJid\n  - Added deep comparison to skip unnecessary database updates\n  - Replaced sequential processing with Promise.allSettled for parallel execution\n  - Sorted JIDs alphabetically in jidOptions for accurate change detection\n  - Added normalizeJid helper function for cleaner code\n\n* **Proxy Integration**: Fix \"Media upload failed on all hosts\" error when using proxy\n  - Created makeProxyAgentUndici() for Undici-compatible proxy agents\n  - Fixed compatibility with Node.js 18+ native fetch() implementation\n  - Replaced traditional HttpsProxyAgent/SocksProxyAgent with Undici ProxyAgent\n  - Maintained legacy makeProxyAgent() for Axios compatibility\n  - Fixed protocol handling in makeProxyAgent to prevent undefined errors\n\n* **WhatsApp Business API**: Fix base64, filename and caption handling\n  - Corrected base64 media conversion in Business API\n  - Fixed filename handling for document messages\n  - Improved caption processing for media messages\n  - Enhanced remoteJid validation and processing\n\n* **Chat Service**: Fix fetchChats and message panel errors\n  - Fixed cleanMessageData errors in Manager message panel\n  - Improved chat fetching reliability\n  - Enhanced message data sanitization\n\n* **Contact Filtering**: Apply where filters correctly in findContacts endpoint\n  - Fixed endpoint to process all where clause fields (id, remoteJid, pushName)\n  - Previously only processed remoteJid field, ignoring other filters\n  - Added remoteJid field to contactValidateSchema for proper validation\n  - Maintained multi-tenant isolation with instanceId filtering\n  - Allows filtering contacts by any supported field instead of returning all contacts\n\n* **Chatwoot and Baileys Integration**: Multiple integration improvements\n  - Enhanced code formatting and consistency\n  - Fixed integration issues between Chatwoot and Baileys services\n  - Improved message handling and delivery\n\n* **Baileys Message Loss**: Prevent message loss from WhatsApp stub placeholders\n  - Fixed messages being lost and not saved to database, especially for channels/newsletters (@lid)\n  - Detects WhatsApp stubs through messageStubParameters containing 'Message absent from node'\n  - Prevents adding stubs to duplicate message cache\n  - Allows real message to be processed when it arrives after decryption\n  - Maintains stub discard to avoid saving empty placeholders\n\n* **Database Contacts**: Respect DATABASE_SAVE_DATA_CONTACTS in contact updates\n  - Added missing conditional checks for DATABASE_SAVE_DATA_CONTACTS configuration\n  - Fixed profile picture updates attempting to save when database save is disabled\n  - Fixed unawaited promise in contacts.upsert handler\n\n* **Prisma/PostgreSQL**: Add unique constraint to Chat model\n  - Generated migration to add unique index on instanceId and remoteJid\n  - Added deduplication step before creating index to prevent constraint violations\n  - Prevents chat duplication in database\n\n* **MinIO Upload**: Handle messageContextInfo in media upload to prevent MinIO errors\n  - Prevents errors when uploading media with messageContextInfo metadata\n  - Improved error handling for media storage operations\n\n* **Typebot**: Fix message routing for @lid JIDs\n  - Typebot now responds to messages from JIDs ending with @lid\n  - Maintains complete JID for @lid instead of extracting only number\n  - Fixed condition: `remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0]`\n  - Handles both @s.whatsapp.net and @lid message formats\n\n* **Message Filtering**: Unify remoteJid filtering using OR with remoteJidAlt\n  - Improved message filtering with alternative JID support\n  - Better handling of messages with different JID formats\n\n* **@lid Integration**: Multiple fixes for @lid problems, message events and chatwoot errors\n  - Reorganized imports and improved message handling in BaileysStartupService\n  - Enhanced remoteJid processing to handle @lid cases\n  - Improved jid normalization and type safety in Chatwoot integration\n  - Streamlined message handling logic and cache management\n  - Refactored message handling and polling updates with decryption logic for poll votes\n  - Improved event processing flow for various message types\n\n* **Chatwoot Contacts**: Fix contact duplication error on import\n  - Resolved 'ON CONFLICT DO UPDATE command cannot affect row a second time' error\n  - Removed attempt to update identifier field in conflict (part of constraint)\n  - Changed to update only updated_at field: `updated_at = NOW()`\n  - Allows duplicate contacts to be updated correctly without errors\n\n* **Chatwoot Service**: Fix async handling in update_last_seen method\n  - Added missing await for chatwootRequest in read message processing\n  - Prevents service failure when processing read messages\n\n* **Metrics Access**: Fix IP validation including x-forwarded-for\n  - Uses all IPs including x-forwarded-for header when checking metrics access\n  - Improved security and access control for metrics endpoint\n\n### Dependencies\n\n* **Baileys**: Updated to version 7.0.0-rc.9\n  - Latest release candidate with multiple improvements and bug fixes\n\n* **AWS SDK**: Updated packages to version 3.936.0\n  - Enhanced functionality and compatibility\n  - Performance improvements\n\n### Code Quality & Refactoring\n\n* **Template Management**: Remove unused template edit/delete DTOs after refactoring\n* **Proxy Utilities**: Improve makeProxyAgent for Undici compatibility\n* **Code Formatting**: Enhance code formatting and consistency across services\n* **BaileysStartupService**: Fix indentation and remove unnecessary blank lines\n* **Event Controllers**: Guard extra spread and prevent core field override in all event controllers\n* **Import Organization**: Reorganize imports for better code structure and maintainability\n\n# 2.3.6 (2025-10-21)\n\n### Features\n\n* **Baileys, Chatwoot, OnWhatsapp Cache**: Multiple implementations and fixes\n  - Fixed cache for PN, LID and g.us numbers to send correct number\n  - Fixed audio and document sending via Chatwoot in Baileys channel\n  - Multiple fixes in Chatwoot integration\n  - Fixed ignored messages when receiving leads\n\n### Fixed\n\n* **Baileys**: Fix buffer storage in database\n  - Correctly save Uint8Array values to database\n* **Baileys**: Simplify logging of messageSent object\n  - Fixed \"this.isZero not is function\" error\n\n### Chore\n\n* **Version**: Bump version to 2.3.6 and update Baileys dependency to 7.0.0-rc.6\n* **Workflows**: Update checkout step to include submodules\n  - Added 'submodules: recursive' option to checkout step in multiple workflow files to ensure submodules are properly initialized during CI/CD processes\n* **Manager**: Update asset files and install process\n  - Updated subproject reference in evolution-manager-v2 to the latest commit\n  - Enhanced the manager_install.sh script to include npm install and build steps\n  - Replaced old JavaScript asset file with a new version for improved performance\n  - Added a new CSS file for consistent styling across the application\n\n# 2.3.5 (2025-10-15)\n\n### Features\n\n* **Chatwoot Enhancements**: Comprehensive improvements to message handling, editing, deletion and i18n\n* **Participants Data**: Add participantsData field maintaining backward compatibility for group participants\n* **LID to Phone Number**: Convert LID to phoneNumber on group participants\n* **Docker Configurations**: Add Kafka and frontend services to Docker configurations\n\n### Fixed\n\n* **Kafka Migration**: Fixed PostgreSQL migration error for Kafka integration\n  - Corrected table reference from `\"public\".\"Instance\"` to `\"Instance\"` in foreign key constraint\n  - Fixed `ERROR: relation \"public.Instance\" does not exist` issue in migration `20250918182355_add_kafka_integration`\n  - Aligned table naming convention with other Evolution API migrations for consistency\n  - Resolved database migration failure that prevented Kafka integration setup\n* **Update Baileys Version**: v7.0.0-rc.5 with compatibility fixes\n  - Fixed assertSessions signature compatibility using type assertion\n  - Fixed incompatibility in voice call (wavoip) with new Baileys version\n  - Handle undefined status in update by defaulting to 'DELETED'\n* **Chatwoot Improvements**: Multiple fixes for enhanced reliability\n  - Correct chatId extraction for non-group JIDs\n  - Resolve webhook timeout on deletion with 5+ images\n  - Improve error handling in Chatwoot messages\n  - Adjust conversation verification logic and cache\n  - Optimize conversation reopening logic and connection notification\n  - Fix conversation reopening and connection loop\n* **Baileys Message Handling**: Enhanced message processing\n  - Add warning log for messages not found\n  - Fix message verification in Baileys service\n  - Simplify linkPreview handling in BaileysStartupService\n* **Media Validation**: Fix media content validation\n* **PostgreSQL Connection**: Refactor connection with PostgreSQL and improve message handling\n\n### Code Quality & Refactoring\n\n* **Exponential Backoff**: Implement exponential backoff patterns and extract magic numbers to constants\n* **TypeScript Build**: Update TypeScript build process and dependencies\n\n### \n\n# 2.3.4 (2025-09-23)\n\n### Features\n\n* **Kafka Integration**: Added Apache Kafka event integration for real-time event streaming\n  - New Kafka controller, router, and schema for event publishing\n  - Support for instance-specific and global event topics\n  - Configurable SASL/SSL authentication and connection settings\n  - Auto-creation of topics with configurable partitions and replication\n  - Consumer group management for reliable event processing\n  - Integration with existing event manager for seamless event distribution\n\n* **Evolution Manager v2 Open Source**: Evolution Manager v2 is now available as open source\n  - Added as git submodule with HTTPS URL for easy access\n  - Complete open source setup with Apache 2.0 license + Evolution API custom conditions\n  - GitHub templates for issues, pull requests, and workflows\n  - Comprehensive documentation and contribution guidelines\n  - Docker support for development and production environments\n  - CI/CD workflows for code quality, security audits, and automated builds\n  - Multi-language support (English, Portuguese, Spanish, French)\n  - Modern React + TypeScript + Vite frontend with Tailwind CSS\n\n* **EvolutionBot Enhancements**: Improved EvolutionBot functionality and message handling\n  - Implemented splitMessages functionality for better message segmentation\n  - Added linkPreview support for enhanced message presentation\n  - Centralized split logic across chatbot services for consistency\n  - Enhanced message formatting and delivery capabilities\n\n### Fixed\n\n* **MySQL Schema**: Fixed invalid default value errors for `createdAt` fields in `Evoai` and `EvoaiSetting` models\n  - Changed `@default(now())` to `@default(dbgenerated(\"CURRENT_TIMESTAMP\"))` for MySQL compatibility\n  - Added missing relation fields (`N8n`, `N8nSetting`, `Evoai`, `EvoaiSetting`) in Instance model\n  - Resolved Prisma schema validation errors for MySQL provider\n\n* **Prisma Schema Validation**: Fixed `instanceName` field error in message creation\n  - Removed invalid `instanceName` field from message objects before database insertion\n  - Resolved `Unknown argument 'instanceName'` Prisma validation error\n  - Streamlined message data structure to match Prisma schema requirements\n\n* **Media Message Processing**: Enhanced media handling across chatbot services\n  - Fixed base64 conversion in EvoAI service for proper image processing\n  - Converted ArrayBuffer to base64 string using `Buffer.from().toString('base64')`\n  - Improved media URL handling and base64 encoding for better chatbot integration\n  - Enhanced image message detection and processing workflow\n\n* **Evolution Manager v2 Linting**: Resolved ESLint configuration conflicts\n  - Disabled conflicting Prettier rules in ESLint configuration\n  - Added comprehensive rule overrides for TypeScript and React patterns\n  - Fixed import ordering and code formatting issues\n  - Updated security vulnerabilities in dependencies (Vite, esbuild)\n\n### Code Quality & Refactoring\n\n* **Chatbot Services**: Streamlined media message handling across all chatbot integrations\n  - Standardized base64 and mediaUrl processing patterns\n  - Improved code readability and maintainability in media handling logic\n  - Enhanced error handling for media download and conversion processes\n  - Unified image message detection across different chatbot services\n\n* **Database Operations**: Improved data consistency and validation\n  - Enhanced Prisma schema compliance across all message operations\n  - Removed redundant instance name references for better data integrity\n  - Optimized message creation workflow with proper field validation\n\n### Environment Variables\n\n* Added comprehensive Kafka configuration options:\n  - `KAFKA_ENABLED`, `KAFKA_CLIENT_ID`, `KAFKA_BROKERS`\n  - `KAFKA_CONSUMER_GROUP_ID`, `KAFKA_TOPIC_PREFIX`\n  - `KAFKA_SASL_*` and `KAFKA_SSL_*` for authentication\n  - `KAFKA_EVENTS_*` for event type configuration\n\n# 2.3.3 (2025-09-18)\n\n### Features\n\n* Add extra fields to object sent to Flowise bot\n* Add Prometheus-compatible /metrics endpoint (gated by PROMETHEUS_METRICS)\n* Implement linkPreview support for Evolution Bot\n\n### Fixed\n\n* Address Path Traversal vulnerability in /assets endpoint by implementing security checks\n* Configure Husky and lint-staged for automated code quality checks on commits and pushes\n* Convert mediaKey from media messages to avoid bad decrypt errors\n* Improve code formatting for better readability in WhatsApp service files\n* Format messageGroupId assignment for improved readability\n* Improve linkPreview implementation based on PR feedback\n* Clean up code formatting for linkPreview implementation\n* Use 'unknown' as fallback for clientName label\n* Remove abort process when status is paused, allowing the chatbot return after the time expires and after being paused due to human interaction (stopBotFromMe)\n* Enhance message content sanitization in Baileys service and improve message retrieval logic in Chatwoot service\n* Integrate Typebot status change events for webhook in chatbot controller and service\n* Mimetype of videos video\n\n### Security\n\n* **CRITICAL**: Fixed Path Traversal vulnerability in /assets endpoint that allowed unauthenticated local file read\n* Customizable Websockets Security\n\n### Testing\n\n* Baileys Updates: v7.0.0-rc.3 ([Link](https://github.com/WhiskeySockets/Baileys/releases/tag/v7.0.0-rc.3))\n\n# 2.3.2 (2025-09-02)\n\n### Features\n\n* Add support to socks proxy\n\n### Fixed\n\n* Added key id into webhook payload in n8n service\n* Enhance RabbitMQ controller with improved connection management and shutdown procedures\n* Convert outgoing images to JPEG before sending with Chatwoot\n* Update baileys dependency to version 6.7.19\n\n# 2.3.1 (2025-07-29)\n\n### Feature\n\n* Add BaileysMessageProcessor for improved message handling and integrate rxjs for asynchronous processing\n* Enhance message processing with retry logic for error handling\n\n### Fixed\n\n* Update Baileys Version\n* Update Dockerhub Repository and Delete Config Session Variable\n* Fixed sending variables in typebot\n* Add unreadMessages in the response\n* Phone number as message ID for Evo AI\n* Fix upload to s3 when media message\n* Simplify edited message check in BaileysStartupService\n* Avoid corrupting URLs with query strings\n* Removed CONFIG_SESSION_PHONE_VERSION environment variable\n\n# 2.3.0 (2025-06-17 09:19)\n\n### Feature\n\n* Add support to get Catalogs and Collections with new routes: '{{baseUrl}}/chat/fetchCatalogs' and '{{baseUrl}}/chat/fetchCollections'\n* Add NATS integration support to the event system\n* Add message location support meta\n* Add S3_SKIP_POLICY env variable to disable setBucketPolicy for incompatible providers\n* Add EvoAI integration with models, services, and routes\n* Add N8n integration with models, services, and routes\n\n### Fixed\n\n* Shell injection vulnerability\n* Update Baileys Version v6.7.18\n* Audio send duplicate from chatwoot\n* Chatwoot csat creating new conversation in another language\n* Refactor SQS controller to correct bug in sqs events by instance\n* Adjustin cloud api send audio and video\n* Preserve animation in GIF and WebP stickers\n* Preventing use conversation from other inbox for the same user\n* Ensure full WhatsApp compatibility for audio conversion (libopus, 48kHz, mono)\n* Enhance message fetching and processing logic\n* Added lid on whatsapp numbers router\n* Now if the CONFIG_SESSION_PHONE_VERSION variable is not filled in it automatically searches for the most updated version\n\n### Security\n\n* Change execSync to execFileSync\n* Enhance WebSocket authentication and connection handling\n\n# 2.2.3 (2025-02-03 11:52)\n\n### Fixed\n\n* Fix cache in local file system\n* Update Baileys Version\n\n# 2.2.2 (2025-01-31 06:55)\n\n### Features\n\n* Added prefix key to queue name in RabbitMQ\n\n### Fixed\n\n* Update Baileys Version\n\n# 2.2.1 (2025-01-22 14:37)\n\n### Features\n\n* Retry system for send webhooks\n* Message filtering to support timestamp range queries\n* Chats filtering to support timestamp range queries\n\n### Fixed\n\n* Correction of webhook global\n* Fixed send audio with whatsapp cloud api\n* Refactor on fetch chats\n* Refactor on Evolution Channel\n\n# 2.2.0 (2024-10-18 10:00)\n\n### Features\n\n* Fake Call function\n* Send List with Baileys\n* Send Buttons with Baileys\n* Added unreadMessages to chats\n* Pusher event integration\n* Add support for splitMessages and timePerChar in Integrations\n* Audio Converter via API\n* Send PTV messages with Baileys\n\n### Fixed\n\n* Fixed prefilledVariables in startTypebot\n* Fix duplicate file upload\n* Mark as read from me and groups\n* Fetch chats query\n* Ads messages in chatwoot\n* Add indexes to improve performance in Evolution\n* Add logical or permanent message deletion based on env config\n* Add support for fetching multiple instances by key\n* Update instance.controller.ts to filter by instanceName\n* Receive template button reply message\n\n# 2.1.2 (2024-10-06 10:09)\n\n### Features\n\n* Sync lost messages on chatwoot\n* Set the maximum number of listeners that can be registered for events\n* Now is possible send medias with form-data\n\n### Fixed\n\n* Fetch status message\n* Adjusts in migrations\n* Update pushName in chatwoot\n* Validate message before sending chatwoot\n* Adds the message status to the return of the \"prepareMessage\" function\n* Fixed openai setting when send a message with chatwoot\n* Fix buildkey function in hSet and hDelete\n* Fix mexico number\n* Update baileys version\n* Update in Baileys version that fixes timeout when updating profile picture\n* Adjusts for fix timeout error on send status message\n* Chatwoot verbose logs\n* Adjusts on prisma connections\n* License terms updated\n* Fixed send message to group without no cache (local or redis)\n* Fixed startTypebot with startSession = true\n* Fixed issue of always creating a new label when saving chatwoot\n* Fixed getBase64FromMediaMessage with convertToMp4\n* Fixed bug when send message when don't have mentionsEveryOne on payload\n* Does not search message without chatwoot Message Id for reply\n* Fixed bot fallback not working on integrations\n\n# 2.1.1 (2024-09-22 10:31)\n\n### Features\n\n* Define a global proxy to be used if the instance does not have one\n* Save is on whatsapp on the database\n* Add headers to the instance's webhook registration\n* Debounce message break is now \"\\n\" instead of white space\n* Single view messages are now supported in chatwoot\n* Chatbots can now send any type of media\n\n### Fixed\n\n* Validate if cache exists before accessing it\n* Missing autoCreate chatwoot in instance create\n* Fixed bugs in the frontend, on the event screens\n* Fixed use chatwoot with evolution channel\n* Fix chatwoot reply quote with Cloud API\n* Use exchange name from .env on RabbitMQ\n* Fixed chatwoot screen\n* It is now possible to send images via the Evolution Channel\n* Removed \"version\" from docker-compose as it is obsolete (https://dev.to/ajeetraina/do-we-still-use-version-in-compose-3inp)\n* Fixed typebot ignoreJids being used only from default settings\n* Fixed Chatwoot inbox creation on save\n* Changed axios timeout for manager requests for 30s\n* Update in Baileys version that fixes timeout when updating profile picture\n* Fixed issue when sending links in markdown by chatbots like Dify\n* Fixed issue with chatbots not respecting settings\n\n# 2.1.0 (2024-08-26 15:33)\n\n### Features\n\n* Improved layout manager\n* Translation in manager: English, Portuguese, Spanish and French\n* Evolution Bot Integration\n* Option to disable chatwoot bot contact with CHATWOOT_BOT_CONTACT\n* Added flowise integration\n* Added evolution channel on instance create\n* Change in license to Apache-2.0\n* Mark All in events\n\n### Fixed\n\n* Refactor integrations structure for modular system\n* Fixed dify agent integration\n* Update Baileys Version\n* Fixed proxy config in manager\n* Fixed send messages in groups\n* S3 saving media sent from me\n* Fixed duplication bot when use startTypebot\n\n### Break Changes\n\n* Payloads for events changed (create Instance and set events). Check postman to understand\n\n# 2.0.10 (2024-08-16 16:23)\n\n### Features\n\n* OpenAI send images when markdown\n* Dify send images when markdown\n* Sentry implemented\n\n### Fixed\n\n* Fix on get profilePicture\n* Added S3_REGION on minio settings\n\n# 2.0.9 (2024-08-15 12:31)\n\n### Features\n\n* Added ignoreJids in chatwoot settings\n* Dify now identifies images\n* Openai now identifies images\n\n### Fixed\n\n* Path mapping & deps fix & bundler changed to tsup\n* Improve database scripts to retrieve the provider from env file\n* Update contacts database with unique index\n* Save chat name\n* Correction of media as attachments in chatwoot when using a Meta API Instance and not Baileys\n* Update Baileys version 6.7.6\n* Deprecate buttons and list in new Baileys version\n* Changed labels to be unique on the same instance\n* Remove instance from redis even if using database\n* Unified integration session system so they don't overlap\n* Temporary fix for pictureUrl bug in groups\n* Fix on migrations\n\n# 2.0.9-rc (2024-08-09 18:00)\n\n### Features\n\n* Added general session button in typebot, dify and openai in manager\n* Added compatibility with mysql through prisma\n\n### Fixed\n\n* Import contacts with image in chatwoot\n* Fix conversationId when is dify agent\n* Fixed loading of selects in the manager\n* Add restart button to sessions screen\n* Adjustments to docker files\n* StopBotFromMe working with chatwoot\n\n# 2.0.8-rc (2024-08-08 20:23)\n\n### Features\n\n* Variables passed to the input in dify\n* OwnerJid passed to typebot\n* Function for openai assistant added\n\n### Fixed\n\n* Adjusts in telemetry\n\n# 2.0.7-rc (2024-08-03 14:04)\n\n### Fixed\n\n* BusinessId added on create instances in manager\n* Adjusts in restart instance\n* Resolve issue with connecting to instance\n* Session is now individual per instance and remoteJid\n* Credentials verify on manager login\n* Added description column on typebot, dify and openai\n* Fixed dify agent integration\n\n# 2.0.6-rc (2024-08-02 19:23)\n\n### Features\n\n* Get models for OpenAI\n\n### Fixed\n\n* fetchInstances with clientName parameter\n* fixed update typebot, openai and dify\n\n# 2.0.5-rc (2024-08-01 18:01)\n\n### Features\n\n* Speech to Text with Openai\n\n### Fixed\n\n* ClientName on infos\n* Instance screen scroll bar in manager\n\n# 2.0.4-rc (2024-07-30 14:13)\n\n### Features\n\n* New manager v2.0\n* Dify integration\n\n### Fixed\n\n* Update Baileys Version\n* Adjusts for new manager\n* Corrected openai trigger validation\n* Corrected typebot trigger validation\n\n# 2.0.3-beta (2024-07-29 09:03)\n\n### Features\n\n* Webhook url by submitted template to send status updates\n* Sending template approval status webhook\n\n### Fixed\n\n* Equations and adjustments for the new manager\n* Adjust TriggerType for OpenAI and Typebot integrations\n* Fixed Typebot start call with active session\n\n# 2.0.2-beta (2024-07-18 21:33)\n\n### Feature\n\n* Open AI implemented\n\n### Fixed\n\n* Fixed the function of saving or not saving data in the database\n* Resolve not find name\n* Removed DEL_TEMP_INSTANCES as it is not being used\n* Fixed global exchange name\n* Add apiKey and serverUrl to prefilledVariables in typebot service\n* Correction in start typebot, if it doesn't exist, create it\n\n# 2.0.1-beta (2024-07-17 17:01)\n\n### Fixed\n\n* Resolved issue with Chatwoot not receiving messages sent by Typebot\n\n# 2.0.0-beta (2024-07-14 17:00)\n\n### Feature\n\n* Added prisma orm, connection to postgres and mysql\n* Added chatwoot integration activation\n* Added typebot integration activation\n* Now you can register several typebots with triggers\n* Media sent to typebot now goes as a template string, example: imageMessage|MESSAGE_ID\n* Organization configuration and logo in chatwoot bot contact\n* Added debounce time for typebot messages\n* Tagging in chatwoot contact by instance\n* Add support for managing WhatsApp templates via official API\n* Fixes and implementation of regex and fallback in typebot\n* Ignore jids configuration added to typebot (will be used for both groups and contacts)\n* Minio and S3 integration\n* When S3 integration enabled, the media sent to typebot now goes as a template string, example: imageMessage|MEDIA_URL\n\n### Fixed\n\n* Removed excessive verbose logs\n* Optimization in instance registration\n* Now in typebot we wait until the terminal block to accept the user's message, if it arrives before the block is sent, it is ignored\n* Correction of audio sending, now we can speed it up and have the audio wireframe\n* Reply with media message on Chatwoot\n* improvements in sending status and groups\n* Correction in response returns from buttons, lists and templates\n* EvolutionAPI/Baileys implemented\n\n### Break changes\n\n* jwt authentication removed\n* Connection to mongodb removed\n* Standardized all request bodies to use camelCase\n* Change in webhook information from owner to instanceId\n* Changed the .env file configuration, removed the yml version and added .env to the repository root\n* Removed the mobile type connection with Baileys\n* Simplified payloads and endpoints\n* Improved Typebot\n  - Now you can register several typebots\n  - Start configuration by trigger or for all\n  - Session search by typebot or remoteJid\n  - KeepOpen configuration (keeps the session even when the bot ends, to run once per contact)\n  - StopBotFromMe configuration, allows me to stop the bot if I send a chat message.\n* Changed the way the goal webhook is configured\n\n# 1.8.2 (2024-07-03 13:50)\n\n### Fixed\n\n* Corretion in globall rabbitmq queue name\n* Improvement in the use of mongodb database for credentials\n* Fixed base64 in webhook for documentWithCaption\n* Fixed Generate pairing code\n\n# 1.8.1 (2024-06-08 21:32)\n\n### Feature\n\n* New method of saving sessions to a file using worker, made in partnership with [codechat](https://github.com/code-chat-br/whatsapp-api)\n\n### Fixed\n\n* Correction of variables breaking lines in typebot\n\n### Fixed\n\n* Correction of variables breaking lines in typebot\n\n# 1.8.0 (2024-05-27 16:10)\n\n### Feature\n\n* Now in the manager, when logging in with the client's apikey, the listing only shows the instance corresponding to the provided apikey (only with MongoDB)\n* New global mode for rabbitmq events\n* Build in docker for linux/amd64, linux/arm64 platforms\n\n### Fixed\n\n* Correction in message formatting when generated by AI as markdown in typebot\n* Security fix in fetch instance with client key when not connected to mongodb\n\n# 1.7.5 (2024-05-21 08:50)\n\n### Fixed\n\n* Add merge_brazil_contacts function to solve nine digit in brazilian numbers\n* Optimize ChatwootService method for updating contact\n* Fix swagger auth\n* Update aws sdk v3\n* Fix getOpenConversationByContact and init queries error\n* Method to mark chat as unread\n* Added environment variable to manually select the WhatsApp web version for the baileys lib (optional)\n\n# 1.7.4 (2024-04-28 09:46)\n\n### Fixed\n\n* Adjusts in proxy on fetchAgent\n* Recovering messages lost with redis cache\n* Log when init redis cache service\n* Recovering messages lost with redis cache\n* Chatwoot inbox name\n* Update Baileys version\n\n# 1.7.3 (2024-04-18 12:07)\n\n### Fixed\n\n* Revert fix audio encoding\n* Recovering messages lost with redis cache\n* Adjusts in redis for save instances\n* Adjusts in proxy\n* Revert pull request #523\n* Added instance name on logs\n* Added support for Spanish\n* Fix error: invalid operator. The allowed operators for identifier are equal_to,not_equal_to in chatwoot\n\n# 1.7.2 (2024-04-12 17:31)\n\n### Feature\n\n* Mobile connection via sms (test)\n\n### Fixed\n\n* Adjusts in redis\n* Send global event in websocket\n* Adjusts in proxy\n* Fix audio encoding\n* Fix conversation read on chatwoot version 3.7\n* Fix when receiving/sending messages from whatsapp desktop with ephemeral messages enabled\n* Changed returned sessions on typebot status change\n* Reorganization of files and folders\n\n# 1.7.1 (2024-04-03 10:19)\n\n### Fixed\n\n* Correction when sending files with captions on Whatsapp Business\n* Correction in receiving messages with response on WhatsApp Business\n* Correction when sending a reaction to a message on WhatsApp Business\n* Correction of receiving reactions on WhatsApp business\n* Removed mandatory description of rows from sendList\n* Feature to collect message type in typebot\n\n# 1.7.0 (2024-03-11 18:23)\n\n### Feature\n\n* Added update message endpoint\n* Add translate capabilities to QRMessages in CW\n* Join in Group by Invite Code\n* Read messages from whatsapp in chatwoot\n* Add support to use use redis in cacheservice\n* Add support for labels\n* Command to clearcache from chatwoot inbox\n* Whatsapp Cloud API Oficial\n\n### Fixed\n\n* Proxy configuration improvements\n* Correction in sending lists\n* Adjust in webhook_base64\n* Correction in typebot text formatting\n* Correction in chatwoot text formatting and render list message\n* Only use a axios request to get file mimetype if necessary\n* When possible use the original file extension\n* When receiving a file from whatsapp, use the original filename in chatwoot if possible\n* Remove message ids cache in chatwoot to use chatwoot's api itself\n* Adjusts the quoted message, now has contextInfo in the message Raw\n* Collecting responses with text or numbers in Typebot\n* Added sendList endpoint to swagger documentation\n* Implemented a function to synchronize message deletions on WhatsApp, automatically reflecting in Chatwoot.\n* Improvement on numbers validation\n* Fix polls in message sending\n* Sending status message\n* Message 'connection successfully' spamming\n* Invalidate the conversation cache if reopen_conversation is false and the conversation was resolved\n* Fix looping when deleting a message in chatwoot\n* When receiving a file from whatsapp, use the original filename in chatwoot if possible\n* Correction in the sendList Function\n* Implement contact upsert in messaging-history.set\n* Improve proxy error handling\n* Refactor fetching participants for group in WhatsApp service\n* Fixed problem where the typebot final keyword did not work\n* Typebot's wait now pauses the flow and composing is defined by the delay_message parameter in set typebot\n* Composing over 20s now loops until finished\n\n# 1.6.1 (2023-12-22 11:43)\n\n### Fixed\n\n* Fixed Lid Messages\n* Fixed sending variables to typebot\n* Fixed sending variables from typebot\n* Correction sending s3/minio media to chatwoot and typebot\n* Fixed the problem with typebot closing at the end of the flow, now this is optional with the TYPEBOT_KEEP_OPEN variable\n* Fixed chatwoot Bold, Italic and Underline formatting using Regex\n* Added the sign_delimiter property to the Chatwoot configuration, allowing you to set a different delimiter for the signature. Default when not defined \\n\n* Include instance Id field in the instance configuration\n* Fixed the pairing code\n* Adjusts in typebot\n* Fix the problem when disconnecting the instance and connecting again using mongodb\n* Options to disable docs and manager\n* When deleting a message in whatsapp, delete the message in chatwoot too\n\n\n# 1.6.0 (2023-12-12 17:24)\n\n### Feature\n\n* Added AWS SQS Integration\n* Added support for new typebot API\n* Added endpoint sendPresence\n* New Instance Manager\n* Added auto_create to the chatwoot set to create the inbox automatically or not\n* Added reply, delete and message reaction in chatwoot v3.3.1\n\n### Fixed\n\n* Adjusts in proxy\n* Adjusts in start session for Typebot\n* Added mimetype field when sending media\n* Ajusts in validations to messages.upsert\n* Fixed messages not received: error handling when updating contact in chatwoot\n* Fix workaround to manage param data as an array in mongodb\n* Removed await from webhook when sending a message\n* Update typebot.service.ts - element.underline change ~ for *\n* Removed api restart on receiving an error\n* Fixes in mongodb and chatwoot\n* Adjusted return from queries in mongodb\n* Added restart instance when update profile picture\n* Correction of chatwoot functioning with admin flows\n* Fixed problem that did not generate qrcode with the chatwoot_conversation_pending option enabled\n* Fixed issue where CSAT opened a new ticket when reopen_conversation was disabled\n* Fixed issue sending contact to Chatwoot via iOS\n\n### Integrations\n\n* Chatwoot: v3.3.1\n* Typebot: v2.20.0\n\n# 1.5.4 (2023-10-09 20:43)\n\n### Fixed\n\n* Baileys logger typing issue resolved\n* Solved problem with duplicate messages in chatwoot\n\n# 1.5.3 (2023-10-06 18:55)\n\n### Feature\n\n* Swagger documentation\n* Added base 64 sending option via webhook\n\n### Fixed\n\n* Remove rabbitmq queues when delete instances\n* Improvement in restart instance to completely redo the connection\n* Update node version: v20\n* Correction of messages sent by the api and typebot not appearing in chatwoot\n* Adjustment to start typebot, added startSession parameter\n* Chatwoot now receives messages sent via api and typebot\n* Fixed problem with starting with an input in typebot\n* Added check to ensure variables are not empty before executing foreach in start typebot\n\n# 1.5.2 (2023-09-28 17:56)\n\n### Fixed\n\n* Fix chatwootSchema in chatwoot model to store reopen_conversation and conversation_pending options\n* Problem resolved when sending files from minio to typebot\n* Improvement in the \"startTypebot\" method to create persistent session when triggered\n* New manager for Evo 1.5.2 - Set Typebot update\n* Resolved problems when reading/querying instances\n\n# 1.5.1 (2023-09-17 13:50)\n\n### Feature\n\n* Added listening_from_me option in Set Typebot\n* Added variables options in Start Typebot\n* Added webhooks for typebot events\n* Added ChamaAI integration\n* Added webhook to send errors\n* Added support for messaging with ads on chatwoot\n\n### Fixed\n\n* Fix looping connection messages in chatwoot\n* Improved performance of fetch instances\n\n# 1.5.0 (2023-08-18 12:47)\n\n### Feature\n\n* New instance manager in /manager route\n* Added extra files for chatwoot and appsmith\n* Added Get Last Message and Archive for Chat\n* Added env var QRCODE_COLOR\n* Added websocket to send events\n* Added rabbitmq to send events\n* Added Typebot integration\n* Added proxy endpoint\n* Added send and date_time in webhook data\n\n### Fixed\n\n* Solved problem when disconnecting from the instance the instance was deleted\n* Encoded spaces in chatwoot webhook\n* Adjustment in the saving of contacts, saving the information of the number and Jid\n* Update Dockerfile\n* If you pass empty events in create instance and set webhook it is understood as all\n* Fixed issue that did not output base64 averages\n* Messages sent by the api now arrive in chatwoot\n\n### Integrations\n\n* Chatwoot: v2.18.0 - v3.0.0\n* Typebot: v2.16.0\n* Manager Evolution API\n\n# 1.4.8 (2023-07-27 10:27)\n\n### Fixed\n\n* Fixed error return bug\n\n# 1.4.7 (2023-07-27 08:47)\n\n### Fixed\n\n* Fixed error return bug\n* Fixed problem of getting message when deleting message in chatwoot\n* Change in error return pattern\n\n# 1.4.6 (2023-07-26 17:54)\n\n### Fixed\n\n* Fixed bug of creating new inbox by chatwoot\n* When conversation reopens is pending when conversation pending is true\n* Added docker-compose file with dockerhub image\n\n# 1.4.5 (2023-07-26 09:32)\n\n### Fixed\n\n* Fixed problems in localization template in chatwoot\n* Fix mids going duplicated in chatwoot\n\n# 1.4.4 (2023-07-25 15:24)\n\n### Fixed\n\n* Fixed chatwoot line wrap issue\n* Solved receive location in chatwoot\n* When requesting the pairing code, it also brings the qr code\n* Option reopen_conversation in chatwoot endpoint\n* Option conversation_pending in chatwoot endpoint\n\n# 1.4.3 (2023-07-25 10:51)\n\n### Fixed\n\n* Adjusts in settings with options always_online, read_messages and read_status\n* Fixed send webhook for event CALL\n* Create instance with settings\n\n# 1.4.2 (2023-07-24 20:52)\n\n### Fixed\n\n* Fixed validation is set settings\n* Adjusts in group validations\n* Ajusts in sticker message to chatwoot\n\n# 1.4.1 (2023-07-24 18:28)\n\n### Fixed\n\n* Fixed reconnect with pairing code or qrcode\n* Fixed problem in createJid\n\n# 1.4.0 (2023-07-24 17:03)\n\n### Features\n\n* Added connection functionality via pairing code\n* Added fetch profile endpoint in chat controller\n* Created settings controller\n* Added reject call and send text message when receiving a call\n* Added setting to ignore group messages\n* Added connection with pairing code in chatwoot with command /init:{NUMBER}\n* Added encoding option in endpoint sendWhatsAppAudio\n\n### Fixed\n\n* Added link preview option in send text message\n* Fixed problem with fileSha256 appearing when sending a sticker in chatwoot\n* Fixed issue where it was not possible to open a conversation when sent at first by me on my cell phone in chatwoot\n* Now it only updates the contact name if it is the same as the phone number in chatwoot\n* Now accepts all chatwoot inbox templates\n* Command to create new instances set to /new_instance:{NAME}:{NUMBER}\n* Fix in chatwoot set, sign msg can now be disabled\n\n### Integrations\n\n* Chatwoot: v2.18.0 - v3.0.0 (Beta)\n\n# 1.3.2 (2023-07-21 17:19)\n\n### Fixed\n\n* Fix in update settings that needed to restart after updated\n* Correction in the use of the api with mongodb\n* Adjustments to search endpoint for contacts, chats, messages and Status messages\n* Now when deleting the instance, the data referring to it in mongodb is also deleted\n* It is now validated if the instance name contains uppercase and special characters\n* For compatibility reasons, container mode has been removed\n* Added docker-compose files example\n\n### Integrations\n\n* Chatwoot: v2.18.0\n\n# 1.3.1 (2023-07-20 07:48)\n\n### Fixed\n\n* Adjust in create store files\n\n### Integrations\n\n* Chatwoot: v2.18.0\n\n# 1.3.0 (2023-07-19 11:33)\n\n### Features\n\n* Added messages.delete event\n* Added restart instance endpoint\n* Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:{INSTANCE_NAME}\n* Change Baileys version to: 6.4.0\n* Send contact in chatwoot\n* Send contact array in chatwoot\n* Added apiKey in webhook and serverUrl in fetchInstance if EXPOSE_IN_FETCH_INSTANCES: true\n* Translation set to default (english) in chatwoot\n\n### Fixed\n\n* Fixed error to send message in large groups\n* Docker files adjusted\n* Fixed in the postman collection the webhookByEvent parameter by webhook_by_events\n* Added validations in create instance\n* Removed link preview endpoint, now it's done automatically from sending conventional text\n* Added group membership validation before sending message to groups\n* Adjusts in docker files\n* Adjusts in returns in endpoints chatwoot and webhook\n* Fixed ghost mentions in send text message\n* Fixed bug that saved contacts from groups came without number in chatwoot\n* Fixed problem to receive csat in chatwoot\n* Fixed require fileName for document only in base64 for send media message\n* Bug fix when sending mobile message change contact name to number in chatwoot\n* Bug fix when connecting whatsapp does not send confirmation message\n* Fixed quoted message with id or message directly\n* Adjust in validation for mexican and argentine numbers\n* Adjust in create store files\n\n### Integrations\n\n* Chatwoot: v2.18.0\n\n# 1.2.2 (2023-07-15 09:36)\n\n### Fixed\n\n* Tweak in route \"/\" with version info\n* Adjusts chatwoot version\n\n### Integrations\n\n* Chatwoot: v2.18.0\n\n# 1.2.1 (2023-07-14 19:04)\n\n### Fixed\n\n* Adjusts in docker files\n* Save picture url groups in chatwoot\n\n# 1.2.0 (2023-07-14 15:28)\n\n### Features\n\n* Native integration with chatwoot\n* Added returning or non-returning participants option in fetchAllGroups\n* Added group integration to chatwoot\n* Added automation on create instance to chatwoot\n* Added verbose logs and format chatwoot service\n\n### Fixed\n\n* Adjusts in docker-compose files\n* Adjusts in number validation for AR and MX numbers\n* Adjusts in env files, removed save old_messages\n* Fix when sending a message to a group I don't belong returns a bad request\n* Fits the format on return from the fetchAllGroups endpoint\n* Adjust in send document with caption from chatwoot\n* Fixed message with undefind in chatwoot\n* Changed message in path /\n* Test duplicate message media in groups chatwoot\n* Optimize send message from group with mentions\n* Fixed name of the profile status in fetchInstances\n* Fixed error 500 when logout in instance with status = close\n\n# 1.1.5 (2023-07-12 07:17)\n\n### Fixed\n\n* Adjusts in temp folder\n* Return with event send_message\n\n# 1.1.4 (2023-07-08 11:01)\n\n### Features\n\n* Route to send status broadcast\n* Added verbose logs\n* Insert allContacts in payload of endpoint sendStatus\n\n### Fixed\n\n* Adjusted set in webhook to go empty when enabled false\n* Adjust in store files\n* Fixed the problem when do not save contacts when receive messages\n* Changed owner of the jid for instanceName\n* Create .env for installation in docker\n\n# 1.1.3 (2023-07-06 11:43)\n\n### Features\n\n* Added configuration for Baileys log level in env\n* Added audio to mp4 converter in optionally get Base64 From MediaMessage\n* Added organization name in vcard\n* Added email in vcard\n* Added url in vcard\n* Added verbose logs\n\n### Fixed\n\n* Added timestamp internally in urls to avoid caching\n* Correction in decryption of poll votes\n* Change in the way the api sent and saved the sent messages, now it goes in the messages.upsert event\n* Fixed cash when sending stickers via url\n* Improved how Redis works for instances\n* Fixed problem when disconnecting the instance it removes the instance\n* Fixed problem sending ack when preview is done by me\n* Adjust in store files\n\n# 1.1.2 (2023-06-28 13:43)\n\n### Fixed\n\n* Fixed baileys version in package.json\n* Fixed problem that did not validate if the token passed in create instance already existed\n* Fixed problem that does not delete instance files in server mode\n\n# 1.1.1 (2023-06-28 10:27)\n\n### Features\n\n* Added group invitation sending\n* Added webhook configuration per event in the individual instance registration\n\n### Fixed\n\n* Adjust dockerfile variables\n\n# 1.1.0 (2023-06-21 11:17)\n\n### Features\n\n* Improved fetch instances endpoint, now it also fetch other instances even if they are not connected\n* Added conversion of audios for sending recorded audio, now it is possible to send mp3 audios and not just ogg\n* Route to fetch all groups that the connection is part of\n* Route to fetch all privacy settings\n* Route to update the privacy settings\n* Route to update group subject\n* Route to update group description\n* Route to accept invite code\n* Added configuration of events by webhook of instances\n* Now the api key can be exposed in fetch instances if the EXPOSE_IN_FETCH_INSTANCES variable is set to true\n* Added option to generate qrcode as soon as the instance is created\n* The created instance token can now also be optionally defined manually in the creation endpoint\n* Route to send Sticker\n\n### Fixed\n\n* Adjust dockerfile variables\n* tweaks in docker-compose to pass variables\n* Adjust the route getProfileBusiness to fetchProfileBusiness\n* fix error after logout and try to get status or to connect again\n* fix sending narrated audio on whatsapp android and ios\n* fixed the problem of not disabling the global webhook by the variable\n* Adjustment in the recording of temporary files and periodic cleaning\n* Fix for container mode also work only with files\n* Remove recording of old messages on sync\n\n# 1.0.9 (2023-06-10)\n\n### Fixed\n\n* Adjust dockerfile variables\n\n# 1.0.8 (2023-06-09)\n\n### Features\n\n* Added Docker compose file\n* Added ChangeLog file\n\n# 1.0.7 (2023-06-08)\n\n### Features\n\n* Ghost mention\n* Mention in reply\n* Profile photo change\n* Profile name change\n* Profile status change\n* Sending a poll\n* Creation of LinkPreview if message contains URL\n* New webhooks system, which can be separated into a url per event\n* Sending the local webhook url as destination in the webhook data for webhook redirection\n* Startup modes, server or container\n* Server Mode works normally as everyone is used to\n* Container mode made to use one instance per container, when starting the application an instance is already created and the qrcode is generated and it starts sending webhook without having to call it manually, it only allows one instance at a time.\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides comprehensive guidance to Claude AI when working with the Evolution API codebase.\n\n## Project Overview\n\n**Evolution API** is a powerful, production-ready REST API for WhatsApp communication that supports multiple WhatsApp providers:\n- **Baileys** (WhatsApp Web) - Open-source WhatsApp Web client\n- **Meta Business API** - Official WhatsApp Business API\n- **Evolution API** - Custom WhatsApp integration\n\nBuilt with **Node.js 20+**, **TypeScript 5+**, and **Express.js**, it provides extensive integrations with chatbots, CRM systems, and messaging platforms in a **multi-tenant architecture**.\n\n## Common Development Commands\n\n### Build and Run\n```bash\n# Development\nnpm run dev:server    # Run in development with hot reload (tsx watch)\n\n# Production\nnpm run build        # TypeScript check + tsup build\nnpm run start:prod   # Run production build\n\n# Direct execution\nnpm start           # Run with tsx\n```\n\n### Code Quality\n```bash\nnpm run lint        # ESLint with auto-fix\nnpm run lint:check  # ESLint check only\nnpm run commit      # Interactive commit with commitizen\n```\n\n### Database Management\n```bash\n# Set database provider first\nexport DATABASE_PROVIDER=postgresql  # or mysql\n\n# Generate Prisma client (automatically uses DATABASE_PROVIDER env)\nnpm run db:generate\n\n# Deploy migrations (production)\nnpm run db:deploy      # Unix/Mac\nnpm run db:deploy:win  # Windows\n\n# Development migrations (with sync to provider folder)\nnpm run db:migrate:dev      # Unix/Mac\nnpm run db:migrate:dev:win  # Windows\n\n# Open Prisma Studio\nnpm run db:studio\n\n# Development migrations\nnpm run db:migrate:dev      # Unix/Mac\nnpm run db:migrate:dev:win  # Windows\n```\n\n### Testing\n```bash\nnpm test    # Run tests with watch mode\n```\n\n## Architecture Overview\n\n### Core Structure\n- **Multi-tenant SaaS**: Complete instance isolation with per-tenant authentication\n- **Multi-provider database**: PostgreSQL and MySQL via Prisma ORM with provider-specific schemas and migrations\n- **WhatsApp integrations**: Baileys, Meta Business API, and Evolution API with unified interface\n- **Event-driven architecture**: EventEmitter2 for internal events + WebSocket, RabbitMQ, SQS, NATS, Pusher for external events\n- **Microservices pattern**: Modular integrations for chatbots, storage, and external services\n\n### Directory Layout\n```\nsrc/\n├── api/\n│   ├── controllers/     # HTTP route handlers (thin layer)\n│   ├── services/        # Business logic (core functionality)\n│   ├── repository/      # Data access layer (Prisma)\n│   ├── dto/            # Data Transfer Objects (simple classes)\n│   ├── guards/         # Authentication/authorization middleware\n│   ├── integrations/   # External service integrations\n│   │   ├── channel/    # WhatsApp providers (Baileys, Business API, Evolution)\n│   │   ├── chatbot/    # AI/Bot integrations (OpenAI, Dify, Typebot, Chatwoot)\n│   │   ├── event/      # Event systems (WebSocket, RabbitMQ, SQS, NATS, Pusher)\n│   │   └── storage/    # File storage (S3, MinIO)\n│   ├── routes/         # Express route definitions (RouterBroker pattern)\n│   └── types/          # TypeScript type definitions\n├── config/             # Environment and app configuration\n├── cache/             # Redis and local cache implementations\n├── exceptions/        # Custom HTTP exception classes\n├── utils/            # Shared utilities and helpers\n└── validate/         # JSONSchema7 validation schemas\n```\n\n### Key Integration Points\n\n**Channel Integrations** (`src/api/integrations/channel/`):\n- **Baileys**: WhatsApp Web client with QR code authentication\n- **Business API**: Official Meta WhatsApp Business API\n- **Evolution API**: Custom WhatsApp integration\n- Connection lifecycle management per instance with automatic reconnection\n\n**Chatbot Integrations** (`src/api/integrations/chatbot/`):\n- **EvolutionBot**: Native chatbot with trigger system\n- **Chatwoot**: Customer service platform integration\n- **Typebot**: Visual chatbot flow builder\n- **OpenAI**: AI capabilities including GPT and Whisper (audio transcription)\n- **Dify**: AI agent workflow platform\n- **Flowise**: LangChain visual builder\n- **N8N**: Workflow automation platform\n- **EvoAI**: Custom AI integration\n\n**Event Integrations** (`src/api/integrations/event/`):\n- **WebSocket**: Real-time Socket.io connections\n- **RabbitMQ**: Message queue for async processing\n- **Amazon SQS**: Cloud-based message queuing\n- **NATS**: High-performance messaging system\n- **Pusher**: Real-time push notifications\n\n**Storage Integrations** (`src/api/integrations/storage/`):\n- **AWS S3**: Cloud object storage\n- **MinIO**: Self-hosted S3-compatible storage\n- Media file management and URL generation\n\n### Database Schema Management\n- Separate schema files: `postgresql-schema.prisma` and `mysql-schema.prisma`\n- Environment variable `DATABASE_PROVIDER` determines active database\n- Migration folders are provider-specific and auto-selected during deployment\n\n### Authentication & Security\n- **API key-based authentication** via `apikey` header (global or per-instance)\n- **Instance-specific tokens** for WhatsApp connection authentication\n- **Guards system** for route protection and authorization\n- **Input validation** using JSONSchema7 with RouterBroker `dataValidate`\n- **Rate limiting** and security middleware\n- **Webhook signature validation** for external integrations\n\n## Important Implementation Details\n\n### WhatsApp Instance Management\n- Each WhatsApp connection is an \"instance\" with unique name\n- Instance data stored in database with connection state\n- Session persistence in database or file system (configurable)\n- Automatic reconnection handling with exponential backoff\n\n### Message Queue Architecture\n- Supports RabbitMQ, Amazon SQS, and WebSocket for events\n- Event types: message.received, message.sent, connection.update, etc.\n- Configurable per instance which events to send\n\n### Media Handling\n- Local storage or S3/Minio for media files\n- Automatic media download from WhatsApp\n- Media URL generation for external access\n- Support for audio transcription via OpenAI\n\n### Multi-tenancy Support\n- Instance isolation at database level\n- Separate webhook configurations per instance\n- Independent integration settings per instance\n\n## Environment Configuration\n\nKey environment variables are defined in `.env.example`. The system uses a strongly-typed configuration system via `src/config/env.config.ts`.\n\nCritical configurations:\n- `DATABASE_PROVIDER`: postgresql or mysql\n- `DATABASE_CONNECTION_URI`: Database connection string\n- `AUTHENTICATION_API_KEY`: Global API authentication\n- `REDIS_ENABLED`: Enable Redis cache\n- `RABBITMQ_ENABLED`/`SQS_ENABLED`: Message queue options\n\n## Development Guidelines\n\nThe project follows comprehensive development standards defined in `.cursor/rules/`:\n\n### Core Principles\n- **Always respond in Portuguese (PT-BR)** for user communication\n- **Follow established architecture patterns** (Service Layer, RouterBroker, etc.)\n- **Robust error handling** with retry logic and graceful degradation\n- **Multi-database compatibility** (PostgreSQL and MySQL)\n- **Security-first approach** with input validation and rate limiting\n- **Performance optimizations** with Redis caching and connection pooling\n\n### Code Standards\n- **TypeScript strict mode** with full type coverage\n- **JSONSchema7** for input validation (not class-validator)\n- **Conventional Commits** enforced by commitlint\n- **ESLint + Prettier** for code formatting\n- **Service Object pattern** for business logic\n- **RouterBroker pattern** for route handling with `dataValidate`\n\n### Architecture Patterns\n- **Multi-tenant isolation** at database and instance level\n- **Event-driven communication** with EventEmitter2\n- **Microservices integration** pattern for external services\n- **Connection pooling** and lifecycle management\n- **Caching strategy** with Redis primary and Node-cache fallback\n\n## Testing Approach\n\nCurrently, the project has minimal formal testing infrastructure:\n- **Manual testing** is the primary approach\n- **Integration testing** in development environment\n- **No unit test suite** currently implemented\n- Test files can be placed in `test/` directory as `*.test.ts`\n- Run `npm test` for watch mode development testing\n\n### Recommended Testing Strategy\n- Focus on **critical business logic** in services\n- **Mock external dependencies** (WhatsApp APIs, databases)\n- **Integration tests** for API endpoints\n- **Manual testing** for WhatsApp connection flows\n\n## Deployment Considerations\n\n- Docker support with `Dockerfile` and `docker-compose.yaml`\n- Graceful shutdown handling for connections\n- Health check endpoints for monitoring\n- Sentry integration for error tracking\n- Telemetry for usage analytics (non-sensitive data only)"
  },
  {
    "path": "Docker/kafka/docker-compose.yaml",
    "content": "version: '3.3'\n\nservices:\n  zookeeper:\n    container_name: zookeeper\n    image: confluentinc/cp-zookeeper:7.5.0\n    environment:\n      - ZOOKEEPER_CLIENT_PORT=2181\n      - ZOOKEEPER_TICK_TIME=2000\n      - ZOOKEEPER_SYNC_LIMIT=2\n    volumes:\n      - zookeeper_data:/var/lib/zookeeper/\n    ports:\n      - 2181:2181\n\n  kafka:\n    container_name: kafka\n    image: confluentinc/cp-kafka:7.5.0\n    depends_on:\n      - zookeeper\n    environment:\n      - KAFKA_BROKER_ID=1\n      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181\n      - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,OUTSIDE:PLAINTEXT\n      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092,OUTSIDE://host.docker.internal:9094\n      - KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT\n      - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1\n      - KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1\n      - KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1\n      - KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS=0\n      - KAFKA_AUTO_CREATE_TOPICS_ENABLE=true\n      - KAFKA_LOG_RETENTION_HOURS=168\n      - KAFKA_LOG_SEGMENT_BYTES=1073741824\n      - KAFKA_LOG_RETENTION_CHECK_INTERVAL_MS=300000\n      - KAFKA_COMPRESSION_TYPE=gzip\n    ports:\n      - 29092:29092\n      - 9092:9092\n      - 9094:9094\n    volumes:\n      - kafka_data:/var/lib/kafka/data\n\nvolumes:\n  zookeeper_data:\n  kafka_data:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge"
  },
  {
    "path": "Docker/minio/docker-compose.yaml",
    "content": "version: '3.3'\n\nservices:\n  minio:\n    container_name: minio\n    image: quay.io/minio/minio\n    networks:\n      - evolution-net\n    command: server /data --console-address \":9001\"\n    restart: always\n    ports:\n      - 5432:5432\n    environment:\n      - MINIO_ROOT_USER=USER\n      - MINIO_ROOT_PASSWORD=PASSWORD\n      - MINIO_BROWSER_REDIRECT_URL=http:/localhost:9001\n      - MINIO_SERVER_URL=http://localhost:9000\n    volumes:\n      - minio_data:/data\n    expose:\n      - 9000\n      - 9001\n\nvolumes:\n  minio_data:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n"
  },
  {
    "path": "Docker/mysql/docker-compose.yaml",
    "content": "version: '3.3'\n\nservices:\n  mysql:\n    container_name: mysql\n    image: percona/percona-server:8.0\n    networks:\n      - evolution-net\n    restart: always\n    ports:\n      - 3306:3306\n    environment:\n      - MYSQL_ROOT_PASSWORD=root\n      - TZ=America/Bahia\n    volumes:\n      - mysql_data:/var/lib/mysql\n    expose:\n      - 3306\n\nvolumes:\n  mysql_data:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n"
  },
  {
    "path": "Docker/postgres/docker-compose.yaml",
    "content": "version: '3.3'\n\nservices:\n  postgres:\n    container_name: postgres\n    image: postgres:15\n    networks:\n      - evolution-net\n    command: [\"postgres\", \"-c\", \"max_connections=1000\"]\n    restart: always\n    ports:\n      - 5432:5432\n    environment:\n      - POSTGRES_PASSWORD=PASSWORD\n    volumes:\n      - postgres_data:/var/lib/postgresql/data\n    expose:\n      - 5432\n\n  pgadmin:\n    image: dpage/pgadmin4:latest\n    networks:\n      - evolution-net\n    environment:\n      - PGADMIN_DEFAULT_EMAIL=EMAIL\n      - PGADMIN_DEFAULT_PASSWORD=PASSWORD  \n    volumes:\n      - pgadmin_data:/var/lib/pgadmin\n    ports:\n      - 4000:80\n    links:\n      - postgres\n\nvolumes:\n  postgres_data:\n  pgadmin_data:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n"
  },
  {
    "path": "Docker/rabbitmq/docker-compose.yaml",
    "content": "version: '3.3'\n\nservices:\n  rabbitmq:\n    container_name: rabbitmq\n    image: rabbitmq:management\n    environment:\n      - RABBITMQ_ERLANG_COOKIE=33H2CdkzF5WrnJ4ud6nkUdRTKXvbCHeFjvVL71p\n      - RABBITMQ_DEFAULT_VHOST=default\n      - RABBITMQ_DEFAULT_USER=USER\n      - RABBITMQ_DEFAULT_PASS=PASSWORD\n    volumes:\n      - rabbitmq_data:/var/lib/rabbitmq/\n    ports:\n      - 5672:5672\n      - 15672:15672\n\nvolumes:\n  rabbitmq_data:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n"
  },
  {
    "path": "Docker/redis/docker-compose.yaml",
    "content": "version: '3.3'\n\nservices:\n  redis:\n    image: redis:latest\n    networks:\n      - evolution-net\n    container_name: redis\n    command: >\n      redis-server --port 6379 --appendonly yes\n    volumes:\n      - evolution_redis:/data\n    ports:\n      - 6379:6379\n\nvolumes:\n  evolution_redis:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n"
  },
  {
    "path": "Docker/scripts/deploy_database.sh",
    "content": "#!/bin/bash\n\nsource ./Docker/scripts/env_functions.sh\n\nif [ \"$DOCKER_ENV\" != \"true\" ]; then\n    export_env_vars\nfi\n\nif [[ \"$DATABASE_PROVIDER\" == \"postgresql\" || \"$DATABASE_PROVIDER\" == \"mysql\" || \"$DATABASE_PROVIDER\" == \"psql_bouncer\" ]]; then\n    export DATABASE_URL\n    echo \"Deploying migrations for $DATABASE_PROVIDER\"\n    echo \"Database URL: $DATABASE_URL\"\n    # rm -rf ./prisma/migrations\n    # cp -r ./prisma/$DATABASE_PROVIDER-migrations ./prisma/migrations\n    npm run db:deploy\n    if [ $? -ne 0 ]; then\n        echo \"Migration failed\"\n        exit 1\n    else\n        echo \"Migration succeeded\"\n    fi\n    npm run db:generate\n    if [ $? -ne 0 ]; then\n        echo \"Prisma generate failed\"\n        exit 1\n    else\n        echo \"Prisma generate succeeded\"\n    fi\nelse\n    echo \"Error: Database provider $DATABASE_PROVIDER invalid.\"\n    exit 1\nfi\n"
  },
  {
    "path": "Docker/scripts/env_functions.sh",
    "content": "export_env_vars() {\n    if [ -f .env ]; then\n        while IFS='=' read -r key value; do\n            if [[ -z \"$key\" || \"$key\" =~ ^\\s*# || -z \"$value\" ]]; then\n                continue\n            fi\n\n            key=$(echo \"$key\" | tr -d '[:space:]')\n            value=$(echo \"$value\" | tr -d '[:space:]')\n            value=$(echo \"$value\" | tr -d \"'\" | tr -d \"\\\"\")\n\n            export \"$key=$value\"\n        done < .env\n    else\n        echo \".env file not found\"\n        exit 1\n    fi\n}\n"
  },
  {
    "path": "Docker/scripts/generate_database.sh",
    "content": "#!/bin/bash\n\nsource ./Docker/scripts/env_functions.sh\n\nif [ \"$DOCKER_ENV\" != \"true\" ]; then\n    export_env_vars\nfi\n\nif [[ \"$DATABASE_PROVIDER\" == \"postgresql\" || \"$DATABASE_PROVIDER\" == \"mysql\" || \"$DATABASE_PROVIDER\" == \"psql_bouncer\" ]]; then\n    export DATABASE_URL\n    echo \"Generating database for $DATABASE_PROVIDER\"\n    echo \"Database URL: $DATABASE_URL\"\n    npm run db:generate\n    if [ $? -ne 0 ]; then\n        echo \"Prisma generate failed\"\n        exit 1\n    else\n        echo \"Prisma generate succeeded\"\n    fi\nelse\n    echo \"Error: Database provider $DATABASE_PROVIDER invalid.\"\n    exit 1\nfi"
  },
  {
    "path": "Docker/swarm/evolution_api_v2.yaml",
    "content": "version: \"3.7\"\n\nservices:\n  evolution_v2:\n    image: evoapicloud/evolution-api:v2.3.7\n    volumes:\n      - evolution_instances:/evolution/instances\n    networks:\n      - network_public\n    environment:\n      - SERVER_URL=https://evo2.site.com\n      - DEL_INSTANCE=false\n      - DATABASE_PROVIDER=postgresql\n      - DATABASE_CONNECTION_URI=postgresql://postgres:SENHA@postgres:5432/evolution\n      - DATABASE_SAVE_DATA_INSTANCE=true\n      - DATABASE_SAVE_DATA_NEW_MESSAGE=true\n      - DATABASE_SAVE_MESSAGE_UPDATE=true\n      - DATABASE_SAVE_DATA_CONTACTS=true\n      - DATABASE_SAVE_DATA_CHATS=true\n      - DATABASE_SAVE_DATA_LABELS=true\n      - DATABASE_SAVE_DATA_HISTORIC=true\n      - DATABASE_CONNECTION_CLIENT_NAME=evolution_v2\n      - RABBITMQ_ENABLED=false\n      - RABBITMQ_URI=amqp://admin:admin@rabbitmq:5672/default\n      - RABBITMQ_EXCHANGE_NAME=evolution_v2\n      - RABBITMQ_GLOBAL_ENABLED=false\n      - RABBITMQ_EVENTS_APPLICATION_STARTUP=false\n      - RABBITMQ_EVENTS_INSTANCE_CREATE=false\n      - RABBITMQ_EVENTS_INSTANCE_DELETE=false\n      - RABBITMQ_EVENTS_QRCODE_UPDATED=false\n      - RABBITMQ_EVENTS_MESSAGES_SET=false\n      - RABBITMQ_EVENTS_MESSAGES_UPSERT=true\n      - RABBITMQ_EVENTS_MESSAGES_EDITED=false\n      - RABBITMQ_EVENTS_MESSAGES_UPDATE=false\n      - RABBITMQ_EVENTS_MESSAGES_DELETE=false\n      - RABBITMQ_EVENTS_SEND_MESSAGE=false\n      - RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE=false\n      - RABBITMQ_EVENTS_CONTACTS_SET=false\n      - RABBITMQ_EVENTS_CONTACTS_UPSERT=false\n      - RABBITMQ_EVENTS_CONTACTS_UPDATE=false\n      - RABBITMQ_EVENTS_PRESENCE_UPDATE=false\n      - RABBITMQ_EVENTS_CHATS_SET=false\n      - RABBITMQ_EVENTS_CHATS_UPSERT=false\n      - RABBITMQ_EVENTS_CHATS_UPDATE=false\n      - RABBITMQ_EVENTS_CHATS_DELETE=false\n      - RABBITMQ_EVENTS_GROUPS_UPSERT=false\n      - RABBITMQ_EVENTS_GROUP_UPDATE=false\n      - RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE=false\n      - RABBITMQ_EVENTS_CONNECTION_UPDATE=true\n      - RABBITMQ_EVENTS_CALL=false\n      - RABBITMQ_EVENTS_TYPEBOT_START=false\n      - RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS=false\n      - SQS_ENABLED=false\n      - SQS_ACCESS_KEY_ID=\n      - SQS_SECRET_ACCESS_KEY=\n      - SQS_ACCOUNT_ID=\n      - SQS_REGION=\n      - WEBSOCKET_ENABLED=false\n      - WEBSOCKET_GLOBAL_EVENTS=false\n      - WA_BUSINESS_TOKEN_WEBHOOK=evolution\n      - WA_BUSINESS_URL=https://graph.facebook.com\n      - WA_BUSINESS_VERSION=v20.0\n      - WA_BUSINESS_LANGUAGE=pt_BR\n      - WEBHOOK_GLOBAL_URL=''\n      - WEBHOOK_GLOBAL_ENABLED=false\n      - WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false\n      - WEBHOOK_EVENTS_APPLICATION_STARTUP=false\n      - WEBHOOK_EVENTS_QRCODE_UPDATED=true\n      - WEBHOOK_EVENTS_MESSAGES_SET=true\n      - WEBHOOK_EVENTS_MESSAGES_UPSERT=true\n      - WEBHOOK_EVENTS_MESSAGES_EDITED=true\n      - WEBHOOK_EVENTS_MESSAGES_UPDATE=true\n      - WEBHOOK_EVENTS_MESSAGES_DELETE=true\n      - WEBHOOK_EVENTS_SEND_MESSAGE=true\n      - WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=true\n      - WEBHOOK_EVENTS_CONTACTS_SET=true\n      - WEBHOOK_EVENTS_CONTACTS_UPSERT=true\n      - WEBHOOK_EVENTS_CONTACTS_UPDATE=true\n      - WEBHOOK_EVENTS_PRESENCE_UPDATE=true\n      - WEBHOOK_EVENTS_CHATS_SET=true\n      - WEBHOOK_EVENTS_CHATS_UPSERT=true\n      - WEBHOOK_EVENTS_CHATS_UPDATE=true\n      - WEBHOOK_EVENTS_CHATS_DELETE=true\n      - WEBHOOK_EVENTS_GROUPS_UPSERT=true\n      - WEBHOOK_EVENTS_GROUPS_UPDATE=true\n      - WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true\n      - WEBHOOK_EVENTS_CONNECTION_UPDATE=true\n      - WEBHOOK_EVENTS_LABELS_EDIT=true\n      - WEBHOOK_EVENTS_LABELS_ASSOCIATION=true\n      - WEBHOOK_EVENTS_CALL=true\n      - WEBHOOK_EVENTS_TYPEBOT_START=false\n      - WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false\n      - WEBHOOK_EVENTS_ERRORS=false\n      - WEBHOOK_EVENTS_ERRORS_WEBHOOK=\n      - CONFIG_SESSION_PHONE_CLIENT=Evolution API V2\n      - CONFIG_SESSION_PHONE_NAME=Chrome\n      - QRCODE_LIMIT=30\n      - OPENAI_ENABLED=true\n      - DIFY_ENABLED=true\n      - TYPEBOT_ENABLED=true\n      - TYPEBOT_API_VERSION=latest\n      - CHATWOOT_ENABLED=true\n      - CHATWOOT_MESSAGE_READ=true\n      - CHATWOOT_MESSAGE_DELETE=true\n      - CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://postgres:PASSWORD@postgres:5432/chatwoot?sslmode=disable\n      - CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true\n      - CACHE_REDIS_ENABLED=true\n      - CACHE_REDIS_URI=redis://evo_redis:6379/1\n      - CACHE_REDIS_PREFIX_KEY=evolution_v2\n      - CACHE_REDIS_SAVE_INSTANCES=false\n      - CACHE_LOCAL_ENABLED=false\n      - S3_ENABLED=true\n      - S3_ACCESS_KEY=\n      - S3_SECRET_KEY=\n      - S3_BUCKET=evolution\n      - S3_PORT=443\n      - S3_ENDPOINT=files.site.com\n      - S3_USE_SSL=true\n      - AUTHENTICATION_API_KEY=429683C4C977415CAAFCCE10F7D57E11\n      - AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true\n      - LANGUAGE=en\n    deploy:\n      mode: replicated\n      replicas: 1\n      placement:\n        constraints:\n          - node.hostname == evolution-manager\n      labels:\n        - traefik.enable=true\n        - traefik.http.routers.evolution_v2.rule=Host(`evo2.site.com`)\n        - traefik.http.routers.evolution_v2.entrypoints=websecure\n        - traefik.http.routers.evolution_v2.tls.certresolver=letsencryptresolver\n        - traefik.http.routers.evolution_v2.priority=1\n        - traefik.http.routers.evolution_v2.service=evolution_v2\n        - traefik.http.services.evolution_v2.loadbalancer.server.port=8080\n        - traefik.http.services.evolution_v2.loadbalancer.passHostHeader=true\n\nvolumes:\n  evolution_instances:\n    external: true\n    name: evolution_v2_data\n\nnetworks:\n  network_public:\n    external: true\n    name: network_public\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node:24-alpine AS builder\n\nRUN apk update && \\\n    apk add --no-cache git ffmpeg wget curl bash openssl\n\nLABEL version=\"2.3.1\" description=\"Api to control whatsapp features through http requests.\" \nLABEL maintainer=\"Davidson Gomes\" git=\"https://github.com/DavidsonGomes\"\nLABEL contact=\"contato@evolution-api.com\"\n\nWORKDIR /evolution\n\nCOPY ./package*.json ./\nCOPY ./tsconfig.json ./\nCOPY ./tsup.config.ts ./\n\nRUN npm ci --silent\n\nCOPY ./src ./src\nCOPY ./public ./public\nCOPY ./prisma ./prisma\nCOPY ./manager ./manager\nCOPY ./.env.example ./.env\nCOPY ./runWithProvider.js ./\n\nCOPY ./Docker ./Docker\n\nRUN chmod +x ./Docker/scripts/* && dos2unix ./Docker/scripts/*\n\nRUN ./Docker/scripts/generate_database.sh\n\nRUN npm run build\n\nFROM node:24-alpine AS final\n\nRUN apk update && \\\n    apk add tzdata ffmpeg bash openssl\n\nENV TZ=America/Sao_Paulo\nENV DOCKER_ENV=true\n\nWORKDIR /evolution\n\nCOPY --from=builder /evolution/package.json ./package.json\nCOPY --from=builder /evolution/package-lock.json ./package-lock.json\n\nCOPY --from=builder /evolution/node_modules ./node_modules\nCOPY --from=builder /evolution/dist ./dist\nCOPY --from=builder /evolution/prisma ./prisma\nCOPY --from=builder /evolution/manager ./manager\nCOPY --from=builder /evolution/public ./public\nCOPY --from=builder /evolution/.env ./.env\nCOPY --from=builder /evolution/Docker ./Docker\nCOPY --from=builder /evolution/runWithProvider.js ./runWithProvider.js\nCOPY --from=builder /evolution/tsup.config.ts ./tsup.config.ts\n\nENV DOCKER_ENV=true\n\nEXPOSE 8080\n\nENTRYPOINT [\"/bin/bash\", \"-c\", \". ./Docker/scripts/deploy_database.sh && npm run start:prod\" ]\n"
  },
  {
    "path": "Dockerfile.metrics",
    "content": "FROM evoapicloud/evolution-api:latest AS base\nWORKDIR /evolution\n\n# Copiamos apenas o necessário para recompilar o dist com as mudanças locais\nCOPY tsconfig.json tsup.config.ts package.json ./\nCOPY src ./src\n\n# Recompila usando os node_modules já presentes na imagem base\nRUN npm run build\n\n# Runtime final: reaproveita a imagem oficial e apenas sobrepõe o dist\nFROM evoapicloud/evolution-api:latest AS final\nWORKDIR /evolution\nCOPY --from=base /evolution/dist ./dist\n\nENV PROMETHEUS_METRICS=true\n\n# Entrada original da imagem oficial já sobe o app em /evolution\n\n"
  },
  {
    "path": "Extras/chatwoot/configurar_admin.json",
    "content": "{\n  \"name\": \"[Evolution] Configurar Admin\",\n  \"nodes\": [\n    {\n      \"parameters\": {\n        \"values\": {\n          \"string\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"CHATWOOT_ADMIN_USER_TOKEN\"\n            },\n            {\n              \"name\": \"chatwoot_url\",\n              \"value\": \"https://CHATWOOT_URL\"\n            },\n            {\n              \"name\": \"n8n_url\",\n              \"value\": \"https://N8N_URL\"\n            },\n            {\n              \"name\": \"organization\",\n              \"value\": \"ORGANIZATION_NAME\"\n            },\n            {\n              \"name\": \"logo\",\n              \"value\": \"ORGANIZATION_LOGO\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"7a89a538-2cae-4032-8896-09627c07bc68\",\n      \"name\": \"Info Base\",\n      \"type\": \"n8n-nodes-base.set\",\n      \"typeVersion\": 2,\n      \"position\": [\n        620,\n        480\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/1/contacts/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"inbox_id\\\": {{ $('Cria Inbox Start').item.json[\\\"id\\\"] }},\\n    \\\"name\\\": \\\"Bot {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"phone_number\\\": \\\"+123456\\\",\\n    \\\"avatar_url\\\": \\\"{{ $('Info Base').item.json[\\\"logo\\\"] }}\\\"\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"12a39df3-6b95-4f83-a0bc-50b25adaca7f\",\n      \"name\": \"Cria Contato Bot\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        1020,\n        480\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/1/inboxes/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"name\\\": \\\"Start {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"channel\\\": {\\n        \\\"type\\\": \\\"api\\\",\\n        \\\"website_url\\\": \\\"\\\"\\n    }\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"bed7c54d-e232-4fe4-9584-0515e9679868\",\n      \"name\": \"Cria Inbox Start\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        820,\n        480\n      ]\n    },\n    {\n      \"parameters\": {},\n      \"id\": \"36ada769-a757-4193-989b-0cc4ea504b80\",\n      \"name\": \"When clicking \\\"Execute Workflow\\\"\",\n      \"type\": \"n8n-nodes-base.manualTrigger\",\n      \"typeVersion\": 1,\n      \"position\": [\n        420,\n        480\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/1/automation_rules/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"name\\\": \\\"Create Company Chatwoot\\\",\\n    \\\"description\\\": \\\"Create Company Chatwoot\\\",\\n    \\\"event_name\\\": \\\"message_created\\\",\\n    \\\"active\\\": true,\\n    \\\"actions\\\": \\n    [\\n        {\\n            \\\"action_name\\\": \\\"send_webhook_event\\\",\\n            \\\"action_params\\\": [\\\"{{ $('Info Base').item.json[\\\"n8n_url\\\"] }}/webhook/criadorchatwoot\\\"]\\n        }\\n    ],\\n    \\\"conditions\\\": \\n    [\\n        {\\n            \\\"attribute_key\\\": \\\"content\\\",\\n            \\\"filter_operator\\\": \\\"contains\\\",\\n            \\\"query_operator\\\": \\\"and\\\",\\n            \\\"values\\\": [\\\"Tema Criador de Empresa:\\\"]\\n        },\\n        {\\n            \\\"attribute_key\\\": \\\"phone_number\\\",\\n            \\\"filter_operator\\\": \\\"equal_to\\\",\\n            \\\"values\\\": [\\\"+123456\\\"]\\n        }\\n    ]\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"f5bbb285-71a8-4c58-a4d7-e56002d697f0\",\n      \"name\": \"Cria Automação Empresas\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        1220,\n        480\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/1/automation_rules/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"name\\\": \\\"Create Inbox {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"description\\\": \\\"Create Inbox {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"event_name\\\": \\\"message_created\\\",\\n    \\\"active\\\": true,\\n    \\\"actions\\\": \\n    [\\n        {\\n            \\\"action_name\\\": \\\"send_webhook_event\\\",\\n            \\\"action_params\\\": [\\\"{{ $('Info Base').item.json[\\\"n8n_url\\\"] }}/webhook/inbox_whatsapp?utoken={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}&organization={{ $('Info Base').item.json[\\\"organization\\\"] }}\\\"]\\n        }\\n    ],\\n    \\\"conditions\\\": \\n    [\\n        {\\n            \\\"attribute_key\\\": \\\"content\\\",\\n            \\\"filter_operator\\\": \\\"contains\\\",\\n            \\\"query_operator\\\": \\\"and\\\",\\n            \\\"values\\\": [\\\"start:\\\"]\\n        },\\n       \\n         {\\n            \\\"attribute_key\\\": \\\"phone_number\\\",\\n            \\\"filter_operator\\\": \\\"equal_to\\\",\\n            \\\"query_operator\\\": \\\"or\\\",\\n            \\\"values\\\": [\\\"+123456\\\"]\\n        },\\n\\n\\n        {\\n            \\\"attribute_key\\\": \\\"content\\\",\\n            \\\"filter_operator\\\": \\\"contains\\\",\\n            \\\"query_operator\\\": \\\"and\\\",\\n            \\\"values\\\": [\\\"new_instance:\\\"]\\n        },\\n        {\\n            \\\"attribute_key\\\": \\\"phone_number\\\",\\n            \\\"filter_operator\\\": \\\"equal_to\\\",\\n            \\\"values\\\": [\\\"+123456\\\"]\\n        }\\n    ]\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"a36bebdc-a318-40a2-8532-c7f476f8adb7\",\n      \"name\": \"Cria Automação Inboxes\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        1420,\n        480\n      ]\n    },\n    {\n      \"parameters\": {\n        \"content\": \"## Workflow Para Configurar admin\\n**Aqui você prepara o Chatwoot Principal com um usuário (Superadmin) que poderá criar empresas e caixas de entrada**\\n**Instruções**\\n**No node Info Base, configure as variáveis de seu Chatwoot e N8N**\\n**Obs: A variável api_access_token é o token do usuário que irá poder criar as empresas**\",\n        \"width\": 894.6435495898575\n      },\n      \"id\": \"db66e867-e9f4-452d-b521-725eeac652c8\",\n      \"name\": \"Sticky Note\",\n      \"type\": \"n8n-nodes-base.stickyNote\",\n      \"typeVersion\": 1,\n      \"position\": [\n        420,\n        280\n      ]\n    }\n  ],\n  \"pinData\": {},\n  \"connections\": {\n    \"Info Base\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Inbox Start\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Contato Bot\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Automação Empresas\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Inbox Start\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Contato Bot\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"When clicking \\\"Execute Workflow\\\"\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Info Base\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Automação Empresas\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Automação Inboxes\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    }\n  },\n  \"active\": false,\n  \"settings\": {},\n  \"versionId\": \"78f155dc-7809-4bfc-9282-63f49b07fc4d\",\n  \"id\": \"BSATyGpGWLR4ZwNm\",\n  \"meta\": {\n    \"instanceId\": \"4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906\"\n  },\n  \"tags\": []\n}"
  },
  {
    "path": "Extras/chatwoot/criador_de_empresas.json",
    "content": "{\n  \"name\": \"[Evolution] Criador de Empresas\",\n  \"nodes\": [\n    {\n      \"parameters\": {\n        \"httpMethod\": \"POST\",\n        \"path\": \"criadorchatwoot\",\n        \"options\": {}\n      },\n      \"id\": \"5a47c10a-e43c-4fa5-baad-4b6cc511bfcd\",\n      \"name\": \"Webhook\",\n      \"type\": \"n8n-nodes-base.webhook\",\n      \"typeVersion\": 1,\n      \"position\": [\n        1420,\n        860\n      ],\n      \"webhookId\": \"6fe428e3-1752-453c-9358-abf18b793387\"\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/platform/api/v1/accounts\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"bodyParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"name\",\n              \"value\": \"={{ $json.name_company }}\"\n            },\n            {\n              \"name\": \"locale\",\n              \"value\": \"pt_BR\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"8295c119-3a96-424e-9386-43d75f6816f5\",\n      \"name\": \"Cria Conta\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2020,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/platform/api/v1/users\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"bodyParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"name\",\n              \"value\": \"={{ $('Info Base').item.json.name_admin }}\"\n            },\n            {\n              \"name\": \"email\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"email\\\"] }}\"\n            },\n            {\n              \"name\": \"password\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"password\\\"] }}\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"4fe5007a-3a6b-490a-a446-e45cc168189f\",\n      \"name\": \"Cria Usuario\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2220,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/platform/api/v1/accounts/{{ $node[\\\"Cria Conta\\\"].json[\\\"id\\\"] }}/account_users\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json[\\\"api_access_token\\\"] }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"bodyParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"user_id\",\n              \"value\": \"={{ $node[\\\"Cria Usuario\\\"].json[\\\"id\\\"] }}\"\n            },\n            {\n              \"name\": \"role\",\n              \"value\": \"administrator\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"848c55e2-5678-4291-9602-c94d994da95b\",\n      \"name\": \"Add Usuario a Conta\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2420,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"fromEmail\": \"={{ $('Info Base').item.json[\\\"from_email\\\"] }}\",\n        \"toEmail\": \"={{ $('LimpaDados').item.json.email }}\",\n        \"subject\": \"=Bem vindo à {{ $('Info Base').item.json[\\\"organization\\\"] }}\",\n        \"text\": \"=Olá seja bem vindo:\\n\\nAbaixo segue seus dados de acesso:\\n\\nURL: {{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}\\n\\nuser: {{ $('LimpaDados').item.json[\\\"email\\\"] }}\\n\\nSenha: {{ $('LimpaDados').item.json[\\\"password\\\"] }}\",\n        \"options\": {}\n      },\n      \"id\": \"27f3b24f-1cf2-4d0d-a354-ecba066059f6\",\n      \"name\": \"Send Email\",\n      \"type\": \"n8n-nodes-base.emailSend\",\n      \"typeVersion\": 2,\n      \"position\": [\n        3220,\n        860\n      ],\n      \"credentials\": {\n        \"smtp\": {\n          \"id\": \"6BxluEUV8zrXKoVG\",\n          \"name\": \"[Dgcode] SMTP\"\n        }\n      }\n    },\n    {\n      \"parameters\": {\n        \"values\": {\n          \"string\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"CHATWOOT_PLATFORM_TOKEN\"\n            },\n            {\n              \"name\": \"chatwoot_url\",\n              \"value\": \"https://CHATWOOT_URL\"\n            },\n            {\n              \"name\": \"n8n_url\",\n              \"value\": \"https://N8N_URL\"\n            },\n            {\n              \"name\": \"organization\",\n              \"value\": \"ORGANIZATION_NAME\"\n            },\n            {\n              \"name\": \"logo\",\n              \"value\": \"ORGANIZATION_LOGO\"\n            },\n            {\n              \"name\": \"from_email\",\n              \"value\": \"FROM_EMAIL\"\n            },\n            {\n              \"name\": \"name\",\n              \"value\": \"={{ $json.name_company }}\"\n            },\n            {\n              \"name\": \"email\",\n              \"value\": \"={{ $json.email }}\"\n            },\n            {\n              \"name\": \"password\",\n              \"value\": \"={{ $json.password }}\"\n            },\n            {\n              \"name\": \"name_company\",\n              \"value\": \"={{ $json.name_company }}\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"38b4069d-e51e-4db7-933f-941b1be6d124\",\n      \"name\": \"Info Base\",\n      \"type\": \"n8n-nodes-base.set\",\n      \"typeVersion\": 2,\n      \"position\": [\n        1820,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"keepOnlySet\": true,\n        \"values\": {\n          \"string\": [\n            {\n              \"name\": \"name_admin\",\n              \"value\": \"={{$node[\\\"Webhook\\\"].json[\\\"body\\\"][\\\"messages\\\"][0][\\\"content\\\"].match(/Nome Usuario Administrador: ([^\\\\n]+)/)[1];}}\"\n            },\n            {\n              \"name\": \"name_company\",\n              \"value\": \"={{$node[\\\"Webhook\\\"].json[\\\"body\\\"][\\\"messages\\\"][0][\\\"content\\\"].match(/Nome da Empresa: ([^\\\\n]+)/)[1];}}\"\n            },\n            {\n              \"name\": \"email\",\n              \"value\": \"={{$node[\\\"Webhook\\\"].json[\\\"body\\\"][\\\"messages\\\"][0][\\\"content\\\"].match(/Email: ([^\\\\s]+)/)[1];}}\"\n            },\n            {\n              \"name\": \"password\",\n              \"value\": \"={{$node[\\\"Webhook\\\"].json[\\\"body\\\"][\\\"messages\\\"][0][\\\"content\\\"].match(/Senha: ([^\\\\s]+)/)[1];}}\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"28e29e73-aadc-49ca-bd6d-b57ee0160a21\",\n      \"name\": \"LimpaDados\",\n      \"type\": \"n8n-nodes-base.set\",\n      \"typeVersion\": 2,\n      \"position\": [\n        1620,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/{{ $('Add Usuario a Conta').item.json.account_id }}/contacts/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Cria Usuario').item.json.access_token }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"inbox_id\\\": {{ $('Cria Inbox Start').item.json[\\\"id\\\"] }},\\n    \\\"name\\\": \\\"Bot {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"phone_number\\\": \\\"+123456\\\",\\n    \\\"avatar_url\\\": \\\"{{ $('Info Base').item.json[\\\"logo\\\"] }}\\\"\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"bb671443-bdb4-4f56-99af-f0baef246a3e\",\n      \"name\": \"Cria Contato Bot\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2820,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/{{ $('Add Usuario a Conta').item.json.account_id }}/automation_rules/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Cria Usuario').item.json.access_token }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"name\\\": \\\"Create Inbox {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"description\\\": \\\"Create Inbox {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"event_name\\\": \\\"message_created\\\",\\n    \\\"active\\\": true,\\n    \\\"actions\\\": \\n    [\\n        {\\n            \\\"action_name\\\": \\\"send_webhook_event\\\",\\n            \\\"action_params\\\": [\\\"{{ $('Info Base').item.json[\\\"n8n_url\\\"] }}/webhook/inbox_whatsapp?utoken={{ $('Cria Usuario').item.json.access_token }}&organization={{ $('Info Base').item.json[\\\"organization\\\"] }}\\\"]\\n        }\\n    ],\\n    \\\"conditions\\\": \\n    [\\n        {\\n            \\\"attribute_key\\\": \\\"content\\\",\\n            \\\"filter_operator\\\": \\\"contains\\\",\\n            \\\"query_operator\\\": \\\"and\\\",\\n            \\\"values\\\": [\\\"start:\\\"]\\n        },\\n        {\\n            \\\"attribute_key\\\": \\\"phone_number\\\",\\n            \\\"filter_operator\\\": \\\"equal_to\\\",\\n            \\\"query_operator\\\": \\\"or\\\",\\n            \\\"values\\\": [\\\"+123456\\\"]\\n        },\\n        {\\n            \\\"attribute_key\\\": \\\"content\\\",\\n            \\\"filter_operator\\\": \\\"contains\\\",\\n            \\\"query_operator\\\": \\\"and\\\",\\n            \\\"values\\\": [\\\"new_instance:\\\"]\\n        },\\n        {\\n            \\\"attribute_key\\\": \\\"phone_number\\\",\\n            \\\"filter_operator\\\": \\\"equal_to\\\",\\n            \\\"values\\\": [\\\"+123456\\\"]\\n        }\\n    ]\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"e016a2af-b212-4e00-a3ff-8cd03530aa06\",\n      \"name\": \"Cria Automação\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        3020,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwoot_url\\\"] }}/api/v1/accounts/{{ $json.account_id }}/inboxes/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Cria Usuario').item.json.access_token }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n    \\\"name\\\": \\\"Start {{ $('Info Base').item.json[\\\"organization\\\"] }}\\\",\\n    \\\"channel\\\": {\\n        \\\"type\\\": \\\"api\\\",\\n        \\\"website_url\\\": \\\"\\\"\\n    }\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"d3c42148-8920-4c98-a874-eb7113f2dd22\",\n      \"name\": \"Cria Inbox Start\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2620,\n        860\n      ]\n    },\n    {\n      \"parameters\": {\n        \"content\": \"## Workflow Criador de Empresas\\n**Cria Contas (Empresas) e Usuários através de tema**\\n**Instruções**\\n**No node Info Base, configure as variáveis de seu Chatwoot e N8N**\\n**Obs: A variável api_access_token é o token PlatformApp encontrado no acesso ao Super Admin**\\n**Tema para criar novas empresa:**\\n\\nTema Criador de Empresa:\\n\\nNome Usuario Administrador: Joao Linhares\\nNome da Empresa: Oficina Linhates\\nEmail: machineteste24@gmail.com\\nSenha: Mfcd62!!\",\n        \"height\": 304.02684563758396,\n        \"width\": 1129.7777777777778\n      },\n      \"id\": \"d07516c0-4c8e-43ab-ba86-c8d063b09be5\",\n      \"name\": \"Sticky Note\",\n      \"type\": \"n8n-nodes-base.stickyNote\",\n      \"typeVersion\": 1,\n      \"position\": [\n        1420,\n        520\n      ]\n    }\n  ],\n  \"pinData\": {},\n  \"connections\": {\n    \"Webhook\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"LimpaDados\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Conta\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Usuario\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Usuario\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Add Usuario a Conta\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Add Usuario a Conta\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Inbox Start\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Info Base\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Conta\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"LimpaDados\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Info Base\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Contato Bot\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Automação\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Automação\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Send Email\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Cria Inbox Start\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Contato Bot\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    }\n  },\n  \"active\": true,\n  \"settings\": {},\n  \"versionId\": \"3ffd6d3f-6966-4de4-af8f-1fda464bc1b8\",\n  \"id\": \"79R6qQDtfyCwgYjJ\",\n  \"meta\": {\n    \"instanceId\": \"4ff16e963c7f5197d7e99e6239192860914312fea0ce2a9a7fd14d74a0a0e906\"\n  },\n  \"tags\": []\n}"
  },
  {
    "path": "Extras/chatwoot/criador_de_inbox.json",
    "content": "{\n  \"name\": \"criador_de_inbox_evo_v2.0\",\n  \"nodes\": [\n    {\n      \"parameters\": {\n        \"method\": \"POST\",\n        \"url\": \"={{ $json.evolution_url }}/instance/create\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"Content-Type\",\n              \"value\": \"application/json\"\n            },\n            {\n              \"name\": \"apikey\",\n              \"value\": \"={{ $json.global_api_key }}\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"bodyParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"instanceName\",\n              \"value\": \"={{ $json.instanceName }}\"\n            },\n            {\n              \"name\": \"qrcode\",\n              \"value\": \"={{ $json.qrcode }}\"\n            },\n            {\n              \"name\": \"chatwootAccountId\",\n              \"value\": \"={{ $json.chatwootAccountId }}\"\n            },\n            {\n              \"name\": \"chatwootToken\",\n              \"value\": \"={{ $json.chatwootToken }}\"\n            },\n            {\n              \"name\": \"chatwootUrl\",\n              \"value\": \"={{ $json.chatwootUrl }}\"\n            },\n            {\n              \"name\": \"chatwootSignMsg\",\n              \"value\": \"={{ $json.chatwootSignMsg }}\"\n            },\n            {\n              \"name\": \"chatwootReopenConversation\",\n              \"value\": \"={{ $json.chatwootReopenConversation }}\"\n            },\n            {\n              \"name\": \"chatwootConversationPending\",\n              \"value\": \"={{ $json.chatwootConversationPending }}\"\n            },\n            {\n              \"name\": \"rejectCall\",\n              \"value\": \"={{ $json.rejectCall }}\"\n            },\n            {\n              \"name\": \"msgCall\",\n              \"value\": \"={{ $json.msgCall }}\"\n            },\n            {\n              \"name\": \"groupsIgnore\",\n              \"value\": \"={{ $json.groupsIgnore }}\"\n            },\n            {\n              \"name\": \"alwaysOnline\",\n              \"value\": \"={{ $json.alwaysOnline }}\"\n            },\n            {\n              \"name\": \"readMessages\",\n              \"value\": \"={{ $json.readMessages }}\"\n            },\n            {\n              \"name\": \"readStatus\",\n              \"value\": \"={{ $json.readStatus }}\"\n            },\n            {\n              \"name\": \"chatwootImportContacts\",\n              \"value\": \"={{ $json.chatwootImportContacts }}\"\n            },\n            {\n              \"name\": \"chatwootImportMessages\",\n              \"value\": \"={{ $json.chatwootImportMessages }}\"\n            },\n            {\n              \"name\": \"chatwootDaysLimitImportMessages\",\n              \"value\": \"={{ $json.chatwootDaysLimitImportMessages }}\"\n            },\n            {\n              \"name\": \"syncFullHistory\",\n              \"value\": \"={{ $json.syncFullHistory }}\"\n            },\n            {\n              \"name\": \"chatwootMergeBrazilContacts\",\n              \"value\": \"={{ $json.chatwootMergeBrazilContacts }}\"\n            },\n            {\n              \"name\": \"integration\",\n              \"value\": \"={{ $json.integration }}\"\n            },\n            {\n              \"name\": \"chatwootNameInbox\",\n              \"value\": \"={{ $json.chatwootNameInbox }}\"\n            },\n            {\n              \"name\": \"token\",\n              \"value\": \"={{ $json.token }}\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"7da41431-cc8e-4eb4-9894-7bf413819fe3\",\n      \"name\": \"Cria Instancia\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 4.1,\n      \"position\": [\n        900,\n        680\n      ]\n    },\n    {\n      \"parameters\": {\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwootUrl\\\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\\\"chatwootAccountId\\\"] }}/inboxes/\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json.chatwootToken }}\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"d51fbbfe-4579-4fba-949f-c29e0b806feb\",\n      \"name\": \"Lista Inboxes\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        1120,\n        680\n      ]\n    },\n    {\n      \"parameters\": {\n        \"content\": \"## Workflow Para Criar Inbox - Evolution 2.0 ou superior\\n**Aqui você configura a comunicação entre o chatwoot e a Evolution API para criar novas instâncias a partir do chatwoot**\\n**Instruções**\\n**No node Info Base, configure as variáveis de seu Chatwoot e Evolution API**\",\n        \"width\": 1129.7777777777778\n      },\n      \"id\": \"7c66af51-b01e-4b76-8a8c-0193e87ec9d5\",\n      \"name\": \"Sticky Note\",\n      \"type\": \"n8n-nodes-base.stickyNote\",\n      \"typeVersion\": 1,\n      \"position\": [\n        460,\n        460\n      ]\n    },\n    {\n      \"parameters\": {\n        \"keepOnlySet\": true,\n        \"values\": {\n          \"string\": [\n            {\n              \"name\": \"chatwootUrl\",\n              \"value\": \"https://chatwootUrl - preencha\"\n            },\n            {\n              \"name\": \"evolution_url\",\n              \"value\": \"https://evolution_url - preencha\"\n            },\n            {\n              \"name\": \"global_api_key\",\n              \"value\": \"global_api_key - preencha\"\n            },\n            {\n              \"name\": \"organization\",\n              \"value\": \"={{ $json.query.organization }}\"\n            },\n            {\n              \"name\": \"instanceName\",\n              \"value\": \"={{ $json.body.messages[0].content.split(':')[1] }}-cwId-{{ $json.body.messages[0].account_id }}\"\n            },\n            {\n              \"name\": \"chatwootToken\",\n              \"value\": \"={{ $json.query.utoken }}\"\n            },\n            {\n              \"name\": \"msgCall\",\n              \"value\": \"Não aceitamos chamadas, por favor deixe uma mensagem!\"\n            },\n            {\n              \"name\": \"integration\",\n              \"value\": \"WHATSAPP-BAILEYS\"\n            },\n            {\n              \"name\": \"chatwootNameInbox\",\n              \"value\": \"={{ $json.body.messages[0].content.split(':')[1] }}\"\n            },\n            {\n              \"name\": \"chatwootAccountId\",\n              \"value\": \"={{ $json.body.messages[0].account_id.toString() }}\"\n            },\n            {\n              \"name\": \"token\",\n              \"value\": \"=AfRw{{ Date.now() }}BeH4\"\n            }\n          ],\n          \"boolean\": [\n            {\n              \"name\": \"qrcode\",\n              \"value\": true\n            },\n            {\n              \"name\": \"chatwootSignMsg\",\n              \"value\": true\n            },\n            {\n              \"name\": \"chatwootReopenConversation\",\n              \"value\": true\n            },\n            {\n              \"name\": \"chatwootConversationPending\"\n            },\n            {\n              \"name\": \"rejectCall\"\n            },\n            {\n              \"name\": \"groupsIgnore\"\n            },\n            {\n              \"name\": \"alwaysOnline\",\n              \"value\": true\n            },\n            {\n              \"name\": \"readMessages\",\n              \"value\": true\n            },\n            {\n              \"name\": \"readStatus\"\n            },\n            {\n              \"name\": \"chatwootImportMessages\",\n              \"value\": true\n            },\n            {\n              \"name\": \"chatwootImportContacts\",\n              \"value\": true\n            },\n            {\n              \"name\": \"syncFullHistory\"\n            },\n            {\n              \"name\": \"chatwootMergeBrazilContacts\",\n              \"value\": true\n            }\n          ],\n          \"number\": [\n            {\n              \"name\": \"chatwootDaysLimitImportMessages\",\n              \"value\": 60\n            }\n          ]\n        },\n        \"options\": {\n          \"dotNotation\": false\n        }\n      },\n      \"id\": \"eaffbc44-3701-4f8d-b923-92061cfb995f\",\n      \"name\": \"Info Base\",\n      \"type\": \"n8n-nodes-base.set\",\n      \"typeVersion\": 2,\n      \"position\": [\n        680,\n        680\n      ]\n    },\n    {\n      \"parameters\": {\n        \"conditions\": {\n          \"string\": [\n            {\n              \"value1\": \"={{ $json.name }}\",\n              \"value2\": \"=Start {{ $('Info Base').item.json[\\\"organization\\\"] }}\"\n            }\n          ]\n        }\n      },\n      \"id\": \"82eb24c8-2269-4622-b012-d6f6ad35c149\",\n      \"name\": \"é Start Inbox?\",\n      \"type\": \"n8n-nodes-base.if\",\n      \"typeVersion\": 1,\n      \"position\": [\n        1800,\n        600\n      ]\n    },\n    {\n      \"parameters\": {\n        \"batchSize\": 1,\n        \"options\": {}\n      },\n      \"id\": \"b9de1318-ab0b-4529-b30a-2daea64dbcfe\",\n      \"name\": \"Split In Batches\",\n      \"type\": \"n8n-nodes-base.splitInBatches\",\n      \"typeVersion\": 2,\n      \"position\": [\n        1560,\n        680\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"DELETE\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwootUrl\\\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\\\"chatwootAccountId\\\"] }}/inboxes/{{ $json.id }}\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json.chatwootToken }}\"\n            }\n          ]\n        },\n        \"options\": {}\n      },\n      \"id\": \"db2ad958-7642-41eb-8e9a-e8b1668230d1\",\n      \"name\": \"Deleta Inbox Start\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2040,\n        480\n      ]\n    },\n    {\n      \"parameters\": {},\n      \"id\": \"6d68d3a7-d613-471f-8492-9ec473481521\",\n      \"name\": \"No Operation, do nothing\",\n      \"type\": \"n8n-nodes-base.noOp\",\n      \"typeVersion\": 1,\n      \"position\": [\n        1800,\n        780\n      ]\n    },\n    {\n      \"parameters\": {\n        \"fieldToSplitOut\": \"payload\",\n        \"options\": {}\n      },\n      \"id\": \"be833e77-b2ae-44c6-b4fc-ad24ffc8ad9a\",\n      \"name\": \"Ajusta lista\",\n      \"type\": \"n8n-nodes-base.itemLists\",\n      \"typeVersion\": 2.2,\n      \"position\": [\n        1340,\n        680\n      ]\n    },\n    {\n      \"parameters\": {\n        \"httpMethod\": \"POST\",\n        \"path\": \"inbox_whatsapp\",\n        \"options\": {}\n      },\n      \"id\": \"faae80e0-9070-4a0c-83bc-d47643a64653\",\n      \"name\": \"Webhook\",\n      \"type\": \"n8n-nodes-base.webhook\",\n      \"typeVersion\": 1,\n      \"position\": [\n        460,\n        680\n      ],\n      \"webhookId\": \"85cb0c27-4223-4339-b7b4-35a16c0a04b8\"\n    },\n    {\n      \"parameters\": {\n        \"conditions\": {\n          \"string\": [\n            {\n              \"value1\": \"={{ $json.name }}\",\n              \"value2\": \"={{ $('Webhook').item.json[\\\"body\\\"][\\\"messages\\\"][0][\\\"content\\\"].split(':')[1] }}\"\n            }\n          ]\n        }\n      },\n      \"id\": \"4ea7b74f-bdc5-4619-8e99-1f5d33c7e28e\",\n      \"name\": \"é_pre-existente?\",\n      \"type\": \"n8n-nodes-base.if\",\n      \"typeVersion\": 1,\n      \"position\": [\n        1980,\n        700\n      ]\n    },\n    {\n      \"parameters\": {\n        \"method\": \"PATCH\",\n        \"url\": \"={{ $('Info Base').item.json[\\\"chatwootUrl\\\"] }}/api/v1/accounts/{{ $('Info Base').item.json[\\\"chatwootAccountId\\\"] }}/inboxes/{{ $json.id }}\",\n        \"sendHeaders\": true,\n        \"headerParameters\": {\n          \"parameters\": [\n            {\n              \"name\": \"api_access_token\",\n              \"value\": \"={{ $('Info Base').item.json.chatwootToken }}\"\n            },\n            {\n              \"name\": \"Content-Type\",\n              \"value\": \"application/json\"\n            }\n          ]\n        },\n        \"sendBody\": true,\n        \"specifyBody\": \"json\",\n        \"jsonBody\": \"={\\n\\\"channel\\\": {\\n\\\"webhook_url\\\": \\\"{{ $('Info Base').item.json[\\\"evolution_url\\\"] }}/chatwoot/webhook/{{ encodeURIComponent($('Info Base').item.json[\\\"instanceName\\\"]) }}\\\"\\n}\\n}\",\n        \"options\": {}\n      },\n      \"id\": \"74d6db21-d49e-48d6-b1a8-ff8bddca67d1\",\n      \"name\": \"Update_webhook_url\",\n      \"type\": \"n8n-nodes-base.httpRequest\",\n      \"typeVersion\": 3,\n      \"position\": [\n        2200,\n        700\n      ]\n    }\n  ],\n  \"pinData\": {},\n  \"connections\": {\n    \"Cria Instancia\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Lista Inboxes\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Lista Inboxes\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Ajusta lista\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Info Base\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Cria Instancia\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"é Start Inbox?\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Deleta Inbox Start\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ],\n        [\n          {\n            \"node\": \"é_pre-existente?\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Split In Batches\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"é Start Inbox?\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ],\n        [\n          {\n            \"node\": \"No Operation, do nothing\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Deleta Inbox Start\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Split In Batches\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Ajusta lista\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Split In Batches\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Webhook\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Info Base\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"é_pre-existente?\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Update_webhook_url\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ],\n        [\n          {\n            \"node\": \"Split In Batches\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    },\n    \"Update_webhook_url\": {\n      \"main\": [\n        [\n          {\n            \"node\": \"Split In Batches\",\n            \"type\": \"main\",\n            \"index\": 0\n          }\n        ]\n      ]\n    }\n  },\n  \"active\": false,\n  \"settings\": {\n    \"executionOrder\": \"v1\"\n  },\n  \"versionId\": \"68f9fa60-e295-4b74-8cb3-c4723d6cb2b2\",\n  \"meta\": {\n    \"templateCredsSetupCompleted\": true,\n    \"instanceId\": \"8ed3edb9203bfe03a4b94f63390235285fbb1c230430fdae73a456b9fae762d5\"\n  },\n  \"id\": \"f6dLbF7I7nrjcDc4\",\n  \"tags\": []\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "# Evolution API License\n\nEvolution API is licensed under the Apache License 2.0, with the following additional conditions:\n\n1. Evolution API may be utilized commercially, including as a backend service for other applications or as an application development platform for enterprises. Should the conditions below be met, a commercial license must be obtained from the producer:\n\na. LOGO and copyright information: In the process of using Evolution API's frontend components, you may not remove or modify the LOGO or copyright information in the Evolution API console or applications. This restriction is inapplicable to uses of Evolution API that do not involve its frontend components.\n\nb. Usage Notification Requirement: If Evolution API is used as part of any project, including closed-source systems (e.g., proprietary software), the user is required to display a clear notification within the system that Evolution API is being utilized. This notification should be visible to system administrators and accessible from the system's documentation or settings page. Failure to comply with this requirement may result in the necessity for a commercial license, as determined by the producer.\n\nPlease contact contato@evolution-api.com to inquire about licensing matters.\n\n2. As a contributor, you should agree that:\n\na. The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.\nb. Your contributed code may be used for commercial purposes, including but not limited to its cloud business operations.\n\nApart from the specific conditions mentioned above, all other rights and restrictions follow the Apache License 2.0. Detailed information about the Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0.\n\n© 2025 Evolution API\n\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">Evolution Api</h1>\n\n<div align=\"center\">\n\n[![Docker Image](https://img.shields.io/badge/Docker-image-blue)](https://hub.docker.com/r/evoapicloud/evolution-api)\n[![Whatsapp Group](https://img.shields.io/badge/Group-WhatsApp-%2322BC18)](https://evolution-api.com/whatsapp)\n[![Discord Community](https://img.shields.io/badge/Discord-Community-blue)](https://evolution-api.com/discord)\n[![Postman Collection](https://img.shields.io/badge/Postman-Collection-orange)](https://evolution-api.com/postman) \n[![Documentation](https://img.shields.io/badge/Documentation-Official-green)](https://doc.evolution-api.com)\n[![Feature Requests](https://img.shields.io/badge/Feature-Requests-purple)](https://evolutionapi.canny.io/feature-requests)\n[![Roadmap](https://img.shields.io/badge/Roadmap-Community-blue)](https://evolutionapi.canny.io/feature-requests)\n[![Changelog](https://img.shields.io/badge/Changelog-Updates-green)](https://evolutionapi.canny.io/changelog)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](./LICENSE)\n[![Support](https://img.shields.io/badge/Donation-picpay-green)](https://app.picpay.com/user/davidsongomes1998)\n[![Sponsors](https://img.shields.io/badge/Github-sponsor-orange)](https://github.com/sponsors/EvolutionAPI)\n\n</div>\n  \n<div align=\"center\"><img src=\"./public/images/cover.png\"></div>\n\n## Evolution API\n\nEvolution API began as a WhatsApp controller API based on [CodeChat](https://github.com/code-chat-br/whatsapp-api), which in turn implemented the [Baileys](https://github.com/WhiskeySockets/Baileys) library. While originally focused on WhatsApp, Evolution API has grown into a comprehensive platform supporting multiple messaging services and integrations. We continue to acknowledge CodeChat for laying the groundwork.\n\nToday, Evolution API is not limited to WhatsApp. It integrates with various platforms such as Typebot, Chatwoot, Dify, and OpenAI, offering a broad array of functionalities beyond messaging. Evolution API supports both the Baileys-based WhatsApp API and the official WhatsApp Business API, with upcoming support for Instagram and Messenger.\n\n## Looking for a Lightweight Version?\nFor those who need a more streamlined and performance-optimized version, check out [Evolution API Lite](https://github.com/EvolutionAPI/evolution-api-lite). It's designed specifically for microservices, focusing solely on connectivity without integrations or audio conversion features. Ideal for environments that prioritize simplicity and efficiency.\n\n## Types of Connections\n\nEvolution API supports multiple types of connections to WhatsApp, enabling flexible and powerful integration options:\n\n- *WhatsApp API - Baileys*:\n  - A free API based on WhatsApp Web, leveraging the [Baileys library](https://github.com/WhiskeySockets/Baileys).\n  - This connection type allows control over WhatsApp Web functionalities through a RESTful API, suitable for multi-service chats, service bots, and other WhatsApp-integrated systems.\n  - Note: This method relies on the web version of WhatsApp and may have limitations compared to official APIs.\n\n- *WhatsApp Cloud API*:\n  - The official API provided by Meta (formerly Facebook).\n  - This connection type offers a robust and reliable solution designed for businesses needing higher volumes of messaging and better integration support.\n  - The Cloud API supports features such as end-to-end encryption, advanced analytics, and more comprehensive customer service tools.\n  - To use this API, you must comply with Meta's policies and potentially pay for usage based on message volume and other factors.\n\n## Integrations\n\nEvolution API supports various integrations to enhance its functionality. Below is a list of available integrations and their uses:\n\n- [Typebot](https://typebot.io/):\n  - Build conversational bots using Typebot, integrated directly into Evolution with trigger management.\n\n- [Chatwoot](https://www.chatwoot.com/):\n  - Direct integration with Chatwoot for handling customer service for your business.\n\n- [RabbitMQ](https://www.rabbitmq.com/):\n  - Receive events from the Evolution API via RabbitMQ.\n\n- [Apache Kafka](https://kafka.apache.org/):\n  - Receive events from the Evolution API via Apache Kafka for real-time event streaming and processing.\n\n- [Amazon SQS](https://aws.amazon.com/pt/sqs/):\n  - Receive events from the Evolution API via Amazon SQS.\n\n- [Socket.io](https://socket.io/):\n  - Receive events from the Evolution API via WebSocket.\n\n- [Dify](https://dify.ai/):\n  - Integrate your Evolution API directly with Dify AI for seamless trigger management and multiple agents.\n\n- [OpenAI](https://openai.com/):\n  - Integrate your Evolution API with OpenAI for AI capabilities, including audio-to-text conversion, available across all Evolution integrations.\n\n- Amazon S3 / Minio:\n  - Store media files received in [Amazon S3](https://aws.amazon.com/pt/s3/) or [Minio](https://min.io/).\n\n## Community & Feedback\n\nWe value community input and feedback to continuously improve Evolution API:\n\n### 🚀 Feature Requests & Roadmap\n- **[Feature Requests](https://evolutionapi.canny.io/feature-requests)**: Submit new feature ideas and vote on community proposals\n- **[Roadmap](https://evolutionapi.canny.io/feature-requests)**: View planned features and development progress\n- **[Changelog](https://evolutionapi.canny.io/changelog)**: Stay updated with the latest releases and improvements\n\n### 💬 Community Support\n- **[WhatsApp Group](https://evolution-api.com/whatsapp)**: Join our community for support and discussions\n- **[Discord Community](https://evolution-api.com/discord)**: Real-time chat with developers and users\n- **[GitHub Issues](https://github.com/EvolutionAPI/evolution-api/issues)**: Report bugs and technical issues\n\n### 🔒 Security\n- **[Security Policy](./SECURITY.md)**: Guidelines for reporting security vulnerabilities\n- **Security Contact**: contato@evolution-api.com\n\n## Telemetry Notice\n\nTo continuously improve our services, we have implemented telemetry that collects data on the routes used, the most accessed routes, and the version of the API in use. We would like to assure you that no sensitive or personal data is collected during this process. The telemetry helps us identify improvements and provide a better experience for users.\n\n## Evolution Support Premium\n\nJoin our Evolution Pro community for expert support and a weekly call to answer questions. Visit the link below to learn more and subscribe:\n\n[Click here to learn more](https://evolution-api.com/suporte-pro)\n\n# Donate to the project.\n\n#### Github Sponsors\n\nhttps://github.com/sponsors/EvolutionAPI\n\n# Content Creator Partners\n\nWe are proud to collaborate with the following content creators who have contributed valuable insights and tutorials about Evolution API:\n\n- [Promovaweb](https://www.youtube.com/@promovaweb)\n- [Sandeco](https://www.youtube.com/@canalsandeco)\n- [Comunidade ZDG](https://www.youtube.com/@ComunidadeZDG)\n- [Francis MNO](https://www.youtube.com/@FrancisMNO)\n- [Pablo Cabral](https://youtube.com/@pablocabral)\n- [XPop Digital](https://www.youtube.com/@xpopdigital)\n- [Costar Wagner Dev](https://www.youtube.com/@costarwagnerdev)\n- [Dante Testa](https://youtube.com/@dantetesta_)\n- [Rubén Salazar](https://youtube.com/channel/UCnYGZIE2riiLqaN9sI6riig)\n- [OrionDesign](youtube.com/OrionDesign_Oficial)\n- [IMPA 365](youtube.com/@impa365_ofc)\n- [Comunidade Hub Connect](https://youtube.com/@comunidadehubconnect)\n- [dSantana Automações](https://www.youtube.com/channel/UCG7DjUmAxtYyURlOGAIryNQ?view_as=subscriber)\n- [Edison Martins](https://www.youtube.com/@edisonmartinsmkt)\n- [Astra Online](https://www.youtube.com/@astraonlineweb)\n- [MKT Seven Automações](https://www.youtube.com/@sevenautomacoes)\n- [Vamos automatizar](https://www.youtube.com/vamosautomatizar)\n\n## License\n\nEvolution API is licensed under the Apache License 2.0, with the following additional conditions:\n\n1. **LOGO and copyright information**: In the process of using Evolution API's frontend components, you may not remove or modify the LOGO or copyright information in the Evolution API console or applications. This restriction is inapplicable to uses of Evolution API that do not involve its frontend components.\n\n2. **Usage Notification Requirement**: If Evolution API is used as part of any project, including closed-source systems (e.g., proprietary software), the user is required to display a clear notification within the system that Evolution API is being utilized. This notification should be visible to system administrators and accessible from the system's documentation or settings page. Failure to comply with this requirement may result in the necessity for a commercial license, as determined by the producer.\n\nPlease contact contato@evolution-api.com to inquire about licensing matters.\n\nApart from the specific conditions mentioned above, all other rights and restrictions follow the Apache License 2.0. Detailed information about the Apache License 2.0 can be found at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\n© 2025 Evolution API\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nWe actively support the following versions of Evolution API with security updates:\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 2.3.x   | ✅ Yes             |\n| 2.2.x   | ✅ Yes             |\n| 2.1.x   | ⚠️ Critical fixes only |\n| < 2.1   | ❌ No              |\n\n## Reporting a Vulnerability\n\nWe take security vulnerabilities seriously. If you discover a security vulnerability in Evolution API, please help us by reporting it responsibly.\n\n### 🔒 Private Disclosure Process\n\n**Please DO NOT create a public GitHub issue for security vulnerabilities.**\n\nInstead, please report security vulnerabilities via email to:\n\n**📧 contato@evolution-api.com**\n\n### 📋 What to Include\n\nWhen reporting a vulnerability, please include:\n\n- **Description**: A clear description of the vulnerability\n- **Impact**: What an attacker could achieve by exploiting this vulnerability\n- **Steps to Reproduce**: Detailed steps to reproduce the issue\n- **Proof of Concept**: If possible, include a minimal proof of concept\n- **Environment**: Version of Evolution API, OS, Node.js version, etc.\n- **Suggested Fix**: If you have ideas for how to fix the issue\n\n### 🕐 Response Timeline\n\nWe will acknowledge receipt of your vulnerability report within **48 hours** and will send you regular updates about our progress.\n\n- **Initial Response**: Within 48 hours\n- **Status Update**: Within 7 days\n- **Resolution Timeline**: Varies based on complexity, typically 30-90 days\n\n### 🎯 Scope\n\nThis security policy applies to:\n\n- Evolution API core application\n- Official Docker images\n- Documentation that could lead to security issues\n\n### 🚫 Out of Scope\n\nThe following are generally considered out of scope:\n\n- Third-party integrations (Chatwoot, Typebot, etc.) - please report to respective projects\n- Issues in dependencies - please report to the dependency maintainers\n- Social engineering attacks\n- Physical attacks\n- Denial of Service attacks\n\n### 🏆 Recognition\n\nWe believe in recognizing security researchers who help us keep Evolution API secure:\n\n- We will acknowledge your contribution in our security advisories (unless you prefer to remain anonymous)\n- For significant vulnerabilities, we may feature you in our Hall of Fame\n- We will work with you on coordinated disclosure timing\n\n### 📚 Security Best Practices\n\nFor users deploying Evolution API:\n\n- Always use the latest supported version\n- Keep your dependencies up to date\n- Use strong authentication methods\n- Implement proper network security\n- Monitor your logs for suspicious activity\n- Follow the principle of least privilege\n\n### 🔄 Security Updates\n\nSecurity updates will be:\n\n- Released as patch versions (e.g., 2.3.1 → 2.3.2)\n- Documented in our [CHANGELOG.md](./CHANGELOG.md)\n- Announced in our community channels\n- Tagged with security labels in GitHub releases\n\n## Contact\n\nFor any questions about this security policy, please contact:\n\n- **Email**: contato@evolution-api.com\n\n---\n\nThank you for helping keep Evolution API and our community safe! 🛡️\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "module.exports = {\n  extends: ['@commitlint/config-conventional'],\n  rules: {\n    'type-enum': [\n      2,\n      'always',\n      [\n        'feat',     // New feature\n        'fix',      // Bug fix\n        'docs',     // Documentation changes\n        'style',    // Code style changes (formatting, etc)\n        'refactor', // Code refactoring\n        'perf',     // Performance improvements\n        'test',     // Adding or updating tests\n        'chore',    // Maintenance tasks\n        'ci',       // CI/CD changes\n        'build',    // Build system changes\n        'revert',   // Reverting changes\n        'security', // Security fixes\n      ],\n    ],\n    'type-case': [2, 'always', 'lower-case'],\n    'type-empty': [2, 'never'],\n    'scope-case': [2, 'always', 'lower-case'],\n    'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],\n    'subject-empty': [2, 'never'],\n    'subject-full-stop': [2, 'never', '.'],\n    'header-max-length': [2, 'always', 100],\n    'body-leading-blank': [1, 'always'],\n    'body-max-line-length': [0, 'always', 150],\n    'footer-leading-blank': [1, 'always'],\n    'footer-max-line-length': [0, 'always', 150],\n  },\n};\n"
  },
  {
    "path": "docker-compose.dev.yaml",
    "content": "services:\n  api:\n    container_name: evolution_api\n    image: evolution/api:local\n    build: .\n    restart: always\n    ports:\n      - 8080:8080\n    volumes:\n      - evolution_instances:/evolution/instances\n    networks:\n      - evolution-net\n    env_file:\n      - .env\n    expose:\n      - 8080\n\n  frontend:\n    container_name: evolution_frontend\n    image: evolution/manager:local\n    build: ./evolution-manager-v2\n    restart: always\n    ports:\n      - \"3000:80\"\n    networks:\n      - evolution-net\n\nvolumes:\n  evolution_instances:\n\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n"
  },
  {
    "path": "docker-compose.yaml",
    "content": "version: \"3.8\"\n\nservices:\n  api:\n    container_name: evolution_api\n    image: evoapicloud/evolution-api:latest\n    restart: always\n    depends_on:\n      - redis\n      - evolution-postgres\n    ports:\n      - \"127.0.0.1:8080:8080\"\n    volumes:\n      - evolution_instances:/evolution/instances\n    networks:\n      - evolution-net\n      - dokploy-network\n    env_file:\n      - .env\n    expose:\n      - \"8080\"\n\n  frontend:\n    container_name: evolution_frontend\n    image: evoapicloud/evolution-manager:latest\n    restart: always\n    ports:\n      - \"3000:80\"\n    networks:\n      - evolution-net\n\n  redis:\n    container_name: evolution_redis\n    image: redis:latest\n    restart: always\n    command: >\n      redis-server --port 6379 --appendonly yes\n    volumes:\n      - evolution_redis:/data\n    networks:\n      evolution-net:\n        aliases:\n          - evolution-redis\n      dokploy-network:\n        aliases:\n          - evolution-redis\n    expose:\n      - \"6379\"\n\n  evolution-postgres:\n    container_name: evolution_postgres\n    image: postgres:15\n    restart: always\n    env_file:\n      - .env\n    command:\n      - postgres\n      - -c\n      - max_connections=1000\n      - -c\n      - listen_addresses=*\n    environment:\n      - POSTGRES_DB=${POSTGRES_DATABASE}\n      - POSTGRES_USER=${POSTGRES_USERNAME}\n      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n    volumes:\n      - postgres_data:/var/lib/postgresql/data\n    networks:\n      - evolution-net\n      - dokploy-network\n    expose:\n      - \"5432\"\n\nvolumes:\n  evolution_instances:\n  evolution_redis:\n  postgres_data:\n\nnetworks:\n  evolution-net:\n    name: evolution-net\n    driver: bridge\n  dokploy-network:\n    external: true"
  },
  {
    "path": "env.example",
    "content": "# ===========================================\n# EVOLUTION API - CONFIGURAÇÃO DE AMBIENTE\n# ===========================================\n\n# ===========================================\n# SERVIDOR\n# ===========================================\nSERVER_NAME=evolution\nSERVER_TYPE=http\nSERVER_PORT=8080\nSERVER_URL=http://localhost:8080\nSERVER_DISABLE_DOCS=false\nSERVER_DISABLE_MANAGER=false\n\n# ===========================================\n# CORS\n# ===========================================\nCORS_ORIGIN=*\nCORS_METHODS=POST,GET,PUT,DELETE\nCORS_CREDENTIALS=true\n\n# ===========================================\n# SSL (opcional)\n# ===========================================\nSSL_CONF_PRIVKEY=\nSSL_CONF_FULLCHAIN=\n\n# ===========================================\n# BANCO DE DADOS\n# ===========================================\nDATABASE_PROVIDER=postgresql\nDATABASE_CONNECTION_URI=postgresql://username:password@localhost:5432/evolution_api\nDATABASE_CONNECTION_CLIENT_NAME=evolution\n\n# Configurações de salvamento de dados\nDATABASE_SAVE_DATA_INSTANCE=true\nDATABASE_SAVE_DATA_NEW_MESSAGE=true\nDATABASE_SAVE_MESSAGE_UPDATE=true\nDATABASE_SAVE_DATA_CONTACTS=true\nDATABASE_SAVE_DATA_CHATS=true\nDATABASE_SAVE_DATA_HISTORIC=true\nDATABASE_SAVE_DATA_LABELS=true\nDATABASE_SAVE_IS_ON_WHATSAPP=true\nDATABASE_SAVE_IS_ON_WHATSAPP_DAYS=7\nDATABASE_DELETE_MESSAGE=false\n\n# ===========================================\n# REDIS\n# ===========================================\nCACHE_REDIS_ENABLED=true\nCACHE_REDIS_URI=redis://localhost:6379\nCACHE_REDIS_PREFIX_KEY=evolution-cache\nCACHE_REDIS_TTL=604800\nCACHE_REDIS_SAVE_INSTANCES=true\n\n# Cache local (fallback)\nCACHE_LOCAL_ENABLED=true\nCACHE_LOCAL_TTL=86400\n\n# ===========================================\n# AUTENTICAÇÃO\n# ===========================================\nAUTHENTICATION_API_KEY=BQYHJGJHJ\nAUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=false\n\n# ===========================================\n# LOGS\n# ===========================================\nLOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS,WEBSOCKET\nLOG_COLOR=true\nLOG_BAILEYS=error\n\n# ===========================================\n# INSTÂNCIAS\n# ===========================================\nDEL_INSTANCE=false\nDEL_TEMP_INSTANCES=true\n\n# ===========================================\n# IDIOMA\n# ===========================================\nLANGUAGE=pt-BR\n\n# ===========================================\n# WEBHOOK\n# ===========================================\nWEBHOOK_GLOBAL_URL=\nWEBHOOK_GLOBAL_ENABLED=false\nWEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS=false\n\n# Eventos de webhook\nWEBHOOK_EVENTS_APPLICATION_STARTUP=false\nWEBHOOK_EVENTS_INSTANCE_CREATE=false\nWEBHOOK_EVENTS_INSTANCE_DELETE=false\nWEBHOOK_EVENTS_QRCODE_UPDATED=false\nWEBHOOK_EVENTS_MESSAGES_SET=false\nWEBHOOK_EVENTS_MESSAGES_UPSERT=false\nWEBHOOK_EVENTS_MESSAGES_EDITED=false\nWEBHOOK_EVENTS_MESSAGES_UPDATE=false\nWEBHOOK_EVENTS_MESSAGES_DELETE=false\nWEBHOOK_EVENTS_SEND_MESSAGE=false\nWEBHOOK_EVENTS_SEND_MESSAGE_UPDATE=false\nWEBHOOK_EVENTS_CONTACTS_SET=false\nWEBHOOK_EVENTS_CONTACTS_UPDATE=false\nWEBHOOK_EVENTS_CONTACTS_UPSERT=false\nWEBHOOK_EVENTS_PRESENCE_UPDATE=false\nWEBHOOK_EVENTS_CHATS_SET=false\nWEBHOOK_EVENTS_CHATS_UPDATE=false\nWEBHOOK_EVENTS_CHATS_UPSERT=false\nWEBHOOK_EVENTS_CHATS_DELETE=false\nWEBHOOK_EVENTS_CONNECTION_UPDATE=false\nWEBHOOK_EVENTS_LABELS_EDIT=false\nWEBHOOK_EVENTS_LABELS_ASSOCIATION=false\nWEBHOOK_EVENTS_GROUPS_UPSERT=false\nWEBHOOK_EVENTS_GROUPS_UPDATE=false\nWEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=false\nWEBHOOK_EVENTS_CALL=false\nWEBHOOK_EVENTS_TYPEBOT_START=false\nWEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false\nWEBHOOK_EVENTS_ERRORS=false\nWEBHOOK_EVENTS_ERRORS_WEBHOOK=\n\n# Configurações de webhook\nWEBHOOK_REQUEST_TIMEOUT_MS=30000\nWEBHOOK_RETRY_MAX_ATTEMPTS=10\nWEBHOOK_RETRY_INITIAL_DELAY_SECONDS=5\nWEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF=true\nWEBHOOK_RETRY_MAX_DELAY_SECONDS=300\nWEBHOOK_RETRY_JITTER_FACTOR=0.2\nWEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES=400,401,403,404,422\n\n# ===========================================\n# WEBSOCKET\n# ===========================================\nWEBSOCKET_ENABLED=true\nWEBSOCKET_GLOBAL_EVENTS=true\nWEBSOCKET_ALLOWED_HOSTS=\n\n# ===========================================\n# RABBITMQ\n# ===========================================\nRABBITMQ_ENABLED=false\nRABBITMQ_GLOBAL_ENABLED=false\nRABBITMQ_PREFIX_KEY=\nRABBITMQ_EXCHANGE_NAME=evolution_exchange\nRABBITMQ_URI=\nRABBITMQ_FRAME_MAX=8192\n\n# ===========================================\n# NATS\n# ===========================================\nNATS_ENABLED=false\nNATS_GLOBAL_ENABLED=false\nNATS_PREFIX_KEY=\nNATS_EXCHANGE_NAME=evolution_exchange\nNATS_URI=\n\n# ===========================================\n# SQS\n# ===========================================\nSQS_ENABLED=false\nSQS_GLOBAL_ENABLED=false\nSQS_GLOBAL_FORCE_SINGLE_QUEUE=false\nSQS_GLOBAL_PREFIX_NAME=global\nSQS_ACCESS_KEY_ID=\nSQS_SECRET_ACCESS_KEY=\nSQS_ACCOUNT_ID=\nSQS_REGION=\nSQS_MAX_PAYLOAD_SIZE=1048576\n\n# ===========================================\n# PUSHER\n# ===========================================\nPUSHER_ENABLED=false\nPUSHER_GLOBAL_ENABLED=false\nPUSHER_GLOBAL_APP_ID=\nPUSHER_GLOBAL_KEY=\nPUSHER_GLOBAL_SECRET=\nPUSHER_GLOBAL_CLUSTER=\nPUSHER_GLOBAL_USE_TLS=false\n\n# ===========================================\n# WHATSAPP BUSINESS\n# ===========================================\nWA_BUSINESS_TOKEN_WEBHOOK=evolution\nWA_BUSINESS_URL=https://graph.facebook.com\nWA_BUSINESS_VERSION=v18.0\nWA_BUSINESS_LANGUAGE=en\n\n# ===========================================\n# CONFIGURAÇÕES DE SESSÃO\n# ===========================================\nCONFIG_SESSION_PHONE_CLIENT=Evolution API\nCONFIG_SESSION_PHONE_NAME=Chrome\n\n# ===========================================\n# QR CODE\n# ===========================================\nQRCODE_LIMIT=30\nQRCODE_COLOR=#198754\n\n# ===========================================\n# INTEGRAÇÕES\n# ===========================================\n\n# Typebot\nTYPEBOT_ENABLED=false\nTYPEBOT_API_VERSION=old\nTYPEBOT_SEND_MEDIA_BASE64=false\n\n# Chatwoot\nCHATWOOT_ENABLED=false\nCHATWOOT_MESSAGE_DELETE=false\nCHATWOOT_MESSAGE_READ=false\nCHATWOOT_BOT_CONTACT=true\nCHATWOOT_IMPORT_DATABASE_CONNECTION_URI=\nCHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=false\n\n# OpenAI\nOPENAI_ENABLED=false\nOPENAI_API_KEY_GLOBAL=\n\n# Dify\nDIFY_ENABLED=false\n\n# N8N\nN8N_ENABLED=false\n\n# EvoAI\nEVOAI_ENABLED=false\n\n# Flowise\nFLOWISE_ENABLED=false\n\n# ===========================================\n# S3 / MINIO\n# ===========================================\nS3_ENABLED=false\nS3_ACCESS_KEY=\nS3_SECRET_KEY=\nS3_ENDPOINT=\nS3_BUCKET=\nS3_PORT=9000\nS3_USE_SSL=false\nS3_REGION=\nS3_SKIP_POLICY=false\nS3_SAVE_VIDEO=false\n\n# ===========================================\n# MÉTRICAS\n# ===========================================\nPROMETHEUS_METRICS=false\nMETRICS_AUTH_REQUIRED=false\nMETRICS_USER=\nMETRICS_PASSWORD=\nMETRICS_ALLOWED_IPS=\n\n# ===========================================\n# TELEMETRIA\n# ===========================================\nTELEMETRY_ENABLED=true\nTELEMETRY_URL=\n\n# ===========================================\n# PROXY\n# ===========================================\nPROXY_HOST=\nPROXY_PORT=\nPROXY_PROTOCOL=\nPROXY_USERNAME=\nPROXY_PASSWORD=\n\n# ===========================================\n# CONVERSOR DE ÁUDIO\n# ===========================================\nAPI_AUDIO_CONVERTER=\nAPI_AUDIO_CONVERTER_KEY=\n\n# ===========================================\n# FACEBOOK\n# ===========================================\nFACEBOOK_APP_ID=\nFACEBOOK_CONFIG_ID=\nFACEBOOK_USER_TOKEN=\n\n# ===========================================\n# SENTRY\n# ===========================================\nSENTRY_DSN=\n\n# ===========================================\n# EVENT EMITTER\n# ===========================================\nEVENT_EMITTER_MAX_LISTENERS=50\n\n# ===========================================\n# PROVIDER\n# ===========================================\nPROVIDER_ENABLED=false\nPROVIDER_HOST=\nPROVIDER_PORT=5656\nPROVIDER_PREFIX=evolution\n"
  },
  {
    "path": "grafana-dashboard.json.example",
    "content": "{\n  \"dashboard\": {\n    \"id\": null,\n    \"title\": \"Evolution API Monitoring\",\n    \"tags\": [\"evolution-api\", \"whatsapp\", \"monitoring\"],\n    \"style\": \"dark\",\n    \"timezone\": \"browser\",\n    \"panels\": [\n      {\n        \"id\": 1,\n        \"title\": \"API Status\",\n        \"type\": \"stat\",\n        \"targets\": [\n          {\n            \"expr\": \"up{job=\\\"evolution-api\\\"}\",\n            \"legendFormat\": \"API Status\"\n          }\n        ],\n        \"fieldConfig\": {\n          \"defaults\": {\n            \"mappings\": [\n              {\n                \"options\": {\n                  \"0\": {\n                    \"text\": \"DOWN\",\n                    \"color\": \"red\"\n                  },\n                  \"1\": {\n                    \"text\": \"UP\",\n                    \"color\": \"green\"\n                  }\n                },\n                \"type\": \"value\"\n              }\n            ]\n          }\n        },\n        \"gridPos\": {\n          \"h\": 8,\n          \"w\": 12,\n          \"x\": 0,\n          \"y\": 0\n        }\n      },\n      {\n        \"id\": 2,\n        \"title\": \"Total Instances\",\n        \"type\": \"stat\",\n        \"targets\": [\n          {\n            \"expr\": \"evolution_instances_total\",\n            \"legendFormat\": \"Total Instances\"\n          }\n        ],\n        \"gridPos\": {\n          \"h\": 8,\n          \"w\": 12,\n          \"x\": 12,\n          \"y\": 0\n        }\n      },\n      {\n        \"id\": 3,\n        \"title\": \"Instance Status Overview\",\n        \"type\": \"piechart\",\n        \"targets\": [\n          {\n            \"expr\": \"sum by (state) (evolution_instance_state)\",\n            \"legendFormat\": \"{{ state }}\"\n          }\n        ],\n        \"gridPos\": {\n          \"h\": 9,\n          \"w\": 12,\n          \"x\": 0,\n          \"y\": 8\n        }\n      },\n      {\n        \"id\": 4,\n        \"title\": \"Instances by Integration Type\",\n        \"type\": \"piechart\",\n        \"targets\": [\n          {\n            \"expr\": \"sum by (integration) (evolution_instance_up)\",\n            \"legendFormat\": \"{{ integration }}\"\n          }\n        ],\n        \"gridPos\": {\n          \"h\": 9,\n          \"w\": 12,\n          \"x\": 12,\n          \"y\": 8\n        }\n      },\n      {\n        \"id\": 5,\n        \"title\": \"Instance Uptime\",\n        \"type\": \"table\",\n        \"targets\": [\n          {\n            \"expr\": \"evolution_instance_up\",\n            \"format\": \"table\",\n            \"instant\": true\n          }\n        ],\n        \"transformations\": [\n          {\n            \"id\": \"organize\",\n            \"options\": {\n              \"excludeByName\": {\n                \"Time\": true,\n                \"__name__\": true\n              },\n              \"renameByName\": {\n                \"instance\": \"Instance Name\",\n                \"integration\": \"Integration Type\",\n                \"Value\": \"Status\"\n              }\n            }\n          }\n        ],\n        \"fieldConfig\": {\n          \"overrides\": [\n            {\n              \"matcher\": {\n                \"id\": \"byName\",\n                \"options\": \"Status\"\n              },\n              \"properties\": [\n                {\n                  \"id\": \"mappings\",\n                  \"value\": [\n                    {\n                      \"options\": {\n                        \"0\": {\n                          \"text\": \"DOWN\",\n                          \"color\": \"red\"\n                        },\n                        \"1\": {\n                          \"text\": \"UP\",\n                          \"color\": \"green\"\n                        }\n                      },\n                      \"type\": \"value\"\n                    }\n                  ]\n                }\n              ]\n            }\n          ]\n        },\n        \"gridPos\": {\n          \"h\": 9,\n          \"w\": 24,\n          \"x\": 0,\n          \"y\": 17\n        }\n      },\n      {\n        \"id\": 6,\n        \"title\": \"Instance Status Timeline\",\n        \"type\": \"timeseries\",\n        \"targets\": [\n          {\n            \"expr\": \"evolution_instance_up\",\n            \"legendFormat\": \"{{ instance }} ({{ integration }})\"\n          }\n        ],\n        \"fieldConfig\": {\n          \"defaults\": {\n            \"custom\": {\n              \"drawStyle\": \"line\",\n              \"lineInterpolation\": \"stepAfter\",\n              \"lineWidth\": 2,\n              \"fillOpacity\": 10,\n              \"gradientMode\": \"none\",\n              \"spanNulls\": false,\n              \"insertNulls\": false,\n              \"showPoints\": \"never\",\n              \"pointSize\": 5,\n              \"stacking\": {\n                \"mode\": \"none\",\n                \"group\": \"A\"\n              },\n              \"axisPlacement\": \"auto\",\n              \"axisLabel\": \"\",\n              \"scaleDistribution\": {\n                \"type\": \"linear\"\n              },\n              \"hideFrom\": {\n                \"legend\": false,\n                \"tooltip\": false,\n                \"vis\": false\n              },\n              \"thresholdsStyle\": {\n                \"mode\": \"off\"\n              }\n            },\n            \"min\": 0,\n            \"max\": 1\n          }\n        },\n        \"gridPos\": {\n          \"h\": 8,\n          \"w\": 24,\n          \"x\": 0,\n          \"y\": 26\n        }\n      }\n    ],\n    \"time\": {\n      \"from\": \"now-1h\",\n      \"to\": \"now\"\n    },\n    \"timepicker\": {},\n    \"templating\": {\n      \"list\": []\n    },\n    \"annotations\": {\n      \"list\": [\n        {\n          \"builtIn\": 1,\n          \"datasource\": \"-- Grafana --\",\n          \"enable\": true,\n          \"hide\": true,\n          \"iconColor\": \"rgba(0, 211, 255, 1)\",\n          \"name\": \"Annotations & Alerts\",\n          \"type\": \"dashboard\"\n        }\n      ]\n    },\n    \"refresh\": \"30s\",\n    \"schemaVersion\": 27,\n    \"version\": 0,\n    \"links\": []\n  }\n}\n"
  },
  {
    "path": "local_install.sh",
    "content": "#!/bin/bash\n\n# Definir cores para melhor legibilidade\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m' # No Color\n\n# Função para log\nlog() {\n    echo -e \"${GREEN}[INFO]${NC} $1\"\n}\nlog_error() {\n    echo -e \"${RED}[ERROR]${NC} $1\"\n}\nlog_warning() {\n    echo -e \"${YELLOW}[WARNING]${NC} $1\"\n}\n\n# Verificar se está rodando como root\nif [ \"$(id -u)\" = \"0\" ]; then\n    log_error \"Este script não deve ser executado como root\"\n    exit 1\nfi\n\n# Verificar sistema operacional\nOS=\"$(uname -s)\"\ncase \"${OS}\" in\n    Linux*)     \n        if [ ! -x \"$(command -v curl)\" ]; then\n            log_warning \"Curl não está instalado. Tentando instalar...\"\n            if [ -x \"$(command -v apt-get)\" ]; then\n                sudo apt-get update && sudo apt-get install -y curl\n            elif [ -x \"$(command -v yum)\" ]; then\n                sudo yum install -y curl\n            else\n                log_error \"Não foi possível instalar curl automaticamente. Por favor, instale manualmente.\"\n                exit 1\n            fi\n        fi\n        ;;\n    Darwin*)    \n        if [ ! -x \"$(command -v curl)\" ]; then\n            log_error \"Curl não está instalado. Por favor, instale o Xcode Command Line Tools.\"\n            exit 1\n        fi\n        ;;\n    *)          \n        log_error \"Sistema operacional não suportado: ${OS}\"\n        exit 1\n        ;;\nesac\n\n# Verificar conexão com a internet antes de prosseguir\nif ! ping -c 1 8.8.8.8 &> /dev/null; then\n    log_error \"Sem conexão com a internet. Por favor, verifique sua conexão.\"\n    exit 1\nfi\n\n# Adicionar verificação de espaço em disco\nREQUIRED_SPACE=1000000 # 1GB em KB\nAVAILABLE_SPACE=$(df -k . | awk 'NR==2 {print $4}')\nif [ $AVAILABLE_SPACE -lt $REQUIRED_SPACE ]; then\n    log_error \"Espaço em disco insuficiente. Necessário pelo menos 1GB livre.\"\n    exit 1\nfi\n\n# Adicionar tratamento de erro para comandos npm\nnpm_install_with_retry() {\n    local max_attempts=3\n    local attempt=1\n    \n    while [ $attempt -le $max_attempts ]; do\n        log \"Tentativa $attempt de $max_attempts para npm install\"\n        if npm install; then\n            return 0\n        fi\n        attempt=$((attempt + 1))\n        [ $attempt -le $max_attempts ] && log_warning \"Falha na instalação. Tentando novamente em 5 segundos...\" && sleep 5\n    done\n    \n    log_error \"Falha ao executar npm install após $max_attempts tentativas\"\n    return 1\n}\n\n# Adicionar timeout para comandos\nexecute_with_timeout() {\n    timeout 300 $@ || log_error \"Comando excedeu o tempo limite de 5 minutos: $@\"\n}\n\n# Verificar se o NVM já está instalado\nif [ -d \"$HOME/.nvm\" ]; then\n    log \"NVM já está instalado.\"\nelse\n    log \"Instalando NVM...\"\n    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash\nfi\n\n# Carregar o NVM no ambiente atual\nexport NVM_DIR=\"$HOME/.nvm\"\n[ -s \"$NVM_DIR/nvm.sh\" ] && \\. \"$NVM_DIR/nvm.sh\"\n[ -s \"$NVM_DIR/bash_completion\" ] && \\. \"$NVM_DIR/bash_completion\"\n\n# Verificar se a versão do Node.js já está instalada\nif command -v node >/dev/null 2>&1 && [ \"$(node -v)\" = \"v20.10.0\" ]; then\n    log \"Node.js v20.10.0 já está instalado.\"\nelse\n    log \"Instalando Node.js v20.10.0...\"\n    nvm install v20.10.0\nfi\n\nnvm use v20.10.0\n\n# Verificar as versões instaladas\nlog \"Verificando as versões instaladas:\"\nlog \"Node.js: $(node -v)\"\nlog \"npm: $(npm -v)\"\n\n# Instala dependências do projeto\nlog \"Instalando dependências do projeto...\"\nrm -rf node_modules\nnpm install\n\n# Deploy do banco de dados\nlog \"Deploy do banco de dados...\"\nnpm run db:generate\nnpm run db:deploy\n\n# Iniciar o projeto\nlog \"Iniciando o projeto...\"\nif [ \"$1\" = \"-dev\" ]; then\n    npm run dev:server\nelse\n    npm run build\n    npm run start:prod\nfi\n\nlog \"Instalação concluída com sucesso!\"\n\n# Criar arquivo de log\nLOGFILE=\"./installation_log_$(date +%Y%m%d_%H%M%S).log\"\nexec 1> >(tee -a \"$LOGFILE\")\nexec 2>&1\n\n# Adicionar trap para limpeza em caso de interrupção\ncleanup() {\n    log \"Limpando recursos temporários...\"\n    # Adicione comandos de limpeza aqui\n}\ntrap cleanup EXIT\n"
  },
  {
    "path": "manager/dist/assets/index-CO3NSIFj.js",
    "content": "var TD=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var tie=TD((ko,jo)=>{function Bk(e,t){for(var n=0;n<t.length;n++){const r=t[n];if(typeof r!=\"string\"&&!Array.isArray(r)){for(const s in r)if(s!==\"default\"&&!(s in e)){const o=Object.getOwnPropertyDescriptor(r,s);o&&Object.defineProperty(e,s,o.get?o:{enumerable:!0,get:()=>r[s]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}))}(function(){const t=document.createElement(\"link\").relList;if(t&&t.supports&&t.supports(\"modulepreload\"))return;for(const s of document.querySelectorAll('link[rel=\"modulepreload\"]'))r(s);new MutationObserver(s=>{for(const o of s)if(o.type===\"childList\")for(const l of o.addedNodes)l.tagName===\"LINK\"&&l.rel===\"modulepreload\"&&r(l)}).observe(document,{childList:!0,subtree:!0});function n(s){const o={};return s.integrity&&(o.integrity=s.integrity),s.referrerPolicy&&(o.referrerPolicy=s.referrerPolicy),s.crossOrigin===\"use-credentials\"?o.credentials=\"include\":s.crossOrigin===\"anonymous\"?o.credentials=\"omit\":o.credentials=\"same-origin\",o}function r(s){if(s.ep)return;s.ep=!0;const o=n(s);fetch(s.href,o)}})();function fd(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}var av={exports:{}},Xc={},iv={exports:{}},Et={};/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */var A0;function ND(){if(A0)return Et;A0=1;var e=Symbol.for(\"react.element\"),t=Symbol.for(\"react.portal\"),n=Symbol.for(\"react.fragment\"),r=Symbol.for(\"react.strict_mode\"),s=Symbol.for(\"react.profiler\"),o=Symbol.for(\"react.provider\"),l=Symbol.for(\"react.context\"),u=Symbol.for(\"react.forward_ref\"),d=Symbol.for(\"react.suspense\"),f=Symbol.for(\"react.memo\"),h=Symbol.for(\"react.lazy\"),m=Symbol.iterator;function g(A){return A===null||typeof A!=\"object\"?null:(A=m&&A[m]||A[\"@@iterator\"],typeof A==\"function\"?A:null)}var x={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},b=Object.assign,w={};function C(A,F,fe){this.props=A,this.context=F,this.refs=w,this.updater=fe||x}C.prototype.isReactComponent={},C.prototype.setState=function(A,F){if(typeof A!=\"object\"&&typeof A!=\"function\"&&A!=null)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,A,F,\"setState\")},C.prototype.forceUpdate=function(A){this.updater.enqueueForceUpdate(this,A,\"forceUpdate\")};function k(){}k.prototype=C.prototype;function j(A,F,fe){this.props=A,this.context=F,this.refs=w,this.updater=fe||x}var M=j.prototype=new k;M.constructor=j,b(M,C.prototype),M.isPureReactComponent=!0;var _=Array.isArray,R=Object.prototype.hasOwnProperty,N={current:null},O={key:!0,ref:!0,__self:!0,__source:!0};function D(A,F,fe){var te,de={},ge=null,Z=null;if(F!=null)for(te in F.ref!==void 0&&(Z=F.ref),F.key!==void 0&&(ge=\"\"+F.key),F)R.call(F,te)&&!O.hasOwnProperty(te)&&(de[te]=F[te]);var ye=arguments.length-2;if(ye===1)de.children=fe;else if(1<ye){for(var Re=Array(ye),$e=0;$e<ye;$e++)Re[$e]=arguments[$e+2];de.children=Re}if(A&&A.defaultProps)for(te in ye=A.defaultProps,ye)de[te]===void 0&&(de[te]=ye[te]);return{$$typeof:e,type:A,key:ge,ref:Z,props:de,_owner:N.current}}function z(A,F){return{$$typeof:e,type:A.type,key:F,ref:A.ref,props:A.props,_owner:A._owner}}function Q(A){return typeof A==\"object\"&&A!==null&&A.$$typeof===e}function pe(A){var F={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+A.replace(/[=:]/g,function(fe){return F[fe]})}var V=/\\/+/g;function G(A,F){return typeof A==\"object\"&&A!==null&&A.key!=null?pe(\"\"+A.key):F.toString(36)}function W(A,F,fe,te,de){var ge=typeof A;(ge===\"undefined\"||ge===\"boolean\")&&(A=null);var Z=!1;if(A===null)Z=!0;else switch(ge){case\"string\":case\"number\":Z=!0;break;case\"object\":switch(A.$$typeof){case e:case t:Z=!0}}if(Z)return Z=A,de=de(Z),A=te===\"\"?\".\"+G(Z,0):te,_(de)?(fe=\"\",A!=null&&(fe=A.replace(V,\"$&/\")+\"/\"),W(de,F,fe,\"\",function($e){return $e})):de!=null&&(Q(de)&&(de=z(de,fe+(!de.key||Z&&Z.key===de.key?\"\":(\"\"+de.key).replace(V,\"$&/\")+\"/\")+A)),F.push(de)),1;if(Z=0,te=te===\"\"?\".\":te+\":\",_(A))for(var ye=0;ye<A.length;ye++){ge=A[ye];var Re=te+G(ge,ye);Z+=W(ge,F,fe,Re,de)}else if(Re=g(A),typeof Re==\"function\")for(A=Re.call(A),ye=0;!(ge=A.next()).done;)ge=ge.value,Re=te+G(ge,ye++),Z+=W(ge,F,fe,Re,de);else if(ge===\"object\")throw F=String(A),Error(\"Objects are not valid as a React child (found: \"+(F===\"[object Object]\"?\"object with keys {\"+Object.keys(A).join(\", \")+\"}\":F)+\"). If you meant to render a collection of children, use an array instead.\");return Z}function ie(A,F,fe){if(A==null)return A;var te=[],de=0;return W(A,te,\"\",\"\",function(ge){return F.call(fe,ge,de++)}),te}function re(A){if(A._status===-1){var F=A._result;F=F(),F.then(function(fe){(A._status===0||A._status===-1)&&(A._status=1,A._result=fe)},function(fe){(A._status===0||A._status===-1)&&(A._status=2,A._result=fe)}),A._status===-1&&(A._status=0,A._result=F)}if(A._status===1)return A._result.default;throw A._result}var Y={current:null},H={transition:null},q={ReactCurrentDispatcher:Y,ReactCurrentBatchConfig:H,ReactCurrentOwner:N};function he(){throw Error(\"act(...) is not supported in production builds of React.\")}return Et.Children={map:ie,forEach:function(A,F,fe){ie(A,function(){F.apply(this,arguments)},fe)},count:function(A){var F=0;return ie(A,function(){F++}),F},toArray:function(A){return ie(A,function(F){return F})||[]},only:function(A){if(!Q(A))throw Error(\"React.Children.only expected to receive a single React element child.\");return A}},Et.Component=C,Et.Fragment=n,Et.Profiler=s,Et.PureComponent=j,Et.StrictMode=r,Et.Suspense=d,Et.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=q,Et.act=he,Et.cloneElement=function(A,F,fe){if(A==null)throw Error(\"React.cloneElement(...): The argument must be a React element, but you passed \"+A+\".\");var te=b({},A.props),de=A.key,ge=A.ref,Z=A._owner;if(F!=null){if(F.ref!==void 0&&(ge=F.ref,Z=N.current),F.key!==void 0&&(de=\"\"+F.key),A.type&&A.type.defaultProps)var ye=A.type.defaultProps;for(Re in F)R.call(F,Re)&&!O.hasOwnProperty(Re)&&(te[Re]=F[Re]===void 0&&ye!==void 0?ye[Re]:F[Re])}var Re=arguments.length-2;if(Re===1)te.children=fe;else if(1<Re){ye=Array(Re);for(var $e=0;$e<Re;$e++)ye[$e]=arguments[$e+2];te.children=ye}return{$$typeof:e,type:A.type,key:de,ref:ge,props:te,_owner:Z}},Et.createContext=function(A){return A={$$typeof:l,_currentValue:A,_currentValue2:A,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},A.Provider={$$typeof:o,_context:A},A.Consumer=A},Et.createElement=D,Et.createFactory=function(A){var F=D.bind(null,A);return F.type=A,F},Et.createRef=function(){return{current:null}},Et.forwardRef=function(A){return{$$typeof:u,render:A}},Et.isValidElement=Q,Et.lazy=function(A){return{$$typeof:h,_payload:{_status:-1,_result:A},_init:re}},Et.memo=function(A,F){return{$$typeof:f,type:A,compare:F===void 0?null:F}},Et.startTransition=function(A){var F=H.transition;H.transition={};try{A()}finally{H.transition=F}},Et.unstable_act=he,Et.useCallback=function(A,F){return Y.current.useCallback(A,F)},Et.useContext=function(A){return Y.current.useContext(A)},Et.useDebugValue=function(){},Et.useDeferredValue=function(A){return Y.current.useDeferredValue(A)},Et.useEffect=function(A,F){return Y.current.useEffect(A,F)},Et.useId=function(){return Y.current.useId()},Et.useImperativeHandle=function(A,F,fe){return Y.current.useImperativeHandle(A,F,fe)},Et.useInsertionEffect=function(A,F){return Y.current.useInsertionEffect(A,F)},Et.useLayoutEffect=function(A,F){return Y.current.useLayoutEffect(A,F)},Et.useMemo=function(A,F){return Y.current.useMemo(A,F)},Et.useReducer=function(A,F,fe){return Y.current.useReducer(A,F,fe)},Et.useRef=function(A){return Y.current.useRef(A)},Et.useState=function(A){return Y.current.useState(A)},Et.useSyncExternalStore=function(A,F,fe){return Y.current.useSyncExternalStore(A,F,fe)},Et.useTransition=function(){return Y.current.useTransition()},Et.version=\"18.3.1\",Et}var D0;function pd(){return D0||(D0=1,iv.exports=ND()),iv.exports}/**\n * @license React\n * react-jsx-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */var F0;function MD(){if(F0)return Xc;F0=1;var e=pd(),t=Symbol.for(\"react.element\"),n=Symbol.for(\"react.fragment\"),r=Object.prototype.hasOwnProperty,s=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function l(u,d,f){var h,m={},g=null,x=null;f!==void 0&&(g=\"\"+f),d.key!==void 0&&(g=\"\"+d.key),d.ref!==void 0&&(x=d.ref);for(h in d)r.call(d,h)&&!o.hasOwnProperty(h)&&(m[h]=d[h]);if(u&&u.defaultProps)for(h in d=u.defaultProps,d)m[h]===void 0&&(m[h]=d[h]);return{$$typeof:t,type:u,key:g,ref:x,props:m,_owner:s.current}}return Xc.Fragment=n,Xc.jsx=l,Xc.jsxs=l,Xc}var L0;function _D(){return L0||(L0=1,av.exports=MD()),av.exports}var i=_D(),Zl=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}},Fl=typeof window>\"u\"||\"Deno\"in globalThis;function ss(){}function RD(e,t){return typeof e==\"function\"?e(t):e}function Sy(e){return typeof e==\"number\"&&e>=0&&e!==1/0}function zk(e,t){return Math.max(e+(t||0)-Date.now(),0)}function _l(e,t){return typeof e==\"function\"?e(t):e}function ws(e,t){return typeof e==\"function\"?e(t):e}function $0(e,t){const{type:n=\"all\",exact:r,fetchStatus:s,predicate:o,queryKey:l,stale:u}=e;if(l){if(r){if(t.queryHash!==_b(l,t.options))return!1}else if(!Ou(t.queryKey,l))return!1}if(n!==\"all\"){const d=t.isActive();if(n===\"active\"&&!d||n===\"inactive\"&&d)return!1}return!(typeof u==\"boolean\"&&t.isStale()!==u||s&&s!==t.state.fetchStatus||o&&!o(t))}function B0(e,t){const{exact:n,status:r,predicate:s,mutationKey:o}=e;if(o){if(!t.options.mutationKey)return!1;if(n){if(xi(t.options.mutationKey)!==xi(o))return!1}else if(!Ou(t.options.mutationKey,o))return!1}return!(r&&t.state.status!==r||s&&!s(t))}function _b(e,t){return(t?.queryKeyHashFn||xi)(e)}function xi(e){return JSON.stringify(e,(t,n)=>Cy(n)?Object.keys(n).sort().reduce((r,s)=>(r[s]=n[s],r),{}):n)}function Ou(e,t){return e===t?!0:typeof e!=typeof t?!1:e&&t&&typeof e==\"object\"&&typeof t==\"object\"?!Object.keys(t).some(n=>!Ou(e[n],t[n])):!1}function Uk(e,t){if(e===t)return e;const n=z0(e)&&z0(t);if(n||Cy(e)&&Cy(t)){const r=n?e:Object.keys(e),s=r.length,o=n?t:Object.keys(t),l=o.length,u=n?[]:{};let d=0;for(let f=0;f<l;f++){const h=n?f:o[f];(!n&&r.includes(h)||n)&&e[h]===void 0&&t[h]===void 0?(u[h]=void 0,d++):(u[h]=Uk(e[h],t[h]),u[h]===e[h]&&e[h]!==void 0&&d++)}return s===l&&d===s?e:u}return t}function Mp(e,t){if(!t||Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(e[n]!==t[n])return!1;return!0}function z0(e){return Array.isArray(e)&&e.length===Object.keys(e).length}function Cy(e){if(!U0(e))return!1;const t=e.constructor;if(t===void 0)return!0;const n=t.prototype;return!(!U0(n)||!n.hasOwnProperty(\"isPrototypeOf\")||Object.getPrototypeOf(e)!==Object.prototype)}function U0(e){return Object.prototype.toString.call(e)===\"[object Object]\"}function PD(e){return new Promise(t=>{setTimeout(t,e)})}function Ey(e,t,n){return typeof n.structuralSharing==\"function\"?n.structuralSharing(e,t):n.structuralSharing!==!1?Uk(e,t):t}function OD(e,t,n=0){const r=[...e,t];return n&&r.length>n?r.slice(1):r}function ID(e,t,n=0){const r=[t,...e];return n&&r.length>n?r.slice(0,-1):r}var Vk=Symbol();function Hk(e,t){return!e.queryFn&&t?.initialPromise?()=>t.initialPromise:!e.queryFn||e.queryFn===Vk?()=>Promise.reject(new Error(`Missing queryFn: '${e.queryHash}'`)):e.queryFn}var AD=class extends Zl{#e;#t;#r;constructor(){super(),this.#r=e=>{if(!Fl&&window.addEventListener){const t=()=>e();return window.addEventListener(\"visibilitychange\",t,!1),()=>{window.removeEventListener(\"visibilitychange\",t)}}}}onSubscribe(){this.#t||this.setEventListener(this.#r)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#r=e,this.#t?.(),this.#t=e(t=>{typeof t==\"boolean\"?this.setFocused(t):this.onFocus()})}setFocused(e){this.#e!==e&&(this.#e=e,this.onFocus())}onFocus(){const e=this.isFocused();this.listeners.forEach(t=>{t(e)})}isFocused(){return typeof this.#e==\"boolean\"?this.#e:globalThis.document?.visibilityState!==\"hidden\"}},Rb=new AD,DD=class extends Zl{#e=!0;#t;#r;constructor(){super(),this.#r=e=>{if(!Fl&&window.addEventListener){const t=()=>e(!0),n=()=>e(!1);return window.addEventListener(\"online\",t,!1),window.addEventListener(\"offline\",n,!1),()=>{window.removeEventListener(\"online\",t),window.removeEventListener(\"offline\",n)}}}}onSubscribe(){this.#t||this.setEventListener(this.#r)}onUnsubscribe(){this.hasListeners()||(this.#t?.(),this.#t=void 0)}setEventListener(e){this.#r=e,this.#t?.(),this.#t=e(this.setOnline.bind(this))}setOnline(e){this.#e!==e&&(this.#e=e,this.listeners.forEach(n=>{n(e)}))}isOnline(){return this.#e}},_p=new DD;function FD(e){return Math.min(1e3*2**e,3e4)}function qk(e){return(e??\"online\")===\"online\"?_p.isOnline():!0}var Kk=class extends Error{constructor(e){super(\"CancelledError\"),this.revert=e?.revert,this.silent=e?.silent}};function lv(e){return e instanceof Kk}function Wk(e){let t=!1,n=0,r=!1,s,o,l;const u=new Promise((k,j)=>{o=k,l=j}),d=k=>{r||(b(new Kk(k)),e.abort?.())},f=()=>{t=!0},h=()=>{t=!1},m=()=>Rb.isFocused()&&(e.networkMode===\"always\"||_p.isOnline())&&e.canRun(),g=()=>qk(e.networkMode)&&e.canRun(),x=k=>{r||(r=!0,e.onSuccess?.(k),s?.(),o(k))},b=k=>{r||(r=!0,e.onError?.(k),s?.(),l(k))},w=()=>new Promise(k=>{s=j=>{(r||m())&&k(j)},e.onPause?.()}).then(()=>{s=void 0,r||e.onContinue?.()}),C=()=>{if(r)return;let k;const j=n===0?e.initialPromise:void 0;try{k=j??e.fn()}catch(M){k=Promise.reject(M)}Promise.resolve(k).then(x).catch(M=>{if(r)return;const _=e.retry??(Fl?0:3),R=e.retryDelay??FD,N=typeof R==\"function\"?R(n,M):R,O=_===!0||typeof _==\"number\"&&n<_||typeof _==\"function\"&&_(n,M);if(t||!O){b(M);return}n++,e.onFail?.(n,M),PD(N).then(()=>m()?void 0:w()).then(()=>{t?b(M):C()})})};return{promise:u,cancel:d,continue:()=>(s?.(),u),cancelRetry:f,continueRetry:h,canStart:g,start:()=>(g()?C():w().then(C),u)}}function LD(){let e=[],t=0,n=g=>{g()},r=g=>{g()},s=g=>setTimeout(g,0);const o=g=>{s=g},l=g=>{let x;t++;try{x=g()}finally{t--,t||f()}return x},u=g=>{t?e.push(g):s(()=>{n(g)})},d=g=>(...x)=>{u(()=>{g(...x)})},f=()=>{const g=e;e=[],g.length&&s(()=>{r(()=>{g.forEach(x=>{n(x)})})})};return{batch:l,batchCalls:d,schedule:u,setNotifyFunction:g=>{n=g},setBatchNotifyFunction:g=>{r=g},setScheduler:o}}var Fn=LD(),Gk=class{#e;destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),Sy(this.gcTime)&&(this.#e=setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??(Fl?1/0:300*1e3))}clearGcTimeout(){this.#e&&(clearTimeout(this.#e),this.#e=void 0)}},$D=class extends Gk{#e;#t;#r;#n;#a;#o;constructor(e){super(),this.#o=!1,this.#a=e.defaultOptions,this.setOptions(e.options),this.observers=[],this.#r=e.cache,this.queryKey=e.queryKey,this.queryHash=e.queryHash,this.#e=BD(this.options),this.state=e.state??this.#e,this.scheduleGc()}get meta(){return this.options.meta}get promise(){return this.#n?.promise}setOptions(e){this.options={...this.#a,...e},this.updateGcTime(this.options.gcTime)}optionalRemove(){!this.observers.length&&this.state.fetchStatus===\"idle\"&&this.#r.remove(this)}setData(e,t){const n=Ey(this.state.data,e,this.options);return this.#s({data:n,type:\"success\",dataUpdatedAt:t?.updatedAt,manual:t?.manual}),n}setState(e,t){this.#s({type:\"setState\",state:e,setStateOptions:t})}cancel(e){const t=this.#n?.promise;return this.#n?.cancel(e),t?t.then(ss).catch(ss):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}reset(){this.destroy(),this.setState(this.#e)}isActive(){return this.observers.some(e=>ws(e.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0&&!this.isActive()}isStale(){return this.state.isInvalidated?!0:this.getObserversCount()>0?this.observers.some(e=>e.getCurrentResult().isStale):this.state.data===void 0}isStaleByTime(e=0){return this.state.isInvalidated||this.state.data===void 0||!zk(this.state.dataUpdatedAt,e)}onFocus(){this.observers.find(t=>t.shouldFetchOnWindowFocus())?.refetch({cancelRefetch:!1}),this.#n?.continue()}onOnline(){this.observers.find(t=>t.shouldFetchOnReconnect())?.refetch({cancelRefetch:!1}),this.#n?.continue()}addObserver(e){this.observers.includes(e)||(this.observers.push(e),this.clearGcTimeout(),this.#r.notify({type:\"observerAdded\",query:this,observer:e}))}removeObserver(e){this.observers.includes(e)&&(this.observers=this.observers.filter(t=>t!==e),this.observers.length||(this.#n&&(this.#o?this.#n.cancel({revert:!0}):this.#n.cancelRetry()),this.scheduleGc()),this.#r.notify({type:\"observerRemoved\",query:this,observer:e}))}getObserversCount(){return this.observers.length}invalidate(){this.state.isInvalidated||this.#s({type:\"invalidate\"})}fetch(e,t){if(this.state.fetchStatus!==\"idle\"){if(this.state.data!==void 0&&t?.cancelRefetch)this.cancel({silent:!0});else if(this.#n)return this.#n.continueRetry(),this.#n.promise}if(e&&this.setOptions(e),!this.options.queryFn){const u=this.observers.find(d=>d.options.queryFn);u&&this.setOptions(u.options)}const n=new AbortController,r=u=>{Object.defineProperty(u,\"signal\",{enumerable:!0,get:()=>(this.#o=!0,n.signal)})},s=()=>{const u=Hk(this.options,t),d={queryKey:this.queryKey,meta:this.meta};return r(d),this.#o=!1,this.options.persister?this.options.persister(u,d,this):u(d)},o={fetchOptions:t,options:this.options,queryKey:this.queryKey,state:this.state,fetchFn:s};r(o),this.options.behavior?.onFetch(o,this),this.#t=this.state,(this.state.fetchStatus===\"idle\"||this.state.fetchMeta!==o.fetchOptions?.meta)&&this.#s({type:\"fetch\",meta:o.fetchOptions?.meta});const l=u=>{lv(u)&&u.silent||this.#s({type:\"error\",error:u}),lv(u)||(this.#r.config.onError?.(u,this),this.#r.config.onSettled?.(this.state.data,u,this)),this.isFetchingOptimistic||this.scheduleGc(),this.isFetchingOptimistic=!1};return this.#n=Wk({initialPromise:t?.initialPromise,fn:o.fetchFn,abort:n.abort.bind(n),onSuccess:u=>{if(u===void 0){l(new Error(`${this.queryHash} data is undefined`));return}try{this.setData(u)}catch(d){l(d);return}this.#r.config.onSuccess?.(u,this),this.#r.config.onSettled?.(u,this.state.error,this),this.isFetchingOptimistic||this.scheduleGc(),this.isFetchingOptimistic=!1},onError:l,onFail:(u,d)=>{this.#s({type:\"failed\",failureCount:u,error:d})},onPause:()=>{this.#s({type:\"pause\"})},onContinue:()=>{this.#s({type:\"continue\"})},retry:o.options.retry,retryDelay:o.options.retryDelay,networkMode:o.options.networkMode,canRun:()=>!0}),this.#n.start()}#s(e){const t=n=>{switch(e.type){case\"failed\":return{...n,fetchFailureCount:e.failureCount,fetchFailureReason:e.error};case\"pause\":return{...n,fetchStatus:\"paused\"};case\"continue\":return{...n,fetchStatus:\"fetching\"};case\"fetch\":return{...n,...Jk(n.data,this.options),fetchMeta:e.meta??null};case\"success\":return{...n,data:e.data,dataUpdateCount:n.dataUpdateCount+1,dataUpdatedAt:e.dataUpdatedAt??Date.now(),error:null,isInvalidated:!1,status:\"success\",...!e.manual&&{fetchStatus:\"idle\",fetchFailureCount:0,fetchFailureReason:null}};case\"error\":const r=e.error;return lv(r)&&r.revert&&this.#t?{...this.#t,fetchStatus:\"idle\"}:{...n,error:r,errorUpdateCount:n.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:n.fetchFailureCount+1,fetchFailureReason:r,fetchStatus:\"idle\",status:\"error\"};case\"invalidate\":return{...n,isInvalidated:!0};case\"setState\":return{...n,...e.state}}};this.state=t(this.state),Fn.batch(()=>{this.observers.forEach(n=>{n.onQueryUpdate()}),this.#r.notify({query:this,type:\"updated\",action:e})})}};function Jk(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:qk(t.networkMode)?\"fetching\":\"paused\",...e===void 0&&{error:null,status:\"pending\"}}}function BD(e){const t=typeof e.initialData==\"function\"?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt==\"function\"?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?\"success\":\"pending\",fetchStatus:\"idle\"}}var zD=class extends Zl{constructor(e={}){super(),this.config=e,this.#e=new Map}#e;build(e,t,n){const r=t.queryKey,s=t.queryHash??_b(r,t);let o=this.get(s);return o||(o=new $D({cache:this,queryKey:r,queryHash:s,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(o)),o}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:\"added\",query:e}))}remove(e){const t=this.#e.get(e.queryHash);t&&(e.destroy(),t===e&&this.#e.delete(e.queryHash),this.notify({type:\"removed\",query:e}))}clear(){Fn.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){const t={exact:!0,...e};return this.getAll().find(n=>$0(t,n))}findAll(e={}){const t=this.getAll();return Object.keys(e).length>0?t.filter(n=>$0(e,n)):t}notify(e){Fn.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){Fn.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){Fn.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},UD=class extends Gk{#e;#t;#r;constructor(e){super(),this.mutationId=e.mutationId,this.#t=e.mutationCache,this.#e=[],this.state=e.state||Qk(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#e.includes(e)||(this.#e.push(e),this.clearGcTimeout(),this.#t.notify({type:\"observerAdded\",mutation:this,observer:e}))}removeObserver(e){this.#e=this.#e.filter(t=>t!==e),this.scheduleGc(),this.#t.notify({type:\"observerRemoved\",mutation:this,observer:e})}optionalRemove(){this.#e.length||(this.state.status===\"pending\"?this.scheduleGc():this.#t.remove(this))}continue(){return this.#r?.continue()??this.execute(this.state.variables)}async execute(e){this.#r=Wk({fn:()=>this.options.mutationFn?this.options.mutationFn(e):Promise.reject(new Error(\"No mutationFn found\")),onFail:(r,s)=>{this.#n({type:\"failed\",failureCount:r,error:s})},onPause:()=>{this.#n({type:\"pause\"})},onContinue:()=>{this.#n({type:\"continue\"})},retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#t.canRun(this)});const t=this.state.status===\"pending\",n=!this.#r.canStart();try{if(!t){this.#n({type:\"pending\",variables:e,isPaused:n}),await this.#t.config.onMutate?.(e,this);const s=await this.options.onMutate?.(e);s!==this.state.context&&this.#n({type:\"pending\",context:s,variables:e,isPaused:n})}const r=await this.#r.start();return await this.#t.config.onSuccess?.(r,e,this.state.context,this),await this.options.onSuccess?.(r,e,this.state.context),await this.#t.config.onSettled?.(r,null,this.state.variables,this.state.context,this),await this.options.onSettled?.(r,null,e,this.state.context),this.#n({type:\"success\",data:r}),r}catch(r){try{throw await this.#t.config.onError?.(r,e,this.state.context,this),await this.options.onError?.(r,e,this.state.context),await this.#t.config.onSettled?.(void 0,r,this.state.variables,this.state.context,this),await this.options.onSettled?.(void 0,r,e,this.state.context),r}finally{this.#n({type:\"error\",error:r})}}finally{this.#t.runNext(this)}}#n(e){const t=n=>{switch(e.type){case\"failed\":return{...n,failureCount:e.failureCount,failureReason:e.error};case\"pause\":return{...n,isPaused:!0};case\"continue\":return{...n,isPaused:!1};case\"pending\":return{...n,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:\"pending\",variables:e.variables,submittedAt:Date.now()};case\"success\":return{...n,data:e.data,failureCount:0,failureReason:null,error:null,status:\"success\",isPaused:!1};case\"error\":return{...n,data:void 0,error:e.error,failureCount:n.failureCount+1,failureReason:e.error,isPaused:!1,status:\"error\"}}};this.state=t(this.state),Fn.batch(()=>{this.#e.forEach(n=>{n.onMutationUpdate(e)}),this.#t.notify({mutation:this,type:\"updated\",action:e})})}};function Qk(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:\"idle\",variables:void 0,submittedAt:0}}var VD=class extends Zl{constructor(e={}){super(),this.config=e,this.#e=new Map,this.#t=Date.now()}#e;#t;build(e,t,n){const r=new UD({mutationCache:this,mutationId:++this.#t,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){const t=Df(e),n=this.#e.get(t)??[];n.push(e),this.#e.set(t,n),this.notify({type:\"added\",mutation:e})}remove(e){const t=Df(e);if(this.#e.has(t)){const n=this.#e.get(t)?.filter(r=>r!==e);n&&(n.length===0?this.#e.delete(t):this.#e.set(t,n))}this.notify({type:\"removed\",mutation:e})}canRun(e){const t=this.#e.get(Df(e))?.find(n=>n.state.status===\"pending\");return!t||t===e}runNext(e){return this.#e.get(Df(e))?.find(n=>n!==e&&n.state.isPaused)?.continue()??Promise.resolve()}clear(){Fn.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}getAll(){return[...this.#e.values()].flat()}find(e){const t={exact:!0,...e};return this.getAll().find(n=>B0(t,n))}findAll(e={}){return this.getAll().filter(t=>B0(e,t))}notify(e){Fn.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){const e=this.getAll().filter(t=>t.state.isPaused);return Fn.batch(()=>Promise.all(e.map(t=>t.continue().catch(ss))))}};function Df(e){return e.options.scope?.id??String(e.mutationId)}function HD(e){return{onFetch:(t,n)=>{const r=async()=>{const s=t.options,o=t.fetchOptions?.meta?.fetchMore?.direction,l=t.state.data?.pages||[],u=t.state.data?.pageParams||[],d={pages:[],pageParams:[]};let f=!1;const h=b=>{Object.defineProperty(b,\"signal\",{enumerable:!0,get:()=>(t.signal.aborted?f=!0:t.signal.addEventListener(\"abort\",()=>{f=!0}),t.signal)})},m=Hk(t.options,t.fetchOptions),g=async(b,w,C)=>{if(f)return Promise.reject();if(w==null&&b.pages.length)return Promise.resolve(b);const k={queryKey:t.queryKey,pageParam:w,direction:C?\"backward\":\"forward\",meta:t.options.meta};h(k);const j=await m(k),{maxPages:M}=t.options,_=C?ID:OD;return{pages:_(b.pages,j,M),pageParams:_(b.pageParams,w,M)}};let x;if(o&&l.length){const b=o===\"backward\",w=b?qD:V0,C={pages:l,pageParams:u},k=w(s,C);x=await g(C,k,b)}else{x=await g(d,u[0]??s.initialPageParam);const b=e??l.length;for(let w=1;w<b;w++){const C=V0(s,x);if(C==null)break;x=await g(x,C)}}return x};t.options.persister?t.fetchFn=()=>t.options.persister?.(r,{queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):t.fetchFn=r}}}function V0(e,{pages:t,pageParams:n}){const r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function qD(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}var KD=class{#e;#t;#r;#n;#a;#o;#s;#i;constructor(e={}){this.#e=e.queryCache||new zD,this.#t=e.mutationCache||new VD,this.#r=e.defaultOptions||{},this.#n=new Map,this.#a=new Map,this.#o=0}mount(){this.#o++,this.#o===1&&(this.#s=Rb.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#i=_p.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#o--,this.#o===0&&(this.#s?.(),this.#s=void 0,this.#i?.(),this.#i=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:\"fetching\"}).length}isMutating(e){return this.#t.findAll({...e,status:\"pending\"}).length}getQueryData(e){const t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){const t=this.getQueryData(e.queryKey);if(t===void 0)return this.fetchQuery(e);{const n=this.defaultQueryOptions(e),r=this.#e.build(this,n);return e.revalidateIfStale&&r.isStaleByTime(_l(n.staleTime,r))&&this.prefetchQuery(n),Promise.resolve(t)}}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:t,state:n})=>{const r=n.data;return[t,r]})}setQueryData(e,t,n){const r=this.defaultQueryOptions({queryKey:e}),o=this.#e.get(r.queryHash)?.state.data,l=RD(t,o);if(l!==void 0)return this.#e.build(this,r).setData(l,{...n,manual:!0})}setQueriesData(e,t,n){return Fn.batch(()=>this.#e.findAll(e).map(({queryKey:r})=>[r,this.setQueryData(r,t,n)]))}getQueryState(e){const t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){const t=this.#e;Fn.batch(()=>{t.findAll(e).forEach(n=>{t.remove(n)})})}resetQueries(e,t){const n=this.#e,r={type:\"active\",...e};return Fn.batch(()=>(n.findAll(e).forEach(s=>{s.reset()}),this.refetchQueries(r,t)))}cancelQueries(e={},t={}){const n={revert:!0,...t},r=Fn.batch(()=>this.#e.findAll(e).map(s=>s.cancel(n)));return Promise.all(r).then(ss).catch(ss)}invalidateQueries(e={},t={}){return Fn.batch(()=>{if(this.#e.findAll(e).forEach(r=>{r.invalidate()}),e.refetchType===\"none\")return Promise.resolve();const n={...e,type:e.refetchType??e.type??\"active\"};return this.refetchQueries(n,t)})}refetchQueries(e={},t){const n={...t,cancelRefetch:t?.cancelRefetch??!0},r=Fn.batch(()=>this.#e.findAll(e).filter(s=>!s.isDisabled()).map(s=>{let o=s.fetch(void 0,n);return n.throwOnError||(o=o.catch(ss)),s.state.fetchStatus===\"paused\"?Promise.resolve():o}));return Promise.all(r).then(ss)}fetchQuery(e){const t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);const n=this.#e.build(this,t);return n.isStaleByTime(_l(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(ss).catch(ss)}fetchInfiniteQuery(e){return e.behavior=HD(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(ss).catch(ss)}resumePausedMutations(){return _p.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#r}setDefaultOptions(e){this.#r=e}setQueryDefaults(e,t){this.#n.set(xi(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){const t=[...this.#n.values()];let n={};return t.forEach(r=>{Ou(e,r.queryKey)&&(n={...n,...r.defaultOptions})}),n}setMutationDefaults(e,t){this.#a.set(xi(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){const t=[...this.#a.values()];let n={};return t.forEach(r=>{Ou(e,r.mutationKey)&&(n={...n,...r.defaultOptions})}),n}defaultQueryOptions(e){if(e._defaulted)return e;const t={...this.#r.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=_b(t.queryKey,t)),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==\"always\"),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=\"offlineFirst\"),t.enabled!==!0&&t.queryFn===Vk&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#r.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}},WD=class extends Zl{constructor(e,t){super(),this.options=t,this.#e=e,this.#s=null,this.bindMethods(),this.setOptions(t)}#e;#t=void 0;#r=void 0;#n=void 0;#a;#o;#s;#i;#f;#p;#c;#u;#l;#h=new Set;bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.#t.addObserver(this),H0(this.#t,this.options)?this.#d():this.updateResult(),this.#y())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return ky(this.#t,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return ky(this.#t,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#b(),this.#x(),this.#t.removeObserver(this)}setOptions(e,t){const n=this.options,r=this.#t;if(this.options=this.#e.defaultQueryOptions(e),this.options.enabled!==void 0&&typeof this.options.enabled!=\"boolean\"&&typeof this.options.enabled!=\"function\"&&typeof ws(this.options.enabled,this.#t)!=\"boolean\")throw new Error(\"Expected enabled to be a boolean or a callback that returns a boolean\");this.#w(),this.#t.setOptions(this.options),n._defaulted&&!Mp(this.options,n)&&this.#e.getQueryCache().notify({type:\"observerOptionsUpdated\",query:this.#t,observer:this});const s=this.hasListeners();s&&q0(this.#t,r,this.options,n)&&this.#d(),this.updateResult(t),s&&(this.#t!==r||ws(this.options.enabled,this.#t)!==ws(n.enabled,this.#t)||_l(this.options.staleTime,this.#t)!==_l(n.staleTime,this.#t))&&this.#g();const o=this.#m();s&&(this.#t!==r||ws(this.options.enabled,this.#t)!==ws(n.enabled,this.#t)||o!==this.#l)&&this.#v(o)}getOptimisticResult(e){const t=this.#e.getQueryCache().build(this.#e,e),n=this.createResult(t,e);return JD(this,n)&&(this.#n=n,this.#o=this.options,this.#a=this.#t.state),n}getCurrentResult(){return this.#n}trackResult(e,t){const n={};return Object.keys(e).forEach(r=>{Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:()=>(this.trackProp(r),t?.(r),e[r])})}),n}trackProp(e){this.#h.add(e)}getCurrentQuery(){return this.#t}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){const t=this.#e.defaultQueryOptions(e),n=this.#e.getQueryCache().build(this.#e,t);return n.isFetchingOptimistic=!0,n.fetch().then(()=>this.createResult(n,t))}fetch(e){return this.#d({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#n))}#d(e){this.#w();let t=this.#t.fetch(this.options,e);return e?.throwOnError||(t=t.catch(ss)),t}#g(){this.#b();const e=_l(this.options.staleTime,this.#t);if(Fl||this.#n.isStale||!Sy(e))return;const n=zk(this.#n.dataUpdatedAt,e)+1;this.#c=setTimeout(()=>{this.#n.isStale||this.updateResult()},n)}#m(){return(typeof this.options.refetchInterval==\"function\"?this.options.refetchInterval(this.#t):this.options.refetchInterval)??!1}#v(e){this.#x(),this.#l=e,!(Fl||ws(this.options.enabled,this.#t)===!1||!Sy(this.#l)||this.#l===0)&&(this.#u=setInterval(()=>{(this.options.refetchIntervalInBackground||Rb.isFocused())&&this.#d()},this.#l))}#y(){this.#g(),this.#v(this.#m())}#b(){this.#c&&(clearTimeout(this.#c),this.#c=void 0)}#x(){this.#u&&(clearInterval(this.#u),this.#u=void 0)}createResult(e,t){const n=this.#t,r=this.options,s=this.#n,o=this.#a,l=this.#o,d=e!==n?e.state:this.#r,{state:f}=e;let h={...f},m=!1,g;if(t._optimisticResults){const N=this.hasListeners(),O=!N&&H0(e,t),D=N&&q0(e,n,t,r);(O||D)&&(h={...h,...Jk(f.data,e.options)}),t._optimisticResults===\"isRestoring\"&&(h.fetchStatus=\"idle\")}let{error:x,errorUpdatedAt:b,status:w}=h;if(t.select&&h.data!==void 0)if(s&&h.data===o?.data&&t.select===this.#i)g=this.#f;else try{this.#i=t.select,g=t.select(h.data),g=Ey(s?.data,g,t),this.#f=g,this.#s=null}catch(N){this.#s=N}else g=h.data;if(t.placeholderData!==void 0&&g===void 0&&w===\"pending\"){let N;if(s?.isPlaceholderData&&t.placeholderData===l?.placeholderData)N=s.data;else if(N=typeof t.placeholderData==\"function\"?t.placeholderData(this.#p?.state.data,this.#p):t.placeholderData,t.select&&N!==void 0)try{N=t.select(N),this.#s=null}catch(O){this.#s=O}N!==void 0&&(w=\"success\",g=Ey(s?.data,N,t),m=!0)}this.#s&&(x=this.#s,g=this.#f,b=Date.now(),w=\"error\");const C=h.fetchStatus===\"fetching\",k=w===\"pending\",j=w===\"error\",M=k&&C,_=g!==void 0;return{status:w,fetchStatus:h.fetchStatus,isPending:k,isSuccess:w===\"success\",isError:j,isInitialLoading:M,isLoading:M,data:g,dataUpdatedAt:h.dataUpdatedAt,error:x,errorUpdatedAt:b,failureCount:h.fetchFailureCount,failureReason:h.fetchFailureReason,errorUpdateCount:h.errorUpdateCount,isFetched:h.dataUpdateCount>0||h.errorUpdateCount>0,isFetchedAfterMount:h.dataUpdateCount>d.dataUpdateCount||h.errorUpdateCount>d.errorUpdateCount,isFetching:C,isRefetching:C&&!k,isLoadingError:j&&!_,isPaused:h.fetchStatus===\"paused\",isPlaceholderData:m,isRefetchError:j&&_,isStale:Pb(e,t),refetch:this.refetch}}updateResult(e){const t=this.#n,n=this.createResult(this.#t,this.options);if(this.#a=this.#t.state,this.#o=this.options,this.#a.data!==void 0&&(this.#p=this.#t),Mp(n,t))return;this.#n=n;const r={},s=()=>{if(!t)return!0;const{notifyOnChangeProps:o}=this.options,l=typeof o==\"function\"?o():o;if(l===\"all\"||!l&&!this.#h.size)return!0;const u=new Set(l??this.#h);return this.options.throwOnError&&u.add(\"error\"),Object.keys(this.#n).some(d=>{const f=d;return this.#n[f]!==t[f]&&u.has(f)})};e?.listeners!==!1&&s()&&(r.listeners=!0),this.#S({...r,...e})}#w(){const e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#t)return;const t=this.#t;this.#t=e,this.#r=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#y()}#S(e){Fn.batch(()=>{e.listeners&&this.listeners.forEach(t=>{t(this.#n)}),this.#e.getQueryCache().notify({query:this.#t,type:\"observerResultsUpdated\"})})}};function GD(e,t){return ws(t.enabled,e)!==!1&&e.state.data===void 0&&!(e.state.status===\"error\"&&t.retryOnMount===!1)}function H0(e,t){return GD(e,t)||e.state.data!==void 0&&ky(e,t,t.refetchOnMount)}function ky(e,t,n){if(ws(t.enabled,e)!==!1){const r=typeof n==\"function\"?n(e):n;return r===\"always\"||r!==!1&&Pb(e,t)}return!1}function q0(e,t,n,r){return(e!==t||ws(r.enabled,e)===!1)&&(!n.suspense||e.state.status!==\"error\")&&Pb(e,n)}function Pb(e,t){return ws(t.enabled,e)!==!1&&e.isStaleByTime(_l(t.staleTime,e))}function JD(e,t){return!Mp(e.getCurrentResult(),t)}var QD=class extends Zl{#e;#t=void 0;#r;#n;constructor(t,n){super(),this.#e=t,this.setOptions(n),this.bindMethods(),this.#a()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(t){const n=this.options;this.options=this.#e.defaultMutationOptions(t),Mp(this.options,n)||this.#e.getMutationCache().notify({type:\"observerOptionsUpdated\",mutation:this.#r,observer:this}),n?.mutationKey&&this.options.mutationKey&&xi(n.mutationKey)!==xi(this.options.mutationKey)?this.reset():this.#r?.state.status===\"pending\"&&this.#r.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#r?.removeObserver(this)}onMutationUpdate(t){this.#a(),this.#o(t)}getCurrentResult(){return this.#t}reset(){this.#r?.removeObserver(this),this.#r=void 0,this.#a(),this.#o()}mutate(t,n){return this.#n=n,this.#r?.removeObserver(this),this.#r=this.#e.getMutationCache().build(this.#e,this.options),this.#r.addObserver(this),this.#r.execute(t)}#a(){const t=this.#r?.state??Qk();this.#t={...t,isPending:t.status===\"pending\",isSuccess:t.status===\"success\",isError:t.status===\"error\",isIdle:t.status===\"idle\",mutate:this.mutate,reset:this.reset}}#o(t){Fn.batch(()=>{if(this.#n&&this.hasListeners()){const n=this.#t.variables,r=this.#t.context;t?.type===\"success\"?(this.#n.onSuccess?.(t.data,n,r),this.#n.onSettled?.(t.data,null,n,r)):t?.type===\"error\"&&(this.#n.onError?.(t.error,n,r),this.#n.onSettled?.(void 0,t.error,n,r))}this.listeners.forEach(n=>{n(this.#t)})})}},y=pd();const qe=fd(y),Yl=Bk({__proto__:null,default:qe},[y]);var Zk=y.createContext(void 0),Ob=e=>{const t=y.useContext(Zk);if(!t)throw new Error(\"No QueryClient set, use QueryClientProvider to set one\");return t},Yk=({client:e,children:t})=>(y.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),i.jsx(Zk.Provider,{value:e,children:t})),Xk=y.createContext(!1),ZD=()=>y.useContext(Xk);Xk.Provider;function YD(){let e=!1;return{clearReset:()=>{e=!1},reset:()=>{e=!0},isReset:()=>e}}var XD=y.createContext(YD()),eF=()=>y.useContext(XD);function ej(e,t){return typeof e==\"function\"?e(...t):!!e}function tF(){}var nF=(e,t)=>{(e.suspense||e.throwOnError)&&(t.isReset()||(e.retryOnMount=!1))},rF=e=>{y.useEffect(()=>{e.clearReset()},[e])},sF=({result:e,errorResetBoundary:t,throwOnError:n,query:r})=>e.isError&&!t.isReset()&&!e.isFetching&&r&&ej(n,[e.error,r]),oF=e=>{e.suspense&&(typeof e.staleTime!=\"number\"&&(e.staleTime=1e3),typeof e.gcTime==\"number\"&&(e.gcTime=Math.max(e.gcTime,1e3)))},aF=(e,t)=>e?.suspense&&t.isPending,iF=(e,t,n)=>t.fetchOptimistic(e).catch(()=>{n.clearReset()});function lF(e,t,n){const r=Ob(),s=ZD(),o=eF(),l=r.defaultQueryOptions(e);r.getDefaultOptions().queries?._experimental_beforeQuery?.(l),l._optimisticResults=s?\"isRestoring\":\"optimistic\",oF(l),nF(l,o),rF(o);const[u]=y.useState(()=>new t(r,l)),d=u.getOptimisticResult(l);if(y.useSyncExternalStore(y.useCallback(f=>{const h=s?()=>{}:u.subscribe(Fn.batchCalls(f));return u.updateResult(),h},[u,s]),()=>u.getCurrentResult(),()=>u.getCurrentResult()),y.useEffect(()=>{u.setOptions(l,{listeners:!1})},[l,u]),aF(l,d))throw iF(l,u,o);if(sF({result:d,errorResetBoundary:o,throwOnError:l.throwOnError,query:r.getQueryCache().get(l.queryHash)}))throw d.error;return r.getDefaultOptions().queries?._experimental_afterQuery?.(l,d),l.notifyOnChangeProps?d:u.trackResult(d)}function mt(e,t){return lF(e,WD)}function cF(e,t){const n=Ob(),[r]=y.useState(()=>new QD(n,e));y.useEffect(()=>{r.setOptions(e)},[r,e]);const s=y.useSyncExternalStore(y.useCallback(l=>r.subscribe(Fn.batchCalls(l)),[r]),()=>r.getCurrentResult(),()=>r.getCurrentResult()),o=y.useCallback((l,u)=>{r.mutate(l,u).catch(tF)},[r]);if(s.error&&ej(r.options.throwOnError,[s.error]))throw s.error;return{...s,mutate:o,mutateAsync:s.mutate}}var Ff={},cv={exports:{}},Cr={},uv={exports:{}},dv={};/**\n * @license React\n * scheduler.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */var K0;function uF(){return K0||(K0=1,(function(e){function t(H,q){var he=H.length;H.push(q);e:for(;0<he;){var A=he-1>>>1,F=H[A];if(0<s(F,q))H[A]=q,H[he]=F,he=A;else break e}}function n(H){return H.length===0?null:H[0]}function r(H){if(H.length===0)return null;var q=H[0],he=H.pop();if(he!==q){H[0]=he;e:for(var A=0,F=H.length,fe=F>>>1;A<fe;){var te=2*(A+1)-1,de=H[te],ge=te+1,Z=H[ge];if(0>s(de,he))ge<F&&0>s(Z,de)?(H[A]=Z,H[ge]=he,A=ge):(H[A]=de,H[te]=he,A=te);else if(ge<F&&0>s(Z,he))H[A]=Z,H[ge]=he,A=ge;else break e}}return q}function s(H,q){var he=H.sortIndex-q.sortIndex;return he!==0?he:H.id-q.id}if(typeof performance==\"object\"&&typeof performance.now==\"function\"){var o=performance;e.unstable_now=function(){return o.now()}}else{var l=Date,u=l.now();e.unstable_now=function(){return l.now()-u}}var d=[],f=[],h=1,m=null,g=3,x=!1,b=!1,w=!1,C=typeof setTimeout==\"function\"?setTimeout:null,k=typeof clearTimeout==\"function\"?clearTimeout:null,j=typeof setImmediate<\"u\"?setImmediate:null;typeof navigator<\"u\"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function M(H){for(var q=n(f);q!==null;){if(q.callback===null)r(f);else if(q.startTime<=H)r(f),q.sortIndex=q.expirationTime,t(d,q);else break;q=n(f)}}function _(H){if(w=!1,M(H),!b)if(n(d)!==null)b=!0,re(R);else{var q=n(f);q!==null&&Y(_,q.startTime-H)}}function R(H,q){b=!1,w&&(w=!1,k(D),D=-1),x=!0;var he=g;try{for(M(q),m=n(d);m!==null&&(!(m.expirationTime>q)||H&&!pe());){var A=m.callback;if(typeof A==\"function\"){m.callback=null,g=m.priorityLevel;var F=A(m.expirationTime<=q);q=e.unstable_now(),typeof F==\"function\"?m.callback=F:m===n(d)&&r(d),M(q)}else r(d);m=n(d)}if(m!==null)var fe=!0;else{var te=n(f);te!==null&&Y(_,te.startTime-q),fe=!1}return fe}finally{m=null,g=he,x=!1}}var N=!1,O=null,D=-1,z=5,Q=-1;function pe(){return!(e.unstable_now()-Q<z)}function V(){if(O!==null){var H=e.unstable_now();Q=H;var q=!0;try{q=O(!0,H)}finally{q?G():(N=!1,O=null)}}else N=!1}var G;if(typeof j==\"function\")G=function(){j(V)};else if(typeof MessageChannel<\"u\"){var W=new MessageChannel,ie=W.port2;W.port1.onmessage=V,G=function(){ie.postMessage(null)}}else G=function(){C(V,0)};function re(H){O=H,N||(N=!0,G())}function Y(H,q){D=C(function(){H(e.unstable_now())},q)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(H){H.callback=null},e.unstable_continueExecution=function(){b||x||(b=!0,re(R))},e.unstable_forceFrameRate=function(H){0>H||125<H?console.error(\"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"):z=0<H?Math.floor(1e3/H):5},e.unstable_getCurrentPriorityLevel=function(){return g},e.unstable_getFirstCallbackNode=function(){return n(d)},e.unstable_next=function(H){switch(g){case 1:case 2:case 3:var q=3;break;default:q=g}var he=g;g=q;try{return H()}finally{g=he}},e.unstable_pauseExecution=function(){},e.unstable_requestPaint=function(){},e.unstable_runWithPriority=function(H,q){switch(H){case 1:case 2:case 3:case 4:case 5:break;default:H=3}var he=g;g=H;try{return q()}finally{g=he}},e.unstable_scheduleCallback=function(H,q,he){var A=e.unstable_now();switch(typeof he==\"object\"&&he!==null?(he=he.delay,he=typeof he==\"number\"&&0<he?A+he:A):he=A,H){case 1:var F=-1;break;case 2:F=250;break;case 5:F=1073741823;break;case 4:F=1e4;break;default:F=5e3}return F=he+F,H={id:h++,callback:q,priorityLevel:H,startTime:he,expirationTime:F,sortIndex:-1},he>A?(H.sortIndex=he,t(f,H),n(d)===null&&H===n(f)&&(w?(k(D),D=-1):w=!0,Y(_,he-A))):(H.sortIndex=F,t(d,H),b||x||(b=!0,re(R))),H},e.unstable_shouldYield=pe,e.unstable_wrapCallback=function(H){var q=g;return function(){var he=g;g=q;try{return H.apply(this,arguments)}finally{g=he}}}})(dv)),dv}var W0;function dF(){return W0||(W0=1,uv.exports=uF()),uv.exports}/**\n * @license React\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */var G0;function fF(){if(G0)return Cr;G0=1;var e=pd(),t=dF();function n(a){for(var c=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,p=1;p<arguments.length;p++)c+=\"&args[]=\"+encodeURIComponent(arguments[p]);return\"Minified React error #\"+a+\"; visit \"+c+\" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"}var r=new Set,s={};function o(a,c){l(a,c),l(a+\"Capture\",c)}function l(a,c){for(s[a]=c,a=0;a<c.length;a++)r.add(c[a])}var u=!(typeof window>\"u\"||typeof window.document>\"u\"||typeof window.document.createElement>\"u\"),d=Object.prototype.hasOwnProperty,f=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,h={},m={};function g(a){return d.call(m,a)?!0:d.call(h,a)?!1:f.test(a)?m[a]=!0:(h[a]=!0,!1)}function x(a,c,p,v){if(p!==null&&p.type===0)return!1;switch(typeof c){case\"function\":case\"symbol\":return!0;case\"boolean\":return v?!1:p!==null?!p.acceptsBooleans:(a=a.toLowerCase().slice(0,5),a!==\"data-\"&&a!==\"aria-\");default:return!1}}function b(a,c,p,v){if(c===null||typeof c>\"u\"||x(a,c,p,v))return!0;if(v)return!1;if(p!==null)switch(p.type){case 3:return!c;case 4:return c===!1;case 5:return isNaN(c);case 6:return isNaN(c)||1>c}return!1}function w(a,c,p,v,S,E,T){this.acceptsBooleans=c===2||c===3||c===4,this.attributeName=v,this.attributeNamespace=S,this.mustUseProperty=p,this.propertyName=a,this.type=c,this.sanitizeURL=E,this.removeEmptyString=T}var C={};\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(a){C[a]=new w(a,0,!1,a,null,!1,!1)}),[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(a){var c=a[0];C[c]=new w(c,1,!1,a[1],null,!1,!1)}),[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(a){C[a]=new w(a,2,!1,a.toLowerCase(),null,!1,!1)}),[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(a){C[a]=new w(a,2,!1,a,null,!1,!1)}),\"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach(function(a){C[a]=new w(a,3,!1,a.toLowerCase(),null,!1,!1)}),[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(a){C[a]=new w(a,3,!0,a,null,!1,!1)}),[\"capture\",\"download\"].forEach(function(a){C[a]=new w(a,4,!1,a,null,!1,!1)}),[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(a){C[a]=new w(a,6,!1,a,null,!1,!1)}),[\"rowSpan\",\"start\"].forEach(function(a){C[a]=new w(a,5,!1,a.toLowerCase(),null,!1,!1)});var k=/[\\-:]([a-z])/g;function j(a){return a[1].toUpperCase()}\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach(function(a){var c=a.replace(k,j);C[c]=new w(c,1,!1,a,null,!1,!1)}),\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(a){var c=a.replace(k,j);C[c]=new w(c,1,!1,a,\"http://www.w3.org/1999/xlink\",!1,!1)}),[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(a){var c=a.replace(k,j);C[c]=new w(c,1,!1,a,\"http://www.w3.org/XML/1998/namespace\",!1,!1)}),[\"tabIndex\",\"crossOrigin\"].forEach(function(a){C[a]=new w(a,1,!1,a.toLowerCase(),null,!1,!1)}),C.xlinkHref=new w(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0,!1),[\"src\",\"href\",\"action\",\"formAction\"].forEach(function(a){C[a]=new w(a,1,!1,a.toLowerCase(),null,!0,!0)});function M(a,c,p,v){var S=C.hasOwnProperty(c)?C[c]:null;(S!==null?S.type!==0:v||!(2<c.length)||c[0]!==\"o\"&&c[0]!==\"O\"||c[1]!==\"n\"&&c[1]!==\"N\")&&(b(c,p,S,v)&&(p=null),v||S===null?g(c)&&(p===null?a.removeAttribute(c):a.setAttribute(c,\"\"+p)):S.mustUseProperty?a[S.propertyName]=p===null?S.type===3?!1:\"\":p:(c=S.attributeName,v=S.attributeNamespace,p===null?a.removeAttribute(c):(S=S.type,p=S===3||S===4&&p===!0?\"\":\"\"+p,v?a.setAttributeNS(v,c,p):a.setAttribute(c,p))))}var _=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,R=Symbol.for(\"react.element\"),N=Symbol.for(\"react.portal\"),O=Symbol.for(\"react.fragment\"),D=Symbol.for(\"react.strict_mode\"),z=Symbol.for(\"react.profiler\"),Q=Symbol.for(\"react.provider\"),pe=Symbol.for(\"react.context\"),V=Symbol.for(\"react.forward_ref\"),G=Symbol.for(\"react.suspense\"),W=Symbol.for(\"react.suspense_list\"),ie=Symbol.for(\"react.memo\"),re=Symbol.for(\"react.lazy\"),Y=Symbol.for(\"react.offscreen\"),H=Symbol.iterator;function q(a){return a===null||typeof a!=\"object\"?null:(a=H&&a[H]||a[\"@@iterator\"],typeof a==\"function\"?a:null)}var he=Object.assign,A;function F(a){if(A===void 0)try{throw Error()}catch(p){var c=p.stack.trim().match(/\\n( *(at )?)/);A=c&&c[1]||\"\"}return`\n`+A+a}var fe=!1;function te(a,c){if(!a||fe)return\"\";fe=!0;var p=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(c)if(c=function(){throw Error()},Object.defineProperty(c.prototype,\"props\",{set:function(){throw Error()}}),typeof Reflect==\"object\"&&Reflect.construct){try{Reflect.construct(c,[])}catch(ae){var v=ae}Reflect.construct(a,[],c)}else{try{c.call()}catch(ae){v=ae}a.call(c.prototype)}else{try{throw Error()}catch(ae){v=ae}a()}}catch(ae){if(ae&&v&&typeof ae.stack==\"string\"){for(var S=ae.stack.split(`\n`),E=v.stack.split(`\n`),T=S.length-1,I=E.length-1;1<=T&&0<=I&&S[T]!==E[I];)I--;for(;1<=T&&0<=I;T--,I--)if(S[T]!==E[I]){if(T!==1||I!==1)do if(T--,I--,0>I||S[T]!==E[I]){var $=`\n`+S[T].replace(\" at new \",\" at \");return a.displayName&&$.includes(\"<anonymous>\")&&($=$.replace(\"<anonymous>\",a.displayName)),$}while(1<=T&&0<=I);break}}}finally{fe=!1,Error.prepareStackTrace=p}return(a=a?a.displayName||a.name:\"\")?F(a):\"\"}function de(a){switch(a.tag){case 5:return F(a.type);case 16:return F(\"Lazy\");case 13:return F(\"Suspense\");case 19:return F(\"SuspenseList\");case 0:case 2:case 15:return a=te(a.type,!1),a;case 11:return a=te(a.type.render,!1),a;case 1:return a=te(a.type,!0),a;default:return\"\"}}function ge(a){if(a==null)return null;if(typeof a==\"function\")return a.displayName||a.name||null;if(typeof a==\"string\")return a;switch(a){case O:return\"Fragment\";case N:return\"Portal\";case z:return\"Profiler\";case D:return\"StrictMode\";case G:return\"Suspense\";case W:return\"SuspenseList\"}if(typeof a==\"object\")switch(a.$$typeof){case pe:return(a.displayName||\"Context\")+\".Consumer\";case Q:return(a._context.displayName||\"Context\")+\".Provider\";case V:var c=a.render;return a=a.displayName,a||(a=c.displayName||c.name||\"\",a=a!==\"\"?\"ForwardRef(\"+a+\")\":\"ForwardRef\"),a;case ie:return c=a.displayName||null,c!==null?c:ge(a.type)||\"Memo\";case re:c=a._payload,a=a._init;try{return ge(a(c))}catch{}}return null}function Z(a){var c=a.type;switch(a.tag){case 24:return\"Cache\";case 9:return(c.displayName||\"Context\")+\".Consumer\";case 10:return(c._context.displayName||\"Context\")+\".Provider\";case 18:return\"DehydratedFragment\";case 11:return a=c.render,a=a.displayName||a.name||\"\",c.displayName||(a!==\"\"?\"ForwardRef(\"+a+\")\":\"ForwardRef\");case 7:return\"Fragment\";case 5:return c;case 4:return\"Portal\";case 3:return\"Root\";case 6:return\"Text\";case 16:return ge(c);case 8:return c===D?\"StrictMode\":\"Mode\";case 22:return\"Offscreen\";case 12:return\"Profiler\";case 21:return\"Scope\";case 13:return\"Suspense\";case 19:return\"SuspenseList\";case 25:return\"TracingMarker\";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof c==\"function\")return c.displayName||c.name||null;if(typeof c==\"string\")return c}return null}function ye(a){switch(typeof a){case\"boolean\":case\"number\":case\"string\":case\"undefined\":return a;case\"object\":return a;default:return\"\"}}function Re(a){var c=a.type;return(a=a.nodeName)&&a.toLowerCase()===\"input\"&&(c===\"checkbox\"||c===\"radio\")}function $e(a){var c=Re(a)?\"checked\":\"value\",p=Object.getOwnPropertyDescriptor(a.constructor.prototype,c),v=\"\"+a[c];if(!a.hasOwnProperty(c)&&typeof p<\"u\"&&typeof p.get==\"function\"&&typeof p.set==\"function\"){var S=p.get,E=p.set;return Object.defineProperty(a,c,{configurable:!0,get:function(){return S.call(this)},set:function(T){v=\"\"+T,E.call(this,T)}}),Object.defineProperty(a,c,{enumerable:p.enumerable}),{getValue:function(){return v},setValue:function(T){v=\"\"+T},stopTracking:function(){a._valueTracker=null,delete a[c]}}}}function Ye(a){a._valueTracker||(a._valueTracker=$e(a))}function Fe(a){if(!a)return!1;var c=a._valueTracker;if(!c)return!0;var p=c.getValue(),v=\"\";return a&&(v=Re(a)?a.checked?\"true\":\"false\":a.value),a=v,a!==p?(c.setValue(a),!0):!1}function ft(a){if(a=a||(typeof document<\"u\"?document:void 0),typeof a>\"u\")return null;try{return a.activeElement||a.body}catch{return a.body}}function ln(a,c){var p=c.checked;return he({},c,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:p??a._wrapperState.initialChecked})}function Sn(a,c){var p=c.defaultValue==null?\"\":c.defaultValue,v=c.checked!=null?c.checked:c.defaultChecked;p=ye(c.value!=null?c.value:p),a._wrapperState={initialChecked:v,initialValue:p,controlled:c.type===\"checkbox\"||c.type===\"radio\"?c.checked!=null:c.value!=null}}function vn(a,c){c=c.checked,c!=null&&M(a,\"checked\",c,!1)}function Cn(a,c){vn(a,c);var p=ye(c.value),v=c.type;if(p!=null)v===\"number\"?(p===0&&a.value===\"\"||a.value!=p)&&(a.value=\"\"+p):a.value!==\"\"+p&&(a.value=\"\"+p);else if(v===\"submit\"||v===\"reset\"){a.removeAttribute(\"value\");return}c.hasOwnProperty(\"value\")?X(a,c.type,p):c.hasOwnProperty(\"defaultValue\")&&X(a,c.type,ye(c.defaultValue)),c.checked==null&&c.defaultChecked!=null&&(a.defaultChecked=!!c.defaultChecked)}function L(a,c,p){if(c.hasOwnProperty(\"value\")||c.hasOwnProperty(\"defaultValue\")){var v=c.type;if(!(v!==\"submit\"&&v!==\"reset\"||c.value!==void 0&&c.value!==null))return;c=\"\"+a._wrapperState.initialValue,p||c===a.value||(a.value=c),a.defaultValue=c}p=a.name,p!==\"\"&&(a.name=\"\"),a.defaultChecked=!!a._wrapperState.initialChecked,p!==\"\"&&(a.name=p)}function X(a,c,p){(c!==\"number\"||ft(a.ownerDocument)!==a)&&(p==null?a.defaultValue=\"\"+a._wrapperState.initialValue:a.defaultValue!==\"\"+p&&(a.defaultValue=\"\"+p))}var ue=Array.isArray;function Ne(a,c,p,v){if(a=a.options,c){c={};for(var S=0;S<p.length;S++)c[\"$\"+p[S]]=!0;for(p=0;p<a.length;p++)S=c.hasOwnProperty(\"$\"+a[p].value),a[p].selected!==S&&(a[p].selected=S),S&&v&&(a[p].defaultSelected=!0)}else{for(p=\"\"+ye(p),c=null,S=0;S<a.length;S++){if(a[S].value===p){a[S].selected=!0,v&&(a[S].defaultSelected=!0);return}c!==null||a[S].disabled||(c=a[S])}c!==null&&(c.selected=!0)}}function je(a,c){if(c.dangerouslySetInnerHTML!=null)throw Error(n(91));return he({},c,{value:void 0,defaultValue:void 0,children:\"\"+a._wrapperState.initialValue})}function Se(a,c){var p=c.value;if(p==null){if(p=c.children,c=c.defaultValue,p!=null){if(c!=null)throw Error(n(92));if(ue(p)){if(1<p.length)throw Error(n(93));p=p[0]}c=p}c==null&&(c=\"\"),p=c}a._wrapperState={initialValue:ye(p)}}function Be(a,c){var p=ye(c.value),v=ye(c.defaultValue);p!=null&&(p=\"\"+p,p!==a.value&&(a.value=p),c.defaultValue==null&&a.defaultValue!==p&&(a.defaultValue=p)),v!=null&&(a.defaultValue=\"\"+v)}function bt(a){var c=a.textContent;c===a._wrapperState.initialValue&&c!==\"\"&&c!==null&&(a.value=c)}function Wt(a){switch(a){case\"svg\":return\"http://www.w3.org/2000/svg\";case\"math\":return\"http://www.w3.org/1998/Math/MathML\";default:return\"http://www.w3.org/1999/xhtml\"}}function yn(a,c){return a==null||a===\"http://www.w3.org/1999/xhtml\"?Wt(c):a===\"http://www.w3.org/2000/svg\"&&c===\"foreignObject\"?\"http://www.w3.org/1999/xhtml\":a}var bn,En=(function(a){return typeof MSApp<\"u\"&&MSApp.execUnsafeLocalFunction?function(c,p,v,S){MSApp.execUnsafeLocalFunction(function(){return a(c,p,v,S)})}:a})(function(a,c){if(a.namespaceURI!==\"http://www.w3.org/2000/svg\"||\"innerHTML\"in a)a.innerHTML=c;else{for(bn=bn||document.createElement(\"div\"),bn.innerHTML=\"<svg>\"+c.valueOf().toString()+\"</svg>\",c=bn.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;c.firstChild;)a.appendChild(c.firstChild)}});function gr(a,c){if(c){var p=a.firstChild;if(p&&p===a.lastChild&&p.nodeType===3){p.nodeValue=c;return}}a.textContent=c}var Qn={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ro=[\"Webkit\",\"ms\",\"Moz\",\"O\"];Object.keys(Qn).forEach(function(a){ro.forEach(function(c){c=c+a.charAt(0).toUpperCase()+a.substring(1),Qn[c]=Qn[a]})});function Bn(a,c,p){return c==null||typeof c==\"boolean\"||c===\"\"?\"\":p||typeof c!=\"number\"||c===0||Qn.hasOwnProperty(a)&&Qn[a]?(\"\"+c).trim():c+\"px\"}function Te(a,c){a=a.style;for(var p in c)if(c.hasOwnProperty(p)){var v=p.indexOf(\"--\")===0,S=Bn(p,c[p],v);p===\"float\"&&(p=\"cssFloat\"),v?a.setProperty(p,S):a[p]=S}}var ut=he({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function It(a,c){if(c){if(ut[a]&&(c.children!=null||c.dangerouslySetInnerHTML!=null))throw Error(n(137,a));if(c.dangerouslySetInnerHTML!=null){if(c.children!=null)throw Error(n(60));if(typeof c.dangerouslySetInnerHTML!=\"object\"||!(\"__html\"in c.dangerouslySetInnerHTML))throw Error(n(61))}if(c.style!=null&&typeof c.style!=\"object\")throw Error(n(62))}}function Tn(a,c){if(a.indexOf(\"-\")===-1)return typeof c.is==\"string\";switch(a){case\"annotation-xml\":case\"color-profile\":case\"font-face\":case\"font-face-src\":case\"font-face-uri\":case\"font-face-format\":case\"font-face-name\":case\"missing-glyph\":return!1;default:return!0}}var mr=null;function vr(a){return a=a.target||a.srcElement||window,a.correspondingUseElement&&(a=a.correspondingUseElement),a.nodeType===3?a.parentNode:a}var Gr=null,Jr=null,_r=null;function Rr(a){if(a=Lc(a)){if(typeof Gr!=\"function\")throw Error(n(280));var c=a.stateNode;c&&(c=Qd(c),Gr(a.stateNode,a.type,c))}}function Uo(a){Jr?_r?_r.push(a):_r=[a]:Jr=a}function vc(){if(Jr){var a=Jr,c=_r;if(_r=Jr=null,Rr(a),c)for(a=0;a<c.length;a++)Rr(c[a])}}function _d(a,c){return a(c)}function yc(){}var Ba=!1;function za(a,c,p){if(Ba)return a(c,p);Ba=!0;try{return _d(a,c,p)}finally{Ba=!1,(Jr!==null||_r!==null)&&(yc(),vc())}}function Ua(a,c){var p=a.stateNode;if(p===null)return null;var v=Qd(p);if(v===null)return null;p=v[c];e:switch(c){case\"onClick\":case\"onClickCapture\":case\"onDoubleClick\":case\"onDoubleClickCapture\":case\"onMouseDown\":case\"onMouseDownCapture\":case\"onMouseMove\":case\"onMouseMoveCapture\":case\"onMouseUp\":case\"onMouseUpCapture\":case\"onMouseEnter\":(v=!v.disabled)||(a=a.type,v=!(a===\"button\"||a===\"input\"||a===\"select\"||a===\"textarea\")),a=!v;break e;default:a=!1}if(a)return null;if(p&&typeof p!=\"function\")throw Error(n(231,c,typeof p));return p}var bc=!1;if(u)try{var B={};Object.defineProperty(B,\"passive\",{get:function(){bc=!0}}),window.addEventListener(\"test\",B,B),window.removeEventListener(\"test\",B,B)}catch{bc=!1}function K(a,c,p,v,S,E,T,I,$){var ae=Array.prototype.slice.call(arguments,3);try{c.apply(p,ae)}catch(xe){this.onError(xe)}}var oe=!1,ve=null,Oe=!1,We=null,st={onError:function(a){oe=!0,ve=a}};function Me(a,c,p,v,S,E,T,I,$){oe=!1,ve=null,K.apply(st,arguments)}function ht(a,c,p,v,S,E,T,I,$){if(Me.apply(this,arguments),oe){if(oe){var ae=ve;oe=!1,ve=null}else throw Error(n(198));Oe||(Oe=!0,We=ae)}}function Ge(a){var c=a,p=a;if(a.alternate)for(;c.return;)c=c.return;else{a=c;do c=a,(c.flags&4098)!==0&&(p=c.return),a=c.return;while(a)}return c.tag===3?p:null}function Xe(a){if(a.tag===13){var c=a.memoizedState;if(c===null&&(a=a.alternate,a!==null&&(c=a.memoizedState)),c!==null)return c.dehydrated}return null}function Ut(a){if(Ge(a)!==a)throw Error(n(188))}function Vt(a){var c=a.alternate;if(!c){if(c=Ge(a),c===null)throw Error(n(188));return c!==a?null:a}for(var p=a,v=c;;){var S=p.return;if(S===null)break;var E=S.alternate;if(E===null){if(v=S.return,v!==null){p=v;continue}break}if(S.child===E.child){for(E=S.child;E;){if(E===p)return Ut(S),a;if(E===v)return Ut(S),c;E=E.sibling}throw Error(n(188))}if(p.return!==v.return)p=S,v=E;else{for(var T=!1,I=S.child;I;){if(I===p){T=!0,p=S,v=E;break}if(I===v){T=!0,v=S,p=E;break}I=I.sibling}if(!T){for(I=E.child;I;){if(I===p){T=!0,p=E,v=S;break}if(I===v){T=!0,v=E,p=S;break}I=I.sibling}if(!T)throw Error(n(189))}}if(p.alternate!==v)throw Error(n(190))}if(p.tag!==3)throw Error(n(188));return p.stateNode.current===p?a:c}function Ht(a){return a=Vt(a),a!==null?At(a):null}function At(a){if(a.tag===5||a.tag===6)return a;for(a=a.child;a!==null;){var c=At(a);if(c!==null)return c;a=a.sibling}return null}var Nn=t.unstable_scheduleCallback,fn=t.unstable_cancelCallback,Va=t.unstable_shouldYield,Os=t.unstable_requestPaint,Gt=t.unstable_now,Vo=t.unstable_getCurrentPriorityLevel,Is=t.unstable_ImmediatePriority,Pr=t.unstable_UserBlockingPriority,so=t.unstable_NormalPriority,Vi=t.unstable_LowPriority,Ha=t.unstable_IdlePriority,pt=null,Dt=null;function or(a){if(Dt&&typeof Dt.onCommitFiberRoot==\"function\")try{Dt.onCommitFiberRoot(pt,a,void 0,(a.current.flags&128)===128)}catch{}}var Tt=Math.clz32?Math.clz32:jg,fs=Math.log,Rd=Math.LN2;function jg(a){return a>>>=0,a===0?32:31-(fs(a)/Rd|0)|0}var Pd=64,Od=4194304;function xc(a){switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return a}}function Id(a,c){var p=a.pendingLanes;if(p===0)return 0;var v=0,S=a.suspendedLanes,E=a.pingedLanes,T=p&268435455;if(T!==0){var I=T&~S;I!==0?v=xc(I):(E&=T,E!==0&&(v=xc(E)))}else T=p&~S,T!==0?v=xc(T):E!==0&&(v=xc(E));if(v===0)return 0;if(c!==0&&c!==v&&(c&S)===0&&(S=v&-v,E=c&-c,S>=E||S===16&&(E&4194240)!==0))return c;if((v&4)!==0&&(v|=p&16),c=a.entangledLanes,c!==0)for(a=a.entanglements,c&=v;0<c;)p=31-Tt(c),S=1<<p,v|=a[p],c&=~S;return v}function KI(a,c){switch(a){case 1:case 2:case 4:return c+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return c+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function WI(a,c){for(var p=a.suspendedLanes,v=a.pingedLanes,S=a.expirationTimes,E=a.pendingLanes;0<E;){var T=31-Tt(E),I=1<<T,$=S[T];$===-1?((I&p)===0||(I&v)!==0)&&(S[T]=KI(I,c)):$<=c&&(a.expiredLanes|=I),E&=~I}}function Tg(a){return a=a.pendingLanes&-1073741825,a!==0?a:a&1073741824?1073741824:0}function fw(){var a=Pd;return Pd<<=1,(Pd&4194240)===0&&(Pd=64),a}function Ng(a){for(var c=[],p=0;31>p;p++)c.push(a);return c}function wc(a,c,p){a.pendingLanes|=c,c!==536870912&&(a.suspendedLanes=0,a.pingedLanes=0),a=a.eventTimes,c=31-Tt(c),a[c]=p}function GI(a,c){var p=a.pendingLanes&~c;a.pendingLanes=c,a.suspendedLanes=0,a.pingedLanes=0,a.expiredLanes&=c,a.mutableReadLanes&=c,a.entangledLanes&=c,c=a.entanglements;var v=a.eventTimes;for(a=a.expirationTimes;0<p;){var S=31-Tt(p),E=1<<S;c[S]=0,v[S]=-1,a[S]=-1,p&=~E}}function Mg(a,c){var p=a.entangledLanes|=c;for(a=a.entanglements;p;){var v=31-Tt(p),S=1<<v;S&c|a[v]&c&&(a[v]|=c),p&=~S}}var Kt=0;function pw(a){return a&=-a,1<a?4<a?(a&268435455)!==0?16:536870912:4:1}var hw,_g,gw,mw,vw,Rg=!1,Ad=[],Ho=null,qo=null,Ko=null,Sc=new Map,Cc=new Map,Wo=[],JI=\"mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit\".split(\" \");function yw(a,c){switch(a){case\"focusin\":case\"focusout\":Ho=null;break;case\"dragenter\":case\"dragleave\":qo=null;break;case\"mouseover\":case\"mouseout\":Ko=null;break;case\"pointerover\":case\"pointerout\":Sc.delete(c.pointerId);break;case\"gotpointercapture\":case\"lostpointercapture\":Cc.delete(c.pointerId)}}function Ec(a,c,p,v,S,E){return a===null||a.nativeEvent!==E?(a={blockedOn:c,domEventName:p,eventSystemFlags:v,nativeEvent:E,targetContainers:[S]},c!==null&&(c=Lc(c),c!==null&&_g(c)),a):(a.eventSystemFlags|=v,c=a.targetContainers,S!==null&&c.indexOf(S)===-1&&c.push(S),a)}function QI(a,c,p,v,S){switch(c){case\"focusin\":return Ho=Ec(Ho,a,c,p,v,S),!0;case\"dragenter\":return qo=Ec(qo,a,c,p,v,S),!0;case\"mouseover\":return Ko=Ec(Ko,a,c,p,v,S),!0;case\"pointerover\":var E=S.pointerId;return Sc.set(E,Ec(Sc.get(E)||null,a,c,p,v,S)),!0;case\"gotpointercapture\":return E=S.pointerId,Cc.set(E,Ec(Cc.get(E)||null,a,c,p,v,S)),!0}return!1}function bw(a){var c=qa(a.target);if(c!==null){var p=Ge(c);if(p!==null){if(c=p.tag,c===13){if(c=Xe(p),c!==null){a.blockedOn=c,vw(a.priority,function(){gw(p)});return}}else if(c===3&&p.stateNode.current.memoizedState.isDehydrated){a.blockedOn=p.tag===3?p.stateNode.containerInfo:null;return}}}a.blockedOn=null}function Dd(a){if(a.blockedOn!==null)return!1;for(var c=a.targetContainers;0<c.length;){var p=Og(a.domEventName,a.eventSystemFlags,c[0],a.nativeEvent);if(p===null){p=a.nativeEvent;var v=new p.constructor(p.type,p);mr=v,p.target.dispatchEvent(v),mr=null}else return c=Lc(p),c!==null&&_g(c),a.blockedOn=p,!1;c.shift()}return!0}function xw(a,c,p){Dd(a)&&p.delete(c)}function ZI(){Rg=!1,Ho!==null&&Dd(Ho)&&(Ho=null),qo!==null&&Dd(qo)&&(qo=null),Ko!==null&&Dd(Ko)&&(Ko=null),Sc.forEach(xw),Cc.forEach(xw)}function kc(a,c){a.blockedOn===c&&(a.blockedOn=null,Rg||(Rg=!0,t.unstable_scheduleCallback(t.unstable_NormalPriority,ZI)))}function jc(a){function c(S){return kc(S,a)}if(0<Ad.length){kc(Ad[0],a);for(var p=1;p<Ad.length;p++){var v=Ad[p];v.blockedOn===a&&(v.blockedOn=null)}}for(Ho!==null&&kc(Ho,a),qo!==null&&kc(qo,a),Ko!==null&&kc(Ko,a),Sc.forEach(c),Cc.forEach(c),p=0;p<Wo.length;p++)v=Wo[p],v.blockedOn===a&&(v.blockedOn=null);for(;0<Wo.length&&(p=Wo[0],p.blockedOn===null);)bw(p),p.blockedOn===null&&Wo.shift()}var Hi=_.ReactCurrentBatchConfig,Fd=!0;function YI(a,c,p,v){var S=Kt,E=Hi.transition;Hi.transition=null;try{Kt=1,Pg(a,c,p,v)}finally{Kt=S,Hi.transition=E}}function XI(a,c,p,v){var S=Kt,E=Hi.transition;Hi.transition=null;try{Kt=4,Pg(a,c,p,v)}finally{Kt=S,Hi.transition=E}}function Pg(a,c,p,v){if(Fd){var S=Og(a,c,p,v);if(S===null)Qg(a,c,v,Ld,p),yw(a,v);else if(QI(S,a,c,p,v))v.stopPropagation();else if(yw(a,v),c&4&&-1<JI.indexOf(a)){for(;S!==null;){var E=Lc(S);if(E!==null&&hw(E),E=Og(a,c,p,v),E===null&&Qg(a,c,v,Ld,p),E===S)break;S=E}S!==null&&v.stopPropagation()}else Qg(a,c,v,null,p)}}var Ld=null;function Og(a,c,p,v){if(Ld=null,a=vr(v),a=qa(a),a!==null)if(c=Ge(a),c===null)a=null;else if(p=c.tag,p===13){if(a=Xe(c),a!==null)return a;a=null}else if(p===3){if(c.stateNode.current.memoizedState.isDehydrated)return c.tag===3?c.stateNode.containerInfo:null;a=null}else c!==a&&(a=null);return Ld=a,null}function ww(a){switch(a){case\"cancel\":case\"click\":case\"close\":case\"contextmenu\":case\"copy\":case\"cut\":case\"auxclick\":case\"dblclick\":case\"dragend\":case\"dragstart\":case\"drop\":case\"focusin\":case\"focusout\":case\"input\":case\"invalid\":case\"keydown\":case\"keypress\":case\"keyup\":case\"mousedown\":case\"mouseup\":case\"paste\":case\"pause\":case\"play\":case\"pointercancel\":case\"pointerdown\":case\"pointerup\":case\"ratechange\":case\"reset\":case\"resize\":case\"seeked\":case\"submit\":case\"touchcancel\":case\"touchend\":case\"touchstart\":case\"volumechange\":case\"change\":case\"selectionchange\":case\"textInput\":case\"compositionstart\":case\"compositionend\":case\"compositionupdate\":case\"beforeblur\":case\"afterblur\":case\"beforeinput\":case\"blur\":case\"fullscreenchange\":case\"focus\":case\"hashchange\":case\"popstate\":case\"select\":case\"selectstart\":return 1;case\"drag\":case\"dragenter\":case\"dragexit\":case\"dragleave\":case\"dragover\":case\"mousemove\":case\"mouseout\":case\"mouseover\":case\"pointermove\":case\"pointerout\":case\"pointerover\":case\"scroll\":case\"toggle\":case\"touchmove\":case\"wheel\":case\"mouseenter\":case\"mouseleave\":case\"pointerenter\":case\"pointerleave\":return 4;case\"message\":switch(Vo()){case Is:return 1;case Pr:return 4;case so:case Vi:return 16;case Ha:return 536870912;default:return 16}default:return 16}}var Go=null,Ig=null,$d=null;function Sw(){if($d)return $d;var a,c=Ig,p=c.length,v,S=\"value\"in Go?Go.value:Go.textContent,E=S.length;for(a=0;a<p&&c[a]===S[a];a++);var T=p-a;for(v=1;v<=T&&c[p-v]===S[E-v];v++);return $d=S.slice(a,1<v?1-v:void 0)}function Bd(a){var c=a.keyCode;return\"charCode\"in a?(a=a.charCode,a===0&&c===13&&(a=13)):a=c,a===10&&(a=13),32<=a||a===13?a:0}function zd(){return!0}function Cw(){return!1}function Or(a){function c(p,v,S,E,T){this._reactName=p,this._targetInst=S,this.type=v,this.nativeEvent=E,this.target=T,this.currentTarget=null;for(var I in a)a.hasOwnProperty(I)&&(p=a[I],this[I]=p?p(E):E[I]);return this.isDefaultPrevented=(E.defaultPrevented!=null?E.defaultPrevented:E.returnValue===!1)?zd:Cw,this.isPropagationStopped=Cw,this}return he(c.prototype,{preventDefault:function(){this.defaultPrevented=!0;var p=this.nativeEvent;p&&(p.preventDefault?p.preventDefault():typeof p.returnValue!=\"unknown\"&&(p.returnValue=!1),this.isDefaultPrevented=zd)},stopPropagation:function(){var p=this.nativeEvent;p&&(p.stopPropagation?p.stopPropagation():typeof p.cancelBubble!=\"unknown\"&&(p.cancelBubble=!0),this.isPropagationStopped=zd)},persist:function(){},isPersistent:zd}),c}var qi={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(a){return a.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},Ag=Or(qi),Tc=he({},qi,{view:0,detail:0}),eA=Or(Tc),Dg,Fg,Nc,Ud=he({},Tc,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:$g,button:0,buttons:0,relatedTarget:function(a){return a.relatedTarget===void 0?a.fromElement===a.srcElement?a.toElement:a.fromElement:a.relatedTarget},movementX:function(a){return\"movementX\"in a?a.movementX:(a!==Nc&&(Nc&&a.type===\"mousemove\"?(Dg=a.screenX-Nc.screenX,Fg=a.screenY-Nc.screenY):Fg=Dg=0,Nc=a),Dg)},movementY:function(a){return\"movementY\"in a?a.movementY:Fg}}),Ew=Or(Ud),tA=he({},Ud,{dataTransfer:0}),nA=Or(tA),rA=he({},Tc,{relatedTarget:0}),Lg=Or(rA),sA=he({},qi,{animationName:0,elapsedTime:0,pseudoElement:0}),oA=Or(sA),aA=he({},qi,{clipboardData:function(a){return\"clipboardData\"in a?a.clipboardData:window.clipboardData}}),iA=Or(aA),lA=he({},qi,{data:0}),kw=Or(lA),cA={Esc:\"Escape\",Spacebar:\" \",Left:\"ArrowLeft\",Up:\"ArrowUp\",Right:\"ArrowRight\",Down:\"ArrowDown\",Del:\"Delete\",Win:\"OS\",Menu:\"ContextMenu\",Apps:\"ContextMenu\",Scroll:\"ScrollLock\",MozPrintableKey:\"Unidentified\"},uA={8:\"Backspace\",9:\"Tab\",12:\"Clear\",13:\"Enter\",16:\"Shift\",17:\"Control\",18:\"Alt\",19:\"Pause\",20:\"CapsLock\",27:\"Escape\",32:\" \",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"ArrowLeft\",38:\"ArrowUp\",39:\"ArrowRight\",40:\"ArrowDown\",45:\"Insert\",46:\"Delete\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"NumLock\",145:\"ScrollLock\",224:\"Meta\"},dA={Alt:\"altKey\",Control:\"ctrlKey\",Meta:\"metaKey\",Shift:\"shiftKey\"};function fA(a){var c=this.nativeEvent;return c.getModifierState?c.getModifierState(a):(a=dA[a])?!!c[a]:!1}function $g(){return fA}var pA=he({},Tc,{key:function(a){if(a.key){var c=cA[a.key]||a.key;if(c!==\"Unidentified\")return c}return a.type===\"keypress\"?(a=Bd(a),a===13?\"Enter\":String.fromCharCode(a)):a.type===\"keydown\"||a.type===\"keyup\"?uA[a.keyCode]||\"Unidentified\":\"\"},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:$g,charCode:function(a){return a.type===\"keypress\"?Bd(a):0},keyCode:function(a){return a.type===\"keydown\"||a.type===\"keyup\"?a.keyCode:0},which:function(a){return a.type===\"keypress\"?Bd(a):a.type===\"keydown\"||a.type===\"keyup\"?a.keyCode:0}}),hA=Or(pA),gA=he({},Ud,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),jw=Or(gA),mA=he({},Tc,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:$g}),vA=Or(mA),yA=he({},qi,{propertyName:0,elapsedTime:0,pseudoElement:0}),bA=Or(yA),xA=he({},Ud,{deltaX:function(a){return\"deltaX\"in a?a.deltaX:\"wheelDeltaX\"in a?-a.wheelDeltaX:0},deltaY:function(a){return\"deltaY\"in a?a.deltaY:\"wheelDeltaY\"in a?-a.wheelDeltaY:\"wheelDelta\"in a?-a.wheelDelta:0},deltaZ:0,deltaMode:0}),wA=Or(xA),SA=[9,13,27,32],Bg=u&&\"CompositionEvent\"in window,Mc=null;u&&\"documentMode\"in document&&(Mc=document.documentMode);var CA=u&&\"TextEvent\"in window&&!Mc,Tw=u&&(!Bg||Mc&&8<Mc&&11>=Mc),Nw=\" \",Mw=!1;function _w(a,c){switch(a){case\"keyup\":return SA.indexOf(c.keyCode)!==-1;case\"keydown\":return c.keyCode!==229;case\"keypress\":case\"mousedown\":case\"focusout\":return!0;default:return!1}}function Rw(a){return a=a.detail,typeof a==\"object\"&&\"data\"in a?a.data:null}var Ki=!1;function EA(a,c){switch(a){case\"compositionend\":return Rw(c);case\"keypress\":return c.which!==32?null:(Mw=!0,Nw);case\"textInput\":return a=c.data,a===Nw&&Mw?null:a;default:return null}}function kA(a,c){if(Ki)return a===\"compositionend\"||!Bg&&_w(a,c)?(a=Sw(),$d=Ig=Go=null,Ki=!1,a):null;switch(a){case\"paste\":return null;case\"keypress\":if(!(c.ctrlKey||c.altKey||c.metaKey)||c.ctrlKey&&c.altKey){if(c.char&&1<c.char.length)return c.char;if(c.which)return String.fromCharCode(c.which)}return null;case\"compositionend\":return Tw&&c.locale!==\"ko\"?null:c.data;default:return null}}var jA={color:!0,date:!0,datetime:!0,\"datetime-local\":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Pw(a){var c=a&&a.nodeName&&a.nodeName.toLowerCase();return c===\"input\"?!!jA[a.type]:c===\"textarea\"}function Ow(a,c,p,v){Uo(v),c=Wd(c,\"onChange\"),0<c.length&&(p=new Ag(\"onChange\",\"change\",null,p,v),a.push({event:p,listeners:c}))}var _c=null,Rc=null;function TA(a){Zw(a,0)}function Vd(a){var c=Zi(a);if(Fe(c))return a}function NA(a,c){if(a===\"change\")return c}var Iw=!1;if(u){var zg;if(u){var Ug=\"oninput\"in document;if(!Ug){var Aw=document.createElement(\"div\");Aw.setAttribute(\"oninput\",\"return;\"),Ug=typeof Aw.oninput==\"function\"}zg=Ug}else zg=!1;Iw=zg&&(!document.documentMode||9<document.documentMode)}function Dw(){_c&&(_c.detachEvent(\"onpropertychange\",Fw),Rc=_c=null)}function Fw(a){if(a.propertyName===\"value\"&&Vd(Rc)){var c=[];Ow(c,Rc,a,vr(a)),za(TA,c)}}function MA(a,c,p){a===\"focusin\"?(Dw(),_c=c,Rc=p,_c.attachEvent(\"onpropertychange\",Fw)):a===\"focusout\"&&Dw()}function _A(a){if(a===\"selectionchange\"||a===\"keyup\"||a===\"keydown\")return Vd(Rc)}function RA(a,c){if(a===\"click\")return Vd(c)}function PA(a,c){if(a===\"input\"||a===\"change\")return Vd(c)}function OA(a,c){return a===c&&(a!==0||1/a===1/c)||a!==a&&c!==c}var ps=typeof Object.is==\"function\"?Object.is:OA;function Pc(a,c){if(ps(a,c))return!0;if(typeof a!=\"object\"||a===null||typeof c!=\"object\"||c===null)return!1;var p=Object.keys(a),v=Object.keys(c);if(p.length!==v.length)return!1;for(v=0;v<p.length;v++){var S=p[v];if(!d.call(c,S)||!ps(a[S],c[S]))return!1}return!0}function Lw(a){for(;a&&a.firstChild;)a=a.firstChild;return a}function $w(a,c){var p=Lw(a);a=0;for(var v;p;){if(p.nodeType===3){if(v=a+p.textContent.length,a<=c&&v>=c)return{node:p,offset:c-a};a=v}e:{for(;p;){if(p.nextSibling){p=p.nextSibling;break e}p=p.parentNode}p=void 0}p=Lw(p)}}function Bw(a,c){return a&&c?a===c?!0:a&&a.nodeType===3?!1:c&&c.nodeType===3?Bw(a,c.parentNode):\"contains\"in a?a.contains(c):a.compareDocumentPosition?!!(a.compareDocumentPosition(c)&16):!1:!1}function zw(){for(var a=window,c=ft();c instanceof a.HTMLIFrameElement;){try{var p=typeof c.contentWindow.location.href==\"string\"}catch{p=!1}if(p)a=c.contentWindow;else break;c=ft(a.document)}return c}function Vg(a){var c=a&&a.nodeName&&a.nodeName.toLowerCase();return c&&(c===\"input\"&&(a.type===\"text\"||a.type===\"search\"||a.type===\"tel\"||a.type===\"url\"||a.type===\"password\")||c===\"textarea\"||a.contentEditable===\"true\")}function IA(a){var c=zw(),p=a.focusedElem,v=a.selectionRange;if(c!==p&&p&&p.ownerDocument&&Bw(p.ownerDocument.documentElement,p)){if(v!==null&&Vg(p)){if(c=v.start,a=v.end,a===void 0&&(a=c),\"selectionStart\"in p)p.selectionStart=c,p.selectionEnd=Math.min(a,p.value.length);else if(a=(c=p.ownerDocument||document)&&c.defaultView||window,a.getSelection){a=a.getSelection();var S=p.textContent.length,E=Math.min(v.start,S);v=v.end===void 0?E:Math.min(v.end,S),!a.extend&&E>v&&(S=v,v=E,E=S),S=$w(p,E);var T=$w(p,v);S&&T&&(a.rangeCount!==1||a.anchorNode!==S.node||a.anchorOffset!==S.offset||a.focusNode!==T.node||a.focusOffset!==T.offset)&&(c=c.createRange(),c.setStart(S.node,S.offset),a.removeAllRanges(),E>v?(a.addRange(c),a.extend(T.node,T.offset)):(c.setEnd(T.node,T.offset),a.addRange(c)))}}for(c=[],a=p;a=a.parentNode;)a.nodeType===1&&c.push({element:a,left:a.scrollLeft,top:a.scrollTop});for(typeof p.focus==\"function\"&&p.focus(),p=0;p<c.length;p++)a=c[p],a.element.scrollLeft=a.left,a.element.scrollTop=a.top}}var AA=u&&\"documentMode\"in document&&11>=document.documentMode,Wi=null,Hg=null,Oc=null,qg=!1;function Uw(a,c,p){var v=p.window===p?p.document:p.nodeType===9?p:p.ownerDocument;qg||Wi==null||Wi!==ft(v)||(v=Wi,\"selectionStart\"in v&&Vg(v)?v={start:v.selectionStart,end:v.selectionEnd}:(v=(v.ownerDocument&&v.ownerDocument.defaultView||window).getSelection(),v={anchorNode:v.anchorNode,anchorOffset:v.anchorOffset,focusNode:v.focusNode,focusOffset:v.focusOffset}),Oc&&Pc(Oc,v)||(Oc=v,v=Wd(Hg,\"onSelect\"),0<v.length&&(c=new Ag(\"onSelect\",\"select\",null,c,p),a.push({event:c,listeners:v}),c.target=Wi)))}function Hd(a,c){var p={};return p[a.toLowerCase()]=c.toLowerCase(),p[\"Webkit\"+a]=\"webkit\"+c,p[\"Moz\"+a]=\"moz\"+c,p}var Gi={animationend:Hd(\"Animation\",\"AnimationEnd\"),animationiteration:Hd(\"Animation\",\"AnimationIteration\"),animationstart:Hd(\"Animation\",\"AnimationStart\"),transitionend:Hd(\"Transition\",\"TransitionEnd\")},Kg={},Vw={};u&&(Vw=document.createElement(\"div\").style,\"AnimationEvent\"in window||(delete Gi.animationend.animation,delete Gi.animationiteration.animation,delete Gi.animationstart.animation),\"TransitionEvent\"in window||delete Gi.transitionend.transition);function qd(a){if(Kg[a])return Kg[a];if(!Gi[a])return a;var c=Gi[a],p;for(p in c)if(c.hasOwnProperty(p)&&p in Vw)return Kg[a]=c[p];return a}var Hw=qd(\"animationend\"),qw=qd(\"animationiteration\"),Kw=qd(\"animationstart\"),Ww=qd(\"transitionend\"),Gw=new Map,Jw=\"abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel\".split(\" \");function Jo(a,c){Gw.set(a,c),o(c,[a])}for(var Wg=0;Wg<Jw.length;Wg++){var Gg=Jw[Wg],DA=Gg.toLowerCase(),FA=Gg[0].toUpperCase()+Gg.slice(1);Jo(DA,\"on\"+FA)}Jo(Hw,\"onAnimationEnd\"),Jo(qw,\"onAnimationIteration\"),Jo(Kw,\"onAnimationStart\"),Jo(\"dblclick\",\"onDoubleClick\"),Jo(\"focusin\",\"onFocus\"),Jo(\"focusout\",\"onBlur\"),Jo(Ww,\"onTransitionEnd\"),l(\"onMouseEnter\",[\"mouseout\",\"mouseover\"]),l(\"onMouseLeave\",[\"mouseout\",\"mouseover\"]),l(\"onPointerEnter\",[\"pointerout\",\"pointerover\"]),l(\"onPointerLeave\",[\"pointerout\",\"pointerover\"]),o(\"onChange\",\"change click focusin focusout input keydown keyup selectionchange\".split(\" \")),o(\"onSelect\",\"focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange\".split(\" \")),o(\"onBeforeInput\",[\"compositionend\",\"keypress\",\"textInput\",\"paste\"]),o(\"onCompositionEnd\",\"compositionend focusout keydown keypress keyup mousedown\".split(\" \")),o(\"onCompositionStart\",\"compositionstart focusout keydown keypress keyup mousedown\".split(\" \")),o(\"onCompositionUpdate\",\"compositionupdate focusout keydown keypress keyup mousedown\".split(\" \"));var Ic=\"abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting\".split(\" \"),LA=new Set(\"cancel close invalid load scroll toggle\".split(\" \").concat(Ic));function Qw(a,c,p){var v=a.type||\"unknown-event\";a.currentTarget=p,ht(v,c,void 0,a),a.currentTarget=null}function Zw(a,c){c=(c&4)!==0;for(var p=0;p<a.length;p++){var v=a[p],S=v.event;v=v.listeners;e:{var E=void 0;if(c)for(var T=v.length-1;0<=T;T--){var I=v[T],$=I.instance,ae=I.currentTarget;if(I=I.listener,$!==E&&S.isPropagationStopped())break e;Qw(S,I,ae),E=$}else for(T=0;T<v.length;T++){if(I=v[T],$=I.instance,ae=I.currentTarget,I=I.listener,$!==E&&S.isPropagationStopped())break e;Qw(S,I,ae),E=$}}}if(Oe)throw a=We,Oe=!1,We=null,a}function Xt(a,c){var p=c[nm];p===void 0&&(p=c[nm]=new Set);var v=a+\"__bubble\";p.has(v)||(Yw(c,a,2,!1),p.add(v))}function Jg(a,c,p){var v=0;c&&(v|=4),Yw(p,a,v,c)}var Kd=\"_reactListening\"+Math.random().toString(36).slice(2);function Ac(a){if(!a[Kd]){a[Kd]=!0,r.forEach(function(p){p!==\"selectionchange\"&&(LA.has(p)||Jg(p,!1,a),Jg(p,!0,a))});var c=a.nodeType===9?a:a.ownerDocument;c===null||c[Kd]||(c[Kd]=!0,Jg(\"selectionchange\",!1,c))}}function Yw(a,c,p,v){switch(ww(c)){case 1:var S=YI;break;case 4:S=XI;break;default:S=Pg}p=S.bind(null,c,p,a),S=void 0,!bc||c!==\"touchstart\"&&c!==\"touchmove\"&&c!==\"wheel\"||(S=!0),v?S!==void 0?a.addEventListener(c,p,{capture:!0,passive:S}):a.addEventListener(c,p,!0):S!==void 0?a.addEventListener(c,p,{passive:S}):a.addEventListener(c,p,!1)}function Qg(a,c,p,v,S){var E=v;if((c&1)===0&&(c&2)===0&&v!==null)e:for(;;){if(v===null)return;var T=v.tag;if(T===3||T===4){var I=v.stateNode.containerInfo;if(I===S||I.nodeType===8&&I.parentNode===S)break;if(T===4)for(T=v.return;T!==null;){var $=T.tag;if(($===3||$===4)&&($=T.stateNode.containerInfo,$===S||$.nodeType===8&&$.parentNode===S))return;T=T.return}for(;I!==null;){if(T=qa(I),T===null)return;if($=T.tag,$===5||$===6){v=E=T;continue e}I=I.parentNode}}v=v.return}za(function(){var ae=E,xe=vr(p),we=[];e:{var be=Gw.get(a);if(be!==void 0){var De=Ag,He=a;switch(a){case\"keypress\":if(Bd(p)===0)break e;case\"keydown\":case\"keyup\":De=hA;break;case\"focusin\":He=\"focus\",De=Lg;break;case\"focusout\":He=\"blur\",De=Lg;break;case\"beforeblur\":case\"afterblur\":De=Lg;break;case\"click\":if(p.button===2)break e;case\"auxclick\":case\"dblclick\":case\"mousedown\":case\"mousemove\":case\"mouseup\":case\"mouseout\":case\"mouseover\":case\"contextmenu\":De=Ew;break;case\"drag\":case\"dragend\":case\"dragenter\":case\"dragexit\":case\"dragleave\":case\"dragover\":case\"dragstart\":case\"drop\":De=nA;break;case\"touchcancel\":case\"touchend\":case\"touchmove\":case\"touchstart\":De=vA;break;case Hw:case qw:case Kw:De=oA;break;case Ww:De=bA;break;case\"scroll\":De=eA;break;case\"wheel\":De=wA;break;case\"copy\":case\"cut\":case\"paste\":De=iA;break;case\"gotpointercapture\":case\"lostpointercapture\":case\"pointercancel\":case\"pointerdown\":case\"pointermove\":case\"pointerout\":case\"pointerover\":case\"pointerup\":De=jw}var Ke=(c&4)!==0,kn=!Ke&&a===\"scroll\",J=Ke?be!==null?be+\"Capture\":null:be;Ke=[];for(var U=ae,ee;U!==null;){ee=U;var ke=ee.stateNode;if(ee.tag===5&&ke!==null&&(ee=ke,J!==null&&(ke=Ua(U,J),ke!=null&&Ke.push(Dc(U,ke,ee)))),kn)break;U=U.return}0<Ke.length&&(be=new De(be,He,null,p,xe),we.push({event:be,listeners:Ke}))}}if((c&7)===0){e:{if(be=a===\"mouseover\"||a===\"pointerover\",De=a===\"mouseout\"||a===\"pointerout\",be&&p!==mr&&(He=p.relatedTarget||p.fromElement)&&(qa(He)||He[oo]))break e;if((De||be)&&(be=xe.window===xe?xe:(be=xe.ownerDocument)?be.defaultView||be.parentWindow:window,De?(He=p.relatedTarget||p.toElement,De=ae,He=He?qa(He):null,He!==null&&(kn=Ge(He),He!==kn||He.tag!==5&&He.tag!==6)&&(He=null)):(De=null,He=ae),De!==He)){if(Ke=Ew,ke=\"onMouseLeave\",J=\"onMouseEnter\",U=\"mouse\",(a===\"pointerout\"||a===\"pointerover\")&&(Ke=jw,ke=\"onPointerLeave\",J=\"onPointerEnter\",U=\"pointer\"),kn=De==null?be:Zi(De),ee=He==null?be:Zi(He),be=new Ke(ke,U+\"leave\",De,p,xe),be.target=kn,be.relatedTarget=ee,ke=null,qa(xe)===ae&&(Ke=new Ke(J,U+\"enter\",He,p,xe),Ke.target=ee,Ke.relatedTarget=kn,ke=Ke),kn=ke,De&&He)t:{for(Ke=De,J=He,U=0,ee=Ke;ee;ee=Ji(ee))U++;for(ee=0,ke=J;ke;ke=Ji(ke))ee++;for(;0<U-ee;)Ke=Ji(Ke),U--;for(;0<ee-U;)J=Ji(J),ee--;for(;U--;){if(Ke===J||J!==null&&Ke===J.alternate)break t;Ke=Ji(Ke),J=Ji(J)}Ke=null}else Ke=null;De!==null&&Xw(we,be,De,Ke,!1),He!==null&&kn!==null&&Xw(we,kn,He,Ke,!0)}}e:{if(be=ae?Zi(ae):window,De=be.nodeName&&be.nodeName.toLowerCase(),De===\"select\"||De===\"input\"&&be.type===\"file\")var Je=NA;else if(Pw(be))if(Iw)Je=PA;else{Je=_A;var et=MA}else(De=be.nodeName)&&De.toLowerCase()===\"input\"&&(be.type===\"checkbox\"||be.type===\"radio\")&&(Je=RA);if(Je&&(Je=Je(a,ae))){Ow(we,Je,p,xe);break e}et&&et(a,be,ae),a===\"focusout\"&&(et=be._wrapperState)&&et.controlled&&be.type===\"number\"&&X(be,\"number\",be.value)}switch(et=ae?Zi(ae):window,a){case\"focusin\":(Pw(et)||et.contentEditable===\"true\")&&(Wi=et,Hg=ae,Oc=null);break;case\"focusout\":Oc=Hg=Wi=null;break;case\"mousedown\":qg=!0;break;case\"contextmenu\":case\"mouseup\":case\"dragend\":qg=!1,Uw(we,p,xe);break;case\"selectionchange\":if(AA)break;case\"keydown\":case\"keyup\":Uw(we,p,xe)}var tt;if(Bg)e:{switch(a){case\"compositionstart\":var dt=\"onCompositionStart\";break e;case\"compositionend\":dt=\"onCompositionEnd\";break e;case\"compositionupdate\":dt=\"onCompositionUpdate\";break e}dt=void 0}else Ki?_w(a,p)&&(dt=\"onCompositionEnd\"):a===\"keydown\"&&p.keyCode===229&&(dt=\"onCompositionStart\");dt&&(Tw&&p.locale!==\"ko\"&&(Ki||dt!==\"onCompositionStart\"?dt===\"onCompositionEnd\"&&Ki&&(tt=Sw()):(Go=xe,Ig=\"value\"in Go?Go.value:Go.textContent,Ki=!0)),et=Wd(ae,dt),0<et.length&&(dt=new kw(dt,a,null,p,xe),we.push({event:dt,listeners:et}),tt?dt.data=tt:(tt=Rw(p),tt!==null&&(dt.data=tt)))),(tt=CA?EA(a,p):kA(a,p))&&(ae=Wd(ae,\"onBeforeInput\"),0<ae.length&&(xe=new kw(\"onBeforeInput\",\"beforeinput\",null,p,xe),we.push({event:xe,listeners:ae}),xe.data=tt))}Zw(we,c)})}function Dc(a,c,p){return{instance:a,listener:c,currentTarget:p}}function Wd(a,c){for(var p=c+\"Capture\",v=[];a!==null;){var S=a,E=S.stateNode;S.tag===5&&E!==null&&(S=E,E=Ua(a,p),E!=null&&v.unshift(Dc(a,E,S)),E=Ua(a,c),E!=null&&v.push(Dc(a,E,S))),a=a.return}return v}function Ji(a){if(a===null)return null;do a=a.return;while(a&&a.tag!==5);return a||null}function Xw(a,c,p,v,S){for(var E=c._reactName,T=[];p!==null&&p!==v;){var I=p,$=I.alternate,ae=I.stateNode;if($!==null&&$===v)break;I.tag===5&&ae!==null&&(I=ae,S?($=Ua(p,E),$!=null&&T.unshift(Dc(p,$,I))):S||($=Ua(p,E),$!=null&&T.push(Dc(p,$,I)))),p=p.return}T.length!==0&&a.push({event:c,listeners:T})}var $A=/\\r\\n?/g,BA=/\\u0000|\\uFFFD/g;function eS(a){return(typeof a==\"string\"?a:\"\"+a).replace($A,`\n`).replace(BA,\"\")}function Gd(a,c,p){if(c=eS(c),eS(a)!==c&&p)throw Error(n(425))}function Jd(){}var Zg=null,Yg=null;function Xg(a,c){return a===\"textarea\"||a===\"noscript\"||typeof c.children==\"string\"||typeof c.children==\"number\"||typeof c.dangerouslySetInnerHTML==\"object\"&&c.dangerouslySetInnerHTML!==null&&c.dangerouslySetInnerHTML.__html!=null}var em=typeof setTimeout==\"function\"?setTimeout:void 0,zA=typeof clearTimeout==\"function\"?clearTimeout:void 0,tS=typeof Promise==\"function\"?Promise:void 0,UA=typeof queueMicrotask==\"function\"?queueMicrotask:typeof tS<\"u\"?function(a){return tS.resolve(null).then(a).catch(VA)}:em;function VA(a){setTimeout(function(){throw a})}function tm(a,c){var p=c,v=0;do{var S=p.nextSibling;if(a.removeChild(p),S&&S.nodeType===8)if(p=S.data,p===\"/$\"){if(v===0){a.removeChild(S),jc(c);return}v--}else p!==\"$\"&&p!==\"$?\"&&p!==\"$!\"||v++;p=S}while(p);jc(c)}function Qo(a){for(;a!=null;a=a.nextSibling){var c=a.nodeType;if(c===1||c===3)break;if(c===8){if(c=a.data,c===\"$\"||c===\"$!\"||c===\"$?\")break;if(c===\"/$\")return null}}return a}function nS(a){a=a.previousSibling;for(var c=0;a;){if(a.nodeType===8){var p=a.data;if(p===\"$\"||p===\"$!\"||p===\"$?\"){if(c===0)return a;c--}else p===\"/$\"&&c++}a=a.previousSibling}return null}var Qi=Math.random().toString(36).slice(2),As=\"__reactFiber$\"+Qi,Fc=\"__reactProps$\"+Qi,oo=\"__reactContainer$\"+Qi,nm=\"__reactEvents$\"+Qi,HA=\"__reactListeners$\"+Qi,qA=\"__reactHandles$\"+Qi;function qa(a){var c=a[As];if(c)return c;for(var p=a.parentNode;p;){if(c=p[oo]||p[As]){if(p=c.alternate,c.child!==null||p!==null&&p.child!==null)for(a=nS(a);a!==null;){if(p=a[As])return p;a=nS(a)}return c}a=p,p=a.parentNode}return null}function Lc(a){return a=a[As]||a[oo],!a||a.tag!==5&&a.tag!==6&&a.tag!==13&&a.tag!==3?null:a}function Zi(a){if(a.tag===5||a.tag===6)return a.stateNode;throw Error(n(33))}function Qd(a){return a[Fc]||null}var rm=[],Yi=-1;function Zo(a){return{current:a}}function en(a){0>Yi||(a.current=rm[Yi],rm[Yi]=null,Yi--)}function Qt(a,c){Yi++,rm[Yi]=a.current,a.current=c}var Yo={},Zn=Zo(Yo),yr=Zo(!1),Ka=Yo;function Xi(a,c){var p=a.type.contextTypes;if(!p)return Yo;var v=a.stateNode;if(v&&v.__reactInternalMemoizedUnmaskedChildContext===c)return v.__reactInternalMemoizedMaskedChildContext;var S={},E;for(E in p)S[E]=c[E];return v&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=c,a.__reactInternalMemoizedMaskedChildContext=S),S}function br(a){return a=a.childContextTypes,a!=null}function Zd(){en(yr),en(Zn)}function rS(a,c,p){if(Zn.current!==Yo)throw Error(n(168));Qt(Zn,c),Qt(yr,p)}function sS(a,c,p){var v=a.stateNode;if(c=c.childContextTypes,typeof v.getChildContext!=\"function\")return p;v=v.getChildContext();for(var S in v)if(!(S in c))throw Error(n(108,Z(a)||\"Unknown\",S));return he({},p,v)}function Yd(a){return a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Yo,Ka=Zn.current,Qt(Zn,a),Qt(yr,yr.current),!0}function oS(a,c,p){var v=a.stateNode;if(!v)throw Error(n(169));p?(a=sS(a,c,Ka),v.__reactInternalMemoizedMergedChildContext=a,en(yr),en(Zn),Qt(Zn,a)):en(yr),Qt(yr,p)}var ao=null,Xd=!1,sm=!1;function aS(a){ao===null?ao=[a]:ao.push(a)}function KA(a){Xd=!0,aS(a)}function Xo(){if(!sm&&ao!==null){sm=!0;var a=0,c=Kt;try{var p=ao;for(Kt=1;a<p.length;a++){var v=p[a];do v=v(!0);while(v!==null)}ao=null,Xd=!1}catch(S){throw ao!==null&&(ao=ao.slice(a+1)),Nn(Is,Xo),S}finally{Kt=c,sm=!1}}return null}var el=[],tl=0,ef=null,tf=0,Qr=[],Zr=0,Wa=null,io=1,lo=\"\";function Ga(a,c){el[tl++]=tf,el[tl++]=ef,ef=a,tf=c}function iS(a,c,p){Qr[Zr++]=io,Qr[Zr++]=lo,Qr[Zr++]=Wa,Wa=a;var v=io;a=lo;var S=32-Tt(v)-1;v&=~(1<<S),p+=1;var E=32-Tt(c)+S;if(30<E){var T=S-S%5;E=(v&(1<<T)-1).toString(32),v>>=T,S-=T,io=1<<32-Tt(c)+S|p<<S|v,lo=E+a}else io=1<<E|p<<S|v,lo=a}function om(a){a.return!==null&&(Ga(a,1),iS(a,1,0))}function am(a){for(;a===ef;)ef=el[--tl],el[tl]=null,tf=el[--tl],el[tl]=null;for(;a===Wa;)Wa=Qr[--Zr],Qr[Zr]=null,lo=Qr[--Zr],Qr[Zr]=null,io=Qr[--Zr],Qr[Zr]=null}var Ir=null,Ar=null,cn=!1,hs=null;function lS(a,c){var p=ts(5,null,null,0);p.elementType=\"DELETED\",p.stateNode=c,p.return=a,c=a.deletions,c===null?(a.deletions=[p],a.flags|=16):c.push(p)}function cS(a,c){switch(a.tag){case 5:var p=a.type;return c=c.nodeType!==1||p.toLowerCase()!==c.nodeName.toLowerCase()?null:c,c!==null?(a.stateNode=c,Ir=a,Ar=Qo(c.firstChild),!0):!1;case 6:return c=a.pendingProps===\"\"||c.nodeType!==3?null:c,c!==null?(a.stateNode=c,Ir=a,Ar=null,!0):!1;case 13:return c=c.nodeType!==8?null:c,c!==null?(p=Wa!==null?{id:io,overflow:lo}:null,a.memoizedState={dehydrated:c,treeContext:p,retryLane:1073741824},p=ts(18,null,null,0),p.stateNode=c,p.return=a,a.child=p,Ir=a,Ar=null,!0):!1;default:return!1}}function im(a){return(a.mode&1)!==0&&(a.flags&128)===0}function lm(a){if(cn){var c=Ar;if(c){var p=c;if(!cS(a,c)){if(im(a))throw Error(n(418));c=Qo(p.nextSibling);var v=Ir;c&&cS(a,c)?lS(v,p):(a.flags=a.flags&-4097|2,cn=!1,Ir=a)}}else{if(im(a))throw Error(n(418));a.flags=a.flags&-4097|2,cn=!1,Ir=a}}}function uS(a){for(a=a.return;a!==null&&a.tag!==5&&a.tag!==3&&a.tag!==13;)a=a.return;Ir=a}function nf(a){if(a!==Ir)return!1;if(!cn)return uS(a),cn=!0,!1;var c;if((c=a.tag!==3)&&!(c=a.tag!==5)&&(c=a.type,c=c!==\"head\"&&c!==\"body\"&&!Xg(a.type,a.memoizedProps)),c&&(c=Ar)){if(im(a))throw dS(),Error(n(418));for(;c;)lS(a,c),c=Qo(c.nextSibling)}if(uS(a),a.tag===13){if(a=a.memoizedState,a=a!==null?a.dehydrated:null,!a)throw Error(n(317));e:{for(a=a.nextSibling,c=0;a;){if(a.nodeType===8){var p=a.data;if(p===\"/$\"){if(c===0){Ar=Qo(a.nextSibling);break e}c--}else p!==\"$\"&&p!==\"$!\"&&p!==\"$?\"||c++}a=a.nextSibling}Ar=null}}else Ar=Ir?Qo(a.stateNode.nextSibling):null;return!0}function dS(){for(var a=Ar;a;)a=Qo(a.nextSibling)}function nl(){Ar=Ir=null,cn=!1}function cm(a){hs===null?hs=[a]:hs.push(a)}var WA=_.ReactCurrentBatchConfig;function $c(a,c,p){if(a=p.ref,a!==null&&typeof a!=\"function\"&&typeof a!=\"object\"){if(p._owner){if(p=p._owner,p){if(p.tag!==1)throw Error(n(309));var v=p.stateNode}if(!v)throw Error(n(147,a));var S=v,E=\"\"+a;return c!==null&&c.ref!==null&&typeof c.ref==\"function\"&&c.ref._stringRef===E?c.ref:(c=function(T){var I=S.refs;T===null?delete I[E]:I[E]=T},c._stringRef=E,c)}if(typeof a!=\"string\")throw Error(n(284));if(!p._owner)throw Error(n(290,a))}return a}function rf(a,c){throw a=Object.prototype.toString.call(c),Error(n(31,a===\"[object Object]\"?\"object with keys {\"+Object.keys(c).join(\", \")+\"}\":a))}function fS(a){var c=a._init;return c(a._payload)}function pS(a){function c(J,U){if(a){var ee=J.deletions;ee===null?(J.deletions=[U],J.flags|=16):ee.push(U)}}function p(J,U){if(!a)return null;for(;U!==null;)c(J,U),U=U.sibling;return null}function v(J,U){for(J=new Map;U!==null;)U.key!==null?J.set(U.key,U):J.set(U.index,U),U=U.sibling;return J}function S(J,U){return J=ia(J,U),J.index=0,J.sibling=null,J}function E(J,U,ee){return J.index=ee,a?(ee=J.alternate,ee!==null?(ee=ee.index,ee<U?(J.flags|=2,U):ee):(J.flags|=2,U)):(J.flags|=1048576,U)}function T(J){return a&&J.alternate===null&&(J.flags|=2),J}function I(J,U,ee,ke){return U===null||U.tag!==6?(U=ev(ee,J.mode,ke),U.return=J,U):(U=S(U,ee),U.return=J,U)}function $(J,U,ee,ke){var Je=ee.type;return Je===O?xe(J,U,ee.props.children,ke,ee.key):U!==null&&(U.elementType===Je||typeof Je==\"object\"&&Je!==null&&Je.$$typeof===re&&fS(Je)===U.type)?(ke=S(U,ee.props),ke.ref=$c(J,U,ee),ke.return=J,ke):(ke=Nf(ee.type,ee.key,ee.props,null,J.mode,ke),ke.ref=$c(J,U,ee),ke.return=J,ke)}function ae(J,U,ee,ke){return U===null||U.tag!==4||U.stateNode.containerInfo!==ee.containerInfo||U.stateNode.implementation!==ee.implementation?(U=tv(ee,J.mode,ke),U.return=J,U):(U=S(U,ee.children||[]),U.return=J,U)}function xe(J,U,ee,ke,Je){return U===null||U.tag!==7?(U=ni(ee,J.mode,ke,Je),U.return=J,U):(U=S(U,ee),U.return=J,U)}function we(J,U,ee){if(typeof U==\"string\"&&U!==\"\"||typeof U==\"number\")return U=ev(\"\"+U,J.mode,ee),U.return=J,U;if(typeof U==\"object\"&&U!==null){switch(U.$$typeof){case R:return ee=Nf(U.type,U.key,U.props,null,J.mode,ee),ee.ref=$c(J,null,U),ee.return=J,ee;case N:return U=tv(U,J.mode,ee),U.return=J,U;case re:var ke=U._init;return we(J,ke(U._payload),ee)}if(ue(U)||q(U))return U=ni(U,J.mode,ee,null),U.return=J,U;rf(J,U)}return null}function be(J,U,ee,ke){var Je=U!==null?U.key:null;if(typeof ee==\"string\"&&ee!==\"\"||typeof ee==\"number\")return Je!==null?null:I(J,U,\"\"+ee,ke);if(typeof ee==\"object\"&&ee!==null){switch(ee.$$typeof){case R:return ee.key===Je?$(J,U,ee,ke):null;case N:return ee.key===Je?ae(J,U,ee,ke):null;case re:return Je=ee._init,be(J,U,Je(ee._payload),ke)}if(ue(ee)||q(ee))return Je!==null?null:xe(J,U,ee,ke,null);rf(J,ee)}return null}function De(J,U,ee,ke,Je){if(typeof ke==\"string\"&&ke!==\"\"||typeof ke==\"number\")return J=J.get(ee)||null,I(U,J,\"\"+ke,Je);if(typeof ke==\"object\"&&ke!==null){switch(ke.$$typeof){case R:return J=J.get(ke.key===null?ee:ke.key)||null,$(U,J,ke,Je);case N:return J=J.get(ke.key===null?ee:ke.key)||null,ae(U,J,ke,Je);case re:var et=ke._init;return De(J,U,ee,et(ke._payload),Je)}if(ue(ke)||q(ke))return J=J.get(ee)||null,xe(U,J,ke,Je,null);rf(U,ke)}return null}function He(J,U,ee,ke){for(var Je=null,et=null,tt=U,dt=U=0,Vn=null;tt!==null&&dt<ee.length;dt++){tt.index>dt?(Vn=tt,tt=null):Vn=tt.sibling;var Lt=be(J,tt,ee[dt],ke);if(Lt===null){tt===null&&(tt=Vn);break}a&&tt&&Lt.alternate===null&&c(J,tt),U=E(Lt,U,dt),et===null?Je=Lt:et.sibling=Lt,et=Lt,tt=Vn}if(dt===ee.length)return p(J,tt),cn&&Ga(J,dt),Je;if(tt===null){for(;dt<ee.length;dt++)tt=we(J,ee[dt],ke),tt!==null&&(U=E(tt,U,dt),et===null?Je=tt:et.sibling=tt,et=tt);return cn&&Ga(J,dt),Je}for(tt=v(J,tt);dt<ee.length;dt++)Vn=De(tt,J,dt,ee[dt],ke),Vn!==null&&(a&&Vn.alternate!==null&&tt.delete(Vn.key===null?dt:Vn.key),U=E(Vn,U,dt),et===null?Je=Vn:et.sibling=Vn,et=Vn);return a&&tt.forEach(function(la){return c(J,la)}),cn&&Ga(J,dt),Je}function Ke(J,U,ee,ke){var Je=q(ee);if(typeof Je!=\"function\")throw Error(n(150));if(ee=Je.call(ee),ee==null)throw Error(n(151));for(var et=Je=null,tt=U,dt=U=0,Vn=null,Lt=ee.next();tt!==null&&!Lt.done;dt++,Lt=ee.next()){tt.index>dt?(Vn=tt,tt=null):Vn=tt.sibling;var la=be(J,tt,Lt.value,ke);if(la===null){tt===null&&(tt=Vn);break}a&&tt&&la.alternate===null&&c(J,tt),U=E(la,U,dt),et===null?Je=la:et.sibling=la,et=la,tt=Vn}if(Lt.done)return p(J,tt),cn&&Ga(J,dt),Je;if(tt===null){for(;!Lt.done;dt++,Lt=ee.next())Lt=we(J,Lt.value,ke),Lt!==null&&(U=E(Lt,U,dt),et===null?Je=Lt:et.sibling=Lt,et=Lt);return cn&&Ga(J,dt),Je}for(tt=v(J,tt);!Lt.done;dt++,Lt=ee.next())Lt=De(tt,J,dt,Lt.value,ke),Lt!==null&&(a&&Lt.alternate!==null&&tt.delete(Lt.key===null?dt:Lt.key),U=E(Lt,U,dt),et===null?Je=Lt:et.sibling=Lt,et=Lt);return a&&tt.forEach(function(jD){return c(J,jD)}),cn&&Ga(J,dt),Je}function kn(J,U,ee,ke){if(typeof ee==\"object\"&&ee!==null&&ee.type===O&&ee.key===null&&(ee=ee.props.children),typeof ee==\"object\"&&ee!==null){switch(ee.$$typeof){case R:e:{for(var Je=ee.key,et=U;et!==null;){if(et.key===Je){if(Je=ee.type,Je===O){if(et.tag===7){p(J,et.sibling),U=S(et,ee.props.children),U.return=J,J=U;break e}}else if(et.elementType===Je||typeof Je==\"object\"&&Je!==null&&Je.$$typeof===re&&fS(Je)===et.type){p(J,et.sibling),U=S(et,ee.props),U.ref=$c(J,et,ee),U.return=J,J=U;break e}p(J,et);break}else c(J,et);et=et.sibling}ee.type===O?(U=ni(ee.props.children,J.mode,ke,ee.key),U.return=J,J=U):(ke=Nf(ee.type,ee.key,ee.props,null,J.mode,ke),ke.ref=$c(J,U,ee),ke.return=J,J=ke)}return T(J);case N:e:{for(et=ee.key;U!==null;){if(U.key===et)if(U.tag===4&&U.stateNode.containerInfo===ee.containerInfo&&U.stateNode.implementation===ee.implementation){p(J,U.sibling),U=S(U,ee.children||[]),U.return=J,J=U;break e}else{p(J,U);break}else c(J,U);U=U.sibling}U=tv(ee,J.mode,ke),U.return=J,J=U}return T(J);case re:return et=ee._init,kn(J,U,et(ee._payload),ke)}if(ue(ee))return He(J,U,ee,ke);if(q(ee))return Ke(J,U,ee,ke);rf(J,ee)}return typeof ee==\"string\"&&ee!==\"\"||typeof ee==\"number\"?(ee=\"\"+ee,U!==null&&U.tag===6?(p(J,U.sibling),U=S(U,ee),U.return=J,J=U):(p(J,U),U=ev(ee,J.mode,ke),U.return=J,J=U),T(J)):p(J,U)}return kn}var rl=pS(!0),hS=pS(!1),sf=Zo(null),of=null,sl=null,um=null;function dm(){um=sl=of=null}function fm(a){var c=sf.current;en(sf),a._currentValue=c}function pm(a,c,p){for(;a!==null;){var v=a.alternate;if((a.childLanes&c)!==c?(a.childLanes|=c,v!==null&&(v.childLanes|=c)):v!==null&&(v.childLanes&c)!==c&&(v.childLanes|=c),a===p)break;a=a.return}}function ol(a,c){of=a,um=sl=null,a=a.dependencies,a!==null&&a.firstContext!==null&&((a.lanes&c)!==0&&(xr=!0),a.firstContext=null)}function Yr(a){var c=a._currentValue;if(um!==a)if(a={context:a,memoizedValue:c,next:null},sl===null){if(of===null)throw Error(n(308));sl=a,of.dependencies={lanes:0,firstContext:a}}else sl=sl.next=a;return c}var Ja=null;function hm(a){Ja===null?Ja=[a]:Ja.push(a)}function gS(a,c,p,v){var S=c.interleaved;return S===null?(p.next=p,hm(c)):(p.next=S.next,S.next=p),c.interleaved=p,co(a,v)}function co(a,c){a.lanes|=c;var p=a.alternate;for(p!==null&&(p.lanes|=c),p=a,a=a.return;a!==null;)a.childLanes|=c,p=a.alternate,p!==null&&(p.childLanes|=c),p=a,a=a.return;return p.tag===3?p.stateNode:null}var ea=!1;function gm(a){a.updateQueue={baseState:a.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function mS(a,c){a=a.updateQueue,c.updateQueue===a&&(c.updateQueue={baseState:a.baseState,firstBaseUpdate:a.firstBaseUpdate,lastBaseUpdate:a.lastBaseUpdate,shared:a.shared,effects:a.effects})}function uo(a,c){return{eventTime:a,lane:c,tag:0,payload:null,callback:null,next:null}}function ta(a,c,p){var v=a.updateQueue;if(v===null)return null;if(v=v.shared,(Ft&2)!==0){var S=v.pending;return S===null?c.next=c:(c.next=S.next,S.next=c),v.pending=c,co(a,p)}return S=v.interleaved,S===null?(c.next=c,hm(v)):(c.next=S.next,S.next=c),v.interleaved=c,co(a,p)}function af(a,c,p){if(c=c.updateQueue,c!==null&&(c=c.shared,(p&4194240)!==0)){var v=c.lanes;v&=a.pendingLanes,p|=v,c.lanes=p,Mg(a,p)}}function vS(a,c){var p=a.updateQueue,v=a.alternate;if(v!==null&&(v=v.updateQueue,p===v)){var S=null,E=null;if(p=p.firstBaseUpdate,p!==null){do{var T={eventTime:p.eventTime,lane:p.lane,tag:p.tag,payload:p.payload,callback:p.callback,next:null};E===null?S=E=T:E=E.next=T,p=p.next}while(p!==null);E===null?S=E=c:E=E.next=c}else S=E=c;p={baseState:v.baseState,firstBaseUpdate:S,lastBaseUpdate:E,shared:v.shared,effects:v.effects},a.updateQueue=p;return}a=p.lastBaseUpdate,a===null?p.firstBaseUpdate=c:a.next=c,p.lastBaseUpdate=c}function lf(a,c,p,v){var S=a.updateQueue;ea=!1;var E=S.firstBaseUpdate,T=S.lastBaseUpdate,I=S.shared.pending;if(I!==null){S.shared.pending=null;var $=I,ae=$.next;$.next=null,T===null?E=ae:T.next=ae,T=$;var xe=a.alternate;xe!==null&&(xe=xe.updateQueue,I=xe.lastBaseUpdate,I!==T&&(I===null?xe.firstBaseUpdate=ae:I.next=ae,xe.lastBaseUpdate=$))}if(E!==null){var we=S.baseState;T=0,xe=ae=$=null,I=E;do{var be=I.lane,De=I.eventTime;if((v&be)===be){xe!==null&&(xe=xe.next={eventTime:De,lane:0,tag:I.tag,payload:I.payload,callback:I.callback,next:null});e:{var He=a,Ke=I;switch(be=c,De=p,Ke.tag){case 1:if(He=Ke.payload,typeof He==\"function\"){we=He.call(De,we,be);break e}we=He;break e;case 3:He.flags=He.flags&-65537|128;case 0:if(He=Ke.payload,be=typeof He==\"function\"?He.call(De,we,be):He,be==null)break e;we=he({},we,be);break e;case 2:ea=!0}}I.callback!==null&&I.lane!==0&&(a.flags|=64,be=S.effects,be===null?S.effects=[I]:be.push(I))}else De={eventTime:De,lane:be,tag:I.tag,payload:I.payload,callback:I.callback,next:null},xe===null?(ae=xe=De,$=we):xe=xe.next=De,T|=be;if(I=I.next,I===null){if(I=S.shared.pending,I===null)break;be=I,I=be.next,be.next=null,S.lastBaseUpdate=be,S.shared.pending=null}}while(!0);if(xe===null&&($=we),S.baseState=$,S.firstBaseUpdate=ae,S.lastBaseUpdate=xe,c=S.shared.interleaved,c!==null){S=c;do T|=S.lane,S=S.next;while(S!==c)}else E===null&&(S.shared.lanes=0);Ya|=T,a.lanes=T,a.memoizedState=we}}function yS(a,c,p){if(a=c.effects,c.effects=null,a!==null)for(c=0;c<a.length;c++){var v=a[c],S=v.callback;if(S!==null){if(v.callback=null,v=p,typeof S!=\"function\")throw Error(n(191,S));S.call(v)}}}var Bc={},Ds=Zo(Bc),zc=Zo(Bc),Uc=Zo(Bc);function Qa(a){if(a===Bc)throw Error(n(174));return a}function mm(a,c){switch(Qt(Uc,c),Qt(zc,a),Qt(Ds,Bc),a=c.nodeType,a){case 9:case 11:c=(c=c.documentElement)?c.namespaceURI:yn(null,\"\");break;default:a=a===8?c.parentNode:c,c=a.namespaceURI||null,a=a.tagName,c=yn(c,a)}en(Ds),Qt(Ds,c)}function al(){en(Ds),en(zc),en(Uc)}function bS(a){Qa(Uc.current);var c=Qa(Ds.current),p=yn(c,a.type);c!==p&&(Qt(zc,a),Qt(Ds,p))}function vm(a){zc.current===a&&(en(Ds),en(zc))}var pn=Zo(0);function cf(a){for(var c=a;c!==null;){if(c.tag===13){var p=c.memoizedState;if(p!==null&&(p=p.dehydrated,p===null||p.data===\"$?\"||p.data===\"$!\"))return c}else if(c.tag===19&&c.memoizedProps.revealOrder!==void 0){if((c.flags&128)!==0)return c}else if(c.child!==null){c.child.return=c,c=c.child;continue}if(c===a)break;for(;c.sibling===null;){if(c.return===null||c.return===a)return null;c=c.return}c.sibling.return=c.return,c=c.sibling}return null}var ym=[];function bm(){for(var a=0;a<ym.length;a++)ym[a]._workInProgressVersionPrimary=null;ym.length=0}var uf=_.ReactCurrentDispatcher,xm=_.ReactCurrentBatchConfig,Za=0,hn=null,In=null,zn=null,df=!1,Vc=!1,Hc=0,GA=0;function Yn(){throw Error(n(321))}function wm(a,c){if(c===null)return!1;for(var p=0;p<c.length&&p<a.length;p++)if(!ps(a[p],c[p]))return!1;return!0}function Sm(a,c,p,v,S,E){if(Za=E,hn=c,c.memoizedState=null,c.updateQueue=null,c.lanes=0,uf.current=a===null||a.memoizedState===null?YA:XA,a=p(v,S),Vc){E=0;do{if(Vc=!1,Hc=0,25<=E)throw Error(n(301));E+=1,zn=In=null,c.updateQueue=null,uf.current=eD,a=p(v,S)}while(Vc)}if(uf.current=hf,c=In!==null&&In.next!==null,Za=0,zn=In=hn=null,df=!1,c)throw Error(n(300));return a}function Cm(){var a=Hc!==0;return Hc=0,a}function Fs(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return zn===null?hn.memoizedState=zn=a:zn=zn.next=a,zn}function Xr(){if(In===null){var a=hn.alternate;a=a!==null?a.memoizedState:null}else a=In.next;var c=zn===null?hn.memoizedState:zn.next;if(c!==null)zn=c,In=a;else{if(a===null)throw Error(n(310));In=a,a={memoizedState:In.memoizedState,baseState:In.baseState,baseQueue:In.baseQueue,queue:In.queue,next:null},zn===null?hn.memoizedState=zn=a:zn=zn.next=a}return zn}function qc(a,c){return typeof c==\"function\"?c(a):c}function Em(a){var c=Xr(),p=c.queue;if(p===null)throw Error(n(311));p.lastRenderedReducer=a;var v=In,S=v.baseQueue,E=p.pending;if(E!==null){if(S!==null){var T=S.next;S.next=E.next,E.next=T}v.baseQueue=S=E,p.pending=null}if(S!==null){E=S.next,v=v.baseState;var I=T=null,$=null,ae=E;do{var xe=ae.lane;if((Za&xe)===xe)$!==null&&($=$.next={lane:0,action:ae.action,hasEagerState:ae.hasEagerState,eagerState:ae.eagerState,next:null}),v=ae.hasEagerState?ae.eagerState:a(v,ae.action);else{var we={lane:xe,action:ae.action,hasEagerState:ae.hasEagerState,eagerState:ae.eagerState,next:null};$===null?(I=$=we,T=v):$=$.next=we,hn.lanes|=xe,Ya|=xe}ae=ae.next}while(ae!==null&&ae!==E);$===null?T=v:$.next=I,ps(v,c.memoizedState)||(xr=!0),c.memoizedState=v,c.baseState=T,c.baseQueue=$,p.lastRenderedState=v}if(a=p.interleaved,a!==null){S=a;do E=S.lane,hn.lanes|=E,Ya|=E,S=S.next;while(S!==a)}else S===null&&(p.lanes=0);return[c.memoizedState,p.dispatch]}function km(a){var c=Xr(),p=c.queue;if(p===null)throw Error(n(311));p.lastRenderedReducer=a;var v=p.dispatch,S=p.pending,E=c.memoizedState;if(S!==null){p.pending=null;var T=S=S.next;do E=a(E,T.action),T=T.next;while(T!==S);ps(E,c.memoizedState)||(xr=!0),c.memoizedState=E,c.baseQueue===null&&(c.baseState=E),p.lastRenderedState=E}return[E,v]}function xS(){}function wS(a,c){var p=hn,v=Xr(),S=c(),E=!ps(v.memoizedState,S);if(E&&(v.memoizedState=S,xr=!0),v=v.queue,jm(ES.bind(null,p,v,a),[a]),v.getSnapshot!==c||E||zn!==null&&zn.memoizedState.tag&1){if(p.flags|=2048,Kc(9,CS.bind(null,p,v,S,c),void 0,null),Un===null)throw Error(n(349));(Za&30)!==0||SS(p,c,S)}return S}function SS(a,c,p){a.flags|=16384,a={getSnapshot:c,value:p},c=hn.updateQueue,c===null?(c={lastEffect:null,stores:null},hn.updateQueue=c,c.stores=[a]):(p=c.stores,p===null?c.stores=[a]:p.push(a))}function CS(a,c,p,v){c.value=p,c.getSnapshot=v,kS(c)&&jS(a)}function ES(a,c,p){return p(function(){kS(c)&&jS(a)})}function kS(a){var c=a.getSnapshot;a=a.value;try{var p=c();return!ps(a,p)}catch{return!0}}function jS(a){var c=co(a,1);c!==null&&ys(c,a,1,-1)}function TS(a){var c=Fs();return typeof a==\"function\"&&(a=a()),c.memoizedState=c.baseState=a,a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:qc,lastRenderedState:a},c.queue=a,a=a.dispatch=ZA.bind(null,hn,a),[c.memoizedState,a]}function Kc(a,c,p,v){return a={tag:a,create:c,destroy:p,deps:v,next:null},c=hn.updateQueue,c===null?(c={lastEffect:null,stores:null},hn.updateQueue=c,c.lastEffect=a.next=a):(p=c.lastEffect,p===null?c.lastEffect=a.next=a:(v=p.next,p.next=a,a.next=v,c.lastEffect=a)),a}function NS(){return Xr().memoizedState}function ff(a,c,p,v){var S=Fs();hn.flags|=a,S.memoizedState=Kc(1|c,p,void 0,v===void 0?null:v)}function pf(a,c,p,v){var S=Xr();v=v===void 0?null:v;var E=void 0;if(In!==null){var T=In.memoizedState;if(E=T.destroy,v!==null&&wm(v,T.deps)){S.memoizedState=Kc(c,p,E,v);return}}hn.flags|=a,S.memoizedState=Kc(1|c,p,E,v)}function MS(a,c){return ff(8390656,8,a,c)}function jm(a,c){return pf(2048,8,a,c)}function _S(a,c){return pf(4,2,a,c)}function RS(a,c){return pf(4,4,a,c)}function PS(a,c){if(typeof c==\"function\")return a=a(),c(a),function(){c(null)};if(c!=null)return a=a(),c.current=a,function(){c.current=null}}function OS(a,c,p){return p=p!=null?p.concat([a]):null,pf(4,4,PS.bind(null,c,a),p)}function Tm(){}function IS(a,c){var p=Xr();c=c===void 0?null:c;var v=p.memoizedState;return v!==null&&c!==null&&wm(c,v[1])?v[0]:(p.memoizedState=[a,c],a)}function AS(a,c){var p=Xr();c=c===void 0?null:c;var v=p.memoizedState;return v!==null&&c!==null&&wm(c,v[1])?v[0]:(a=a(),p.memoizedState=[a,c],a)}function DS(a,c,p){return(Za&21)===0?(a.baseState&&(a.baseState=!1,xr=!0),a.memoizedState=p):(ps(p,c)||(p=fw(),hn.lanes|=p,Ya|=p,a.baseState=!0),c)}function JA(a,c){var p=Kt;Kt=p!==0&&4>p?p:4,a(!0);var v=xm.transition;xm.transition={};try{a(!1),c()}finally{Kt=p,xm.transition=v}}function FS(){return Xr().memoizedState}function QA(a,c,p){var v=oa(a);if(p={lane:v,action:p,hasEagerState:!1,eagerState:null,next:null},LS(a))$S(c,p);else if(p=gS(a,c,p,v),p!==null){var S=ir();ys(p,a,v,S),BS(p,c,v)}}function ZA(a,c,p){var v=oa(a),S={lane:v,action:p,hasEagerState:!1,eagerState:null,next:null};if(LS(a))$S(c,S);else{var E=a.alternate;if(a.lanes===0&&(E===null||E.lanes===0)&&(E=c.lastRenderedReducer,E!==null))try{var T=c.lastRenderedState,I=E(T,p);if(S.hasEagerState=!0,S.eagerState=I,ps(I,T)){var $=c.interleaved;$===null?(S.next=S,hm(c)):(S.next=$.next,$.next=S),c.interleaved=S;return}}catch{}finally{}p=gS(a,c,S,v),p!==null&&(S=ir(),ys(p,a,v,S),BS(p,c,v))}}function LS(a){var c=a.alternate;return a===hn||c!==null&&c===hn}function $S(a,c){Vc=df=!0;var p=a.pending;p===null?c.next=c:(c.next=p.next,p.next=c),a.pending=c}function BS(a,c,p){if((p&4194240)!==0){var v=c.lanes;v&=a.pendingLanes,p|=v,c.lanes=p,Mg(a,p)}}var hf={readContext:Yr,useCallback:Yn,useContext:Yn,useEffect:Yn,useImperativeHandle:Yn,useInsertionEffect:Yn,useLayoutEffect:Yn,useMemo:Yn,useReducer:Yn,useRef:Yn,useState:Yn,useDebugValue:Yn,useDeferredValue:Yn,useTransition:Yn,useMutableSource:Yn,useSyncExternalStore:Yn,useId:Yn,unstable_isNewReconciler:!1},YA={readContext:Yr,useCallback:function(a,c){return Fs().memoizedState=[a,c===void 0?null:c],a},useContext:Yr,useEffect:MS,useImperativeHandle:function(a,c,p){return p=p!=null?p.concat([a]):null,ff(4194308,4,PS.bind(null,c,a),p)},useLayoutEffect:function(a,c){return ff(4194308,4,a,c)},useInsertionEffect:function(a,c){return ff(4,2,a,c)},useMemo:function(a,c){var p=Fs();return c=c===void 0?null:c,a=a(),p.memoizedState=[a,c],a},useReducer:function(a,c,p){var v=Fs();return c=p!==void 0?p(c):c,v.memoizedState=v.baseState=c,a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:c},v.queue=a,a=a.dispatch=QA.bind(null,hn,a),[v.memoizedState,a]},useRef:function(a){var c=Fs();return a={current:a},c.memoizedState=a},useState:TS,useDebugValue:Tm,useDeferredValue:function(a){return Fs().memoizedState=a},useTransition:function(){var a=TS(!1),c=a[0];return a=JA.bind(null,a[1]),Fs().memoizedState=a,[c,a]},useMutableSource:function(){},useSyncExternalStore:function(a,c,p){var v=hn,S=Fs();if(cn){if(p===void 0)throw Error(n(407));p=p()}else{if(p=c(),Un===null)throw Error(n(349));(Za&30)!==0||SS(v,c,p)}S.memoizedState=p;var E={value:p,getSnapshot:c};return S.queue=E,MS(ES.bind(null,v,E,a),[a]),v.flags|=2048,Kc(9,CS.bind(null,v,E,p,c),void 0,null),p},useId:function(){var a=Fs(),c=Un.identifierPrefix;if(cn){var p=lo,v=io;p=(v&~(1<<32-Tt(v)-1)).toString(32)+p,c=\":\"+c+\"R\"+p,p=Hc++,0<p&&(c+=\"H\"+p.toString(32)),c+=\":\"}else p=GA++,c=\":\"+c+\"r\"+p.toString(32)+\":\";return a.memoizedState=c},unstable_isNewReconciler:!1},XA={readContext:Yr,useCallback:IS,useContext:Yr,useEffect:jm,useImperativeHandle:OS,useInsertionEffect:_S,useLayoutEffect:RS,useMemo:AS,useReducer:Em,useRef:NS,useState:function(){return Em(qc)},useDebugValue:Tm,useDeferredValue:function(a){var c=Xr();return DS(c,In.memoizedState,a)},useTransition:function(){var a=Em(qc)[0],c=Xr().memoizedState;return[a,c]},useMutableSource:xS,useSyncExternalStore:wS,useId:FS,unstable_isNewReconciler:!1},eD={readContext:Yr,useCallback:IS,useContext:Yr,useEffect:jm,useImperativeHandle:OS,useInsertionEffect:_S,useLayoutEffect:RS,useMemo:AS,useReducer:km,useRef:NS,useState:function(){return km(qc)},useDebugValue:Tm,useDeferredValue:function(a){var c=Xr();return In===null?c.memoizedState=a:DS(c,In.memoizedState,a)},useTransition:function(){var a=km(qc)[0],c=Xr().memoizedState;return[a,c]},useMutableSource:xS,useSyncExternalStore:wS,useId:FS,unstable_isNewReconciler:!1};function gs(a,c){if(a&&a.defaultProps){c=he({},c),a=a.defaultProps;for(var p in a)c[p]===void 0&&(c[p]=a[p]);return c}return c}function Nm(a,c,p,v){c=a.memoizedState,p=p(v,c),p=p==null?c:he({},c,p),a.memoizedState=p,a.lanes===0&&(a.updateQueue.baseState=p)}var gf={isMounted:function(a){return(a=a._reactInternals)?Ge(a)===a:!1},enqueueSetState:function(a,c,p){a=a._reactInternals;var v=ir(),S=oa(a),E=uo(v,S);E.payload=c,p!=null&&(E.callback=p),c=ta(a,E,S),c!==null&&(ys(c,a,S,v),af(c,a,S))},enqueueReplaceState:function(a,c,p){a=a._reactInternals;var v=ir(),S=oa(a),E=uo(v,S);E.tag=1,E.payload=c,p!=null&&(E.callback=p),c=ta(a,E,S),c!==null&&(ys(c,a,S,v),af(c,a,S))},enqueueForceUpdate:function(a,c){a=a._reactInternals;var p=ir(),v=oa(a),S=uo(p,v);S.tag=2,c!=null&&(S.callback=c),c=ta(a,S,v),c!==null&&(ys(c,a,v,p),af(c,a,v))}};function zS(a,c,p,v,S,E,T){return a=a.stateNode,typeof a.shouldComponentUpdate==\"function\"?a.shouldComponentUpdate(v,E,T):c.prototype&&c.prototype.isPureReactComponent?!Pc(p,v)||!Pc(S,E):!0}function US(a,c,p){var v=!1,S=Yo,E=c.contextType;return typeof E==\"object\"&&E!==null?E=Yr(E):(S=br(c)?Ka:Zn.current,v=c.contextTypes,E=(v=v!=null)?Xi(a,S):Yo),c=new c(p,E),a.memoizedState=c.state!==null&&c.state!==void 0?c.state:null,c.updater=gf,a.stateNode=c,c._reactInternals=a,v&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=S,a.__reactInternalMemoizedMaskedChildContext=E),c}function VS(a,c,p,v){a=c.state,typeof c.componentWillReceiveProps==\"function\"&&c.componentWillReceiveProps(p,v),typeof c.UNSAFE_componentWillReceiveProps==\"function\"&&c.UNSAFE_componentWillReceiveProps(p,v),c.state!==a&&gf.enqueueReplaceState(c,c.state,null)}function Mm(a,c,p,v){var S=a.stateNode;S.props=p,S.state=a.memoizedState,S.refs={},gm(a);var E=c.contextType;typeof E==\"object\"&&E!==null?S.context=Yr(E):(E=br(c)?Ka:Zn.current,S.context=Xi(a,E)),S.state=a.memoizedState,E=c.getDerivedStateFromProps,typeof E==\"function\"&&(Nm(a,c,E,p),S.state=a.memoizedState),typeof c.getDerivedStateFromProps==\"function\"||typeof S.getSnapshotBeforeUpdate==\"function\"||typeof S.UNSAFE_componentWillMount!=\"function\"&&typeof S.componentWillMount!=\"function\"||(c=S.state,typeof S.componentWillMount==\"function\"&&S.componentWillMount(),typeof S.UNSAFE_componentWillMount==\"function\"&&S.UNSAFE_componentWillMount(),c!==S.state&&gf.enqueueReplaceState(S,S.state,null),lf(a,p,S,v),S.state=a.memoizedState),typeof S.componentDidMount==\"function\"&&(a.flags|=4194308)}function il(a,c){try{var p=\"\",v=c;do p+=de(v),v=v.return;while(v);var S=p}catch(E){S=`\nError generating stack: `+E.message+`\n`+E.stack}return{value:a,source:c,stack:S,digest:null}}function _m(a,c,p){return{value:a,source:null,stack:p??null,digest:c??null}}function Rm(a,c){try{console.error(c.value)}catch(p){setTimeout(function(){throw p})}}var tD=typeof WeakMap==\"function\"?WeakMap:Map;function HS(a,c,p){p=uo(-1,p),p.tag=3,p.payload={element:null};var v=c.value;return p.callback=function(){Sf||(Sf=!0,Km=v),Rm(a,c)},p}function qS(a,c,p){p=uo(-1,p),p.tag=3;var v=a.type.getDerivedStateFromError;if(typeof v==\"function\"){var S=c.value;p.payload=function(){return v(S)},p.callback=function(){Rm(a,c)}}var E=a.stateNode;return E!==null&&typeof E.componentDidCatch==\"function\"&&(p.callback=function(){Rm(a,c),typeof v!=\"function\"&&(ra===null?ra=new Set([this]):ra.add(this));var T=c.stack;this.componentDidCatch(c.value,{componentStack:T!==null?T:\"\"})}),p}function KS(a,c,p){var v=a.pingCache;if(v===null){v=a.pingCache=new tD;var S=new Set;v.set(c,S)}else S=v.get(c),S===void 0&&(S=new Set,v.set(c,S));S.has(p)||(S.add(p),a=gD.bind(null,a,c,p),c.then(a,a))}function WS(a){do{var c;if((c=a.tag===13)&&(c=a.memoizedState,c=c!==null?c.dehydrated!==null:!0),c)return a;a=a.return}while(a!==null);return null}function GS(a,c,p,v,S){return(a.mode&1)===0?(a===c?a.flags|=65536:(a.flags|=128,p.flags|=131072,p.flags&=-52805,p.tag===1&&(p.alternate===null?p.tag=17:(c=uo(-1,1),c.tag=2,ta(p,c,1))),p.lanes|=1),a):(a.flags|=65536,a.lanes=S,a)}var nD=_.ReactCurrentOwner,xr=!1;function ar(a,c,p,v){c.child=a===null?hS(c,null,p,v):rl(c,a.child,p,v)}function JS(a,c,p,v,S){p=p.render;var E=c.ref;return ol(c,S),v=Sm(a,c,p,v,E,S),p=Cm(),a!==null&&!xr?(c.updateQueue=a.updateQueue,c.flags&=-2053,a.lanes&=~S,fo(a,c,S)):(cn&&p&&om(c),c.flags|=1,ar(a,c,v,S),c.child)}function QS(a,c,p,v,S){if(a===null){var E=p.type;return typeof E==\"function\"&&!Xm(E)&&E.defaultProps===void 0&&p.compare===null&&p.defaultProps===void 0?(c.tag=15,c.type=E,ZS(a,c,E,v,S)):(a=Nf(p.type,null,v,c,c.mode,S),a.ref=c.ref,a.return=c,c.child=a)}if(E=a.child,(a.lanes&S)===0){var T=E.memoizedProps;if(p=p.compare,p=p!==null?p:Pc,p(T,v)&&a.ref===c.ref)return fo(a,c,S)}return c.flags|=1,a=ia(E,v),a.ref=c.ref,a.return=c,c.child=a}function ZS(a,c,p,v,S){if(a!==null){var E=a.memoizedProps;if(Pc(E,v)&&a.ref===c.ref)if(xr=!1,c.pendingProps=v=E,(a.lanes&S)!==0)(a.flags&131072)!==0&&(xr=!0);else return c.lanes=a.lanes,fo(a,c,S)}return Pm(a,c,p,v,S)}function YS(a,c,p){var v=c.pendingProps,S=v.children,E=a!==null?a.memoizedState:null;if(v.mode===\"hidden\")if((c.mode&1)===0)c.memoizedState={baseLanes:0,cachePool:null,transitions:null},Qt(cl,Dr),Dr|=p;else{if((p&1073741824)===0)return a=E!==null?E.baseLanes|p:p,c.lanes=c.childLanes=1073741824,c.memoizedState={baseLanes:a,cachePool:null,transitions:null},c.updateQueue=null,Qt(cl,Dr),Dr|=a,null;c.memoizedState={baseLanes:0,cachePool:null,transitions:null},v=E!==null?E.baseLanes:p,Qt(cl,Dr),Dr|=v}else E!==null?(v=E.baseLanes|p,c.memoizedState=null):v=p,Qt(cl,Dr),Dr|=v;return ar(a,c,S,p),c.child}function XS(a,c){var p=c.ref;(a===null&&p!==null||a!==null&&a.ref!==p)&&(c.flags|=512,c.flags|=2097152)}function Pm(a,c,p,v,S){var E=br(p)?Ka:Zn.current;return E=Xi(c,E),ol(c,S),p=Sm(a,c,p,v,E,S),v=Cm(),a!==null&&!xr?(c.updateQueue=a.updateQueue,c.flags&=-2053,a.lanes&=~S,fo(a,c,S)):(cn&&v&&om(c),c.flags|=1,ar(a,c,p,S),c.child)}function e0(a,c,p,v,S){if(br(p)){var E=!0;Yd(c)}else E=!1;if(ol(c,S),c.stateNode===null)vf(a,c),US(c,p,v),Mm(c,p,v,S),v=!0;else if(a===null){var T=c.stateNode,I=c.memoizedProps;T.props=I;var $=T.context,ae=p.contextType;typeof ae==\"object\"&&ae!==null?ae=Yr(ae):(ae=br(p)?Ka:Zn.current,ae=Xi(c,ae));var xe=p.getDerivedStateFromProps,we=typeof xe==\"function\"||typeof T.getSnapshotBeforeUpdate==\"function\";we||typeof T.UNSAFE_componentWillReceiveProps!=\"function\"&&typeof T.componentWillReceiveProps!=\"function\"||(I!==v||$!==ae)&&VS(c,T,v,ae),ea=!1;var be=c.memoizedState;T.state=be,lf(c,v,T,S),$=c.memoizedState,I!==v||be!==$||yr.current||ea?(typeof xe==\"function\"&&(Nm(c,p,xe,v),$=c.memoizedState),(I=ea||zS(c,p,I,v,be,$,ae))?(we||typeof T.UNSAFE_componentWillMount!=\"function\"&&typeof T.componentWillMount!=\"function\"||(typeof T.componentWillMount==\"function\"&&T.componentWillMount(),typeof T.UNSAFE_componentWillMount==\"function\"&&T.UNSAFE_componentWillMount()),typeof T.componentDidMount==\"function\"&&(c.flags|=4194308)):(typeof T.componentDidMount==\"function\"&&(c.flags|=4194308),c.memoizedProps=v,c.memoizedState=$),T.props=v,T.state=$,T.context=ae,v=I):(typeof T.componentDidMount==\"function\"&&(c.flags|=4194308),v=!1)}else{T=c.stateNode,mS(a,c),I=c.memoizedProps,ae=c.type===c.elementType?I:gs(c.type,I),T.props=ae,we=c.pendingProps,be=T.context,$=p.contextType,typeof $==\"object\"&&$!==null?$=Yr($):($=br(p)?Ka:Zn.current,$=Xi(c,$));var De=p.getDerivedStateFromProps;(xe=typeof De==\"function\"||typeof T.getSnapshotBeforeUpdate==\"function\")||typeof T.UNSAFE_componentWillReceiveProps!=\"function\"&&typeof T.componentWillReceiveProps!=\"function\"||(I!==we||be!==$)&&VS(c,T,v,$),ea=!1,be=c.memoizedState,T.state=be,lf(c,v,T,S);var He=c.memoizedState;I!==we||be!==He||yr.current||ea?(typeof De==\"function\"&&(Nm(c,p,De,v),He=c.memoizedState),(ae=ea||zS(c,p,ae,v,be,He,$)||!1)?(xe||typeof T.UNSAFE_componentWillUpdate!=\"function\"&&typeof T.componentWillUpdate!=\"function\"||(typeof T.componentWillUpdate==\"function\"&&T.componentWillUpdate(v,He,$),typeof T.UNSAFE_componentWillUpdate==\"function\"&&T.UNSAFE_componentWillUpdate(v,He,$)),typeof T.componentDidUpdate==\"function\"&&(c.flags|=4),typeof T.getSnapshotBeforeUpdate==\"function\"&&(c.flags|=1024)):(typeof T.componentDidUpdate!=\"function\"||I===a.memoizedProps&&be===a.memoizedState||(c.flags|=4),typeof T.getSnapshotBeforeUpdate!=\"function\"||I===a.memoizedProps&&be===a.memoizedState||(c.flags|=1024),c.memoizedProps=v,c.memoizedState=He),T.props=v,T.state=He,T.context=$,v=ae):(typeof T.componentDidUpdate!=\"function\"||I===a.memoizedProps&&be===a.memoizedState||(c.flags|=4),typeof T.getSnapshotBeforeUpdate!=\"function\"||I===a.memoizedProps&&be===a.memoizedState||(c.flags|=1024),v=!1)}return Om(a,c,p,v,E,S)}function Om(a,c,p,v,S,E){XS(a,c);var T=(c.flags&128)!==0;if(!v&&!T)return S&&oS(c,p,!1),fo(a,c,E);v=c.stateNode,nD.current=c;var I=T&&typeof p.getDerivedStateFromError!=\"function\"?null:v.render();return c.flags|=1,a!==null&&T?(c.child=rl(c,a.child,null,E),c.child=rl(c,null,I,E)):ar(a,c,I,E),c.memoizedState=v.state,S&&oS(c,p,!0),c.child}function t0(a){var c=a.stateNode;c.pendingContext?rS(a,c.pendingContext,c.pendingContext!==c.context):c.context&&rS(a,c.context,!1),mm(a,c.containerInfo)}function n0(a,c,p,v,S){return nl(),cm(S),c.flags|=256,ar(a,c,p,v),c.child}var Im={dehydrated:null,treeContext:null,retryLane:0};function Am(a){return{baseLanes:a,cachePool:null,transitions:null}}function r0(a,c,p){var v=c.pendingProps,S=pn.current,E=!1,T=(c.flags&128)!==0,I;if((I=T)||(I=a!==null&&a.memoizedState===null?!1:(S&2)!==0),I?(E=!0,c.flags&=-129):(a===null||a.memoizedState!==null)&&(S|=1),Qt(pn,S&1),a===null)return lm(c),a=c.memoizedState,a!==null&&(a=a.dehydrated,a!==null)?((c.mode&1)===0?c.lanes=1:a.data===\"$!\"?c.lanes=8:c.lanes=1073741824,null):(T=v.children,a=v.fallback,E?(v=c.mode,E=c.child,T={mode:\"hidden\",children:T},(v&1)===0&&E!==null?(E.childLanes=0,E.pendingProps=T):E=Mf(T,v,0,null),a=ni(a,v,p,null),E.return=c,a.return=c,E.sibling=a,c.child=E,c.child.memoizedState=Am(p),c.memoizedState=Im,a):Dm(c,T));if(S=a.memoizedState,S!==null&&(I=S.dehydrated,I!==null))return rD(a,c,T,v,I,S,p);if(E){E=v.fallback,T=c.mode,S=a.child,I=S.sibling;var $={mode:\"hidden\",children:v.children};return(T&1)===0&&c.child!==S?(v=c.child,v.childLanes=0,v.pendingProps=$,c.deletions=null):(v=ia(S,$),v.subtreeFlags=S.subtreeFlags&14680064),I!==null?E=ia(I,E):(E=ni(E,T,p,null),E.flags|=2),E.return=c,v.return=c,v.sibling=E,c.child=v,v=E,E=c.child,T=a.child.memoizedState,T=T===null?Am(p):{baseLanes:T.baseLanes|p,cachePool:null,transitions:T.transitions},E.memoizedState=T,E.childLanes=a.childLanes&~p,c.memoizedState=Im,v}return E=a.child,a=E.sibling,v=ia(E,{mode:\"visible\",children:v.children}),(c.mode&1)===0&&(v.lanes=p),v.return=c,v.sibling=null,a!==null&&(p=c.deletions,p===null?(c.deletions=[a],c.flags|=16):p.push(a)),c.child=v,c.memoizedState=null,v}function Dm(a,c){return c=Mf({mode:\"visible\",children:c},a.mode,0,null),c.return=a,a.child=c}function mf(a,c,p,v){return v!==null&&cm(v),rl(c,a.child,null,p),a=Dm(c,c.pendingProps.children),a.flags|=2,c.memoizedState=null,a}function rD(a,c,p,v,S,E,T){if(p)return c.flags&256?(c.flags&=-257,v=_m(Error(n(422))),mf(a,c,T,v)):c.memoizedState!==null?(c.child=a.child,c.flags|=128,null):(E=v.fallback,S=c.mode,v=Mf({mode:\"visible\",children:v.children},S,0,null),E=ni(E,S,T,null),E.flags|=2,v.return=c,E.return=c,v.sibling=E,c.child=v,(c.mode&1)!==0&&rl(c,a.child,null,T),c.child.memoizedState=Am(T),c.memoizedState=Im,E);if((c.mode&1)===0)return mf(a,c,T,null);if(S.data===\"$!\"){if(v=S.nextSibling&&S.nextSibling.dataset,v)var I=v.dgst;return v=I,E=Error(n(419)),v=_m(E,v,void 0),mf(a,c,T,v)}if(I=(T&a.childLanes)!==0,xr||I){if(v=Un,v!==null){switch(T&-T){case 4:S=2;break;case 16:S=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:S=32;break;case 536870912:S=268435456;break;default:S=0}S=(S&(v.suspendedLanes|T))!==0?0:S,S!==0&&S!==E.retryLane&&(E.retryLane=S,co(a,S),ys(v,a,S,-1))}return Ym(),v=_m(Error(n(421))),mf(a,c,T,v)}return S.data===\"$?\"?(c.flags|=128,c.child=a.child,c=mD.bind(null,a),S._reactRetry=c,null):(a=E.treeContext,Ar=Qo(S.nextSibling),Ir=c,cn=!0,hs=null,a!==null&&(Qr[Zr++]=io,Qr[Zr++]=lo,Qr[Zr++]=Wa,io=a.id,lo=a.overflow,Wa=c),c=Dm(c,v.children),c.flags|=4096,c)}function s0(a,c,p){a.lanes|=c;var v=a.alternate;v!==null&&(v.lanes|=c),pm(a.return,c,p)}function Fm(a,c,p,v,S){var E=a.memoizedState;E===null?a.memoizedState={isBackwards:c,rendering:null,renderingStartTime:0,last:v,tail:p,tailMode:S}:(E.isBackwards=c,E.rendering=null,E.renderingStartTime=0,E.last=v,E.tail=p,E.tailMode=S)}function o0(a,c,p){var v=c.pendingProps,S=v.revealOrder,E=v.tail;if(ar(a,c,v.children,p),v=pn.current,(v&2)!==0)v=v&1|2,c.flags|=128;else{if(a!==null&&(a.flags&128)!==0)e:for(a=c.child;a!==null;){if(a.tag===13)a.memoizedState!==null&&s0(a,p,c);else if(a.tag===19)s0(a,p,c);else if(a.child!==null){a.child.return=a,a=a.child;continue}if(a===c)break e;for(;a.sibling===null;){if(a.return===null||a.return===c)break e;a=a.return}a.sibling.return=a.return,a=a.sibling}v&=1}if(Qt(pn,v),(c.mode&1)===0)c.memoizedState=null;else switch(S){case\"forwards\":for(p=c.child,S=null;p!==null;)a=p.alternate,a!==null&&cf(a)===null&&(S=p),p=p.sibling;p=S,p===null?(S=c.child,c.child=null):(S=p.sibling,p.sibling=null),Fm(c,!1,S,p,E);break;case\"backwards\":for(p=null,S=c.child,c.child=null;S!==null;){if(a=S.alternate,a!==null&&cf(a)===null){c.child=S;break}a=S.sibling,S.sibling=p,p=S,S=a}Fm(c,!0,p,null,E);break;case\"together\":Fm(c,!1,null,null,void 0);break;default:c.memoizedState=null}return c.child}function vf(a,c){(c.mode&1)===0&&a!==null&&(a.alternate=null,c.alternate=null,c.flags|=2)}function fo(a,c,p){if(a!==null&&(c.dependencies=a.dependencies),Ya|=c.lanes,(p&c.childLanes)===0)return null;if(a!==null&&c.child!==a.child)throw Error(n(153));if(c.child!==null){for(a=c.child,p=ia(a,a.pendingProps),c.child=p,p.return=c;a.sibling!==null;)a=a.sibling,p=p.sibling=ia(a,a.pendingProps),p.return=c;p.sibling=null}return c.child}function sD(a,c,p){switch(c.tag){case 3:t0(c),nl();break;case 5:bS(c);break;case 1:br(c.type)&&Yd(c);break;case 4:mm(c,c.stateNode.containerInfo);break;case 10:var v=c.type._context,S=c.memoizedProps.value;Qt(sf,v._currentValue),v._currentValue=S;break;case 13:if(v=c.memoizedState,v!==null)return v.dehydrated!==null?(Qt(pn,pn.current&1),c.flags|=128,null):(p&c.child.childLanes)!==0?r0(a,c,p):(Qt(pn,pn.current&1),a=fo(a,c,p),a!==null?a.sibling:null);Qt(pn,pn.current&1);break;case 19:if(v=(p&c.childLanes)!==0,(a.flags&128)!==0){if(v)return o0(a,c,p);c.flags|=128}if(S=c.memoizedState,S!==null&&(S.rendering=null,S.tail=null,S.lastEffect=null),Qt(pn,pn.current),v)break;return null;case 22:case 23:return c.lanes=0,YS(a,c,p)}return fo(a,c,p)}var a0,Lm,i0,l0;a0=function(a,c){for(var p=c.child;p!==null;){if(p.tag===5||p.tag===6)a.appendChild(p.stateNode);else if(p.tag!==4&&p.child!==null){p.child.return=p,p=p.child;continue}if(p===c)break;for(;p.sibling===null;){if(p.return===null||p.return===c)return;p=p.return}p.sibling.return=p.return,p=p.sibling}},Lm=function(){},i0=function(a,c,p,v){var S=a.memoizedProps;if(S!==v){a=c.stateNode,Qa(Ds.current);var E=null;switch(p){case\"input\":S=ln(a,S),v=ln(a,v),E=[];break;case\"select\":S=he({},S,{value:void 0}),v=he({},v,{value:void 0}),E=[];break;case\"textarea\":S=je(a,S),v=je(a,v),E=[];break;default:typeof S.onClick!=\"function\"&&typeof v.onClick==\"function\"&&(a.onclick=Jd)}It(p,v);var T;p=null;for(ae in S)if(!v.hasOwnProperty(ae)&&S.hasOwnProperty(ae)&&S[ae]!=null)if(ae===\"style\"){var I=S[ae];for(T in I)I.hasOwnProperty(T)&&(p||(p={}),p[T]=\"\")}else ae!==\"dangerouslySetInnerHTML\"&&ae!==\"children\"&&ae!==\"suppressContentEditableWarning\"&&ae!==\"suppressHydrationWarning\"&&ae!==\"autoFocus\"&&(s.hasOwnProperty(ae)?E||(E=[]):(E=E||[]).push(ae,null));for(ae in v){var $=v[ae];if(I=S?.[ae],v.hasOwnProperty(ae)&&$!==I&&($!=null||I!=null))if(ae===\"style\")if(I){for(T in I)!I.hasOwnProperty(T)||$&&$.hasOwnProperty(T)||(p||(p={}),p[T]=\"\");for(T in $)$.hasOwnProperty(T)&&I[T]!==$[T]&&(p||(p={}),p[T]=$[T])}else p||(E||(E=[]),E.push(ae,p)),p=$;else ae===\"dangerouslySetInnerHTML\"?($=$?$.__html:void 0,I=I?I.__html:void 0,$!=null&&I!==$&&(E=E||[]).push(ae,$)):ae===\"children\"?typeof $!=\"string\"&&typeof $!=\"number\"||(E=E||[]).push(ae,\"\"+$):ae!==\"suppressContentEditableWarning\"&&ae!==\"suppressHydrationWarning\"&&(s.hasOwnProperty(ae)?($!=null&&ae===\"onScroll\"&&Xt(\"scroll\",a),E||I===$||(E=[])):(E=E||[]).push(ae,$))}p&&(E=E||[]).push(\"style\",p);var ae=E;(c.updateQueue=ae)&&(c.flags|=4)}},l0=function(a,c,p,v){p!==v&&(c.flags|=4)};function Wc(a,c){if(!cn)switch(a.tailMode){case\"hidden\":c=a.tail;for(var p=null;c!==null;)c.alternate!==null&&(p=c),c=c.sibling;p===null?a.tail=null:p.sibling=null;break;case\"collapsed\":p=a.tail;for(var v=null;p!==null;)p.alternate!==null&&(v=p),p=p.sibling;v===null?c||a.tail===null?a.tail=null:a.tail.sibling=null:v.sibling=null}}function Xn(a){var c=a.alternate!==null&&a.alternate.child===a.child,p=0,v=0;if(c)for(var S=a.child;S!==null;)p|=S.lanes|S.childLanes,v|=S.subtreeFlags&14680064,v|=S.flags&14680064,S.return=a,S=S.sibling;else for(S=a.child;S!==null;)p|=S.lanes|S.childLanes,v|=S.subtreeFlags,v|=S.flags,S.return=a,S=S.sibling;return a.subtreeFlags|=v,a.childLanes=p,c}function oD(a,c,p){var v=c.pendingProps;switch(am(c),c.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Xn(c),null;case 1:return br(c.type)&&Zd(),Xn(c),null;case 3:return v=c.stateNode,al(),en(yr),en(Zn),bm(),v.pendingContext&&(v.context=v.pendingContext,v.pendingContext=null),(a===null||a.child===null)&&(nf(c)?c.flags|=4:a===null||a.memoizedState.isDehydrated&&(c.flags&256)===0||(c.flags|=1024,hs!==null&&(Jm(hs),hs=null))),Lm(a,c),Xn(c),null;case 5:vm(c);var S=Qa(Uc.current);if(p=c.type,a!==null&&c.stateNode!=null)i0(a,c,p,v,S),a.ref!==c.ref&&(c.flags|=512,c.flags|=2097152);else{if(!v){if(c.stateNode===null)throw Error(n(166));return Xn(c),null}if(a=Qa(Ds.current),nf(c)){v=c.stateNode,p=c.type;var E=c.memoizedProps;switch(v[As]=c,v[Fc]=E,a=(c.mode&1)!==0,p){case\"dialog\":Xt(\"cancel\",v),Xt(\"close\",v);break;case\"iframe\":case\"object\":case\"embed\":Xt(\"load\",v);break;case\"video\":case\"audio\":for(S=0;S<Ic.length;S++)Xt(Ic[S],v);break;case\"source\":Xt(\"error\",v);break;case\"img\":case\"image\":case\"link\":Xt(\"error\",v),Xt(\"load\",v);break;case\"details\":Xt(\"toggle\",v);break;case\"input\":Sn(v,E),Xt(\"invalid\",v);break;case\"select\":v._wrapperState={wasMultiple:!!E.multiple},Xt(\"invalid\",v);break;case\"textarea\":Se(v,E),Xt(\"invalid\",v)}It(p,E),S=null;for(var T in E)if(E.hasOwnProperty(T)){var I=E[T];T===\"children\"?typeof I==\"string\"?v.textContent!==I&&(E.suppressHydrationWarning!==!0&&Gd(v.textContent,I,a),S=[\"children\",I]):typeof I==\"number\"&&v.textContent!==\"\"+I&&(E.suppressHydrationWarning!==!0&&Gd(v.textContent,I,a),S=[\"children\",\"\"+I]):s.hasOwnProperty(T)&&I!=null&&T===\"onScroll\"&&Xt(\"scroll\",v)}switch(p){case\"input\":Ye(v),L(v,E,!0);break;case\"textarea\":Ye(v),bt(v);break;case\"select\":case\"option\":break;default:typeof E.onClick==\"function\"&&(v.onclick=Jd)}v=S,c.updateQueue=v,v!==null&&(c.flags|=4)}else{T=S.nodeType===9?S:S.ownerDocument,a===\"http://www.w3.org/1999/xhtml\"&&(a=Wt(p)),a===\"http://www.w3.org/1999/xhtml\"?p===\"script\"?(a=T.createElement(\"div\"),a.innerHTML=\"<script><\\/script>\",a=a.removeChild(a.firstChild)):typeof v.is==\"string\"?a=T.createElement(p,{is:v.is}):(a=T.createElement(p),p===\"select\"&&(T=a,v.multiple?T.multiple=!0:v.size&&(T.size=v.size))):a=T.createElementNS(a,p),a[As]=c,a[Fc]=v,a0(a,c,!1,!1),c.stateNode=a;e:{switch(T=Tn(p,v),p){case\"dialog\":Xt(\"cancel\",a),Xt(\"close\",a),S=v;break;case\"iframe\":case\"object\":case\"embed\":Xt(\"load\",a),S=v;break;case\"video\":case\"audio\":for(S=0;S<Ic.length;S++)Xt(Ic[S],a);S=v;break;case\"source\":Xt(\"error\",a),S=v;break;case\"img\":case\"image\":case\"link\":Xt(\"error\",a),Xt(\"load\",a),S=v;break;case\"details\":Xt(\"toggle\",a),S=v;break;case\"input\":Sn(a,v),S=ln(a,v),Xt(\"invalid\",a);break;case\"option\":S=v;break;case\"select\":a._wrapperState={wasMultiple:!!v.multiple},S=he({},v,{value:void 0}),Xt(\"invalid\",a);break;case\"textarea\":Se(a,v),S=je(a,v),Xt(\"invalid\",a);break;default:S=v}It(p,S),I=S;for(E in I)if(I.hasOwnProperty(E)){var $=I[E];E===\"style\"?Te(a,$):E===\"dangerouslySetInnerHTML\"?($=$?$.__html:void 0,$!=null&&En(a,$)):E===\"children\"?typeof $==\"string\"?(p!==\"textarea\"||$!==\"\")&&gr(a,$):typeof $==\"number\"&&gr(a,\"\"+$):E!==\"suppressContentEditableWarning\"&&E!==\"suppressHydrationWarning\"&&E!==\"autoFocus\"&&(s.hasOwnProperty(E)?$!=null&&E===\"onScroll\"&&Xt(\"scroll\",a):$!=null&&M(a,E,$,T))}switch(p){case\"input\":Ye(a),L(a,v,!1);break;case\"textarea\":Ye(a),bt(a);break;case\"option\":v.value!=null&&a.setAttribute(\"value\",\"\"+ye(v.value));break;case\"select\":a.multiple=!!v.multiple,E=v.value,E!=null?Ne(a,!!v.multiple,E,!1):v.defaultValue!=null&&Ne(a,!!v.multiple,v.defaultValue,!0);break;default:typeof S.onClick==\"function\"&&(a.onclick=Jd)}switch(p){case\"button\":case\"input\":case\"select\":case\"textarea\":v=!!v.autoFocus;break e;case\"img\":v=!0;break e;default:v=!1}}v&&(c.flags|=4)}c.ref!==null&&(c.flags|=512,c.flags|=2097152)}return Xn(c),null;case 6:if(a&&c.stateNode!=null)l0(a,c,a.memoizedProps,v);else{if(typeof v!=\"string\"&&c.stateNode===null)throw Error(n(166));if(p=Qa(Uc.current),Qa(Ds.current),nf(c)){if(v=c.stateNode,p=c.memoizedProps,v[As]=c,(E=v.nodeValue!==p)&&(a=Ir,a!==null))switch(a.tag){case 3:Gd(v.nodeValue,p,(a.mode&1)!==0);break;case 5:a.memoizedProps.suppressHydrationWarning!==!0&&Gd(v.nodeValue,p,(a.mode&1)!==0)}E&&(c.flags|=4)}else v=(p.nodeType===9?p:p.ownerDocument).createTextNode(v),v[As]=c,c.stateNode=v}return Xn(c),null;case 13:if(en(pn),v=c.memoizedState,a===null||a.memoizedState!==null&&a.memoizedState.dehydrated!==null){if(cn&&Ar!==null&&(c.mode&1)!==0&&(c.flags&128)===0)dS(),nl(),c.flags|=98560,E=!1;else if(E=nf(c),v!==null&&v.dehydrated!==null){if(a===null){if(!E)throw Error(n(318));if(E=c.memoizedState,E=E!==null?E.dehydrated:null,!E)throw Error(n(317));E[As]=c}else nl(),(c.flags&128)===0&&(c.memoizedState=null),c.flags|=4;Xn(c),E=!1}else hs!==null&&(Jm(hs),hs=null),E=!0;if(!E)return c.flags&65536?c:null}return(c.flags&128)!==0?(c.lanes=p,c):(v=v!==null,v!==(a!==null&&a.memoizedState!==null)&&v&&(c.child.flags|=8192,(c.mode&1)!==0&&(a===null||(pn.current&1)!==0?An===0&&(An=3):Ym())),c.updateQueue!==null&&(c.flags|=4),Xn(c),null);case 4:return al(),Lm(a,c),a===null&&Ac(c.stateNode.containerInfo),Xn(c),null;case 10:return fm(c.type._context),Xn(c),null;case 17:return br(c.type)&&Zd(),Xn(c),null;case 19:if(en(pn),E=c.memoizedState,E===null)return Xn(c),null;if(v=(c.flags&128)!==0,T=E.rendering,T===null)if(v)Wc(E,!1);else{if(An!==0||a!==null&&(a.flags&128)!==0)for(a=c.child;a!==null;){if(T=cf(a),T!==null){for(c.flags|=128,Wc(E,!1),v=T.updateQueue,v!==null&&(c.updateQueue=v,c.flags|=4),c.subtreeFlags=0,v=p,p=c.child;p!==null;)E=p,a=v,E.flags&=14680066,T=E.alternate,T===null?(E.childLanes=0,E.lanes=a,E.child=null,E.subtreeFlags=0,E.memoizedProps=null,E.memoizedState=null,E.updateQueue=null,E.dependencies=null,E.stateNode=null):(E.childLanes=T.childLanes,E.lanes=T.lanes,E.child=T.child,E.subtreeFlags=0,E.deletions=null,E.memoizedProps=T.memoizedProps,E.memoizedState=T.memoizedState,E.updateQueue=T.updateQueue,E.type=T.type,a=T.dependencies,E.dependencies=a===null?null:{lanes:a.lanes,firstContext:a.firstContext}),p=p.sibling;return Qt(pn,pn.current&1|2),c.child}a=a.sibling}E.tail!==null&&Gt()>ul&&(c.flags|=128,v=!0,Wc(E,!1),c.lanes=4194304)}else{if(!v)if(a=cf(T),a!==null){if(c.flags|=128,v=!0,p=a.updateQueue,p!==null&&(c.updateQueue=p,c.flags|=4),Wc(E,!0),E.tail===null&&E.tailMode===\"hidden\"&&!T.alternate&&!cn)return Xn(c),null}else 2*Gt()-E.renderingStartTime>ul&&p!==1073741824&&(c.flags|=128,v=!0,Wc(E,!1),c.lanes=4194304);E.isBackwards?(T.sibling=c.child,c.child=T):(p=E.last,p!==null?p.sibling=T:c.child=T,E.last=T)}return E.tail!==null?(c=E.tail,E.rendering=c,E.tail=c.sibling,E.renderingStartTime=Gt(),c.sibling=null,p=pn.current,Qt(pn,v?p&1|2:p&1),c):(Xn(c),null);case 22:case 23:return Zm(),v=c.memoizedState!==null,a!==null&&a.memoizedState!==null!==v&&(c.flags|=8192),v&&(c.mode&1)!==0?(Dr&1073741824)!==0&&(Xn(c),c.subtreeFlags&6&&(c.flags|=8192)):Xn(c),null;case 24:return null;case 25:return null}throw Error(n(156,c.tag))}function aD(a,c){switch(am(c),c.tag){case 1:return br(c.type)&&Zd(),a=c.flags,a&65536?(c.flags=a&-65537|128,c):null;case 3:return al(),en(yr),en(Zn),bm(),a=c.flags,(a&65536)!==0&&(a&128)===0?(c.flags=a&-65537|128,c):null;case 5:return vm(c),null;case 13:if(en(pn),a=c.memoizedState,a!==null&&a.dehydrated!==null){if(c.alternate===null)throw Error(n(340));nl()}return a=c.flags,a&65536?(c.flags=a&-65537|128,c):null;case 19:return en(pn),null;case 4:return al(),null;case 10:return fm(c.type._context),null;case 22:case 23:return Zm(),null;case 24:return null;default:return null}}var yf=!1,er=!1,iD=typeof WeakSet==\"function\"?WeakSet:Set,ze=null;function ll(a,c){var p=a.ref;if(p!==null)if(typeof p==\"function\")try{p(null)}catch(v){xn(a,c,v)}else p.current=null}function $m(a,c,p){try{p()}catch(v){xn(a,c,v)}}var c0=!1;function lD(a,c){if(Zg=Fd,a=zw(),Vg(a)){if(\"selectionStart\"in a)var p={start:a.selectionStart,end:a.selectionEnd};else e:{p=(p=a.ownerDocument)&&p.defaultView||window;var v=p.getSelection&&p.getSelection();if(v&&v.rangeCount!==0){p=v.anchorNode;var S=v.anchorOffset,E=v.focusNode;v=v.focusOffset;try{p.nodeType,E.nodeType}catch{p=null;break e}var T=0,I=-1,$=-1,ae=0,xe=0,we=a,be=null;t:for(;;){for(var De;we!==p||S!==0&&we.nodeType!==3||(I=T+S),we!==E||v!==0&&we.nodeType!==3||($=T+v),we.nodeType===3&&(T+=we.nodeValue.length),(De=we.firstChild)!==null;)be=we,we=De;for(;;){if(we===a)break t;if(be===p&&++ae===S&&(I=T),be===E&&++xe===v&&($=T),(De=we.nextSibling)!==null)break;we=be,be=we.parentNode}we=De}p=I===-1||$===-1?null:{start:I,end:$}}else p=null}p=p||{start:0,end:0}}else p=null;for(Yg={focusedElem:a,selectionRange:p},Fd=!1,ze=c;ze!==null;)if(c=ze,a=c.child,(c.subtreeFlags&1028)!==0&&a!==null)a.return=c,ze=a;else for(;ze!==null;){c=ze;try{var He=c.alternate;if((c.flags&1024)!==0)switch(c.tag){case 0:case 11:case 15:break;case 1:if(He!==null){var Ke=He.memoizedProps,kn=He.memoizedState,J=c.stateNode,U=J.getSnapshotBeforeUpdate(c.elementType===c.type?Ke:gs(c.type,Ke),kn);J.__reactInternalSnapshotBeforeUpdate=U}break;case 3:var ee=c.stateNode.containerInfo;ee.nodeType===1?ee.textContent=\"\":ee.nodeType===9&&ee.documentElement&&ee.removeChild(ee.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(n(163))}}catch(ke){xn(c,c.return,ke)}if(a=c.sibling,a!==null){a.return=c.return,ze=a;break}ze=c.return}return He=c0,c0=!1,He}function Gc(a,c,p){var v=c.updateQueue;if(v=v!==null?v.lastEffect:null,v!==null){var S=v=v.next;do{if((S.tag&a)===a){var E=S.destroy;S.destroy=void 0,E!==void 0&&$m(c,p,E)}S=S.next}while(S!==v)}}function bf(a,c){if(c=c.updateQueue,c=c!==null?c.lastEffect:null,c!==null){var p=c=c.next;do{if((p.tag&a)===a){var v=p.create;p.destroy=v()}p=p.next}while(p!==c)}}function Bm(a){var c=a.ref;if(c!==null){var p=a.stateNode;switch(a.tag){case 5:a=p;break;default:a=p}typeof c==\"function\"?c(a):c.current=a}}function u0(a){var c=a.alternate;c!==null&&(a.alternate=null,u0(c)),a.child=null,a.deletions=null,a.sibling=null,a.tag===5&&(c=a.stateNode,c!==null&&(delete c[As],delete c[Fc],delete c[nm],delete c[HA],delete c[qA])),a.stateNode=null,a.return=null,a.dependencies=null,a.memoizedProps=null,a.memoizedState=null,a.pendingProps=null,a.stateNode=null,a.updateQueue=null}function d0(a){return a.tag===5||a.tag===3||a.tag===4}function f0(a){e:for(;;){for(;a.sibling===null;){if(a.return===null||d0(a.return))return null;a=a.return}for(a.sibling.return=a.return,a=a.sibling;a.tag!==5&&a.tag!==6&&a.tag!==18;){if(a.flags&2||a.child===null||a.tag===4)continue e;a.child.return=a,a=a.child}if(!(a.flags&2))return a.stateNode}}function zm(a,c,p){var v=a.tag;if(v===5||v===6)a=a.stateNode,c?p.nodeType===8?p.parentNode.insertBefore(a,c):p.insertBefore(a,c):(p.nodeType===8?(c=p.parentNode,c.insertBefore(a,p)):(c=p,c.appendChild(a)),p=p._reactRootContainer,p!=null||c.onclick!==null||(c.onclick=Jd));else if(v!==4&&(a=a.child,a!==null))for(zm(a,c,p),a=a.sibling;a!==null;)zm(a,c,p),a=a.sibling}function Um(a,c,p){var v=a.tag;if(v===5||v===6)a=a.stateNode,c?p.insertBefore(a,c):p.appendChild(a);else if(v!==4&&(a=a.child,a!==null))for(Um(a,c,p),a=a.sibling;a!==null;)Um(a,c,p),a=a.sibling}var qn=null,ms=!1;function na(a,c,p){for(p=p.child;p!==null;)p0(a,c,p),p=p.sibling}function p0(a,c,p){if(Dt&&typeof Dt.onCommitFiberUnmount==\"function\")try{Dt.onCommitFiberUnmount(pt,p)}catch{}switch(p.tag){case 5:er||ll(p,c);case 6:var v=qn,S=ms;qn=null,na(a,c,p),qn=v,ms=S,qn!==null&&(ms?(a=qn,p=p.stateNode,a.nodeType===8?a.parentNode.removeChild(p):a.removeChild(p)):qn.removeChild(p.stateNode));break;case 18:qn!==null&&(ms?(a=qn,p=p.stateNode,a.nodeType===8?tm(a.parentNode,p):a.nodeType===1&&tm(a,p),jc(a)):tm(qn,p.stateNode));break;case 4:v=qn,S=ms,qn=p.stateNode.containerInfo,ms=!0,na(a,c,p),qn=v,ms=S;break;case 0:case 11:case 14:case 15:if(!er&&(v=p.updateQueue,v!==null&&(v=v.lastEffect,v!==null))){S=v=v.next;do{var E=S,T=E.destroy;E=E.tag,T!==void 0&&((E&2)!==0||(E&4)!==0)&&$m(p,c,T),S=S.next}while(S!==v)}na(a,c,p);break;case 1:if(!er&&(ll(p,c),v=p.stateNode,typeof v.componentWillUnmount==\"function\"))try{v.props=p.memoizedProps,v.state=p.memoizedState,v.componentWillUnmount()}catch(I){xn(p,c,I)}na(a,c,p);break;case 21:na(a,c,p);break;case 22:p.mode&1?(er=(v=er)||p.memoizedState!==null,na(a,c,p),er=v):na(a,c,p);break;default:na(a,c,p)}}function h0(a){var c=a.updateQueue;if(c!==null){a.updateQueue=null;var p=a.stateNode;p===null&&(p=a.stateNode=new iD),c.forEach(function(v){var S=vD.bind(null,a,v);p.has(v)||(p.add(v),v.then(S,S))})}}function vs(a,c){var p=c.deletions;if(p!==null)for(var v=0;v<p.length;v++){var S=p[v];try{var E=a,T=c,I=T;e:for(;I!==null;){switch(I.tag){case 5:qn=I.stateNode,ms=!1;break e;case 3:qn=I.stateNode.containerInfo,ms=!0;break e;case 4:qn=I.stateNode.containerInfo,ms=!0;break e}I=I.return}if(qn===null)throw Error(n(160));p0(E,T,S),qn=null,ms=!1;var $=S.alternate;$!==null&&($.return=null),S.return=null}catch(ae){xn(S,c,ae)}}if(c.subtreeFlags&12854)for(c=c.child;c!==null;)g0(c,a),c=c.sibling}function g0(a,c){var p=a.alternate,v=a.flags;switch(a.tag){case 0:case 11:case 14:case 15:if(vs(c,a),Ls(a),v&4){try{Gc(3,a,a.return),bf(3,a)}catch(Ke){xn(a,a.return,Ke)}try{Gc(5,a,a.return)}catch(Ke){xn(a,a.return,Ke)}}break;case 1:vs(c,a),Ls(a),v&512&&p!==null&&ll(p,p.return);break;case 5:if(vs(c,a),Ls(a),v&512&&p!==null&&ll(p,p.return),a.flags&32){var S=a.stateNode;try{gr(S,\"\")}catch(Ke){xn(a,a.return,Ke)}}if(v&4&&(S=a.stateNode,S!=null)){var E=a.memoizedProps,T=p!==null?p.memoizedProps:E,I=a.type,$=a.updateQueue;if(a.updateQueue=null,$!==null)try{I===\"input\"&&E.type===\"radio\"&&E.name!=null&&vn(S,E),Tn(I,T);var ae=Tn(I,E);for(T=0;T<$.length;T+=2){var xe=$[T],we=$[T+1];xe===\"style\"?Te(S,we):xe===\"dangerouslySetInnerHTML\"?En(S,we):xe===\"children\"?gr(S,we):M(S,xe,we,ae)}switch(I){case\"input\":Cn(S,E);break;case\"textarea\":Be(S,E);break;case\"select\":var be=S._wrapperState.wasMultiple;S._wrapperState.wasMultiple=!!E.multiple;var De=E.value;De!=null?Ne(S,!!E.multiple,De,!1):be!==!!E.multiple&&(E.defaultValue!=null?Ne(S,!!E.multiple,E.defaultValue,!0):Ne(S,!!E.multiple,E.multiple?[]:\"\",!1))}S[Fc]=E}catch(Ke){xn(a,a.return,Ke)}}break;case 6:if(vs(c,a),Ls(a),v&4){if(a.stateNode===null)throw Error(n(162));S=a.stateNode,E=a.memoizedProps;try{S.nodeValue=E}catch(Ke){xn(a,a.return,Ke)}}break;case 3:if(vs(c,a),Ls(a),v&4&&p!==null&&p.memoizedState.isDehydrated)try{jc(c.containerInfo)}catch(Ke){xn(a,a.return,Ke)}break;case 4:vs(c,a),Ls(a);break;case 13:vs(c,a),Ls(a),S=a.child,S.flags&8192&&(E=S.memoizedState!==null,S.stateNode.isHidden=E,!E||S.alternate!==null&&S.alternate.memoizedState!==null||(qm=Gt())),v&4&&h0(a);break;case 22:if(xe=p!==null&&p.memoizedState!==null,a.mode&1?(er=(ae=er)||xe,vs(c,a),er=ae):vs(c,a),Ls(a),v&8192){if(ae=a.memoizedState!==null,(a.stateNode.isHidden=ae)&&!xe&&(a.mode&1)!==0)for(ze=a,xe=a.child;xe!==null;){for(we=ze=xe;ze!==null;){switch(be=ze,De=be.child,be.tag){case 0:case 11:case 14:case 15:Gc(4,be,be.return);break;case 1:ll(be,be.return);var He=be.stateNode;if(typeof He.componentWillUnmount==\"function\"){v=be,p=be.return;try{c=v,He.props=c.memoizedProps,He.state=c.memoizedState,He.componentWillUnmount()}catch(Ke){xn(v,p,Ke)}}break;case 5:ll(be,be.return);break;case 22:if(be.memoizedState!==null){y0(we);continue}}De!==null?(De.return=be,ze=De):y0(we)}xe=xe.sibling}e:for(xe=null,we=a;;){if(we.tag===5){if(xe===null){xe=we;try{S=we.stateNode,ae?(E=S.style,typeof E.setProperty==\"function\"?E.setProperty(\"display\",\"none\",\"important\"):E.display=\"none\"):(I=we.stateNode,$=we.memoizedProps.style,T=$!=null&&$.hasOwnProperty(\"display\")?$.display:null,I.style.display=Bn(\"display\",T))}catch(Ke){xn(a,a.return,Ke)}}}else if(we.tag===6){if(xe===null)try{we.stateNode.nodeValue=ae?\"\":we.memoizedProps}catch(Ke){xn(a,a.return,Ke)}}else if((we.tag!==22&&we.tag!==23||we.memoizedState===null||we===a)&&we.child!==null){we.child.return=we,we=we.child;continue}if(we===a)break e;for(;we.sibling===null;){if(we.return===null||we.return===a)break e;xe===we&&(xe=null),we=we.return}xe===we&&(xe=null),we.sibling.return=we.return,we=we.sibling}}break;case 19:vs(c,a),Ls(a),v&4&&h0(a);break;case 21:break;default:vs(c,a),Ls(a)}}function Ls(a){var c=a.flags;if(c&2){try{e:{for(var p=a.return;p!==null;){if(d0(p)){var v=p;break e}p=p.return}throw Error(n(160))}switch(v.tag){case 5:var S=v.stateNode;v.flags&32&&(gr(S,\"\"),v.flags&=-33);var E=f0(a);Um(a,E,S);break;case 3:case 4:var T=v.stateNode.containerInfo,I=f0(a);zm(a,I,T);break;default:throw Error(n(161))}}catch($){xn(a,a.return,$)}a.flags&=-3}c&4096&&(a.flags&=-4097)}function cD(a,c,p){ze=a,m0(a)}function m0(a,c,p){for(var v=(a.mode&1)!==0;ze!==null;){var S=ze,E=S.child;if(S.tag===22&&v){var T=S.memoizedState!==null||yf;if(!T){var I=S.alternate,$=I!==null&&I.memoizedState!==null||er;I=yf;var ae=er;if(yf=T,(er=$)&&!ae)for(ze=S;ze!==null;)T=ze,$=T.child,T.tag===22&&T.memoizedState!==null?b0(S):$!==null?($.return=T,ze=$):b0(S);for(;E!==null;)ze=E,m0(E),E=E.sibling;ze=S,yf=I,er=ae}v0(a)}else(S.subtreeFlags&8772)!==0&&E!==null?(E.return=S,ze=E):v0(a)}}function v0(a){for(;ze!==null;){var c=ze;if((c.flags&8772)!==0){var p=c.alternate;try{if((c.flags&8772)!==0)switch(c.tag){case 0:case 11:case 15:er||bf(5,c);break;case 1:var v=c.stateNode;if(c.flags&4&&!er)if(p===null)v.componentDidMount();else{var S=c.elementType===c.type?p.memoizedProps:gs(c.type,p.memoizedProps);v.componentDidUpdate(S,p.memoizedState,v.__reactInternalSnapshotBeforeUpdate)}var E=c.updateQueue;E!==null&&yS(c,E,v);break;case 3:var T=c.updateQueue;if(T!==null){if(p=null,c.child!==null)switch(c.child.tag){case 5:p=c.child.stateNode;break;case 1:p=c.child.stateNode}yS(c,T,p)}break;case 5:var I=c.stateNode;if(p===null&&c.flags&4){p=I;var $=c.memoizedProps;switch(c.type){case\"button\":case\"input\":case\"select\":case\"textarea\":$.autoFocus&&p.focus();break;case\"img\":$.src&&(p.src=$.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(c.memoizedState===null){var ae=c.alternate;if(ae!==null){var xe=ae.memoizedState;if(xe!==null){var we=xe.dehydrated;we!==null&&jc(we)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(n(163))}er||c.flags&512&&Bm(c)}catch(be){xn(c,c.return,be)}}if(c===a){ze=null;break}if(p=c.sibling,p!==null){p.return=c.return,ze=p;break}ze=c.return}}function y0(a){for(;ze!==null;){var c=ze;if(c===a){ze=null;break}var p=c.sibling;if(p!==null){p.return=c.return,ze=p;break}ze=c.return}}function b0(a){for(;ze!==null;){var c=ze;try{switch(c.tag){case 0:case 11:case 15:var p=c.return;try{bf(4,c)}catch($){xn(c,p,$)}break;case 1:var v=c.stateNode;if(typeof v.componentDidMount==\"function\"){var S=c.return;try{v.componentDidMount()}catch($){xn(c,S,$)}}var E=c.return;try{Bm(c)}catch($){xn(c,E,$)}break;case 5:var T=c.return;try{Bm(c)}catch($){xn(c,T,$)}}}catch($){xn(c,c.return,$)}if(c===a){ze=null;break}var I=c.sibling;if(I!==null){I.return=c.return,ze=I;break}ze=c.return}}var uD=Math.ceil,xf=_.ReactCurrentDispatcher,Vm=_.ReactCurrentOwner,es=_.ReactCurrentBatchConfig,Ft=0,Un=null,Mn=null,Kn=0,Dr=0,cl=Zo(0),An=0,Jc=null,Ya=0,wf=0,Hm=0,Qc=null,wr=null,qm=0,ul=1/0,po=null,Sf=!1,Km=null,ra=null,Cf=!1,sa=null,Ef=0,Zc=0,Wm=null,kf=-1,jf=0;function ir(){return(Ft&6)!==0?Gt():kf!==-1?kf:kf=Gt()}function oa(a){return(a.mode&1)===0?1:(Ft&2)!==0&&Kn!==0?Kn&-Kn:WA.transition!==null?(jf===0&&(jf=fw()),jf):(a=Kt,a!==0||(a=window.event,a=a===void 0?16:ww(a.type)),a)}function ys(a,c,p,v){if(50<Zc)throw Zc=0,Wm=null,Error(n(185));wc(a,p,v),((Ft&2)===0||a!==Un)&&(a===Un&&((Ft&2)===0&&(wf|=p),An===4&&aa(a,Kn)),Sr(a,v),p===1&&Ft===0&&(c.mode&1)===0&&(ul=Gt()+500,Xd&&Xo()))}function Sr(a,c){var p=a.callbackNode;WI(a,c);var v=Id(a,a===Un?Kn:0);if(v===0)p!==null&&fn(p),a.callbackNode=null,a.callbackPriority=0;else if(c=v&-v,a.callbackPriority!==c){if(p!=null&&fn(p),c===1)a.tag===0?KA(w0.bind(null,a)):aS(w0.bind(null,a)),UA(function(){(Ft&6)===0&&Xo()}),p=null;else{switch(pw(v)){case 1:p=Is;break;case 4:p=Pr;break;case 16:p=so;break;case 536870912:p=Ha;break;default:p=so}p=M0(p,x0.bind(null,a))}a.callbackPriority=c,a.callbackNode=p}}function x0(a,c){if(kf=-1,jf=0,(Ft&6)!==0)throw Error(n(327));var p=a.callbackNode;if(dl()&&a.callbackNode!==p)return null;var v=Id(a,a===Un?Kn:0);if(v===0)return null;if((v&30)!==0||(v&a.expiredLanes)!==0||c)c=Tf(a,v);else{c=v;var S=Ft;Ft|=2;var E=C0();(Un!==a||Kn!==c)&&(po=null,ul=Gt()+500,ei(a,c));do try{pD();break}catch(I){S0(a,I)}while(!0);dm(),xf.current=E,Ft=S,Mn!==null?c=0:(Un=null,Kn=0,c=An)}if(c!==0){if(c===2&&(S=Tg(a),S!==0&&(v=S,c=Gm(a,S))),c===1)throw p=Jc,ei(a,0),aa(a,v),Sr(a,Gt()),p;if(c===6)aa(a,v);else{if(S=a.current.alternate,(v&30)===0&&!dD(S)&&(c=Tf(a,v),c===2&&(E=Tg(a),E!==0&&(v=E,c=Gm(a,E))),c===1))throw p=Jc,ei(a,0),aa(a,v),Sr(a,Gt()),p;switch(a.finishedWork=S,a.finishedLanes=v,c){case 0:case 1:throw Error(n(345));case 2:ti(a,wr,po);break;case 3:if(aa(a,v),(v&130023424)===v&&(c=qm+500-Gt(),10<c)){if(Id(a,0)!==0)break;if(S=a.suspendedLanes,(S&v)!==v){ir(),a.pingedLanes|=a.suspendedLanes&S;break}a.timeoutHandle=em(ti.bind(null,a,wr,po),c);break}ti(a,wr,po);break;case 4:if(aa(a,v),(v&4194240)===v)break;for(c=a.eventTimes,S=-1;0<v;){var T=31-Tt(v);E=1<<T,T=c[T],T>S&&(S=T),v&=~E}if(v=S,v=Gt()-v,v=(120>v?120:480>v?480:1080>v?1080:1920>v?1920:3e3>v?3e3:4320>v?4320:1960*uD(v/1960))-v,10<v){a.timeoutHandle=em(ti.bind(null,a,wr,po),v);break}ti(a,wr,po);break;case 5:ti(a,wr,po);break;default:throw Error(n(329))}}}return Sr(a,Gt()),a.callbackNode===p?x0.bind(null,a):null}function Gm(a,c){var p=Qc;return a.current.memoizedState.isDehydrated&&(ei(a,c).flags|=256),a=Tf(a,c),a!==2&&(c=wr,wr=p,c!==null&&Jm(c)),a}function Jm(a){wr===null?wr=a:wr.push.apply(wr,a)}function dD(a){for(var c=a;;){if(c.flags&16384){var p=c.updateQueue;if(p!==null&&(p=p.stores,p!==null))for(var v=0;v<p.length;v++){var S=p[v],E=S.getSnapshot;S=S.value;try{if(!ps(E(),S))return!1}catch{return!1}}}if(p=c.child,c.subtreeFlags&16384&&p!==null)p.return=c,c=p;else{if(c===a)break;for(;c.sibling===null;){if(c.return===null||c.return===a)return!0;c=c.return}c.sibling.return=c.return,c=c.sibling}}return!0}function aa(a,c){for(c&=~Hm,c&=~wf,a.suspendedLanes|=c,a.pingedLanes&=~c,a=a.expirationTimes;0<c;){var p=31-Tt(c),v=1<<p;a[p]=-1,c&=~v}}function w0(a){if((Ft&6)!==0)throw Error(n(327));dl();var c=Id(a,0);if((c&1)===0)return Sr(a,Gt()),null;var p=Tf(a,c);if(a.tag!==0&&p===2){var v=Tg(a);v!==0&&(c=v,p=Gm(a,v))}if(p===1)throw p=Jc,ei(a,0),aa(a,c),Sr(a,Gt()),p;if(p===6)throw Error(n(345));return a.finishedWork=a.current.alternate,a.finishedLanes=c,ti(a,wr,po),Sr(a,Gt()),null}function Qm(a,c){var p=Ft;Ft|=1;try{return a(c)}finally{Ft=p,Ft===0&&(ul=Gt()+500,Xd&&Xo())}}function Xa(a){sa!==null&&sa.tag===0&&(Ft&6)===0&&dl();var c=Ft;Ft|=1;var p=es.transition,v=Kt;try{if(es.transition=null,Kt=1,a)return a()}finally{Kt=v,es.transition=p,Ft=c,(Ft&6)===0&&Xo()}}function Zm(){Dr=cl.current,en(cl)}function ei(a,c){a.finishedWork=null,a.finishedLanes=0;var p=a.timeoutHandle;if(p!==-1&&(a.timeoutHandle=-1,zA(p)),Mn!==null)for(p=Mn.return;p!==null;){var v=p;switch(am(v),v.tag){case 1:v=v.type.childContextTypes,v!=null&&Zd();break;case 3:al(),en(yr),en(Zn),bm();break;case 5:vm(v);break;case 4:al();break;case 13:en(pn);break;case 19:en(pn);break;case 10:fm(v.type._context);break;case 22:case 23:Zm()}p=p.return}if(Un=a,Mn=a=ia(a.current,null),Kn=Dr=c,An=0,Jc=null,Hm=wf=Ya=0,wr=Qc=null,Ja!==null){for(c=0;c<Ja.length;c++)if(p=Ja[c],v=p.interleaved,v!==null){p.interleaved=null;var S=v.next,E=p.pending;if(E!==null){var T=E.next;E.next=S,v.next=T}p.pending=v}Ja=null}return a}function S0(a,c){do{var p=Mn;try{if(dm(),uf.current=hf,df){for(var v=hn.memoizedState;v!==null;){var S=v.queue;S!==null&&(S.pending=null),v=v.next}df=!1}if(Za=0,zn=In=hn=null,Vc=!1,Hc=0,Vm.current=null,p===null||p.return===null){An=1,Jc=c,Mn=null;break}e:{var E=a,T=p.return,I=p,$=c;if(c=Kn,I.flags|=32768,$!==null&&typeof $==\"object\"&&typeof $.then==\"function\"){var ae=$,xe=I,we=xe.tag;if((xe.mode&1)===0&&(we===0||we===11||we===15)){var be=xe.alternate;be?(xe.updateQueue=be.updateQueue,xe.memoizedState=be.memoizedState,xe.lanes=be.lanes):(xe.updateQueue=null,xe.memoizedState=null)}var De=WS(T);if(De!==null){De.flags&=-257,GS(De,T,I,E,c),De.mode&1&&KS(E,ae,c),c=De,$=ae;var He=c.updateQueue;if(He===null){var Ke=new Set;Ke.add($),c.updateQueue=Ke}else He.add($);break e}else{if((c&1)===0){KS(E,ae,c),Ym();break e}$=Error(n(426))}}else if(cn&&I.mode&1){var kn=WS(T);if(kn!==null){(kn.flags&65536)===0&&(kn.flags|=256),GS(kn,T,I,E,c),cm(il($,I));break e}}E=$=il($,I),An!==4&&(An=2),Qc===null?Qc=[E]:Qc.push(E),E=T;do{switch(E.tag){case 3:E.flags|=65536,c&=-c,E.lanes|=c;var J=HS(E,$,c);vS(E,J);break e;case 1:I=$;var U=E.type,ee=E.stateNode;if((E.flags&128)===0&&(typeof U.getDerivedStateFromError==\"function\"||ee!==null&&typeof ee.componentDidCatch==\"function\"&&(ra===null||!ra.has(ee)))){E.flags|=65536,c&=-c,E.lanes|=c;var ke=qS(E,I,c);vS(E,ke);break e}}E=E.return}while(E!==null)}k0(p)}catch(Je){c=Je,Mn===p&&p!==null&&(Mn=p=p.return);continue}break}while(!0)}function C0(){var a=xf.current;return xf.current=hf,a===null?hf:a}function Ym(){(An===0||An===3||An===2)&&(An=4),Un===null||(Ya&268435455)===0&&(wf&268435455)===0||aa(Un,Kn)}function Tf(a,c){var p=Ft;Ft|=2;var v=C0();(Un!==a||Kn!==c)&&(po=null,ei(a,c));do try{fD();break}catch(S){S0(a,S)}while(!0);if(dm(),Ft=p,xf.current=v,Mn!==null)throw Error(n(261));return Un=null,Kn=0,An}function fD(){for(;Mn!==null;)E0(Mn)}function pD(){for(;Mn!==null&&!Va();)E0(Mn)}function E0(a){var c=N0(a.alternate,a,Dr);a.memoizedProps=a.pendingProps,c===null?k0(a):Mn=c,Vm.current=null}function k0(a){var c=a;do{var p=c.alternate;if(a=c.return,(c.flags&32768)===0){if(p=oD(p,c,Dr),p!==null){Mn=p;return}}else{if(p=aD(p,c),p!==null){p.flags&=32767,Mn=p;return}if(a!==null)a.flags|=32768,a.subtreeFlags=0,a.deletions=null;else{An=6,Mn=null;return}}if(c=c.sibling,c!==null){Mn=c;return}Mn=c=a}while(c!==null);An===0&&(An=5)}function ti(a,c,p){var v=Kt,S=es.transition;try{es.transition=null,Kt=1,hD(a,c,p,v)}finally{es.transition=S,Kt=v}return null}function hD(a,c,p,v){do dl();while(sa!==null);if((Ft&6)!==0)throw Error(n(327));p=a.finishedWork;var S=a.finishedLanes;if(p===null)return null;if(a.finishedWork=null,a.finishedLanes=0,p===a.current)throw Error(n(177));a.callbackNode=null,a.callbackPriority=0;var E=p.lanes|p.childLanes;if(GI(a,E),a===Un&&(Mn=Un=null,Kn=0),(p.subtreeFlags&2064)===0&&(p.flags&2064)===0||Cf||(Cf=!0,M0(so,function(){return dl(),null})),E=(p.flags&15990)!==0,(p.subtreeFlags&15990)!==0||E){E=es.transition,es.transition=null;var T=Kt;Kt=1;var I=Ft;Ft|=4,Vm.current=null,lD(a,p),g0(p,a),IA(Yg),Fd=!!Zg,Yg=Zg=null,a.current=p,cD(p),Os(),Ft=I,Kt=T,es.transition=E}else a.current=p;if(Cf&&(Cf=!1,sa=a,Ef=S),E=a.pendingLanes,E===0&&(ra=null),or(p.stateNode),Sr(a,Gt()),c!==null)for(v=a.onRecoverableError,p=0;p<c.length;p++)S=c[p],v(S.value,{componentStack:S.stack,digest:S.digest});if(Sf)throw Sf=!1,a=Km,Km=null,a;return(Ef&1)!==0&&a.tag!==0&&dl(),E=a.pendingLanes,(E&1)!==0?a===Wm?Zc++:(Zc=0,Wm=a):Zc=0,Xo(),null}function dl(){if(sa!==null){var a=pw(Ef),c=es.transition,p=Kt;try{if(es.transition=null,Kt=16>a?16:a,sa===null)var v=!1;else{if(a=sa,sa=null,Ef=0,(Ft&6)!==0)throw Error(n(331));var S=Ft;for(Ft|=4,ze=a.current;ze!==null;){var E=ze,T=E.child;if((ze.flags&16)!==0){var I=E.deletions;if(I!==null){for(var $=0;$<I.length;$++){var ae=I[$];for(ze=ae;ze!==null;){var xe=ze;switch(xe.tag){case 0:case 11:case 15:Gc(8,xe,E)}var we=xe.child;if(we!==null)we.return=xe,ze=we;else for(;ze!==null;){xe=ze;var be=xe.sibling,De=xe.return;if(u0(xe),xe===ae){ze=null;break}if(be!==null){be.return=De,ze=be;break}ze=De}}}var He=E.alternate;if(He!==null){var Ke=He.child;if(Ke!==null){He.child=null;do{var kn=Ke.sibling;Ke.sibling=null,Ke=kn}while(Ke!==null)}}ze=E}}if((E.subtreeFlags&2064)!==0&&T!==null)T.return=E,ze=T;else e:for(;ze!==null;){if(E=ze,(E.flags&2048)!==0)switch(E.tag){case 0:case 11:case 15:Gc(9,E,E.return)}var J=E.sibling;if(J!==null){J.return=E.return,ze=J;break e}ze=E.return}}var U=a.current;for(ze=U;ze!==null;){T=ze;var ee=T.child;if((T.subtreeFlags&2064)!==0&&ee!==null)ee.return=T,ze=ee;else e:for(T=U;ze!==null;){if(I=ze,(I.flags&2048)!==0)try{switch(I.tag){case 0:case 11:case 15:bf(9,I)}}catch(Je){xn(I,I.return,Je)}if(I===T){ze=null;break e}var ke=I.sibling;if(ke!==null){ke.return=I.return,ze=ke;break e}ze=I.return}}if(Ft=S,Xo(),Dt&&typeof Dt.onPostCommitFiberRoot==\"function\")try{Dt.onPostCommitFiberRoot(pt,a)}catch{}v=!0}return v}finally{Kt=p,es.transition=c}}return!1}function j0(a,c,p){c=il(p,c),c=HS(a,c,1),a=ta(a,c,1),c=ir(),a!==null&&(wc(a,1,c),Sr(a,c))}function xn(a,c,p){if(a.tag===3)j0(a,a,p);else for(;c!==null;){if(c.tag===3){j0(c,a,p);break}else if(c.tag===1){var v=c.stateNode;if(typeof c.type.getDerivedStateFromError==\"function\"||typeof v.componentDidCatch==\"function\"&&(ra===null||!ra.has(v))){a=il(p,a),a=qS(c,a,1),c=ta(c,a,1),a=ir(),c!==null&&(wc(c,1,a),Sr(c,a));break}}c=c.return}}function gD(a,c,p){var v=a.pingCache;v!==null&&v.delete(c),c=ir(),a.pingedLanes|=a.suspendedLanes&p,Un===a&&(Kn&p)===p&&(An===4||An===3&&(Kn&130023424)===Kn&&500>Gt()-qm?ei(a,0):Hm|=p),Sr(a,c)}function T0(a,c){c===0&&((a.mode&1)===0?c=1:(c=Od,Od<<=1,(Od&130023424)===0&&(Od=4194304)));var p=ir();a=co(a,c),a!==null&&(wc(a,c,p),Sr(a,p))}function mD(a){var c=a.memoizedState,p=0;c!==null&&(p=c.retryLane),T0(a,p)}function vD(a,c){var p=0;switch(a.tag){case 13:var v=a.stateNode,S=a.memoizedState;S!==null&&(p=S.retryLane);break;case 19:v=a.stateNode;break;default:throw Error(n(314))}v!==null&&v.delete(c),T0(a,p)}var N0;N0=function(a,c,p){if(a!==null)if(a.memoizedProps!==c.pendingProps||yr.current)xr=!0;else{if((a.lanes&p)===0&&(c.flags&128)===0)return xr=!1,sD(a,c,p);xr=(a.flags&131072)!==0}else xr=!1,cn&&(c.flags&1048576)!==0&&iS(c,tf,c.index);switch(c.lanes=0,c.tag){case 2:var v=c.type;vf(a,c),a=c.pendingProps;var S=Xi(c,Zn.current);ol(c,p),S=Sm(null,c,v,a,S,p);var E=Cm();return c.flags|=1,typeof S==\"object\"&&S!==null&&typeof S.render==\"function\"&&S.$$typeof===void 0?(c.tag=1,c.memoizedState=null,c.updateQueue=null,br(v)?(E=!0,Yd(c)):E=!1,c.memoizedState=S.state!==null&&S.state!==void 0?S.state:null,gm(c),S.updater=gf,c.stateNode=S,S._reactInternals=c,Mm(c,v,a,p),c=Om(null,c,v,!0,E,p)):(c.tag=0,cn&&E&&om(c),ar(null,c,S,p),c=c.child),c;case 16:v=c.elementType;e:{switch(vf(a,c),a=c.pendingProps,S=v._init,v=S(v._payload),c.type=v,S=c.tag=bD(v),a=gs(v,a),S){case 0:c=Pm(null,c,v,a,p);break e;case 1:c=e0(null,c,v,a,p);break e;case 11:c=JS(null,c,v,a,p);break e;case 14:c=QS(null,c,v,gs(v.type,a),p);break e}throw Error(n(306,v,\"\"))}return c;case 0:return v=c.type,S=c.pendingProps,S=c.elementType===v?S:gs(v,S),Pm(a,c,v,S,p);case 1:return v=c.type,S=c.pendingProps,S=c.elementType===v?S:gs(v,S),e0(a,c,v,S,p);case 3:e:{if(t0(c),a===null)throw Error(n(387));v=c.pendingProps,E=c.memoizedState,S=E.element,mS(a,c),lf(c,v,null,p);var T=c.memoizedState;if(v=T.element,E.isDehydrated)if(E={element:v,isDehydrated:!1,cache:T.cache,pendingSuspenseBoundaries:T.pendingSuspenseBoundaries,transitions:T.transitions},c.updateQueue.baseState=E,c.memoizedState=E,c.flags&256){S=il(Error(n(423)),c),c=n0(a,c,v,p,S);break e}else if(v!==S){S=il(Error(n(424)),c),c=n0(a,c,v,p,S);break e}else for(Ar=Qo(c.stateNode.containerInfo.firstChild),Ir=c,cn=!0,hs=null,p=hS(c,null,v,p),c.child=p;p;)p.flags=p.flags&-3|4096,p=p.sibling;else{if(nl(),v===S){c=fo(a,c,p);break e}ar(a,c,v,p)}c=c.child}return c;case 5:return bS(c),a===null&&lm(c),v=c.type,S=c.pendingProps,E=a!==null?a.memoizedProps:null,T=S.children,Xg(v,S)?T=null:E!==null&&Xg(v,E)&&(c.flags|=32),XS(a,c),ar(a,c,T,p),c.child;case 6:return a===null&&lm(c),null;case 13:return r0(a,c,p);case 4:return mm(c,c.stateNode.containerInfo),v=c.pendingProps,a===null?c.child=rl(c,null,v,p):ar(a,c,v,p),c.child;case 11:return v=c.type,S=c.pendingProps,S=c.elementType===v?S:gs(v,S),JS(a,c,v,S,p);case 7:return ar(a,c,c.pendingProps,p),c.child;case 8:return ar(a,c,c.pendingProps.children,p),c.child;case 12:return ar(a,c,c.pendingProps.children,p),c.child;case 10:e:{if(v=c.type._context,S=c.pendingProps,E=c.memoizedProps,T=S.value,Qt(sf,v._currentValue),v._currentValue=T,E!==null)if(ps(E.value,T)){if(E.children===S.children&&!yr.current){c=fo(a,c,p);break e}}else for(E=c.child,E!==null&&(E.return=c);E!==null;){var I=E.dependencies;if(I!==null){T=E.child;for(var $=I.firstContext;$!==null;){if($.context===v){if(E.tag===1){$=uo(-1,p&-p),$.tag=2;var ae=E.updateQueue;if(ae!==null){ae=ae.shared;var xe=ae.pending;xe===null?$.next=$:($.next=xe.next,xe.next=$),ae.pending=$}}E.lanes|=p,$=E.alternate,$!==null&&($.lanes|=p),pm(E.return,p,c),I.lanes|=p;break}$=$.next}}else if(E.tag===10)T=E.type===c.type?null:E.child;else if(E.tag===18){if(T=E.return,T===null)throw Error(n(341));T.lanes|=p,I=T.alternate,I!==null&&(I.lanes|=p),pm(T,p,c),T=E.sibling}else T=E.child;if(T!==null)T.return=E;else for(T=E;T!==null;){if(T===c){T=null;break}if(E=T.sibling,E!==null){E.return=T.return,T=E;break}T=T.return}E=T}ar(a,c,S.children,p),c=c.child}return c;case 9:return S=c.type,v=c.pendingProps.children,ol(c,p),S=Yr(S),v=v(S),c.flags|=1,ar(a,c,v,p),c.child;case 14:return v=c.type,S=gs(v,c.pendingProps),S=gs(v.type,S),QS(a,c,v,S,p);case 15:return ZS(a,c,c.type,c.pendingProps,p);case 17:return v=c.type,S=c.pendingProps,S=c.elementType===v?S:gs(v,S),vf(a,c),c.tag=1,br(v)?(a=!0,Yd(c)):a=!1,ol(c,p),US(c,v,S),Mm(c,v,S,p),Om(null,c,v,!0,a,p);case 19:return o0(a,c,p);case 22:return YS(a,c,p)}throw Error(n(156,c.tag))};function M0(a,c){return Nn(a,c)}function yD(a,c,p,v){this.tag=a,this.key=p,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=c,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=v,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ts(a,c,p,v){return new yD(a,c,p,v)}function Xm(a){return a=a.prototype,!(!a||!a.isReactComponent)}function bD(a){if(typeof a==\"function\")return Xm(a)?1:0;if(a!=null){if(a=a.$$typeof,a===V)return 11;if(a===ie)return 14}return 2}function ia(a,c){var p=a.alternate;return p===null?(p=ts(a.tag,c,a.key,a.mode),p.elementType=a.elementType,p.type=a.type,p.stateNode=a.stateNode,p.alternate=a,a.alternate=p):(p.pendingProps=c,p.type=a.type,p.flags=0,p.subtreeFlags=0,p.deletions=null),p.flags=a.flags&14680064,p.childLanes=a.childLanes,p.lanes=a.lanes,p.child=a.child,p.memoizedProps=a.memoizedProps,p.memoizedState=a.memoizedState,p.updateQueue=a.updateQueue,c=a.dependencies,p.dependencies=c===null?null:{lanes:c.lanes,firstContext:c.firstContext},p.sibling=a.sibling,p.index=a.index,p.ref=a.ref,p}function Nf(a,c,p,v,S,E){var T=2;if(v=a,typeof a==\"function\")Xm(a)&&(T=1);else if(typeof a==\"string\")T=5;else e:switch(a){case O:return ni(p.children,S,E,c);case D:T=8,S|=8;break;case z:return a=ts(12,p,c,S|2),a.elementType=z,a.lanes=E,a;case G:return a=ts(13,p,c,S),a.elementType=G,a.lanes=E,a;case W:return a=ts(19,p,c,S),a.elementType=W,a.lanes=E,a;case Y:return Mf(p,S,E,c);default:if(typeof a==\"object\"&&a!==null)switch(a.$$typeof){case Q:T=10;break e;case pe:T=9;break e;case V:T=11;break e;case ie:T=14;break e;case re:T=16,v=null;break e}throw Error(n(130,a==null?a:typeof a,\"\"))}return c=ts(T,p,c,S),c.elementType=a,c.type=v,c.lanes=E,c}function ni(a,c,p,v){return a=ts(7,a,v,c),a.lanes=p,a}function Mf(a,c,p,v){return a=ts(22,a,v,c),a.elementType=Y,a.lanes=p,a.stateNode={isHidden:!1},a}function ev(a,c,p){return a=ts(6,a,null,c),a.lanes=p,a}function tv(a,c,p){return c=ts(4,a.children!==null?a.children:[],a.key,c),c.lanes=p,c.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation},c}function xD(a,c,p,v,S){this.tag=c,this.containerInfo=a,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Ng(0),this.expirationTimes=Ng(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ng(0),this.identifierPrefix=v,this.onRecoverableError=S,this.mutableSourceEagerHydrationData=null}function nv(a,c,p,v,S,E,T,I,$){return a=new xD(a,c,p,I,$),c===1?(c=1,E===!0&&(c|=8)):c=0,E=ts(3,null,null,c),a.current=E,E.stateNode=a,E.memoizedState={element:v,isDehydrated:p,cache:null,transitions:null,pendingSuspenseBoundaries:null},gm(E),a}function wD(a,c,p){var v=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:N,key:v==null?null:\"\"+v,children:a,containerInfo:c,implementation:p}}function _0(a){if(!a)return Yo;a=a._reactInternals;e:{if(Ge(a)!==a||a.tag!==1)throw Error(n(170));var c=a;do{switch(c.tag){case 3:c=c.stateNode.context;break e;case 1:if(br(c.type)){c=c.stateNode.__reactInternalMemoizedMergedChildContext;break e}}c=c.return}while(c!==null);throw Error(n(171))}if(a.tag===1){var p=a.type;if(br(p))return sS(a,p,c)}return c}function R0(a,c,p,v,S,E,T,I,$){return a=nv(p,v,!0,a,S,E,T,I,$),a.context=_0(null),p=a.current,v=ir(),S=oa(p),E=uo(v,S),E.callback=c??null,ta(p,E,S),a.current.lanes=S,wc(a,S,v),Sr(a,v),a}function _f(a,c,p,v){var S=c.current,E=ir(),T=oa(S);return p=_0(p),c.context===null?c.context=p:c.pendingContext=p,c=uo(E,T),c.payload={element:a},v=v===void 0?null:v,v!==null&&(c.callback=v),a=ta(S,c,T),a!==null&&(ys(a,S,T,E),af(a,S,T)),T}function Rf(a){if(a=a.current,!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function P0(a,c){if(a=a.memoizedState,a!==null&&a.dehydrated!==null){var p=a.retryLane;a.retryLane=p!==0&&p<c?p:c}}function rv(a,c){P0(a,c),(a=a.alternate)&&P0(a,c)}function SD(){return null}var O0=typeof reportError==\"function\"?reportError:function(a){console.error(a)};function sv(a){this._internalRoot=a}Pf.prototype.render=sv.prototype.render=function(a){var c=this._internalRoot;if(c===null)throw Error(n(409));_f(a,c,null,null)},Pf.prototype.unmount=sv.prototype.unmount=function(){var a=this._internalRoot;if(a!==null){this._internalRoot=null;var c=a.containerInfo;Xa(function(){_f(null,a,null,null)}),c[oo]=null}};function Pf(a){this._internalRoot=a}Pf.prototype.unstable_scheduleHydration=function(a){if(a){var c=mw();a={blockedOn:null,target:a,priority:c};for(var p=0;p<Wo.length&&c!==0&&c<Wo[p].priority;p++);Wo.splice(p,0,a),p===0&&bw(a)}};function ov(a){return!(!a||a.nodeType!==1&&a.nodeType!==9&&a.nodeType!==11)}function Of(a){return!(!a||a.nodeType!==1&&a.nodeType!==9&&a.nodeType!==11&&(a.nodeType!==8||a.nodeValue!==\" react-mount-point-unstable \"))}function I0(){}function CD(a,c,p,v,S){if(S){if(typeof v==\"function\"){var E=v;v=function(){var ae=Rf(T);E.call(ae)}}var T=R0(c,v,a,0,null,!1,!1,\"\",I0);return a._reactRootContainer=T,a[oo]=T.current,Ac(a.nodeType===8?a.parentNode:a),Xa(),T}for(;S=a.lastChild;)a.removeChild(S);if(typeof v==\"function\"){var I=v;v=function(){var ae=Rf($);I.call(ae)}}var $=nv(a,0,!1,null,null,!1,!1,\"\",I0);return a._reactRootContainer=$,a[oo]=$.current,Ac(a.nodeType===8?a.parentNode:a),Xa(function(){_f(c,$,p,v)}),$}function If(a,c,p,v,S){var E=p._reactRootContainer;if(E){var T=E;if(typeof S==\"function\"){var I=S;S=function(){var $=Rf(T);I.call($)}}_f(c,T,a,S)}else T=CD(p,c,a,S,v);return Rf(T)}hw=function(a){switch(a.tag){case 3:var c=a.stateNode;if(c.current.memoizedState.isDehydrated){var p=xc(c.pendingLanes);p!==0&&(Mg(c,p|1),Sr(c,Gt()),(Ft&6)===0&&(ul=Gt()+500,Xo()))}break;case 13:Xa(function(){var v=co(a,1);if(v!==null){var S=ir();ys(v,a,1,S)}}),rv(a,1)}},_g=function(a){if(a.tag===13){var c=co(a,134217728);if(c!==null){var p=ir();ys(c,a,134217728,p)}rv(a,134217728)}},gw=function(a){if(a.tag===13){var c=oa(a),p=co(a,c);if(p!==null){var v=ir();ys(p,a,c,v)}rv(a,c)}},mw=function(){return Kt},vw=function(a,c){var p=Kt;try{return Kt=a,c()}finally{Kt=p}},Gr=function(a,c,p){switch(c){case\"input\":if(Cn(a,p),c=p.name,p.type===\"radio\"&&c!=null){for(p=a;p.parentNode;)p=p.parentNode;for(p=p.querySelectorAll(\"input[name=\"+JSON.stringify(\"\"+c)+'][type=\"radio\"]'),c=0;c<p.length;c++){var v=p[c];if(v!==a&&v.form===a.form){var S=Qd(v);if(!S)throw Error(n(90));Fe(v),Cn(v,S)}}}break;case\"textarea\":Be(a,p);break;case\"select\":c=p.value,c!=null&&Ne(a,!!p.multiple,c,!1)}},_d=Qm,yc=Xa;var ED={usingClientEntryPoint:!1,Events:[Lc,Zi,Qd,Uo,vc,Qm]},Yc={findFiberByHostInstance:qa,bundleType:0,version:\"18.3.1\",rendererPackageName:\"react-dom\"},kD={bundleType:Yc.bundleType,version:Yc.version,rendererPackageName:Yc.rendererPackageName,rendererConfig:Yc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:_.ReactCurrentDispatcher,findHostInstanceByFiber:function(a){return a=Ht(a),a===null?null:a.stateNode},findFiberByHostInstance:Yc.findFiberByHostInstance||SD,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:\"18.3.1-next-f1338f8080-20240426\"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<\"u\"){var Af=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Af.isDisabled&&Af.supportsFiber)try{pt=Af.inject(kD),Dt=Af}catch{}}return Cr.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=ED,Cr.createPortal=function(a,c){var p=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!ov(c))throw Error(n(200));return wD(a,c,null,p)},Cr.createRoot=function(a,c){if(!ov(a))throw Error(n(299));var p=!1,v=\"\",S=O0;return c!=null&&(c.unstable_strictMode===!0&&(p=!0),c.identifierPrefix!==void 0&&(v=c.identifierPrefix),c.onRecoverableError!==void 0&&(S=c.onRecoverableError)),c=nv(a,1,!1,null,null,p,!1,v,S),a[oo]=c.current,Ac(a.nodeType===8?a.parentNode:a),new sv(c)},Cr.findDOMNode=function(a){if(a==null)return null;if(a.nodeType===1)return a;var c=a._reactInternals;if(c===void 0)throw typeof a.render==\"function\"?Error(n(188)):(a=Object.keys(a).join(\",\"),Error(n(268,a)));return a=Ht(c),a=a===null?null:a.stateNode,a},Cr.flushSync=function(a){return Xa(a)},Cr.hydrate=function(a,c,p){if(!Of(c))throw Error(n(200));return If(null,a,c,!0,p)},Cr.hydrateRoot=function(a,c,p){if(!ov(a))throw Error(n(405));var v=p!=null&&p.hydratedSources||null,S=!1,E=\"\",T=O0;if(p!=null&&(p.unstable_strictMode===!0&&(S=!0),p.identifierPrefix!==void 0&&(E=p.identifierPrefix),p.onRecoverableError!==void 0&&(T=p.onRecoverableError)),c=R0(c,null,a,1,p??null,S,!1,E,T),a[oo]=c.current,Ac(a),v)for(a=0;a<v.length;a++)p=v[a],S=p._getVersion,S=S(p._source),c.mutableSourceEagerHydrationData==null?c.mutableSourceEagerHydrationData=[p,S]:c.mutableSourceEagerHydrationData.push(p,S);return new Pf(c)},Cr.render=function(a,c,p){if(!Of(c))throw Error(n(200));return If(null,a,c,!1,p)},Cr.unmountComponentAtNode=function(a){if(!Of(a))throw Error(n(40));return a._reactRootContainer?(Xa(function(){If(null,null,a,!1,function(){a._reactRootContainer=null,a[oo]=null})}),!0):!1},Cr.unstable_batchedUpdates=Qm,Cr.unstable_renderSubtreeIntoContainer=function(a,c,p,v){if(!Of(p))throw Error(n(200));if(a==null||a._reactInternals===void 0)throw Error(n(38));return If(a,c,p,!1,v)},Cr.version=\"18.3.1-next-f1338f8080-20240426\",Cr}var J0;function tj(){if(J0)return cv.exports;J0=1;function e(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>\"u\"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=\"function\"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}return e(),cv.exports=fF(),cv.exports}var Q0;function pF(){if(Q0)return Ff;Q0=1;var e=tj();return Ff.createRoot=e.createRoot,Ff.hydrateRoot=e.hydrateRoot,Ff}var hF=pF();const gF=fd(hF),mF=(...e)=>{console?.warn&&(fi(e[0])&&(e[0]=`react-i18next:: ${e[0]}`),console.warn(...e))},Z0={},jy=(...e)=>{fi(e[0])&&Z0[e[0]]||(fi(e[0])&&(Z0[e[0]]=new Date),mF(...e))},nj=(e,t)=>()=>{if(e.isInitialized)t();else{const n=()=>{setTimeout(()=>{e.off(\"initialized\",n)},0),t()};e.on(\"initialized\",n)}},Y0=(e,t,n)=>{e.loadNamespaces(t,nj(e,n))},X0=(e,t,n,r)=>{fi(n)&&(n=[n]),n.forEach(s=>{e.options.ns.indexOf(s)<0&&e.options.ns.push(s)}),e.loadLanguages(t,nj(e,r))},vF=(e,t,n={})=>!t.languages||!t.languages.length?(jy(\"i18n.languages were undefined or empty\",t.languages),!0):t.hasLoadedNamespace(e,{lng:n.lng,precheck:(r,s)=>{if(n.bindI18n?.indexOf(\"languageChanging\")>-1&&r.services.backendConnector.backend&&r.isLanguageChangingTo&&!s(r.isLanguageChangingTo,e))return!1}}),fi=e=>typeof e==\"string\",yF=e=>typeof e==\"object\"&&e!==null,bF=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,xF={\"&amp;\":\"&\",\"&#38;\":\"&\",\"&lt;\":\"<\",\"&#60;\":\"<\",\"&gt;\":\">\",\"&#62;\":\">\",\"&apos;\":\"'\",\"&#39;\":\"'\",\"&quot;\":'\"',\"&#34;\":'\"',\"&nbsp;\":\" \",\"&#160;\":\" \",\"&copy;\":\"©\",\"&#169;\":\"©\",\"&reg;\":\"®\",\"&#174;\":\"®\",\"&hellip;\":\"…\",\"&#8230;\":\"…\",\"&#x2F;\":\"/\",\"&#47;\":\"/\"},wF=e=>xF[e],SF=e=>e.replace(bF,wF);let Ty={bindI18n:\"languageChanged\",bindI18nStore:\"\",transEmptyNodeValue:\"\",transSupportBasicHtmlNodes:!0,transWrapTextNodes:\"\",transKeepBasicHtmlNodesFor:[\"br\",\"strong\",\"i\",\"p\"],useSuspense:!0,unescape:SF};const CF=(e={})=>{Ty={...Ty,...e}},EF=()=>Ty;let rj;const kF=e=>{rj=e},jF=()=>rj,TF={type:\"3rdParty\",init(e){CF(e.options.react),kF(e)}},sj=y.createContext();class NF{constructor(){this.usedNamespaces={}}addUsedNamespaces(t){t.forEach(n=>{this.usedNamespaces[n]??=!0})}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}const MF=(e,t)=>{const n=y.useRef();return y.useEffect(()=>{n.current=e},[e,t]),n.current},oj=(e,t,n,r)=>e.getFixedT(t,n,r),_F=(e,t,n,r)=>y.useCallback(oj(e,t,n,r),[e,t,n,r]),Ve=(e,t={})=>{const{i18n:n}=t,{i18n:r,defaultNS:s}=y.useContext(sj)||{},o=n||r||jF();if(o&&!o.reportNamespaces&&(o.reportNamespaces=new NF),!o){jy(\"You will need to pass in an i18next instance by using initReactI18next\");const _=(N,O)=>fi(O)?O:yF(O)&&fi(O.defaultValue)?O.defaultValue:Array.isArray(N)?N[N.length-1]:N,R=[_,{},!1];return R.t=_,R.i18n={},R.ready=!1,R}o.options.react?.wait&&jy(\"It seems you are still using the old wait option, you may migrate to the new useSuspense behaviour.\");const l={...EF(),...o.options.react,...t},{useSuspense:u,keyPrefix:d}=l;let f=s||o.options?.defaultNS;f=fi(f)?[f]:f||[\"translation\"],o.reportNamespaces.addUsedNamespaces?.(f);const h=(o.isInitialized||o.initializedStoreOnce)&&f.every(_=>vF(_,o,l)),m=_F(o,t.lng||null,l.nsMode===\"fallback\"?f:f[0],d),g=()=>m,x=()=>oj(o,t.lng||null,l.nsMode===\"fallback\"?f:f[0],d),[b,w]=y.useState(g);let C=f.join();t.lng&&(C=`${t.lng}${C}`);const k=MF(C),j=y.useRef(!0);y.useEffect(()=>{const{bindI18n:_,bindI18nStore:R}=l;j.current=!0,!h&&!u&&(t.lng?X0(o,t.lng,f,()=>{j.current&&w(x)}):Y0(o,f,()=>{j.current&&w(x)})),h&&k&&k!==C&&j.current&&w(x);const N=()=>{j.current&&w(x)};return _&&o?.on(_,N),R&&o?.store.on(R,N),()=>{j.current=!1,o&&_?.split(\" \").forEach(O=>o.off(O,N)),R&&o&&R.split(\" \").forEach(O=>o.store.off(O,N))}},[o,C]),y.useEffect(()=>{j.current&&h&&w(g)},[o,d,h]);const M=[b,o,h];if(M.t=b,M.i18n=o,M.ready=h,h||!h&&!u)return M;throw new Promise(_=>{t.lng?X0(o,t.lng,f,()=>_()):Y0(o,f,()=>_())})};function RF({i18n:e,defaultNS:t,children:n}){const r=y.useMemo(()=>({i18n:e,defaultNS:t}),[e,t]);return y.createElement(sj.Provider,{value:r},n)}var Ma=tj();const Ib=fd(Ma),PF=Bk({__proto__:null,default:Ib},[Ma]);/**\n * @remix-run/router v1.18.0\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */function mn(){return mn=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},mn.apply(this,arguments)}var _n;(function(e){e.Pop=\"POP\",e.Push=\"PUSH\",e.Replace=\"REPLACE\"})(_n||(_n={}));const eC=\"popstate\";function OF(e){e===void 0&&(e={});function t(r,s){let{pathname:o,search:l,hash:u}=r.location;return Iu(\"\",{pathname:o,search:l,hash:u},s.state&&s.state.usr||null,s.state&&s.state.key||\"default\")}function n(r,s){return typeof s==\"string\"?s:wi(s)}return AF(t,n,null,e)}function Ct(e,t){if(e===!1||e===null||typeof e>\"u\")throw new Error(t)}function Ll(e,t){if(!e){typeof console<\"u\"&&console.warn(t);try{throw new Error(t)}catch{}}}function IF(){return Math.random().toString(36).substr(2,8)}function tC(e,t){return{usr:e.state,key:e.key,idx:t}}function Iu(e,t,n,r){return n===void 0&&(n=null),mn({pathname:typeof e==\"string\"?e:e.pathname,search:\"\",hash:\"\"},typeof t==\"string\"?_a(t):t,{state:n,key:t&&t.key||r||IF()})}function wi(e){let{pathname:t=\"/\",search:n=\"\",hash:r=\"\"}=e;return n&&n!==\"?\"&&(t+=n.charAt(0)===\"?\"?n:\"?\"+n),r&&r!==\"#\"&&(t+=r.charAt(0)===\"#\"?r:\"#\"+r),t}function _a(e){let t={};if(e){let n=e.indexOf(\"#\");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf(\"?\");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function AF(e,t,n,r){r===void 0&&(r={});let{window:s=document.defaultView,v5Compat:o=!1}=r,l=s.history,u=_n.Pop,d=null,f=h();f==null&&(f=0,l.replaceState(mn({},l.state,{idx:f}),\"\"));function h(){return(l.state||{idx:null}).idx}function m(){u=_n.Pop;let C=h(),k=C==null?null:C-f;f=C,d&&d({action:u,location:w.location,delta:k})}function g(C,k){u=_n.Push;let j=Iu(w.location,C,k);f=h()+1;let M=tC(j,f),_=w.createHref(j);try{l.pushState(M,\"\",_)}catch(R){if(R instanceof DOMException&&R.name===\"DataCloneError\")throw R;s.location.assign(_)}o&&d&&d({action:u,location:w.location,delta:1})}function x(C,k){u=_n.Replace;let j=Iu(w.location,C,k);f=h();let M=tC(j,f),_=w.createHref(j);l.replaceState(M,\"\",_),o&&d&&d({action:u,location:w.location,delta:0})}function b(C){let k=s.location.origin!==\"null\"?s.location.origin:s.location.href,j=typeof C==\"string\"?C:wi(C);return j=j.replace(/ $/,\"%20\"),Ct(k,\"No window.location.(origin|href) available to create URL for href: \"+j),new URL(j,k)}let w={get action(){return u},get location(){return e(s,l)},listen(C){if(d)throw new Error(\"A history only accepts one active listener\");return s.addEventListener(eC,m),d=C,()=>{s.removeEventListener(eC,m),d=null}},createHref(C){return t(s,C)},createURL:b,encodeLocation(C){let k=b(C);return{pathname:k.pathname,search:k.search,hash:k.hash}},push:g,replace:x,go(C){return l.go(C)}};return w}var Zt;(function(e){e.data=\"data\",e.deferred=\"deferred\",e.redirect=\"redirect\",e.error=\"error\"})(Zt||(Zt={}));const DF=new Set([\"lazy\",\"caseSensitive\",\"path\",\"id\",\"index\",\"children\"]);function FF(e){return e.index===!0}function Au(e,t,n,r){return n===void 0&&(n=[]),r===void 0&&(r={}),e.map((s,o)=>{let l=[...n,String(o)],u=typeof s.id==\"string\"?s.id:l.join(\"-\");if(Ct(s.index!==!0||!s.children,\"Cannot specify children on an index route\"),Ct(!r[u],'Found a route id collision on id \"'+u+`\".  Route id's must be globally unique within Data Router usages`),FF(s)){let d=mn({},s,t(s),{id:u});return r[u]=d,d}else{let d=mn({},s,t(s),{id:u,children:void 0});return r[u]=d,s.children&&(d.children=Au(s.children,t,l,r)),d}})}function oi(e,t,n){return n===void 0&&(n=\"/\"),cp(e,t,n,!1)}function cp(e,t,n,r){let s=typeof t==\"string\"?_a(t):t,o=Xl(s.pathname||\"/\",n);if(o==null)return null;let l=aj(e);$F(l);let u=null;for(let d=0;u==null&&d<l.length;++d){let f=QF(o);u=GF(l[d],f,r)}return u}function LF(e,t){let{route:n,pathname:r,params:s}=e;return{id:n.id,pathname:r,params:s,data:t[n.id],handle:n.handle}}function aj(e,t,n,r){t===void 0&&(t=[]),n===void 0&&(n=[]),r===void 0&&(r=\"\");let s=(o,l,u)=>{let d={relativePath:u===void 0?o.path||\"\":u,caseSensitive:o.caseSensitive===!0,childrenIndex:l,route:o};d.relativePath.startsWith(\"/\")&&(Ct(d.relativePath.startsWith(r),'Absolute route path \"'+d.relativePath+'\" nested under path '+('\"'+r+'\" is not valid. An absolute child route path ')+\"must start with the combined path of all its parent routes.\"),d.relativePath=d.relativePath.slice(r.length));let f=To([r,d.relativePath]),h=n.concat(d);o.children&&o.children.length>0&&(Ct(o.index!==!0,\"Index routes must not have child routes. Please remove \"+('all child routes from route path \"'+f+'\".')),aj(o.children,t,h,f)),!(o.path==null&&!o.index)&&t.push({path:f,score:KF(f,o.index),routesMeta:h})};return e.forEach((o,l)=>{var u;if(o.path===\"\"||!((u=o.path)!=null&&u.includes(\"?\")))s(o,l);else for(let d of ij(o.path))s(o,l,d)}),t}function ij(e){let t=e.split(\"/\");if(t.length===0)return[];let[n,...r]=t,s=n.endsWith(\"?\"),o=n.replace(/\\?$/,\"\");if(r.length===0)return s?[o,\"\"]:[o];let l=ij(r.join(\"/\")),u=[];return u.push(...l.map(d=>d===\"\"?o:[o,d].join(\"/\"))),s&&u.push(...l),u.map(d=>e.startsWith(\"/\")&&d===\"\"?\"/\":d)}function $F(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:WF(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const BF=/^:[\\w-]+$/,zF=3,UF=2,VF=1,HF=10,qF=-2,nC=e=>e===\"*\";function KF(e,t){let n=e.split(\"/\"),r=n.length;return n.some(nC)&&(r+=qF),t&&(r+=UF),n.filter(s=>!nC(s)).reduce((s,o)=>s+(BF.test(o)?zF:o===\"\"?VF:HF),r)}function WF(e,t){return e.length===t.length&&e.slice(0,-1).every((r,s)=>r===t[s])?e[e.length-1]-t[t.length-1]:0}function GF(e,t,n){n===void 0&&(n=!1);let{routesMeta:r}=e,s={},o=\"/\",l=[];for(let u=0;u<r.length;++u){let d=r[u],f=u===r.length-1,h=o===\"/\"?t:t.slice(o.length)||\"/\",m=rC({path:d.relativePath,caseSensitive:d.caseSensitive,end:f},h),g=d.route;if(!m&&f&&n&&!r[r.length-1].route.index&&(m=rC({path:d.relativePath,caseSensitive:d.caseSensitive,end:!1},h)),!m)return null;Object.assign(s,m.params),l.push({params:s,pathname:To([o,m.pathname]),pathnameBase:XF(To([o,m.pathnameBase])),route:g}),m.pathnameBase!==\"/\"&&(o=To([o,m.pathnameBase]))}return l}function rC(e,t){typeof e==\"string\"&&(e={path:e,caseSensitive:!1,end:!0});let[n,r]=JF(e.path,e.caseSensitive,e.end),s=t.match(n);if(!s)return null;let o=s[0],l=o.replace(/(.)\\/+$/,\"$1\"),u=s.slice(1);return{params:r.reduce((f,h,m)=>{let{paramName:g,isOptional:x}=h;if(g===\"*\"){let w=u[m]||\"\";l=o.slice(0,o.length-w.length).replace(/(.)\\/+$/,\"$1\")}const b=u[m];return x&&!b?f[g]=void 0:f[g]=(b||\"\").replace(/%2F/g,\"/\"),f},{}),pathname:o,pathnameBase:l,pattern:e}}function JF(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),Ll(e===\"*\"||!e.endsWith(\"*\")||e.endsWith(\"/*\"),'Route path \"'+e+'\" will be treated as if it were '+('\"'+e.replace(/\\*$/,\"/*\")+'\" because the `*` character must ')+\"always follow a `/` in the pattern. To get rid of this warning, \"+('please change the route path to \"'+e.replace(/\\*$/,\"/*\")+'\".'));let r=[],s=\"^\"+e.replace(/\\/*\\*?$/,\"\").replace(/^\\/*/,\"/\").replace(/[\\\\.*+^${}|()[\\]]/g,\"\\\\$&\").replace(/\\/:([\\w-]+)(\\?)?/g,(l,u,d)=>(r.push({paramName:u,isOptional:d!=null}),d?\"/?([^\\\\/]+)?\":\"/([^\\\\/]+)\"));return e.endsWith(\"*\")?(r.push({paramName:\"*\"}),s+=e===\"*\"||e===\"/*\"?\"(.*)$\":\"(?:\\\\/(.+)|\\\\/*)$\"):n?s+=\"\\\\/*$\":e!==\"\"&&e!==\"/\"&&(s+=\"(?:(?=\\\\/|$))\"),[new RegExp(s,t?void 0:\"i\"),r]}function QF(e){try{return e.split(\"/\").map(t=>decodeURIComponent(t).replace(/\\//g,\"%2F\")).join(\"/\")}catch(t){return Ll(!1,'The URL path \"'+e+'\" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+(\"encoding (\"+t+\").\")),e}}function Xl(e,t){if(t===\"/\")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith(\"/\")?t.length-1:t.length,r=e.charAt(n);return r&&r!==\"/\"?null:e.slice(n)||\"/\"}function ZF(e,t){t===void 0&&(t=\"/\");let{pathname:n,search:r=\"\",hash:s=\"\"}=typeof e==\"string\"?_a(e):e;return{pathname:n?n.startsWith(\"/\")?n:YF(n,t):t,search:e2(r),hash:t2(s)}}function YF(e,t){let n=t.replace(/\\/+$/,\"\").split(\"/\");return e.split(\"/\").forEach(s=>{s===\"..\"?n.length>1&&n.pop():s!==\".\"&&n.push(s)}),n.length>1?n.join(\"/\"):\"/\"}function fv(e,t,n,r){return\"Cannot include a '\"+e+\"' character in a manually specified \"+(\"`to.\"+t+\"` field [\"+JSON.stringify(r)+\"].  Please separate it out to the \")+(\"`to.\"+n+\"` field. Alternatively you may provide the full path as \")+'a string in <Link to=\"...\"> and the router will parse it for you.'}function lj(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function hh(e,t){let n=lj(e);return t?n.map((r,s)=>s===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function gh(e,t,n,r){r===void 0&&(r=!1);let s;typeof e==\"string\"?s=_a(e):(s=mn({},e),Ct(!s.pathname||!s.pathname.includes(\"?\"),fv(\"?\",\"pathname\",\"search\",s)),Ct(!s.pathname||!s.pathname.includes(\"#\"),fv(\"#\",\"pathname\",\"hash\",s)),Ct(!s.search||!s.search.includes(\"#\"),fv(\"#\",\"search\",\"hash\",s)));let o=e===\"\"||s.pathname===\"\",l=o?\"/\":s.pathname,u;if(l==null)u=n;else{let m=t.length-1;if(!r&&l.startsWith(\"..\")){let g=l.split(\"/\");for(;g[0]===\"..\";)g.shift(),m-=1;s.pathname=g.join(\"/\")}u=m>=0?t[m]:\"/\"}let d=ZF(s,u),f=l&&l!==\"/\"&&l.endsWith(\"/\"),h=(o||l===\".\")&&n.endsWith(\"/\");return!d.pathname.endsWith(\"/\")&&(f||h)&&(d.pathname+=\"/\"),d}const To=e=>e.join(\"/\").replace(/\\/\\/+/g,\"/\"),XF=e=>e.replace(/\\/+$/,\"\").replace(/^\\/*/,\"/\"),e2=e=>!e||e===\"?\"?\"\":e.startsWith(\"?\")?e:\"?\"+e,t2=e=>!e||e===\"#\"?\"\":e.startsWith(\"#\")?e:\"#\"+e;class Ab{constructor(t,n,r,s){s===void 0&&(s=!1),this.status=t,this.statusText=n||\"\",this.internal=s,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}}function mh(e){return e!=null&&typeof e.status==\"number\"&&typeof e.statusText==\"string\"&&typeof e.internal==\"boolean\"&&\"data\"in e}const cj=[\"post\",\"put\",\"patch\",\"delete\"],n2=new Set(cj),r2=[\"get\",...cj],s2=new Set(r2),o2=new Set([301,302,303,307,308]),a2=new Set([307,308]),pv={state:\"idle\",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},i2={state:\"idle\",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},eu={state:\"unblocked\",proceed:void 0,reset:void 0,location:void 0},Db=/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i,l2=e=>({hasErrorBoundary:!!e.hasErrorBoundary}),uj=\"remix-router-transitions\";function c2(e){const t=e.window?e.window:typeof window<\"u\"?window:void 0,n=typeof t<\"u\"&&typeof t.document<\"u\"&&typeof t.document.createElement<\"u\",r=!n;Ct(e.routes.length>0,\"You must provide a non-empty routes array to createRouter\");let s;if(e.mapRouteProperties)s=e.mapRouteProperties;else if(e.detectErrorBoundary){let B=e.detectErrorBoundary;s=K=>({hasErrorBoundary:B(K)})}else s=l2;let o={},l=Au(e.routes,s,void 0,o),u,d=e.basename||\"/\",f=e.unstable_dataStrategy||h2,h=e.unstable_patchRoutesOnMiss,m=mn({v7_fetcherPersist:!1,v7_normalizeFormMethod:!1,v7_partialHydration:!1,v7_prependBasename:!1,v7_relativeSplatPath:!1,v7_skipActionErrorRevalidation:!1},e.future),g=null,x=new Set,b=null,w=null,C=null,k=e.hydrationData!=null,j=oi(l,e.history.location,d),M=null;if(j==null&&!h){let B=lr(404,{pathname:e.history.location.pathname}),{matches:K,route:oe}=pC(l);j=K,M={[oe.id]:B}}j&&h&&!e.hydrationData&&Ba(j,l,e.history.location.pathname).active&&(j=null);let _;if(!j)_=!1,j=[];else if(j.some(B=>B.route.lazy))_=!1;else if(!j.some(B=>B.route.loader))_=!0;else if(m.v7_partialHydration){let B=e.hydrationData?e.hydrationData.loaderData:null,K=e.hydrationData?e.hydrationData.errors:null,oe=ve=>ve.route.loader?typeof ve.route.loader==\"function\"&&ve.route.loader.hydrate===!0?!1:B&&B[ve.route.id]!==void 0||K&&K[ve.route.id]!==void 0:!0;if(K){let ve=j.findIndex(Oe=>K[Oe.route.id]!==void 0);_=j.slice(0,ve+1).every(oe)}else _=j.every(oe)}else _=e.hydrationData!=null;let R,N={historyAction:e.history.action,location:e.history.location,matches:j,initialized:_,navigation:pv,restoreScrollPosition:e.hydrationData!=null?!1:null,preventScrollReset:!1,revalidation:\"idle\",loaderData:e.hydrationData&&e.hydrationData.loaderData||{},actionData:e.hydrationData&&e.hydrationData.actionData||null,errors:e.hydrationData&&e.hydrationData.errors||M,fetchers:new Map,blockers:new Map},O=_n.Pop,D=!1,z,Q=!1,pe=new Map,V=null,G=!1,W=!1,ie=[],re=[],Y=new Map,H=0,q=-1,he=new Map,A=new Set,F=new Map,fe=new Map,te=new Set,de=new Map,ge=new Map,Z=new Map,ye=!1;function Re(){if(g=e.history.listen(B=>{let{action:K,location:oe,delta:ve}=B;if(ye){ye=!1;return}Ll(ge.size===0||ve!=null,\"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs.  This can also happen if you are using createHashRouter and the user manually changes the URL.\");let Oe=Gr({currentLocation:N.location,nextLocation:oe,historyAction:K});if(Oe&&ve!=null){ye=!0,e.history.go(ve*-1),vr(Oe,{state:\"blocked\",location:oe,proceed(){vr(Oe,{state:\"proceeding\",proceed:void 0,reset:void 0,location:oe}),e.history.go(ve)},reset(){let We=new Map(N.blockers);We.set(Oe,eu),Fe({blockers:We})}});return}return vn(K,oe)}),n){T2(t,pe);let B=()=>N2(t,pe);t.addEventListener(\"pagehide\",B),V=()=>t.removeEventListener(\"pagehide\",B)}return N.initialized||vn(_n.Pop,N.location,{initialHydration:!0}),R}function $e(){g&&g(),V&&V(),x.clear(),z&&z.abort(),N.fetchers.forEach((B,K)=>Qn(K)),N.blockers.forEach((B,K)=>mr(K))}function Ye(B){return x.add(B),()=>x.delete(B)}function Fe(B,K){K===void 0&&(K={}),N=mn({},N,B);let oe=[],ve=[];m.v7_fetcherPersist&&N.fetchers.forEach((Oe,We)=>{Oe.state===\"idle\"&&(te.has(We)?ve.push(We):oe.push(We))}),[...x].forEach(Oe=>Oe(N,{deletedFetchers:ve,unstable_viewTransitionOpts:K.viewTransitionOpts,unstable_flushSync:K.flushSync===!0})),m.v7_fetcherPersist&&(oe.forEach(Oe=>N.fetchers.delete(Oe)),ve.forEach(Oe=>Qn(Oe)))}function ft(B,K,oe){var ve,Oe;let{flushSync:We}=oe===void 0?{}:oe,st=N.actionData!=null&&N.navigation.formMethod!=null&&bs(N.navigation.formMethod)&&N.navigation.state===\"loading\"&&((ve=B.state)==null?void 0:ve._isRedirect)!==!0,Me;K.actionData?Object.keys(K.actionData).length>0?Me=K.actionData:Me=null:st?Me=N.actionData:Me=null;let ht=K.loaderData?dC(N.loaderData,K.loaderData,K.matches||[],K.errors):N.loaderData,Ge=N.blockers;Ge.size>0&&(Ge=new Map(Ge),Ge.forEach((Vt,Ht)=>Ge.set(Ht,eu)));let Xe=D===!0||N.navigation.formMethod!=null&&bs(N.navigation.formMethod)&&((Oe=B.state)==null?void 0:Oe._isRedirect)!==!0;u&&(l=u,u=void 0),G||O===_n.Pop||(O===_n.Push?e.history.push(B,B.state):O===_n.Replace&&e.history.replace(B,B.state));let Ut;if(O===_n.Pop){let Vt=pe.get(N.location.pathname);Vt&&Vt.has(B.pathname)?Ut={currentLocation:N.location,nextLocation:B}:pe.has(B.pathname)&&(Ut={currentLocation:B,nextLocation:N.location})}else if(Q){let Vt=pe.get(N.location.pathname);Vt?Vt.add(B.pathname):(Vt=new Set([B.pathname]),pe.set(N.location.pathname,Vt)),Ut={currentLocation:N.location,nextLocation:B}}Fe(mn({},K,{actionData:Me,loaderData:ht,historyAction:O,location:B,initialized:!0,navigation:pv,revalidation:\"idle\",restoreScrollPosition:yc(B,K.matches||N.matches),preventScrollReset:Xe,blockers:Ge}),{viewTransitionOpts:Ut,flushSync:We===!0}),O=_n.Pop,D=!1,Q=!1,G=!1,W=!1,ie=[],re=[]}async function ln(B,K){if(typeof B==\"number\"){e.history.go(B);return}let oe=Ny(N.location,N.matches,d,m.v7_prependBasename,B,m.v7_relativeSplatPath,K?.fromRouteId,K?.relative),{path:ve,submission:Oe,error:We}=sC(m.v7_normalizeFormMethod,!1,oe,K),st=N.location,Me=Iu(N.location,ve,K&&K.state);Me=mn({},Me,e.history.encodeLocation(Me));let ht=K&&K.replace!=null?K.replace:void 0,Ge=_n.Push;ht===!0?Ge=_n.Replace:ht===!1||Oe!=null&&bs(Oe.formMethod)&&Oe.formAction===N.location.pathname+N.location.search&&(Ge=_n.Replace);let Xe=K&&\"preventScrollReset\"in K?K.preventScrollReset===!0:void 0,Ut=(K&&K.unstable_flushSync)===!0,Vt=Gr({currentLocation:st,nextLocation:Me,historyAction:Ge});if(Vt){vr(Vt,{state:\"blocked\",location:Me,proceed(){vr(Vt,{state:\"proceeding\",proceed:void 0,reset:void 0,location:Me}),ln(B,K)},reset(){let Ht=new Map(N.blockers);Ht.set(Vt,eu),Fe({blockers:Ht})}});return}return await vn(Ge,Me,{submission:Oe,pendingError:We,preventScrollReset:Xe,replace:K&&K.replace,enableViewTransition:K&&K.unstable_viewTransition,flushSync:Ut})}function Sn(){if(yn(),Fe({revalidation:\"loading\"}),N.navigation.state!==\"submitting\"){if(N.navigation.state===\"idle\"){vn(N.historyAction,N.location,{startUninterruptedRevalidation:!0});return}vn(O||N.historyAction,N.navigation.location,{overrideNavigation:N.navigation})}}async function vn(B,K,oe){z&&z.abort(),z=null,O=B,G=(oe&&oe.startUninterruptedRevalidation)===!0,_d(N.location,N.matches),D=(oe&&oe.preventScrollReset)===!0,Q=(oe&&oe.enableViewTransition)===!0;let ve=u||l,Oe=oe&&oe.overrideNavigation,We=oi(ve,K,d),st=(oe&&oe.flushSync)===!0,Me=Ba(We,ve,K.pathname);if(Me.active&&Me.matches&&(We=Me.matches),!We){let{error:At,notFoundMatches:Nn,route:fn}=Jr(K.pathname);ft(K,{matches:Nn,loaderData:{},errors:{[fn.id]:At}},{flushSync:st});return}if(N.initialized&&!W&&x2(N.location,K)&&!(oe&&oe.submission&&bs(oe.submission.formMethod))){ft(K,{matches:We},{flushSync:st});return}z=new AbortController;let ht=fl(e.history,K,z.signal,oe&&oe.submission),Ge;if(oe&&oe.pendingError)Ge=[jl(We).route.id,{type:Zt.error,error:oe.pendingError}];else if(oe&&oe.submission&&bs(oe.submission.formMethod)){let At=await Cn(ht,K,oe.submission,We,Me.active,{replace:oe.replace,flushSync:st});if(At.shortCircuited)return;if(At.pendingActionResult){let[Nn,fn]=At.pendingActionResult;if(Br(fn)&&mh(fn.error)&&fn.error.status===404){z=null,ft(K,{matches:At.matches,loaderData:{},errors:{[Nn]:fn.error}});return}}We=At.matches||We,Ge=At.pendingActionResult,Oe=hv(K,oe.submission),st=!1,Me.active=!1,ht=fl(e.history,ht.url,ht.signal)}let{shortCircuited:Xe,matches:Ut,loaderData:Vt,errors:Ht}=await L(ht,K,We,Me.active,Oe,oe&&oe.submission,oe&&oe.fetcherSubmission,oe&&oe.replace,oe&&oe.initialHydration===!0,st,Ge);Xe||(z=null,ft(K,mn({matches:Ut||We},fC(Ge),{loaderData:Vt,errors:Ht})))}async function Cn(B,K,oe,ve,Oe,We){We===void 0&&(We={}),yn();let st=k2(K,oe);if(Fe({navigation:st},{flushSync:We.flushSync===!0}),Oe){let Ge=await za(ve,K.pathname,B.signal);if(Ge.type===\"aborted\")return{shortCircuited:!0};if(Ge.type===\"error\"){let{boundaryId:Xe,error:Ut}=_r(K.pathname,Ge);return{matches:Ge.partialMatches,pendingActionResult:[Xe,{type:Zt.error,error:Ut}]}}else if(Ge.matches)ve=Ge.matches;else{let{notFoundMatches:Xe,error:Ut,route:Vt}=Jr(K.pathname);return{matches:Xe,pendingActionResult:[Vt.id,{type:Zt.error,error:Ut}]}}}let Me,ht=gu(ve,K);if(!ht.route.action&&!ht.route.lazy)Me={type:Zt.error,error:lr(405,{method:B.method,pathname:K.pathname,routeId:ht.route.id})};else if(Me=(await bt(\"action\",B,[ht],ve))[0],B.signal.aborted)return{shortCircuited:!0};if(ii(Me)){let Ge;return We&&We.replace!=null?Ge=We.replace:Ge=lC(Me.response.headers.get(\"Location\"),new URL(B.url),d)===N.location.pathname+N.location.search,await Be(B,Me,{submission:oe,replace:Ge}),{shortCircuited:!0}}if(ai(Me))throw lr(400,{type:\"defer-action\"});if(Br(Me)){let Ge=jl(ve,ht.route.id);return(We&&We.replace)!==!0&&(O=_n.Push),{matches:ve,pendingActionResult:[Ge.route.id,Me]}}return{matches:ve,pendingActionResult:[ht.route.id,Me]}}async function L(B,K,oe,ve,Oe,We,st,Me,ht,Ge,Xe){let Ut=Oe||hv(K,We),Vt=We||st||mC(Ut),Ht=!G&&(!m.v7_partialHydration||!ht);if(ve){if(Ht){let Dt=X(Xe);Fe(mn({navigation:Ut},Dt!==void 0?{actionData:Dt}:{}),{flushSync:Ge})}let pt=await za(oe,K.pathname,B.signal);if(pt.type===\"aborted\")return{shortCircuited:!0};if(pt.type===\"error\"){let{boundaryId:Dt,error:or}=_r(K.pathname,pt);return{matches:pt.partialMatches,loaderData:{},errors:{[Dt]:or}}}else if(pt.matches)oe=pt.matches;else{let{error:Dt,notFoundMatches:or,route:Tt}=Jr(K.pathname);return{matches:or,loaderData:{},errors:{[Tt.id]:Dt}}}}let At=u||l,[Nn,fn]=oC(e.history,N,oe,Vt,K,m.v7_partialHydration&&ht===!0,m.v7_skipActionErrorRevalidation,W,ie,re,te,F,A,At,d,Xe);if(Rr(pt=>!(oe&&oe.some(Dt=>Dt.route.id===pt))||Nn&&Nn.some(Dt=>Dt.route.id===pt)),q=++H,Nn.length===0&&fn.length===0){let pt=ut();return ft(K,mn({matches:oe,loaderData:{},errors:Xe&&Br(Xe[1])?{[Xe[0]]:Xe[1].error}:null},fC(Xe),pt?{fetchers:new Map(N.fetchers)}:{}),{flushSync:Ge}),{shortCircuited:!0}}if(Ht){let pt={};if(!ve){pt.navigation=Ut;let Dt=X(Xe);Dt!==void 0&&(pt.actionData=Dt)}fn.length>0&&(pt.fetchers=ue(fn)),Fe(pt,{flushSync:Ge})}fn.forEach(pt=>{Y.has(pt.key)&&Bn(pt.key),pt.controller&&Y.set(pt.key,pt.controller)});let Va=()=>fn.forEach(pt=>Bn(pt.key));z&&z.signal.addEventListener(\"abort\",Va);let{loaderResults:Os,fetcherResults:Gt}=await Wt(N.matches,oe,Nn,fn,B);if(B.signal.aborted)return{shortCircuited:!0};z&&z.signal.removeEventListener(\"abort\",Va),fn.forEach(pt=>Y.delete(pt.key));let Vo=hC([...Os,...Gt]);if(Vo){if(Vo.idx>=Nn.length){let pt=fn[Vo.idx-Nn.length].key;A.add(pt)}return await Be(B,Vo.result,{replace:Me}),{shortCircuited:!0}}let{loaderData:Is,errors:Pr}=uC(N,oe,Nn,Os,Xe,fn,Gt,de);de.forEach((pt,Dt)=>{pt.subscribe(or=>{(or||pt.done)&&de.delete(Dt)})}),m.v7_partialHydration&&ht&&N.errors&&Object.entries(N.errors).filter(pt=>{let[Dt]=pt;return!Nn.some(or=>or.route.id===Dt)}).forEach(pt=>{let[Dt,or]=pt;Pr=Object.assign(Pr||{},{[Dt]:or})});let so=ut(),Vi=It(q),Ha=so||Vi||fn.length>0;return mn({matches:oe,loaderData:Is,errors:Pr},Ha?{fetchers:new Map(N.fetchers)}:{})}function X(B){if(B&&!Br(B[1]))return{[B[0]]:B[1].data};if(N.actionData)return Object.keys(N.actionData).length===0?null:N.actionData}function ue(B){return B.forEach(K=>{let oe=N.fetchers.get(K.key),ve=tu(void 0,oe?oe.data:void 0);N.fetchers.set(K.key,ve)}),new Map(N.fetchers)}function Ne(B,K,oe,ve){if(r)throw new Error(\"router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.\");Y.has(B)&&Bn(B);let Oe=(ve&&ve.unstable_flushSync)===!0,We=u||l,st=Ny(N.location,N.matches,d,m.v7_prependBasename,oe,m.v7_relativeSplatPath,K,ve?.relative),Me=oi(We,st,d),ht=Ba(Me,We,st);if(ht.active&&ht.matches&&(Me=ht.matches),!Me){En(B,K,lr(404,{pathname:st}),{flushSync:Oe});return}let{path:Ge,submission:Xe,error:Ut}=sC(m.v7_normalizeFormMethod,!0,st,ve);if(Ut){En(B,K,Ut,{flushSync:Oe});return}let Vt=gu(Me,Ge);if(D=(ve&&ve.preventScrollReset)===!0,Xe&&bs(Xe.formMethod)){je(B,K,Ge,Vt,Me,ht.active,Oe,Xe);return}F.set(B,{routeId:K,path:Ge}),Se(B,K,Ge,Vt,Me,ht.active,Oe,Xe)}async function je(B,K,oe,ve,Oe,We,st,Me){yn(),F.delete(B);function ht(Tt){if(!Tt.route.action&&!Tt.route.lazy){let fs=lr(405,{method:Me.formMethod,pathname:oe,routeId:K});return En(B,K,fs,{flushSync:st}),!0}return!1}if(!We&&ht(ve))return;let Ge=N.fetchers.get(B);bn(B,j2(Me,Ge),{flushSync:st});let Xe=new AbortController,Ut=fl(e.history,oe,Xe.signal,Me);if(We){let Tt=await za(Oe,oe,Ut.signal);if(Tt.type===\"aborted\")return;if(Tt.type===\"error\"){let{error:fs}=_r(oe,Tt);En(B,K,fs,{flushSync:st});return}else if(Tt.matches){if(Oe=Tt.matches,ve=gu(Oe,oe),ht(ve))return}else{En(B,K,lr(404,{pathname:oe}),{flushSync:st});return}}Y.set(B,Xe);let Vt=H,At=(await bt(\"action\",Ut,[ve],Oe))[0];if(Ut.signal.aborted){Y.get(B)===Xe&&Y.delete(B);return}if(m.v7_fetcherPersist&&te.has(B)){if(ii(At)||Br(At)){bn(B,da(void 0));return}}else{if(ii(At))if(Y.delete(B),q>Vt){bn(B,da(void 0));return}else return A.add(B),bn(B,tu(Me)),Be(Ut,At,{fetcherSubmission:Me});if(Br(At)){En(B,K,At.error);return}}if(ai(At))throw lr(400,{type:\"defer-action\"});let Nn=N.navigation.location||N.location,fn=fl(e.history,Nn,Xe.signal),Va=u||l,Os=N.navigation.state!==\"idle\"?oi(Va,N.navigation.location,d):N.matches;Ct(Os,\"Didn't find any matches after fetcher action\");let Gt=++H;he.set(B,Gt);let Vo=tu(Me,At.data);N.fetchers.set(B,Vo);let[Is,Pr]=oC(e.history,N,Os,Me,Nn,!1,m.v7_skipActionErrorRevalidation,W,ie,re,te,F,A,Va,d,[ve.route.id,At]);Pr.filter(Tt=>Tt.key!==B).forEach(Tt=>{let fs=Tt.key,Rd=N.fetchers.get(fs),jg=tu(void 0,Rd?Rd.data:void 0);N.fetchers.set(fs,jg),Y.has(fs)&&Bn(fs),Tt.controller&&Y.set(fs,Tt.controller)}),Fe({fetchers:new Map(N.fetchers)});let so=()=>Pr.forEach(Tt=>Bn(Tt.key));Xe.signal.addEventListener(\"abort\",so);let{loaderResults:Vi,fetcherResults:Ha}=await Wt(N.matches,Os,Is,Pr,fn);if(Xe.signal.aborted)return;Xe.signal.removeEventListener(\"abort\",so),he.delete(B),Y.delete(B),Pr.forEach(Tt=>Y.delete(Tt.key));let pt=hC([...Vi,...Ha]);if(pt){if(pt.idx>=Is.length){let Tt=Pr[pt.idx-Is.length].key;A.add(Tt)}return Be(fn,pt.result)}let{loaderData:Dt,errors:or}=uC(N,N.matches,Is,Vi,void 0,Pr,Ha,de);if(N.fetchers.has(B)){let Tt=da(At.data);N.fetchers.set(B,Tt)}It(Gt),N.navigation.state===\"loading\"&&Gt>q?(Ct(O,\"Expected pending action\"),z&&z.abort(),ft(N.navigation.location,{matches:Os,loaderData:Dt,errors:or,fetchers:new Map(N.fetchers)})):(Fe({errors:or,loaderData:dC(N.loaderData,Dt,Os,or),fetchers:new Map(N.fetchers)}),W=!1)}async function Se(B,K,oe,ve,Oe,We,st,Me){let ht=N.fetchers.get(B);bn(B,tu(Me,ht?ht.data:void 0),{flushSync:st});let Ge=new AbortController,Xe=fl(e.history,oe,Ge.signal);if(We){let At=await za(Oe,oe,Xe.signal);if(At.type===\"aborted\")return;if(At.type===\"error\"){let{error:Nn}=_r(oe,At);En(B,K,Nn,{flushSync:st});return}else if(At.matches)Oe=At.matches,ve=gu(Oe,oe);else{En(B,K,lr(404,{pathname:oe}),{flushSync:st});return}}Y.set(B,Ge);let Ut=H,Ht=(await bt(\"loader\",Xe,[ve],Oe))[0];if(ai(Ht)&&(Ht=await gj(Ht,Xe.signal,!0)||Ht),Y.get(B)===Ge&&Y.delete(B),!Xe.signal.aborted){if(te.has(B)){bn(B,da(void 0));return}if(ii(Ht))if(q>Ut){bn(B,da(void 0));return}else{A.add(B),await Be(Xe,Ht);return}if(Br(Ht)){En(B,K,Ht.error);return}Ct(!ai(Ht),\"Unhandled fetcher deferred data\"),bn(B,da(Ht.data))}}async function Be(B,K,oe){let{submission:ve,fetcherSubmission:Oe,replace:We}=oe===void 0?{}:oe;K.response.headers.has(\"X-Remix-Revalidate\")&&(W=!0);let st=K.response.headers.get(\"Location\");Ct(st,\"Expected a Location header on the redirect Response\"),st=lC(st,new URL(B.url),d);let Me=Iu(N.location,st,{_isRedirect:!0});if(n){let Ht=!1;if(K.response.headers.has(\"X-Remix-Reload-Document\"))Ht=!0;else if(Db.test(st)){const At=e.history.createURL(st);Ht=At.origin!==t.location.origin||Xl(At.pathname,d)==null}if(Ht){We?t.location.replace(st):t.location.assign(st);return}}z=null;let ht=We===!0?_n.Replace:_n.Push,{formMethod:Ge,formAction:Xe,formEncType:Ut}=N.navigation;!ve&&!Oe&&Ge&&Xe&&Ut&&(ve=mC(N.navigation));let Vt=ve||Oe;if(a2.has(K.response.status)&&Vt&&bs(Vt.formMethod))await vn(ht,Me,{submission:mn({},Vt,{formAction:st}),preventScrollReset:D});else{let Ht=hv(Me,ve);await vn(ht,Me,{overrideNavigation:Ht,fetcherSubmission:Oe,preventScrollReset:D})}}async function bt(B,K,oe,ve){try{let Oe=await g2(f,B,K,oe,ve,o,s);return await Promise.all(Oe.map((We,st)=>{if(S2(We)){let Me=We.result;return{type:Zt.redirect,response:y2(Me,K,oe[st].route.id,ve,d,m.v7_relativeSplatPath)}}return v2(We)}))}catch(Oe){return oe.map(()=>({type:Zt.error,error:Oe}))}}async function Wt(B,K,oe,ve,Oe){let[We,...st]=await Promise.all([oe.length?bt(\"loader\",Oe,oe,K):[],...ve.map(Me=>{if(Me.matches&&Me.match&&Me.controller){let ht=fl(e.history,Me.path,Me.controller.signal);return bt(\"loader\",ht,[Me.match],Me.matches).then(Ge=>Ge[0])}else return Promise.resolve({type:Zt.error,error:lr(404,{pathname:Me.path})})})]);return await Promise.all([gC(B,oe,We,We.map(()=>Oe.signal),!1,N.loaderData),gC(B,ve.map(Me=>Me.match),st,ve.map(Me=>Me.controller?Me.controller.signal:null),!0)]),{loaderResults:We,fetcherResults:st}}function yn(){W=!0,ie.push(...Rr()),F.forEach((B,K)=>{Y.has(K)&&(re.push(K),Bn(K))})}function bn(B,K,oe){oe===void 0&&(oe={}),N.fetchers.set(B,K),Fe({fetchers:new Map(N.fetchers)},{flushSync:(oe&&oe.flushSync)===!0})}function En(B,K,oe,ve){ve===void 0&&(ve={});let Oe=jl(N.matches,K);Qn(B),Fe({errors:{[Oe.route.id]:oe},fetchers:new Map(N.fetchers)},{flushSync:(ve&&ve.flushSync)===!0})}function gr(B){return m.v7_fetcherPersist&&(fe.set(B,(fe.get(B)||0)+1),te.has(B)&&te.delete(B)),N.fetchers.get(B)||i2}function Qn(B){let K=N.fetchers.get(B);Y.has(B)&&!(K&&K.state===\"loading\"&&he.has(B))&&Bn(B),F.delete(B),he.delete(B),A.delete(B),te.delete(B),N.fetchers.delete(B)}function ro(B){if(m.v7_fetcherPersist){let K=(fe.get(B)||0)-1;K<=0?(fe.delete(B),te.add(B)):fe.set(B,K)}else Qn(B);Fe({fetchers:new Map(N.fetchers)})}function Bn(B){let K=Y.get(B);Ct(K,\"Expected fetch controller: \"+B),K.abort(),Y.delete(B)}function Te(B){for(let K of B){let oe=gr(K),ve=da(oe.data);N.fetchers.set(K,ve)}}function ut(){let B=[],K=!1;for(let oe of A){let ve=N.fetchers.get(oe);Ct(ve,\"Expected fetcher: \"+oe),ve.state===\"loading\"&&(A.delete(oe),B.push(oe),K=!0)}return Te(B),K}function It(B){let K=[];for(let[oe,ve]of he)if(ve<B){let Oe=N.fetchers.get(oe);Ct(Oe,\"Expected fetcher: \"+oe),Oe.state===\"loading\"&&(Bn(oe),he.delete(oe),K.push(oe))}return Te(K),K.length>0}function Tn(B,K){let oe=N.blockers.get(B)||eu;return ge.get(B)!==K&&ge.set(B,K),oe}function mr(B){N.blockers.delete(B),ge.delete(B)}function vr(B,K){let oe=N.blockers.get(B)||eu;Ct(oe.state===\"unblocked\"&&K.state===\"blocked\"||oe.state===\"blocked\"&&K.state===\"blocked\"||oe.state===\"blocked\"&&K.state===\"proceeding\"||oe.state===\"blocked\"&&K.state===\"unblocked\"||oe.state===\"proceeding\"&&K.state===\"unblocked\",\"Invalid blocker state transition: \"+oe.state+\" -> \"+K.state);let ve=new Map(N.blockers);ve.set(B,K),Fe({blockers:ve})}function Gr(B){let{currentLocation:K,nextLocation:oe,historyAction:ve}=B;if(ge.size===0)return;ge.size>1&&Ll(!1,\"A router only supports one blocker at a time\");let Oe=Array.from(ge.entries()),[We,st]=Oe[Oe.length-1],Me=N.blockers.get(We);if(!(Me&&Me.state===\"proceeding\")&&st({currentLocation:K,nextLocation:oe,historyAction:ve}))return We}function Jr(B){let K=lr(404,{pathname:B}),oe=u||l,{matches:ve,route:Oe}=pC(oe);return Rr(),{notFoundMatches:ve,route:Oe,error:K}}function _r(B,K){return{boundaryId:jl(K.partialMatches).route.id,error:lr(400,{type:\"route-discovery\",pathname:B,message:K.error!=null&&\"message\"in K.error?K.error:String(K.error)})}}function Rr(B){let K=[];return de.forEach((oe,ve)=>{(!B||B(ve))&&(oe.cancel(),K.push(ve),de.delete(ve))}),K}function Uo(B,K,oe){if(b=B,C=K,w=oe||null,!k&&N.navigation===pv){k=!0;let ve=yc(N.location,N.matches);ve!=null&&Fe({restoreScrollPosition:ve})}return()=>{b=null,C=null,w=null}}function vc(B,K){return w&&w(B,K.map(ve=>LF(ve,N.loaderData)))||B.key}function _d(B,K){if(b&&C){let oe=vc(B,K);b[oe]=C()}}function yc(B,K){if(b){let oe=vc(B,K),ve=b[oe];if(typeof ve==\"number\")return ve}return null}function Ba(B,K,oe){if(h)if(B){let ve=B[B.length-1].route;if(ve.path&&(ve.path===\"*\"||ve.path.endsWith(\"/*\")))return{active:!0,matches:cp(K,oe,d,!0)}}else return{active:!0,matches:cp(K,oe,d,!0)||[]};return{active:!1,matches:null}}async function za(B,K,oe){let ve=B,Oe=ve.length>0?ve[ve.length-1].route:null;for(;;){let We=u==null,st=u||l;try{await p2(h,K,ve,st,o,s,Z,oe)}catch(Xe){return{type:\"error\",error:Xe,partialMatches:ve}}finally{We&&(l=[...l])}if(oe.aborted)return{type:\"aborted\"};let Me=oi(st,K,d),ht=!1;if(Me){let Xe=Me[Me.length-1].route;if(Xe.index)return{type:\"success\",matches:Me};if(Xe.path&&Xe.path.length>0)if(Xe.path===\"*\")ht=!0;else return{type:\"success\",matches:Me}}let Ge=cp(st,K,d,!0);if(!Ge||ve.map(Xe=>Xe.route.id).join(\"-\")===Ge.map(Xe=>Xe.route.id).join(\"-\"))return{type:\"success\",matches:ht?Me:null};if(ve=Ge,Oe=ve[ve.length-1].route,Oe.path===\"*\")return{type:\"success\",matches:ve}}}function Ua(B){o={},u=Au(B,s,void 0,o)}function bc(B,K){let oe=u==null;fj(B,K,u||l,o,s),oe&&(l=[...l],Fe({}))}return R={get basename(){return d},get future(){return m},get state(){return N},get routes(){return l},get window(){return t},initialize:Re,subscribe:Ye,enableScrollRestoration:Uo,navigate:ln,fetch:Ne,revalidate:Sn,createHref:B=>e.history.createHref(B),encodeLocation:B=>e.history.encodeLocation(B),getFetcher:gr,deleteFetcher:ro,dispose:$e,getBlocker:Tn,deleteBlocker:mr,patchRoutes:bc,_internalFetchControllers:Y,_internalActiveDeferreds:de,_internalSetRoutes:Ua},R}function u2(e){return e!=null&&(\"formData\"in e&&e.formData!=null||\"body\"in e&&e.body!==void 0)}function Ny(e,t,n,r,s,o,l,u){let d,f;if(l){d=[];for(let m of t)if(d.push(m),m.route.id===l){f=m;break}}else d=t,f=t[t.length-1];let h=gh(s||\".\",hh(d,o),Xl(e.pathname,n)||e.pathname,u===\"path\");return s==null&&(h.search=e.search,h.hash=e.hash),(s==null||s===\"\"||s===\".\")&&f&&f.route.index&&!Fb(h.search)&&(h.search=h.search?h.search.replace(/^\\?/,\"?index&\"):\"?index\"),r&&n!==\"/\"&&(h.pathname=h.pathname===\"/\"?n:To([n,h.pathname])),wi(h)}function sC(e,t,n,r){if(!r||!u2(r))return{path:n};if(r.formMethod&&!E2(r.formMethod))return{path:n,error:lr(405,{method:r.formMethod})};let s=()=>({path:n,error:lr(400,{type:\"invalid-body\"})}),o=r.formMethod||\"get\",l=e?o.toUpperCase():o.toLowerCase(),u=pj(n);if(r.body!==void 0){if(r.formEncType===\"text/plain\"){if(!bs(l))return s();let g=typeof r.body==\"string\"?r.body:r.body instanceof FormData||r.body instanceof URLSearchParams?Array.from(r.body.entries()).reduce((x,b)=>{let[w,C]=b;return\"\"+x+w+\"=\"+C+`\n`},\"\"):String(r.body);return{path:n,submission:{formMethod:l,formAction:u,formEncType:r.formEncType,formData:void 0,json:void 0,text:g}}}else if(r.formEncType===\"application/json\"){if(!bs(l))return s();try{let g=typeof r.body==\"string\"?JSON.parse(r.body):r.body;return{path:n,submission:{formMethod:l,formAction:u,formEncType:r.formEncType,formData:void 0,json:g,text:void 0}}}catch{return s()}}}Ct(typeof FormData==\"function\",\"FormData is not available in this environment\");let d,f;if(r.formData)d=My(r.formData),f=r.formData;else if(r.body instanceof FormData)d=My(r.body),f=r.body;else if(r.body instanceof URLSearchParams)d=r.body,f=cC(d);else if(r.body==null)d=new URLSearchParams,f=new FormData;else try{d=new URLSearchParams(r.body),f=cC(d)}catch{return s()}let h={formMethod:l,formAction:u,formEncType:r&&r.formEncType||\"application/x-www-form-urlencoded\",formData:f,json:void 0,text:void 0};if(bs(h.formMethod))return{path:n,submission:h};let m=_a(n);return t&&m.search&&Fb(m.search)&&d.append(\"index\",\"\"),m.search=\"?\"+d,{path:wi(m),submission:h}}function d2(e,t){let n=e;if(t){let r=e.findIndex(s=>s.route.id===t);r>=0&&(n=e.slice(0,r))}return n}function oC(e,t,n,r,s,o,l,u,d,f,h,m,g,x,b,w){let C=w?Br(w[1])?w[1].error:w[1].data:void 0,k=e.createURL(t.location),j=e.createURL(s),M=w&&Br(w[1])?w[0]:void 0,_=M?d2(n,M):n,R=w?w[1].statusCode:void 0,N=l&&R&&R>=400,O=_.filter((z,Q)=>{let{route:pe}=z;if(pe.lazy)return!0;if(pe.loader==null)return!1;if(o)return typeof pe.loader!=\"function\"||pe.loader.hydrate?!0:t.loaderData[pe.id]===void 0&&(!t.errors||t.errors[pe.id]===void 0);if(f2(t.loaderData,t.matches[Q],z)||d.some(W=>W===z.route.id))return!0;let V=t.matches[Q],G=z;return aC(z,mn({currentUrl:k,currentParams:V.params,nextUrl:j,nextParams:G.params},r,{actionResult:C,actionStatus:R,defaultShouldRevalidate:N?!1:u||k.pathname+k.search===j.pathname+j.search||k.search!==j.search||dj(V,G)}))}),D=[];return m.forEach((z,Q)=>{if(o||!n.some(ie=>ie.route.id===z.routeId)||h.has(Q))return;let pe=oi(x,z.path,b);if(!pe){D.push({key:Q,routeId:z.routeId,path:z.path,matches:null,match:null,controller:null});return}let V=t.fetchers.get(Q),G=gu(pe,z.path),W=!1;g.has(Q)?W=!1:f.includes(Q)?W=!0:V&&V.state!==\"idle\"&&V.data===void 0?W=u:W=aC(G,mn({currentUrl:k,currentParams:t.matches[t.matches.length-1].params,nextUrl:j,nextParams:n[n.length-1].params},r,{actionResult:C,actionStatus:R,defaultShouldRevalidate:N?!1:u})),W&&D.push({key:Q,routeId:z.routeId,path:z.path,matches:pe,match:G,controller:new AbortController})}),[O,D]}function f2(e,t,n){let r=!t||n.route.id!==t.route.id,s=e[n.route.id]===void 0;return r||s}function dj(e,t){let n=e.route.path;return e.pathname!==t.pathname||n!=null&&n.endsWith(\"*\")&&e.params[\"*\"]!==t.params[\"*\"]}function aC(e,t){if(e.route.shouldRevalidate){let n=e.route.shouldRevalidate(t);if(typeof n==\"boolean\")return n}return t.defaultShouldRevalidate}async function p2(e,t,n,r,s,o,l,u){let d=[t,...n.map(f=>f.route.id)].join(\"-\");try{let f=l.get(d);f||(f=e({path:t,matches:n,patch:(h,m)=>{u.aborted||fj(h,m,r,s,o)}}),l.set(d,f)),f&&w2(f)&&await f}finally{l.delete(d)}}function fj(e,t,n,r,s){if(e){var o;let l=r[e];Ct(l,\"No route found to patch children into: routeId = \"+e);let u=Au(t,s,[e,\"patch\",String(((o=l.children)==null?void 0:o.length)||\"0\")],r);l.children?l.children.push(...u):l.children=u}else{let l=Au(t,s,[\"patch\",String(n.length||\"0\")],r);n.push(...l)}}async function iC(e,t,n){if(!e.lazy)return;let r=await e.lazy();if(!e.lazy)return;let s=n[e.id];Ct(s,\"No route found in manifest\");let o={};for(let l in r){let d=s[l]!==void 0&&l!==\"hasErrorBoundary\";Ll(!d,'Route \"'+s.id+'\" has a static property \"'+l+'\" defined but its lazy function is also returning a value for this property. '+('The lazy route property \"'+l+'\" will be ignored.')),!d&&!DF.has(l)&&(o[l]=r[l])}Object.assign(s,o),Object.assign(s,mn({},t(s),{lazy:void 0}))}function h2(e){return Promise.all(e.matches.map(t=>t.resolve()))}async function g2(e,t,n,r,s,o,l,u){let d=r.reduce((m,g)=>m.add(g.route.id),new Set),f=new Set,h=await e({matches:s.map(m=>{let g=d.has(m.route.id);return mn({},m,{shouldLoad:g,resolve:b=>(f.add(m.route.id),g?m2(t,n,m,o,l,b,u):Promise.resolve({type:Zt.data,result:void 0}))})}),request:n,params:s[0].params,context:u});return s.forEach(m=>Ct(f.has(m.route.id),'`match.resolve()` was not called for route id \"'+m.route.id+'\". You must call `match.resolve()` on every match passed to `dataStrategy` to ensure all routes are properly loaded.')),h.filter((m,g)=>d.has(s[g].route.id))}async function m2(e,t,n,r,s,o,l){let u,d,f=h=>{let m,g=new Promise((w,C)=>m=C);d=()=>m(),t.signal.addEventListener(\"abort\",d);let x=w=>typeof h!=\"function\"?Promise.reject(new Error(\"You cannot call the handler for a route which defines a boolean \"+('\"'+e+'\" [routeId: '+n.route.id+\"]\"))):h({request:t,params:n.params,context:l},...w!==void 0?[w]:[]),b;return o?b=o(w=>x(w)):b=(async()=>{try{return{type:\"data\",result:await x()}}catch(w){return{type:\"error\",result:w}}})(),Promise.race([b,g])};try{let h=n.route[e];if(n.route.lazy)if(h){let m,[g]=await Promise.all([f(h).catch(x=>{m=x}),iC(n.route,s,r)]);if(m!==void 0)throw m;u=g}else if(await iC(n.route,s,r),h=n.route[e],h)u=await f(h);else if(e===\"action\"){let m=new URL(t.url),g=m.pathname+m.search;throw lr(405,{method:t.method,pathname:g,routeId:n.route.id})}else return{type:Zt.data,result:void 0};else if(h)u=await f(h);else{let m=new URL(t.url),g=m.pathname+m.search;throw lr(404,{pathname:g})}Ct(u.result!==void 0,\"You defined \"+(e===\"action\"?\"an action\":\"a loader\")+\" for route \"+('\"'+n.route.id+\"\\\" but didn't return anything from your `\"+e+\"` \")+\"function. Please return a value or `null`.\")}catch(h){return{type:Zt.error,result:h}}finally{d&&t.signal.removeEventListener(\"abort\",d)}return u}async function v2(e){let{result:t,type:n,status:r}=e;if(hj(t)){let l;try{let u=t.headers.get(\"Content-Type\");u&&/\\bapplication\\/json\\b/.test(u)?t.body==null?l=null:l=await t.json():l=await t.text()}catch(u){return{type:Zt.error,error:u}}return n===Zt.error?{type:Zt.error,error:new Ab(t.status,t.statusText,l),statusCode:t.status,headers:t.headers}:{type:Zt.data,data:l,statusCode:t.status,headers:t.headers}}if(n===Zt.error)return{type:Zt.error,error:t,statusCode:mh(t)?t.status:r};if(C2(t)){var s,o;return{type:Zt.deferred,deferredData:t,statusCode:(s=t.init)==null?void 0:s.status,headers:((o=t.init)==null?void 0:o.headers)&&new Headers(t.init.headers)}}return{type:Zt.data,data:t,statusCode:r}}function y2(e,t,n,r,s,o){let l=e.headers.get(\"Location\");if(Ct(l,\"Redirects returned/thrown from loaders/actions must have a Location header\"),!Db.test(l)){let u=r.slice(0,r.findIndex(d=>d.route.id===n)+1);l=Ny(new URL(t.url),u,s,!0,l,o),e.headers.set(\"Location\",l)}return e}function lC(e,t,n){if(Db.test(e)){let r=e,s=r.startsWith(\"//\")?new URL(t.protocol+r):new URL(r),o=Xl(s.pathname,n)!=null;if(s.origin===t.origin&&o)return s.pathname+s.search+s.hash}return e}function fl(e,t,n,r){let s=e.createURL(pj(t)).toString(),o={signal:n};if(r&&bs(r.formMethod)){let{formMethod:l,formEncType:u}=r;o.method=l.toUpperCase(),u===\"application/json\"?(o.headers=new Headers({\"Content-Type\":u}),o.body=JSON.stringify(r.json)):u===\"text/plain\"?o.body=r.text:u===\"application/x-www-form-urlencoded\"&&r.formData?o.body=My(r.formData):o.body=r.formData}return new Request(s,o)}function My(e){let t=new URLSearchParams;for(let[n,r]of e.entries())t.append(n,typeof r==\"string\"?r:r.name);return t}function cC(e){let t=new FormData;for(let[n,r]of e.entries())t.append(n,r);return t}function b2(e,t,n,r,s,o){let l={},u=null,d,f=!1,h={},m=r&&Br(r[1])?r[1].error:void 0;return n.forEach((g,x)=>{let b=t[x].route.id;if(Ct(!ii(g),\"Cannot handle redirect results in processLoaderData\"),Br(g)){let w=g.error;m!==void 0&&(w=m,m=void 0),u=u||{};{let C=jl(e,b);u[C.route.id]==null&&(u[C.route.id]=w)}l[b]=void 0,f||(f=!0,d=mh(g.error)?g.error.status:500),g.headers&&(h[b]=g.headers)}else ai(g)?(s.set(b,g.deferredData),l[b]=g.deferredData.data,g.statusCode!=null&&g.statusCode!==200&&!f&&(d=g.statusCode),g.headers&&(h[b]=g.headers)):(l[b]=g.data,g.statusCode&&g.statusCode!==200&&!f&&(d=g.statusCode),g.headers&&(h[b]=g.headers))}),m!==void 0&&r&&(u={[r[0]]:m},l[r[0]]=void 0),{loaderData:l,errors:u,statusCode:d||200,loaderHeaders:h}}function uC(e,t,n,r,s,o,l,u){let{loaderData:d,errors:f}=b2(t,n,r,s,u);for(let h=0;h<o.length;h++){let{key:m,match:g,controller:x}=o[h];Ct(l!==void 0&&l[h]!==void 0,\"Did not find corresponding fetcher result\");let b=l[h];if(!(x&&x.signal.aborted))if(Br(b)){let w=jl(e.matches,g?.route.id);f&&f[w.route.id]||(f=mn({},f,{[w.route.id]:b.error})),e.fetchers.delete(m)}else if(ii(b))Ct(!1,\"Unhandled fetcher revalidation redirect\");else if(ai(b))Ct(!1,\"Unhandled fetcher deferred data\");else{let w=da(b.data);e.fetchers.set(m,w)}}return{loaderData:d,errors:f}}function dC(e,t,n,r){let s=mn({},t);for(let o of n){let l=o.route.id;if(t.hasOwnProperty(l)?t[l]!==void 0&&(s[l]=t[l]):e[l]!==void 0&&o.route.loader&&(s[l]=e[l]),r&&r.hasOwnProperty(l))break}return s}function fC(e){return e?Br(e[1])?{actionData:{}}:{actionData:{[e[0]]:e[1].data}}:{}}function jl(e,t){return(t?e.slice(0,e.findIndex(r=>r.route.id===t)+1):[...e]).reverse().find(r=>r.route.hasErrorBoundary===!0)||e[0]}function pC(e){let t=e.length===1?e[0]:e.find(n=>n.index||!n.path||n.path===\"/\")||{id:\"__shim-error-route__\"};return{matches:[{params:{},pathname:\"\",pathnameBase:\"\",route:t}],route:t}}function lr(e,t){let{pathname:n,routeId:r,method:s,type:o,message:l}=t===void 0?{}:t,u=\"Unknown Server Error\",d=\"Unknown @remix-run/router error\";return e===400?(u=\"Bad Request\",o===\"route-discovery\"?d='Unable to match URL \"'+n+'\" - the `unstable_patchRoutesOnMiss()` '+(`function threw the following error:\n`+l):s&&n&&r?d=\"You made a \"+s+' request to \"'+n+'\" but '+('did not provide a `loader` for route \"'+r+'\", ')+\"so there is no way to handle the request.\":o===\"defer-action\"?d=\"defer() is not supported in actions\":o===\"invalid-body\"&&(d=\"Unable to encode submission body\")):e===403?(u=\"Forbidden\",d='Route \"'+r+'\" does not match URL \"'+n+'\"'):e===404?(u=\"Not Found\",d='No route matches URL \"'+n+'\"'):e===405&&(u=\"Method Not Allowed\",s&&n&&r?d=\"You made a \"+s.toUpperCase()+' request to \"'+n+'\" but '+('did not provide an `action` for route \"'+r+'\", ')+\"so there is no way to handle the request.\":s&&(d='Invalid request method \"'+s.toUpperCase()+'\"')),new Ab(e||500,u,new Error(d),!0)}function hC(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(ii(n))return{result:n,idx:t}}}function pj(e){let t=typeof e==\"string\"?_a(e):e;return wi(mn({},t,{hash:\"\"}))}function x2(e,t){return e.pathname!==t.pathname||e.search!==t.search?!1:e.hash===\"\"?t.hash!==\"\":e.hash===t.hash?!0:t.hash!==\"\"}function w2(e){return typeof e==\"object\"&&e!=null&&\"then\"in e}function S2(e){return hj(e.result)&&o2.has(e.result.status)}function ai(e){return e.type===Zt.deferred}function Br(e){return e.type===Zt.error}function ii(e){return(e&&e.type)===Zt.redirect}function C2(e){let t=e;return t&&typeof t==\"object\"&&typeof t.data==\"object\"&&typeof t.subscribe==\"function\"&&typeof t.cancel==\"function\"&&typeof t.resolveData==\"function\"}function hj(e){return e!=null&&typeof e.status==\"number\"&&typeof e.statusText==\"string\"&&typeof e.headers==\"object\"&&typeof e.body<\"u\"}function E2(e){return s2.has(e.toLowerCase())}function bs(e){return n2.has(e.toLowerCase())}async function gC(e,t,n,r,s,o){for(let l=0;l<n.length;l++){let u=n[l],d=t[l];if(!d)continue;let f=e.find(m=>m.route.id===d.route.id),h=f!=null&&!dj(f,d)&&(o&&o[d.route.id])!==void 0;if(ai(u)&&(s||h)){let m=r[l];Ct(m,\"Expected an AbortSignal for revalidating fetcher deferred result\"),await gj(u,m,s).then(g=>{g&&(n[l]=g||n[l])})}}}async function gj(e,t,n){if(n===void 0&&(n=!1),!await e.deferredData.resolveData(t)){if(n)try{return{type:Zt.data,data:e.deferredData.unwrappedData}}catch(s){return{type:Zt.error,error:s}}return{type:Zt.data,data:e.deferredData.data}}}function Fb(e){return new URLSearchParams(e).getAll(\"index\").some(t=>t===\"\")}function gu(e,t){let n=typeof t==\"string\"?_a(t).search:t.search;if(e[e.length-1].route.index&&Fb(n||\"\"))return e[e.length-1];let r=lj(e);return r[r.length-1]}function mC(e){let{formMethod:t,formAction:n,formEncType:r,text:s,formData:o,json:l}=e;if(!(!t||!n||!r)){if(s!=null)return{formMethod:t,formAction:n,formEncType:r,formData:void 0,json:void 0,text:s};if(o!=null)return{formMethod:t,formAction:n,formEncType:r,formData:o,json:void 0,text:void 0};if(l!==void 0)return{formMethod:t,formAction:n,formEncType:r,formData:void 0,json:l,text:void 0}}}function hv(e,t){return t?{state:\"loading\",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}:{state:\"loading\",location:e,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}function k2(e,t){return{state:\"submitting\",location:e,formMethod:t.formMethod,formAction:t.formAction,formEncType:t.formEncType,formData:t.formData,json:t.json,text:t.text}}function tu(e,t){return e?{state:\"loading\",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t}:{state:\"loading\",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:t}}function j2(e,t){return{state:\"submitting\",formMethod:e.formMethod,formAction:e.formAction,formEncType:e.formEncType,formData:e.formData,json:e.json,text:e.text,data:t?t.data:void 0}}function da(e){return{state:\"idle\",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:e}}function T2(e,t){try{let n=e.sessionStorage.getItem(uj);if(n){let r=JSON.parse(n);for(let[s,o]of Object.entries(r||{}))o&&Array.isArray(o)&&t.set(s,new Set(o||[]))}}catch{}}function N2(e,t){if(t.size>0){let n={};for(let[r,s]of t)n[r]=[...s];try{e.sessionStorage.setItem(uj,JSON.stringify(n))}catch(r){Ll(!1,\"Failed to save applied view transitions in sessionStorage (\"+r+\").\")}}}/**\n * React Router v6.25.1\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */function Rp(){return Rp=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Rp.apply(this,arguments)}const vh=y.createContext(null),mj=y.createContext(null),Ra=y.createContext(null),Lb=y.createContext(null),Po=y.createContext({outlet:null,matches:[],isDataRoute:!1}),vj=y.createContext(null);function M2(e,t){let{relative:n}=t===void 0?{}:t;ec()||Ct(!1);let{basename:r,navigator:s}=y.useContext(Ra),{hash:o,pathname:l,search:u}=bj(e,{relative:n}),d=l;return r!==\"/\"&&(d=l===\"/\"?r:To([r,l])),s.createHref({pathname:d,search:u,hash:o})}function ec(){return y.useContext(Lb)!=null}function Pi(){return ec()||Ct(!1),y.useContext(Lb).location}function yj(e){y.useContext(Ra).static||y.useLayoutEffect(e)}function dn(){let{isDataRoute:e}=y.useContext(Po);return e?z2():_2()}function _2(){ec()||Ct(!1);let e=y.useContext(vh),{basename:t,future:n,navigator:r}=y.useContext(Ra),{matches:s}=y.useContext(Po),{pathname:o}=Pi(),l=JSON.stringify(hh(s,n.v7_relativeSplatPath)),u=y.useRef(!1);return yj(()=>{u.current=!0}),y.useCallback(function(f,h){if(h===void 0&&(h={}),!u.current)return;if(typeof f==\"number\"){r.go(f);return}let m=gh(f,JSON.parse(l),o,h.relative===\"path\");e==null&&t!==\"/\"&&(m.pathname=m.pathname===\"/\"?t:To([t,m.pathname])),(h.replace?r.replace:r.push)(m,h.state,h)},[t,r,l,o,e])}function ls(){let{matches:e}=y.useContext(Po),t=e[e.length-1];return t?t.params:{}}function bj(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=y.useContext(Ra),{matches:s}=y.useContext(Po),{pathname:o}=Pi(),l=JSON.stringify(hh(s,r.v7_relativeSplatPath));return y.useMemo(()=>gh(e,JSON.parse(l),o,n===\"path\"),[e,l,o,n])}function R2(e,t,n,r){ec()||Ct(!1);let{navigator:s}=y.useContext(Ra),{matches:o}=y.useContext(Po),l=o[o.length-1],u=l?l.params:{};l&&l.pathname;let d=l?l.pathnameBase:\"/\";l&&l.route;let f=Pi(),h;h=f;let m=h.pathname||\"/\",g=m;if(d!==\"/\"){let w=d.replace(/^\\//,\"\").split(\"/\");g=\"/\"+m.replace(/^\\//,\"\").split(\"/\").slice(w.length).join(\"/\")}let x=oi(e,{pathname:g});return D2(x&&x.map(w=>Object.assign({},w,{params:Object.assign({},u,w.params),pathname:To([d,s.encodeLocation?s.encodeLocation(w.pathname).pathname:w.pathname]),pathnameBase:w.pathnameBase===\"/\"?d:To([d,s.encodeLocation?s.encodeLocation(w.pathnameBase).pathname:w.pathnameBase])})),o,n,r)}function P2(){let e=B2(),t=mh(e)?e.status+\" \"+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,s={padding:\"0.5rem\",backgroundColor:\"rgba(200,200,200, 0.5)\"};return y.createElement(y.Fragment,null,y.createElement(\"h2\",null,\"Unexpected Application Error!\"),y.createElement(\"h3\",{style:{fontStyle:\"italic\"}},t),n?y.createElement(\"pre\",{style:s},n):null,null)}const O2=y.createElement(P2,null);class I2 extends y.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,n){return n.location!==t.location||n.revalidation!==\"idle\"&&t.revalidation===\"idle\"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error(\"React Router caught the following error during render\",t,n)}render(){return this.state.error!==void 0?y.createElement(Po.Provider,{value:this.props.routeContext},y.createElement(vj.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function A2(e){let{routeContext:t,match:n,children:r}=e,s=y.useContext(vh);return s&&s.static&&s.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=n.route.id),y.createElement(Po.Provider,{value:t},r)}function D2(e,t,n,r){var s;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var o;if((o=n)!=null&&o.errors)e=n.matches;else return null}let l=e,u=(s=n)==null?void 0:s.errors;if(u!=null){let h=l.findIndex(m=>m.route.id&&u?.[m.route.id]!==void 0);h>=0||Ct(!1),l=l.slice(0,Math.min(l.length,h+1))}let d=!1,f=-1;if(n&&r&&r.v7_partialHydration)for(let h=0;h<l.length;h++){let m=l[h];if((m.route.HydrateFallback||m.route.hydrateFallbackElement)&&(f=h),m.route.id){let{loaderData:g,errors:x}=n,b=m.route.loader&&g[m.route.id]===void 0&&(!x||x[m.route.id]===void 0);if(m.route.lazy||b){d=!0,f>=0?l=l.slice(0,f+1):l=[l[0]];break}}}return l.reduceRight((h,m,g)=>{let x,b=!1,w=null,C=null;n&&(x=u&&m.route.id?u[m.route.id]:void 0,w=m.route.errorElement||O2,d&&(f<0&&g===0?(U2(\"route-fallback\"),b=!0,C=null):f===g&&(b=!0,C=m.route.hydrateFallbackElement||null)));let k=t.concat(l.slice(0,g+1)),j=()=>{let M;return x?M=w:b?M=C:m.route.Component?M=y.createElement(m.route.Component,null):m.route.element?M=m.route.element:M=h,y.createElement(A2,{match:m,routeContext:{outlet:h,matches:k,isDataRoute:n!=null},children:M})};return n&&(m.route.ErrorBoundary||m.route.errorElement||g===0)?y.createElement(I2,{location:n.location,revalidation:n.revalidation,component:w,error:x,children:j(),routeContext:{outlet:null,matches:k,isDataRoute:!0}}):j()},null)}var xj=(function(e){return e.UseBlocker=\"useBlocker\",e.UseRevalidator=\"useRevalidator\",e.UseNavigateStable=\"useNavigate\",e})(xj||{}),wj=(function(e){return e.UseBlocker=\"useBlocker\",e.UseLoaderData=\"useLoaderData\",e.UseActionData=\"useActionData\",e.UseRouteError=\"useRouteError\",e.UseNavigation=\"useNavigation\",e.UseRouteLoaderData=\"useRouteLoaderData\",e.UseMatches=\"useMatches\",e.UseRevalidator=\"useRevalidator\",e.UseNavigateStable=\"useNavigate\",e.UseRouteId=\"useRouteId\",e})(wj||{});function F2(e){let t=y.useContext(vh);return t||Ct(!1),t}function L2(e){let t=y.useContext(mj);return t||Ct(!1),t}function $2(e){let t=y.useContext(Po);return t||Ct(!1),t}function Sj(e){let t=$2(),n=t.matches[t.matches.length-1];return n.route.id||Ct(!1),n.route.id}function B2(){var e;let t=y.useContext(vj),n=L2(wj.UseRouteError),r=Sj();return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function z2(){let{router:e}=F2(xj.UseNavigateStable),t=Sj(),n=y.useRef(!1);return yj(()=>{n.current=!0}),y.useCallback(function(s,o){o===void 0&&(o={}),n.current&&(typeof s==\"number\"?e.navigate(s):e.navigate(s,Rp({fromRouteId:t},o)))},[e,t])}const vC={};function U2(e,t,n){vC[e]||(vC[e]=!0)}function Cj(e){let{to:t,replace:n,state:r,relative:s}=e;ec()||Ct(!1);let{future:o,static:l}=y.useContext(Ra),{matches:u}=y.useContext(Po),{pathname:d}=Pi(),f=dn(),h=gh(t,hh(u,o.v7_relativeSplatPath),d,s===\"path\"),m=JSON.stringify(h);return y.useEffect(()=>f(JSON.parse(m),{replace:n,state:r,relative:s}),[f,m,s,n,r]),null}function V2(e){let{basename:t=\"/\",children:n=null,location:r,navigationType:s=_n.Pop,navigator:o,static:l=!1,future:u}=e;ec()&&Ct(!1);let d=t.replace(/^\\/*/,\"/\"),f=y.useMemo(()=>({basename:d,navigator:o,static:l,future:Rp({v7_relativeSplatPath:!1},u)}),[d,u,o,l]);typeof r==\"string\"&&(r=_a(r));let{pathname:h=\"/\",search:m=\"\",hash:g=\"\",state:x=null,key:b=\"default\"}=r,w=y.useMemo(()=>{let C=Xl(h,d);return C==null?null:{location:{pathname:C,search:m,hash:g,state:x,key:b},navigationType:s}},[d,h,m,g,x,b,s]);return w==null?null:y.createElement(Ra.Provider,{value:f},y.createElement(Lb.Provider,{children:n,value:w}))}new Promise(()=>{});function H2(e){let t={hasErrorBoundary:e.ErrorBoundary!=null||e.errorElement!=null};return e.Component&&Object.assign(t,{element:y.createElement(e.Component),Component:void 0}),e.HydrateFallback&&Object.assign(t,{hydrateFallbackElement:y.createElement(e.HydrateFallback),HydrateFallback:void 0}),e.ErrorBoundary&&Object.assign(t,{errorElement:y.createElement(e.ErrorBoundary),ErrorBoundary:void 0}),t}/**\n * React Router DOM v6.25.1\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */function Du(){return Du=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Du.apply(this,arguments)}function q2(e,t){if(e==null)return{};var n={},r=Object.keys(e),s,o;for(o=0;o<r.length;o++)s=r[o],!(t.indexOf(s)>=0)&&(n[s]=e[s]);return n}function K2(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function W2(e,t){return e.button===0&&(!t||t===\"_self\")&&!K2(e)}function _y(e){return e===void 0&&(e=\"\"),new URLSearchParams(typeof e==\"string\"||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(s=>[n,s]):[[n,r]])},[]))}function G2(e,t){let n=_y(e);return t&&t.forEach((r,s)=>{n.has(s)||t.getAll(s).forEach(o=>{n.append(s,o)})}),n}const J2=[\"onClick\",\"relative\",\"reloadDocument\",\"replace\",\"state\",\"target\",\"to\",\"preventScrollReset\",\"unstable_viewTransition\"],Q2=\"6\";try{window.__reactRouterVersion=Q2}catch{}function Z2(e,t){return c2({basename:void 0,future:Du({},void 0,{v7_prependBasename:!0}),history:OF({window:void 0}),hydrationData:Y2(),routes:e,mapRouteProperties:H2,unstable_dataStrategy:void 0,unstable_patchRoutesOnMiss:void 0,window:void 0}).initialize()}function Y2(){var e;let t=(e=window)==null?void 0:e.__staticRouterHydrationData;return t&&t.errors&&(t=Du({},t,{errors:X2(t.errors)})),t}function X2(e){if(!e)return null;let t=Object.entries(e),n={};for(let[r,s]of t)if(s&&s.__type===\"RouteErrorResponse\")n[r]=new Ab(s.status,s.statusText,s.data,s.internal===!0);else if(s&&s.__type===\"Error\"){if(s.__subType){let o=window[s.__subType];if(typeof o==\"function\")try{let l=new o(s.message);l.stack=\"\",n[r]=l}catch{}}if(n[r]==null){let o=new Error(s.message);o.stack=\"\",n[r]=o}}else n[r]=s;return n}const eL=y.createContext({isTransitioning:!1}),tL=y.createContext(new Map),nL=\"startTransition\",yC=Yl[nL],rL=\"flushSync\",bC=PF[rL];function sL(e){yC?yC(e):e()}function nu(e){bC?bC(e):e()}class oL{constructor(){this.status=\"pending\",this.promise=new Promise((t,n)=>{this.resolve=r=>{this.status===\"pending\"&&(this.status=\"resolved\",t(r))},this.reject=r=>{this.status===\"pending\"&&(this.status=\"rejected\",n(r))}})}}function aL(e){let{fallbackElement:t,router:n,future:r}=e,[s,o]=y.useState(n.state),[l,u]=y.useState(),[d,f]=y.useState({isTransitioning:!1}),[h,m]=y.useState(),[g,x]=y.useState(),[b,w]=y.useState(),C=y.useRef(new Map),{v7_startTransition:k}=r||{},j=y.useCallback(D=>{k?sL(D):D()},[k]),M=y.useCallback((D,z)=>{let{deletedFetchers:Q,unstable_flushSync:pe,unstable_viewTransitionOpts:V}=z;Q.forEach(W=>C.current.delete(W)),D.fetchers.forEach((W,ie)=>{W.data!==void 0&&C.current.set(ie,W.data)});let G=n.window==null||n.window.document==null||typeof n.window.document.startViewTransition!=\"function\";if(!V||G){pe?nu(()=>o(D)):j(()=>o(D));return}if(pe){nu(()=>{g&&(h&&h.resolve(),g.skipTransition()),f({isTransitioning:!0,flushSync:!0,currentLocation:V.currentLocation,nextLocation:V.nextLocation})});let W=n.window.document.startViewTransition(()=>{nu(()=>o(D))});W.finished.finally(()=>{nu(()=>{m(void 0),x(void 0),u(void 0),f({isTransitioning:!1})})}),nu(()=>x(W));return}g?(h&&h.resolve(),g.skipTransition(),w({state:D,currentLocation:V.currentLocation,nextLocation:V.nextLocation})):(u(D),f({isTransitioning:!0,flushSync:!1,currentLocation:V.currentLocation,nextLocation:V.nextLocation}))},[n.window,g,h,C,j]);y.useLayoutEffect(()=>n.subscribe(M),[n,M]),y.useEffect(()=>{d.isTransitioning&&!d.flushSync&&m(new oL)},[d]),y.useEffect(()=>{if(h&&l&&n.window){let D=l,z=h.promise,Q=n.window.document.startViewTransition(async()=>{j(()=>o(D)),await z});Q.finished.finally(()=>{m(void 0),x(void 0),u(void 0),f({isTransitioning:!1})}),x(Q)}},[j,l,h,n.window]),y.useEffect(()=>{h&&l&&s.location.key===l.location.key&&h.resolve()},[h,g,s.location,l]),y.useEffect(()=>{!d.isTransitioning&&b&&(u(b.state),f({isTransitioning:!0,flushSync:!1,currentLocation:b.currentLocation,nextLocation:b.nextLocation}),w(void 0))},[d.isTransitioning,b]),y.useEffect(()=>{},[]);let _=y.useMemo(()=>({createHref:n.createHref,encodeLocation:n.encodeLocation,go:D=>n.navigate(D),push:(D,z,Q)=>n.navigate(D,{state:z,preventScrollReset:Q?.preventScrollReset}),replace:(D,z,Q)=>n.navigate(D,{replace:!0,state:z,preventScrollReset:Q?.preventScrollReset})}),[n]),R=n.basename||\"/\",N=y.useMemo(()=>({router:n,navigator:_,static:!1,basename:R}),[n,_,R]),O=y.useMemo(()=>({v7_relativeSplatPath:n.future.v7_relativeSplatPath}),[n.future.v7_relativeSplatPath]);return y.createElement(y.Fragment,null,y.createElement(vh.Provider,{value:N},y.createElement(mj.Provider,{value:s},y.createElement(tL.Provider,{value:C.current},y.createElement(eL.Provider,{value:d},y.createElement(V2,{basename:R,location:s.location,navigationType:s.historyAction,navigator:_,future:O},s.initialized||n.future.v7_partialHydration?y.createElement(iL,{routes:n.routes,future:n.future,state:s}):t))))),null)}const iL=y.memo(lL);function lL(e){let{routes:t,future:n,state:r}=e;return R2(t,void 0,r,n)}const cL=typeof window<\"u\"&&typeof window.document<\"u\"&&typeof window.document.createElement<\"u\",uL=/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i,Fu=y.forwardRef(function(t,n){let{onClick:r,relative:s,reloadDocument:o,replace:l,state:u,target:d,to:f,preventScrollReset:h,unstable_viewTransition:m}=t,g=q2(t,J2),{basename:x}=y.useContext(Ra),b,w=!1;if(typeof f==\"string\"&&uL.test(f)&&(b=f,cL))try{let M=new URL(window.location.href),_=f.startsWith(\"//\")?new URL(M.protocol+f):new URL(f),R=Xl(_.pathname,x);_.origin===M.origin&&R!=null?f=R+_.search+_.hash:w=!0}catch{}let C=M2(f,{relative:s}),k=dL(f,{replace:l,state:u,target:d,preventScrollReset:h,relative:s,unstable_viewTransition:m});function j(M){r&&r(M),M.defaultPrevented||k(M)}return y.createElement(\"a\",Du({},g,{href:b||C,onClick:w||o?r:j,ref:n,target:d}))});var xC;(function(e){e.UseScrollRestoration=\"useScrollRestoration\",e.UseSubmit=\"useSubmit\",e.UseSubmitFetcher=\"useSubmitFetcher\",e.UseFetcher=\"useFetcher\",e.useViewTransitionState=\"useViewTransitionState\"})(xC||(xC={}));var wC;(function(e){e.UseFetcher=\"useFetcher\",e.UseFetchers=\"useFetchers\",e.UseScrollRestoration=\"useScrollRestoration\"})(wC||(wC={}));function dL(e,t){let{target:n,replace:r,state:s,preventScrollReset:o,relative:l,unstable_viewTransition:u}=t===void 0?{}:t,d=dn(),f=Pi(),h=bj(e,{relative:l});return y.useCallback(m=>{if(W2(m,n)){m.preventDefault();let g=r!==void 0?r:wi(f)===wi(h);d(e,{replace:g,state:s,preventScrollReset:o,relative:l,unstable_viewTransition:u})}},[f,d,h,r,s,n,e,o,l,u])}function hd(e){let t=y.useRef(_y(e)),n=y.useRef(!1),r=Pi(),s=y.useMemo(()=>G2(r.search,n.current?null:t.current),[r.search]),o=dn(),l=y.useCallback((u,d)=>{const f=_y(typeof u==\"function\"?u(s):u);n.current=!0,o(\"?\"+f,d)},[o,s]);return[s,l]}function Ej(e){var t,n,r=\"\";if(typeof e==\"string\"||typeof e==\"number\")r+=e;else if(typeof e==\"object\")if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(n=Ej(e[t]))&&(r&&(r+=\" \"),r+=n)}else for(n in e)e[n]&&(r&&(r+=\" \"),r+=n);return r}function wo(){for(var e,t,n=0,r=\"\",s=arguments.length;n<s;n++)(e=arguments[n])&&(t=Ej(e))&&(r&&(r+=\" \"),r+=t);return r}const Lu=e=>typeof e==\"number\"&&!isNaN(e),pi=e=>typeof e==\"string\",Ur=e=>typeof e==\"function\",up=e=>pi(e)||Ur(e)?e:null,Ry=e=>y.isValidElement(e)||pi(e)||Ur(e)||Lu(e);function fL(e,t,n){n===void 0&&(n=300);const{scrollHeight:r,style:s}=e;requestAnimationFrame(()=>{s.minHeight=\"initial\",s.height=r+\"px\",s.transition=`all ${n}ms`,requestAnimationFrame(()=>{s.height=\"0\",s.padding=\"0\",s.margin=\"0\",setTimeout(t,n)})})}function yh(e){let{enter:t,exit:n,appendPosition:r=!1,collapse:s=!0,collapseDuration:o=300}=e;return function(l){let{children:u,position:d,preventExitTransition:f,done:h,nodeRef:m,isIn:g,playToast:x}=l;const b=r?`${t}--${d}`:t,w=r?`${n}--${d}`:n,C=y.useRef(0);return y.useLayoutEffect(()=>{const k=m.current,j=b.split(\" \"),M=_=>{_.target===m.current&&(x(),k.removeEventListener(\"animationend\",M),k.removeEventListener(\"animationcancel\",M),C.current===0&&_.type!==\"animationcancel\"&&k.classList.remove(...j))};k.classList.add(...j),k.addEventListener(\"animationend\",M),k.addEventListener(\"animationcancel\",M)},[]),y.useEffect(()=>{const k=m.current,j=()=>{k.removeEventListener(\"animationend\",j),s?fL(k,h,o):h()};g||(f?j():(C.current=1,k.className+=` ${w}`,k.addEventListener(\"animationend\",j)))},[g]),qe.createElement(qe.Fragment,null,u)}}function SC(e,t){return e!=null?{content:e.content,containerId:e.props.containerId,id:e.props.toastId,theme:e.props.theme,type:e.props.type,data:e.props.data||{},isLoading:e.props.isLoading,icon:e.props.icon,status:t}:{}}const ur=new Map;let $u=[];const Py=new Set,pL=e=>Py.forEach(t=>t(e)),kj=()=>ur.size>0;function jj(e,t){var n;if(t)return!((n=ur.get(t))==null||!n.isToastActive(e));let r=!1;return ur.forEach(s=>{s.isToastActive(e)&&(r=!0)}),r}function Tj(e,t){Ry(e)&&(kj()||$u.push({content:e,options:t}),ur.forEach(n=>{n.buildToast(e,t)}))}function CC(e,t){ur.forEach(n=>{t!=null&&t!=null&&t.containerId?t?.containerId===n.id&&n.toggle(e,t?.id):n.toggle(e,t?.id)})}function hL(e){const{subscribe:t,getSnapshot:n,setProps:r}=y.useRef((function(o){const l=o.containerId||1;return{subscribe(u){const d=(function(h,m,g){let x=1,b=0,w=[],C=[],k=[],j=m;const M=new Map,_=new Set,R=()=>{k=Array.from(M.values()),_.forEach(D=>D())},N=D=>{C=D==null?[]:C.filter(z=>z!==D),R()},O=D=>{const{toastId:z,onOpen:Q,updateId:pe,children:V}=D.props,G=pe==null;D.staleId&&M.delete(D.staleId),M.set(z,D),C=[...C,D.props.toastId].filter(W=>W!==D.staleId),R(),g(SC(D,G?\"added\":\"updated\")),G&&Ur(Q)&&Q(y.isValidElement(V)&&V.props)};return{id:h,props:j,observe:D=>(_.add(D),()=>_.delete(D)),toggle:(D,z)=>{M.forEach(Q=>{z!=null&&z!==Q.props.toastId||Ur(Q.toggle)&&Q.toggle(D)})},removeToast:N,toasts:M,clearQueue:()=>{b-=w.length,w=[]},buildToast:(D,z)=>{if((F=>{let{containerId:fe,toastId:te,updateId:de}=F;const ge=fe?fe!==h:h!==1,Z=M.has(te)&&de==null;return ge||Z})(z))return;const{toastId:Q,updateId:pe,data:V,staleId:G,delay:W}=z,ie=()=>{N(Q)},re=pe==null;re&&b++;const Y={...j,style:j.toastStyle,key:x++,...Object.fromEntries(Object.entries(z).filter(F=>{let[fe,te]=F;return te!=null})),toastId:Q,updateId:pe,data:V,closeToast:ie,isIn:!1,className:up(z.className||j.toastClassName),bodyClassName:up(z.bodyClassName||j.bodyClassName),progressClassName:up(z.progressClassName||j.progressClassName),autoClose:!z.isLoading&&(H=z.autoClose,q=j.autoClose,H===!1||Lu(H)&&H>0?H:q),deleteToast(){const F=M.get(Q),{onClose:fe,children:te}=F.props;Ur(fe)&&fe(y.isValidElement(te)&&te.props),g(SC(F,\"removed\")),M.delete(Q),b--,b<0&&(b=0),w.length>0?O(w.shift()):R()}};var H,q;Y.closeButton=j.closeButton,z.closeButton===!1||Ry(z.closeButton)?Y.closeButton=z.closeButton:z.closeButton===!0&&(Y.closeButton=!Ry(j.closeButton)||j.closeButton);let he=D;y.isValidElement(D)&&!pi(D.type)?he=y.cloneElement(D,{closeToast:ie,toastProps:Y,data:V}):Ur(D)&&(he=D({closeToast:ie,toastProps:Y,data:V}));const A={content:he,props:Y,staleId:G};j.limit&&j.limit>0&&b>j.limit&&re?w.push(A):Lu(W)?setTimeout(()=>{O(A)},W):O(A)},setProps(D){j=D},setToggle:(D,z)=>{M.get(D).toggle=z},isToastActive:D=>C.some(z=>z===D),getSnapshot:()=>j.newestOnTop?k.reverse():k}})(l,o,pL);ur.set(l,d);const f=d.observe(u);return $u.forEach(h=>Tj(h.content,h.options)),$u=[],()=>{f(),ur.delete(l)}},setProps(u){var d;(d=ur.get(l))==null||d.setProps(u)},getSnapshot(){var u;return(u=ur.get(l))==null?void 0:u.getSnapshot()}}})(e)).current;r(e);const s=y.useSyncExternalStore(t,n,n);return{getToastToRender:function(o){if(!s)return[];const l=new Map;return s.forEach(u=>{const{position:d}=u.props;l.has(d)||l.set(d,[]),l.get(d).push(u)}),Array.from(l,u=>o(u[0],u[1]))},isToastActive:jj,count:s?.length}}function gL(e){const[t,n]=y.useState(!1),[r,s]=y.useState(!1),o=y.useRef(null),l=y.useRef({start:0,delta:0,removalDistance:0,canCloseOnClick:!0,canDrag:!1,didMove:!1}).current,{autoClose:u,pauseOnHover:d,closeToast:f,onClick:h,closeOnClick:m}=e;var g,x;function b(){n(!0)}function w(){n(!1)}function C(M){const _=o.current;l.canDrag&&_&&(l.didMove=!0,t&&w(),l.delta=e.draggableDirection===\"x\"?M.clientX-l.start:M.clientY-l.start,l.start!==M.clientX&&(l.canCloseOnClick=!1),_.style.transform=`translate3d(${e.draggableDirection===\"x\"?`${l.delta}px, var(--y)`:`0, calc(${l.delta}px + var(--y))`},0)`,_.style.opacity=\"\"+(1-Math.abs(l.delta/l.removalDistance)))}function k(){document.removeEventListener(\"pointermove\",C),document.removeEventListener(\"pointerup\",k);const M=o.current;if(l.canDrag&&l.didMove&&M){if(l.canDrag=!1,Math.abs(l.delta)>l.removalDistance)return s(!0),e.closeToast(),void e.collapseAll();M.style.transition=\"transform 0.2s, opacity 0.2s\",M.style.removeProperty(\"transform\"),M.style.removeProperty(\"opacity\")}}(x=ur.get((g={id:e.toastId,containerId:e.containerId,fn:n}).containerId||1))==null||x.setToggle(g.id,g.fn),y.useEffect(()=>{if(e.pauseOnFocusLoss)return document.hasFocus()||w(),window.addEventListener(\"focus\",b),window.addEventListener(\"blur\",w),()=>{window.removeEventListener(\"focus\",b),window.removeEventListener(\"blur\",w)}},[e.pauseOnFocusLoss]);const j={onPointerDown:function(M){if(e.draggable===!0||e.draggable===M.pointerType){l.didMove=!1,document.addEventListener(\"pointermove\",C),document.addEventListener(\"pointerup\",k);const _=o.current;l.canCloseOnClick=!0,l.canDrag=!0,_.style.transition=\"none\",e.draggableDirection===\"x\"?(l.start=M.clientX,l.removalDistance=_.offsetWidth*(e.draggablePercent/100)):(l.start=M.clientY,l.removalDistance=_.offsetHeight*(e.draggablePercent===80?1.5*e.draggablePercent:e.draggablePercent)/100)}},onPointerUp:function(M){const{top:_,bottom:R,left:N,right:O}=o.current.getBoundingClientRect();M.nativeEvent.type!==\"touchend\"&&e.pauseOnHover&&M.clientX>=N&&M.clientX<=O&&M.clientY>=_&&M.clientY<=R?w():b()}};return u&&d&&(j.onMouseEnter=w,e.stacked||(j.onMouseLeave=b)),m&&(j.onClick=M=>{h&&h(M),l.canCloseOnClick&&f()}),{playToast:b,pauseToast:w,isRunning:t,preventExitTransition:r,toastRef:o,eventHandlers:j}}function mL(e){let{delay:t,isRunning:n,closeToast:r,type:s=\"default\",hide:o,className:l,style:u,controlledProgress:d,progress:f,rtl:h,isIn:m,theme:g}=e;const x=o||d&&f===0,b={...u,animationDuration:`${t}ms`,animationPlayState:n?\"running\":\"paused\"};d&&(b.transform=`scaleX(${f})`);const w=wo(\"Toastify__progress-bar\",d?\"Toastify__progress-bar--controlled\":\"Toastify__progress-bar--animated\",`Toastify__progress-bar-theme--${g}`,`Toastify__progress-bar--${s}`,{\"Toastify__progress-bar--rtl\":h}),C=Ur(l)?l({rtl:h,type:s,defaultClassName:w}):wo(w,l),k={[d&&f>=1?\"onTransitionEnd\":\"onAnimationEnd\"]:d&&f<1?null:()=>{m&&r()}};return qe.createElement(\"div\",{className:\"Toastify__progress-bar--wrp\",\"data-hidden\":x},qe.createElement(\"div\",{className:`Toastify__progress-bar--bg Toastify__progress-bar-theme--${g} Toastify__progress-bar--${s}`}),qe.createElement(\"div\",{role:\"progressbar\",\"aria-hidden\":x?\"true\":\"false\",\"aria-label\":\"notification timer\",className:C,style:b,...k}))}let vL=1;const Nj=()=>\"\"+vL++;function yL(e){return e&&(pi(e.toastId)||Lu(e.toastId))?e.toastId:Nj()}function ku(e,t){return Tj(e,t),t.toastId}function Pp(e,t){return{...t,type:t&&t.type||e,toastId:yL(t)}}function Lf(e){return(t,n)=>ku(t,Pp(e,n))}function me(e,t){return ku(e,Pp(\"default\",t))}me.loading=(e,t)=>ku(e,Pp(\"default\",{isLoading:!0,autoClose:!1,closeOnClick:!1,closeButton:!1,draggable:!1,...t})),me.promise=function(e,t,n){let r,{pending:s,error:o,success:l}=t;s&&(r=pi(s)?me.loading(s,n):me.loading(s.render,{...n,...s}));const u={isLoading:null,autoClose:null,closeOnClick:null,closeButton:null,draggable:null},d=(h,m,g)=>{if(m==null)return void me.dismiss(r);const x={type:h,...u,...n,data:g},b=pi(m)?{render:m}:m;return r?me.update(r,{...x,...b}):me(b.render,{...x,...b}),g},f=Ur(e)?e():e;return f.then(h=>d(\"success\",l,h)).catch(h=>d(\"error\",o,h)),f},me.success=Lf(\"success\"),me.info=Lf(\"info\"),me.error=Lf(\"error\"),me.warning=Lf(\"warning\"),me.warn=me.warning,me.dark=(e,t)=>ku(e,Pp(\"default\",{theme:\"dark\",...t})),me.dismiss=function(e){(function(t){var n;if(kj()){if(t==null||pi(n=t)||Lu(n))ur.forEach(r=>{r.removeToast(t)});else if(t&&(\"containerId\"in t||\"id\"in t)){const r=ur.get(t.containerId);r?r.removeToast(t.id):ur.forEach(s=>{s.removeToast(t.id)})}}else $u=$u.filter(r=>t!=null&&r.options.toastId!==t)})(e)},me.clearWaitingQueue=function(e){e===void 0&&(e={}),ur.forEach(t=>{!t.props.limit||e.containerId&&t.id!==e.containerId||t.clearQueue()})},me.isActive=jj,me.update=function(e,t){t===void 0&&(t={});const n=((r,s)=>{var o;let{containerId:l}=s;return(o=ur.get(l||1))==null?void 0:o.toasts.get(r)})(e,t);if(n){const{props:r,content:s}=n,o={delay:100,...r,...t,toastId:t.toastId||e,updateId:Nj()};o.toastId!==e&&(o.staleId=e);const l=o.render||s;delete o.render,ku(l,o)}},me.done=e=>{me.update(e,{progress:1})},me.onChange=function(e){return Py.add(e),()=>{Py.delete(e)}},me.play=e=>CC(!0,e),me.pause=e=>CC(!1,e);const bL=typeof window<\"u\"?y.useLayoutEffect:y.useEffect,$f=e=>{let{theme:t,type:n,isLoading:r,...s}=e;return qe.createElement(\"svg\",{viewBox:\"0 0 24 24\",width:\"100%\",height:\"100%\",fill:t===\"colored\"?\"currentColor\":`var(--toastify-icon-color-${n})`,...s})},gv={info:function(e){return qe.createElement($f,{...e},qe.createElement(\"path\",{d:\"M12 0a12 12 0 1012 12A12.013 12.013 0 0012 0zm.25 5a1.5 1.5 0 11-1.5 1.5 1.5 1.5 0 011.5-1.5zm2.25 13.5h-4a1 1 0 010-2h.75a.25.25 0 00.25-.25v-4.5a.25.25 0 00-.25-.25h-.75a1 1 0 010-2h1a2 2 0 012 2v4.75a.25.25 0 00.25.25h.75a1 1 0 110 2z\"}))},warning:function(e){return qe.createElement($f,{...e},qe.createElement(\"path\",{d:\"M23.32 17.191L15.438 2.184C14.728.833 13.416 0 11.996 0c-1.42 0-2.733.833-3.443 2.184L.533 17.448a4.744 4.744 0 000 4.368C1.243 23.167 2.555 24 3.975 24h16.05C22.22 24 24 22.044 24 19.632c0-.904-.251-1.746-.68-2.44zm-9.622 1.46c0 1.033-.724 1.823-1.698 1.823s-1.698-.79-1.698-1.822v-.043c0-1.028.724-1.822 1.698-1.822s1.698.79 1.698 1.822v.043zm.039-12.285l-.84 8.06c-.057.581-.408.943-.897.943-.49 0-.84-.367-.896-.942l-.84-8.065c-.057-.624.25-1.095.779-1.095h1.91c.528.005.84.476.784 1.1z\"}))},success:function(e){return qe.createElement($f,{...e},qe.createElement(\"path\",{d:\"M12 0a12 12 0 1012 12A12.014 12.014 0 0012 0zm6.927 8.2l-6.845 9.289a1.011 1.011 0 01-1.43.188l-4.888-3.908a1 1 0 111.25-1.562l4.076 3.261 6.227-8.451a1 1 0 111.61 1.183z\"}))},error:function(e){return qe.createElement($f,{...e},qe.createElement(\"path\",{d:\"M11.983 0a12.206 12.206 0 00-8.51 3.653A11.8 11.8 0 000 12.207 11.779 11.779 0 0011.8 24h.214A12.111 12.111 0 0024 11.791 11.766 11.766 0 0011.983 0zM10.5 16.542a1.476 1.476 0 011.449-1.53h.027a1.527 1.527 0 011.523 1.47 1.475 1.475 0 01-1.449 1.53h-.027a1.529 1.529 0 01-1.523-1.47zM11 12.5v-6a1 1 0 012 0v6a1 1 0 11-2 0z\"}))},spinner:function(){return qe.createElement(\"div\",{className:\"Toastify__spinner\"})}},xL=e=>{const{isRunning:t,preventExitTransition:n,toastRef:r,eventHandlers:s,playToast:o}=gL(e),{closeButton:l,children:u,autoClose:d,onClick:f,type:h,hideProgressBar:m,closeToast:g,transition:x,position:b,className:w,style:C,bodyClassName:k,bodyStyle:j,progressClassName:M,progressStyle:_,updateId:R,role:N,progress:O,rtl:D,toastId:z,deleteToast:Q,isIn:pe,isLoading:V,closeOnClick:G,theme:W}=e,ie=wo(\"Toastify__toast\",`Toastify__toast-theme--${W}`,`Toastify__toast--${h}`,{\"Toastify__toast--rtl\":D},{\"Toastify__toast--close-on-click\":G}),re=Ur(w)?w({rtl:D,position:b,type:h,defaultClassName:ie}):wo(ie,w),Y=(function(A){let{theme:F,type:fe,isLoading:te,icon:de}=A,ge=null;const Z={theme:F,type:fe};return de===!1||(Ur(de)?ge=de({...Z,isLoading:te}):y.isValidElement(de)?ge=y.cloneElement(de,Z):te?ge=gv.spinner():(ye=>ye in gv)(fe)&&(ge=gv[fe](Z))),ge})(e),H=!!O||!d,q={closeToast:g,type:h,theme:W};let he=null;return l===!1||(he=Ur(l)?l(q):y.isValidElement(l)?y.cloneElement(l,q):(function(A){let{closeToast:F,theme:fe,ariaLabel:te=\"close\"}=A;return qe.createElement(\"button\",{className:`Toastify__close-button Toastify__close-button--${fe}`,type:\"button\",onClick:de=>{de.stopPropagation(),F(de)},\"aria-label\":te},qe.createElement(\"svg\",{\"aria-hidden\":\"true\",viewBox:\"0 0 14 16\"},qe.createElement(\"path\",{fillRule:\"evenodd\",d:\"M7.71 8.23l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75L1 11.98l3.75-3.75L1 4.48 2.48 3l3.75 3.75L9.98 3l1.48 1.48-3.75 3.75z\"})))})(q)),qe.createElement(x,{isIn:pe,done:Q,position:b,preventExitTransition:n,nodeRef:r,playToast:o},qe.createElement(\"div\",{id:z,onClick:f,\"data-in\":pe,className:re,...s,style:C,ref:r},qe.createElement(\"div\",{...pe&&{role:N},className:Ur(k)?k({type:h}):wo(\"Toastify__toast-body\",k),style:j},Y!=null&&qe.createElement(\"div\",{className:wo(\"Toastify__toast-icon\",{\"Toastify--animate-icon Toastify__zoom-enter\":!V})},Y),qe.createElement(\"div\",null,u)),he,qe.createElement(mL,{...R&&!H?{key:`pb-${R}`}:{},rtl:D,theme:W,delay:d,isRunning:t,isIn:pe,closeToast:g,hide:m,type:h,style:_,className:M,controlledProgress:H,progress:O||0})))},bh=function(e,t){return t===void 0&&(t=!1),{enter:`Toastify--animate Toastify__${e}-enter`,exit:`Toastify--animate Toastify__${e}-exit`,appendPosition:t}},wL=yh(bh(\"bounce\",!0));yh(bh(\"slide\",!0));yh(bh(\"zoom\"));yh(bh(\"flip\"));const SL={position:\"top-right\",transition:wL,autoClose:5e3,closeButton:!0,pauseOnHover:!0,pauseOnFocusLoss:!0,draggable:\"touch\",draggablePercent:80,draggableDirection:\"x\",role:\"alert\",theme:\"light\"};function CL(e){let t={...SL,...e};const n=e.stacked,[r,s]=y.useState(!0),o=y.useRef(null),{getToastToRender:l,isToastActive:u,count:d}=hL(t),{className:f,style:h,rtl:m,containerId:g}=t;function x(w){const C=wo(\"Toastify__toast-container\",`Toastify__toast-container--${w}`,{\"Toastify__toast-container--rtl\":m});return Ur(f)?f({position:w,rtl:m,defaultClassName:C}):wo(C,up(f))}function b(){n&&(s(!0),me.play())}return bL(()=>{if(n){var w;const C=o.current.querySelectorAll('[data-in=\"true\"]'),k=12,j=(w=t.position)==null?void 0:w.includes(\"top\");let M=0,_=0;Array.from(C).reverse().forEach((R,N)=>{const O=R;O.classList.add(\"Toastify__toast--stacked\"),N>0&&(O.dataset.collapsed=`${r}`),O.dataset.pos||(O.dataset.pos=j?\"top\":\"bot\");const D=M*(r?.2:1)+(r?0:k*N);O.style.setProperty(\"--y\",`${j?D:-1*D}px`),O.style.setProperty(\"--g\",`${k}`),O.style.setProperty(\"--s\",\"\"+(1-(r?_:0))),M+=O.offsetHeight,_+=.025})}},[r,d,n]),qe.createElement(\"div\",{ref:o,className:\"Toastify\",id:g,onMouseEnter:()=>{n&&(s(!1),me.pause())},onMouseLeave:b},l((w,C)=>{const k=C.length?{...h}:{...h,pointerEvents:\"none\"};return qe.createElement(\"div\",{className:x(w),style:k,key:`container-${w}`},C.map(j=>{let{content:M,props:_}=j;return qe.createElement(xL,{..._,stacked:n,collapseAll:b,isIn:u(_.toastId,_.containerId),style:_.style,key:`toast-${_.key}`},M)}))}))}const EL={theme:\"system\",setTheme:()=>null},Mj=y.createContext(EL);function kL({children:e,defaultTheme:t=\"system\",storageKey:n=\"vite-ui-theme\",...r}){const[s,o]=y.useState(()=>localStorage.getItem(n)||t);y.useEffect(()=>{const u=window.document.documentElement;if(u.classList.remove(\"light\",\"dark\"),s===\"system\"){const d=window.matchMedia(\"(prefers-color-scheme: dark)\").matches?\"dark\":\"light\";u.classList.add(d);return}u.classList.add(s)},[s]);const l={theme:s,setTheme:u=>{localStorage.setItem(n,u),o(u)}};return i.jsx(Mj.Provider,{...r,value:l,children:e})}const tc=()=>{const e=y.useContext(Mj);if(e===void 0)throw new Error(\"useTheme must be used within a ThemeProvider\");return e};let mv=!1;const _j=new KD({defaultOptions:{queries:{staleTime:1e3*60*5,retry(e){return e>=3?(mv===!1&&(mv=!0,me.error(\"The application is taking longer than expected to load, please try again in a few minutes.\",{onClose:()=>{mv=!1}})),!1):!0}}}});var jn=(e=>(e.API_URL=\"apiUrl\",e.TOKEN=\"token\",e.INSTANCE_ID=\"instanceId\",e.INSTANCE_NAME=\"instanceName\",e.INSTANCE_TOKEN=\"instanceToken\",e.VERSION=\"version\",e.FACEBOOK_APP_ID=\"facebookAppId\",e.FACEBOOK_CONFIG_ID=\"facebookConfigId\",e.FACEBOOK_USER_TOKEN=\"facebookUserToken\",e.CLIENT_NAME=\"clientName\",e))(jn||{});const Rj=async e=>{if(e.url){const t=e.url.endsWith(\"/\")?e.url.slice(0,-1):e.url;localStorage.setItem(\"apiUrl\",t)}e.token&&localStorage.setItem(\"token\",e.token),e.version&&localStorage.setItem(\"version\",e.version),e.facebookAppId&&localStorage.setItem(\"facebookAppId\",e.facebookAppId),e.facebookConfigId&&localStorage.setItem(\"facebookConfigId\",e.facebookConfigId),e.facebookUserToken&&localStorage.setItem(\"facebookUserToken\",e.facebookUserToken),e.clientName&&localStorage.setItem(\"clientName\",e.clientName)},Pj=()=>{localStorage.removeItem(\"apiUrl\"),localStorage.removeItem(\"token\"),localStorage.removeItem(\"version\"),localStorage.removeItem(\"facebookAppId\"),localStorage.removeItem(\"facebookConfigId\"),localStorage.removeItem(\"facebookUserToken\"),localStorage.removeItem(\"clientName\")},dr=e=>localStorage.getItem(e),tn=({children:e})=>{const t=dr(jn.API_URL),n=dr(jn.TOKEN),r=dr(jn.VERSION);return!t||!n||!r?i.jsx(Cj,{to:\"/manager/login\"}):e},jL=({children:e})=>{const t=dr(jn.API_URL),n=dr(jn.TOKEN),r=dr(jn.VERSION);return t&&n&&r?i.jsx(Cj,{to:\"/\"}):e};function Oj(e,t){return function(){return e.apply(t,arguments)}}const{toString:TL}=Object.prototype,{getPrototypeOf:$b}=Object,{iterator:xh,toStringTag:Ij}=Symbol,wh=(e=>t=>{const n=TL.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),Rs=e=>(e=e.toLowerCase(),t=>wh(t)===e),Sh=e=>t=>typeof t===e,{isArray:nc}=Array,$l=Sh(\"undefined\");function gd(e){return e!==null&&!$l(e)&&e.constructor!==null&&!$l(e.constructor)&&jr(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Aj=Rs(\"ArrayBuffer\");function NL(e){let t;return typeof ArrayBuffer<\"u\"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Aj(e.buffer),t}const ML=Sh(\"string\"),jr=Sh(\"function\"),Dj=Sh(\"number\"),md=e=>e!==null&&typeof e==\"object\",_L=e=>e===!0||e===!1,dp=e=>{if(wh(e)!==\"object\")return!1;const t=$b(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Ij in e)&&!(xh in e)},RL=e=>{if(!md(e)||gd(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},PL=Rs(\"Date\"),OL=Rs(\"File\"),IL=Rs(\"Blob\"),AL=Rs(\"FileList\"),DL=e=>md(e)&&jr(e.pipe),FL=e=>{let t;return e&&(typeof FormData==\"function\"&&e instanceof FormData||jr(e.append)&&((t=wh(e))===\"formdata\"||t===\"object\"&&jr(e.toString)&&e.toString()===\"[object FormData]\"))},LL=Rs(\"URLSearchParams\"),[$L,BL,zL,UL]=[\"ReadableStream\",\"Request\",\"Response\",\"Headers\"].map(Rs),VL=e=>e.trim?e.trim():e.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\"\");function vd(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>\"u\")return;let r,s;if(typeof e!=\"object\"&&(e=[e]),nc(e))for(r=0,s=e.length;r<s;r++)t.call(null,e[r],r,e);else{if(gd(e))return;const o=n?Object.getOwnPropertyNames(e):Object.keys(e),l=o.length;let u;for(r=0;r<l;r++)u=o[r],t.call(null,e[u],u,e)}}function Fj(e,t){if(gd(e))return null;t=t.toLowerCase();const n=Object.keys(e);let r=n.length,s;for(;r-- >0;)if(s=n[r],t===s.toLowerCase())return s;return null}const li=typeof globalThis<\"u\"?globalThis:typeof self<\"u\"?self:typeof window<\"u\"?window:global,Lj=e=>!$l(e)&&e!==li;function Oy(){const{caseless:e,skipUndefined:t}=Lj(this)&&this||{},n={},r=(s,o)=>{const l=e&&Fj(n,o)||o;dp(n[l])&&dp(s)?n[l]=Oy(n[l],s):dp(s)?n[l]=Oy({},s):nc(s)?n[l]=s.slice():(!t||!$l(s))&&(n[l]=s)};for(let s=0,o=arguments.length;s<o;s++)arguments[s]&&vd(arguments[s],r);return n}const HL=(e,t,n,{allOwnKeys:r}={})=>(vd(t,(s,o)=>{n&&jr(s)?e[o]=Oj(s,n):e[o]=s},{allOwnKeys:r}),e),qL=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),KL=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,\"super\",{value:t.prototype}),n&&Object.assign(e.prototype,n)},WL=(e,t,n,r)=>{let s,o,l;const u={};if(t=t||{},e==null)return t;do{for(s=Object.getOwnPropertyNames(e),o=s.length;o-- >0;)l=s[o],(!r||r(l,e,t))&&!u[l]&&(t[l]=e[l],u[l]=!0);e=n!==!1&&$b(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},GL=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return r!==-1&&r===n},JL=e=>{if(!e)return null;if(nc(e))return e;let t=e.length;if(!Dj(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},QL=(e=>t=>e&&t instanceof e)(typeof Uint8Array<\"u\"&&$b(Uint8Array)),ZL=(e,t)=>{const r=(e&&e[xh]).call(e);let s;for(;(s=r.next())&&!s.done;){const o=s.value;t.call(e,o[0],o[1])}},YL=(e,t)=>{let n;const r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},XL=Rs(\"HTMLFormElement\"),e4=e=>e.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,function(n,r,s){return r.toUpperCase()+s}),EC=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),t4=Rs(\"RegExp\"),$j=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};vd(n,(s,o)=>{let l;(l=t(s,o,e))!==!1&&(r[o]=l||s)}),Object.defineProperties(e,r)},n4=e=>{$j(e,(t,n)=>{if(jr(e)&&[\"arguments\",\"caller\",\"callee\"].indexOf(n)!==-1)return!1;const r=e[n];if(jr(r)){if(t.enumerable=!1,\"writable\"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error(\"Can not rewrite read-only method '\"+n+\"'\")})}})},r4=(e,t)=>{const n={},r=s=>{s.forEach(o=>{n[o]=!0})};return nc(e)?r(e):r(String(e).split(t)),n},s4=()=>{},o4=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function a4(e){return!!(e&&jr(e.append)&&e[Ij]===\"FormData\"&&e[xh])}const i4=e=>{const t=new Array(10),n=(r,s)=>{if(md(r)){if(t.indexOf(r)>=0)return;if(gd(r))return r;if(!(\"toJSON\"in r)){t[s]=r;const o=nc(r)?[]:{};return vd(r,(l,u)=>{const d=n(l,s+1);!$l(d)&&(o[u]=d)}),t[s]=void 0,o}}return r};return n(e,0)},l4=Rs(\"AsyncFunction\"),c4=e=>e&&(md(e)||jr(e))&&jr(e.then)&&jr(e.catch),Bj=((e,t)=>e?setImmediate:t?((n,r)=>(li.addEventListener(\"message\",({source:s,data:o})=>{s===li&&o===n&&r.length&&r.shift()()},!1),s=>{r.push(s),li.postMessage(n,\"*\")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate==\"function\",jr(li.postMessage)),u4=typeof queueMicrotask<\"u\"?queueMicrotask.bind(li):typeof process<\"u\"&&process.nextTick||Bj,d4=e=>e!=null&&jr(e[xh]),ce={isArray:nc,isArrayBuffer:Aj,isBuffer:gd,isFormData:FL,isArrayBufferView:NL,isString:ML,isNumber:Dj,isBoolean:_L,isObject:md,isPlainObject:dp,isEmptyObject:RL,isReadableStream:$L,isRequest:BL,isResponse:zL,isHeaders:UL,isUndefined:$l,isDate:PL,isFile:OL,isBlob:IL,isRegExp:t4,isFunction:jr,isStream:DL,isURLSearchParams:LL,isTypedArray:QL,isFileList:AL,forEach:vd,merge:Oy,extend:HL,trim:VL,stripBOM:qL,inherits:KL,toFlatObject:WL,kindOf:wh,kindOfTest:Rs,endsWith:GL,toArray:JL,forEachEntry:ZL,matchAll:YL,isHTMLForm:XL,hasOwnProperty:EC,hasOwnProp:EC,reduceDescriptors:$j,freezeMethods:n4,toObjectSet:r4,toCamelCase:e4,noop:s4,toFiniteNumber:o4,findKey:Fj,global:li,isContextDefined:Lj,isSpecCompliantForm:a4,toJSONObject:i4,isAsyncFn:l4,isThenable:c4,setImmediate:Bj,asap:u4,isIterable:d4};function vt(e,t,n,r,s){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name=\"AxiosError\",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),s&&(this.response=s,this.status=s.status?s.status:null)}ce.inherits(vt,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:ce.toJSONObject(this.config),code:this.code,status:this.status}}});const zj=vt.prototype,Uj={};[\"ERR_BAD_OPTION_VALUE\",\"ERR_BAD_OPTION\",\"ECONNABORTED\",\"ETIMEDOUT\",\"ERR_NETWORK\",\"ERR_FR_TOO_MANY_REDIRECTS\",\"ERR_DEPRECATED\",\"ERR_BAD_RESPONSE\",\"ERR_BAD_REQUEST\",\"ERR_CANCELED\",\"ERR_NOT_SUPPORT\",\"ERR_INVALID_URL\"].forEach(e=>{Uj[e]={value:e}});Object.defineProperties(vt,Uj);Object.defineProperty(zj,\"isAxiosError\",{value:!0});vt.from=(e,t,n,r,s,o)=>{const l=Object.create(zj);ce.toFlatObject(e,l,function(h){return h!==Error.prototype},f=>f!==\"isAxiosError\");const u=e&&e.message?e.message:\"Error\",d=t==null&&e?e.code:t;return vt.call(l,u,d,n,r,s),e&&l.cause==null&&Object.defineProperty(l,\"cause\",{value:e,configurable:!0}),l.name=e&&e.name||\"Error\",o&&Object.assign(l,o),l};const f4=null;function Iy(e){return ce.isPlainObject(e)||ce.isArray(e)}function Vj(e){return ce.endsWith(e,\"[]\")?e.slice(0,-2):e}function kC(e,t,n){return e?e.concat(t).map(function(s,o){return s=Vj(s),!n&&o?\"[\"+s+\"]\":s}).join(n?\".\":\"\"):t}function p4(e){return ce.isArray(e)&&!e.some(Iy)}const h4=ce.toFlatObject(ce,{},null,function(t){return/^is[A-Z]/.test(t)});function Ch(e,t,n){if(!ce.isObject(e))throw new TypeError(\"target must be an object\");t=t||new FormData,n=ce.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(w,C){return!ce.isUndefined(C[w])});const r=n.metaTokens,s=n.visitor||h,o=n.dots,l=n.indexes,d=(n.Blob||typeof Blob<\"u\"&&Blob)&&ce.isSpecCompliantForm(t);if(!ce.isFunction(s))throw new TypeError(\"visitor must be a function\");function f(b){if(b===null)return\"\";if(ce.isDate(b))return b.toISOString();if(ce.isBoolean(b))return b.toString();if(!d&&ce.isBlob(b))throw new vt(\"Blob is not supported. Use a Buffer instead.\");return ce.isArrayBuffer(b)||ce.isTypedArray(b)?d&&typeof Blob==\"function\"?new Blob([b]):Buffer.from(b):b}function h(b,w,C){let k=b;if(b&&!C&&typeof b==\"object\"){if(ce.endsWith(w,\"{}\"))w=r?w:w.slice(0,-2),b=JSON.stringify(b);else if(ce.isArray(b)&&p4(b)||(ce.isFileList(b)||ce.endsWith(w,\"[]\"))&&(k=ce.toArray(b)))return w=Vj(w),k.forEach(function(M,_){!(ce.isUndefined(M)||M===null)&&t.append(l===!0?kC([w],_,o):l===null?w:w+\"[]\",f(M))}),!1}return Iy(b)?!0:(t.append(kC(C,w,o),f(b)),!1)}const m=[],g=Object.assign(h4,{defaultVisitor:h,convertValue:f,isVisitable:Iy});function x(b,w){if(!ce.isUndefined(b)){if(m.indexOf(b)!==-1)throw Error(\"Circular reference detected in \"+w.join(\".\"));m.push(b),ce.forEach(b,function(k,j){(!(ce.isUndefined(k)||k===null)&&s.call(t,k,ce.isString(j)?j.trim():j,w,g))===!0&&x(k,w?w.concat(j):[j])}),m.pop()}}if(!ce.isObject(e))throw new TypeError(\"data must be an object\");return x(e),t}function jC(e){const t={\"!\":\"%21\",\"'\":\"%27\",\"(\":\"%28\",\")\":\"%29\",\"~\":\"%7E\",\"%20\":\"+\",\"%00\":\"\\0\"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(r){return t[r]})}function Bb(e,t){this._pairs=[],e&&Ch(e,this,t)}const Hj=Bb.prototype;Hj.append=function(t,n){this._pairs.push([t,n])};Hj.toString=function(t){const n=t?function(r){return t.call(this,r,jC)}:jC;return this._pairs.map(function(s){return n(s[0])+\"=\"+n(s[1])},\"\").join(\"&\")};function g4(e){return encodeURIComponent(e).replace(/%3A/gi,\":\").replace(/%24/g,\"$\").replace(/%2C/gi,\",\").replace(/%20/g,\"+\")}function qj(e,t,n){if(!t)return e;const r=n&&n.encode||g4;ce.isFunction(n)&&(n={serialize:n});const s=n&&n.serialize;let o;if(s?o=s(t,n):o=ce.isURLSearchParams(t)?t.toString():new Bb(t,n).toString(r),o){const l=e.indexOf(\"#\");l!==-1&&(e=e.slice(0,l)),e+=(e.indexOf(\"?\")===-1?\"?\":\"&\")+o}return e}class TC{constructor(){this.handlers=[]}use(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){ce.forEach(this.handlers,function(r){r!==null&&t(r)})}}const Kj={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},m4=typeof URLSearchParams<\"u\"?URLSearchParams:Bb,v4=typeof FormData<\"u\"?FormData:null,y4=typeof Blob<\"u\"?Blob:null,b4={isBrowser:!0,classes:{URLSearchParams:m4,FormData:v4,Blob:y4},protocols:[\"http\",\"https\",\"file\",\"blob\",\"url\",\"data\"]},zb=typeof window<\"u\"&&typeof document<\"u\",Ay=typeof navigator==\"object\"&&navigator||void 0,x4=zb&&(!Ay||[\"ReactNative\",\"NativeScript\",\"NS\"].indexOf(Ay.product)<0),w4=typeof WorkerGlobalScope<\"u\"&&self instanceof WorkerGlobalScope&&typeof self.importScripts==\"function\",S4=zb&&window.location.href||\"http://localhost\",C4=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:zb,hasStandardBrowserEnv:x4,hasStandardBrowserWebWorkerEnv:w4,navigator:Ay,origin:S4},Symbol.toStringTag,{value:\"Module\"})),rr={...C4,...b4};function E4(e,t){return Ch(e,new rr.classes.URLSearchParams,{visitor:function(n,r,s,o){return rr.isNode&&ce.isBuffer(n)?(this.append(r,n.toString(\"base64\")),!1):o.defaultVisitor.apply(this,arguments)},...t})}function k4(e){return ce.matchAll(/\\w+|\\[(\\w*)]/g,e).map(t=>t[0]===\"[]\"?\"\":t[1]||t[0])}function j4(e){const t={},n=Object.keys(e);let r;const s=n.length;let o;for(r=0;r<s;r++)o=n[r],t[o]=e[o];return t}function Wj(e){function t(n,r,s,o){let l=n[o++];if(l===\"__proto__\")return!0;const u=Number.isFinite(+l),d=o>=n.length;return l=!l&&ce.isArray(s)?s.length:l,d?(ce.hasOwnProp(s,l)?s[l]=[s[l],r]:s[l]=r,!u):((!s[l]||!ce.isObject(s[l]))&&(s[l]=[]),t(n,r,s[l],o)&&ce.isArray(s[l])&&(s[l]=j4(s[l])),!u)}if(ce.isFormData(e)&&ce.isFunction(e.entries)){const n={};return ce.forEachEntry(e,(r,s)=>{t(k4(r),s,n,0)}),n}return null}function T4(e,t,n){if(ce.isString(e))try{return(t||JSON.parse)(e),ce.trim(e)}catch(r){if(r.name!==\"SyntaxError\")throw r}return(n||JSON.stringify)(e)}const yd={transitional:Kj,adapter:[\"xhr\",\"http\",\"fetch\"],transformRequest:[function(t,n){const r=n.getContentType()||\"\",s=r.indexOf(\"application/json\")>-1,o=ce.isObject(t);if(o&&ce.isHTMLForm(t)&&(t=new FormData(t)),ce.isFormData(t))return s?JSON.stringify(Wj(t)):t;if(ce.isArrayBuffer(t)||ce.isBuffer(t)||ce.isStream(t)||ce.isFile(t)||ce.isBlob(t)||ce.isReadableStream(t))return t;if(ce.isArrayBufferView(t))return t.buffer;if(ce.isURLSearchParams(t))return n.setContentType(\"application/x-www-form-urlencoded;charset=utf-8\",!1),t.toString();let u;if(o){if(r.indexOf(\"application/x-www-form-urlencoded\")>-1)return E4(t,this.formSerializer).toString();if((u=ce.isFileList(t))||r.indexOf(\"multipart/form-data\")>-1){const d=this.env&&this.env.FormData;return Ch(u?{\"files[]\":t}:t,d&&new d,this.formSerializer)}}return o||s?(n.setContentType(\"application/json\",!1),T4(t)):t}],transformResponse:[function(t){const n=this.transitional||yd.transitional,r=n&&n.forcedJSONParsing,s=this.responseType===\"json\";if(ce.isResponse(t)||ce.isReadableStream(t))return t;if(t&&ce.isString(t)&&(r&&!this.responseType||s)){const l=!(n&&n.silentJSONParsing)&&s;try{return JSON.parse(t,this.parseReviver)}catch(u){if(l)throw u.name===\"SyntaxError\"?vt.from(u,vt.ERR_BAD_RESPONSE,this,null,this.response):u}}return t}],timeout:0,xsrfCookieName:\"XSRF-TOKEN\",xsrfHeaderName:\"X-XSRF-TOKEN\",maxContentLength:-1,maxBodyLength:-1,env:{FormData:rr.classes.FormData,Blob:rr.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:\"application/json, text/plain, */*\",\"Content-Type\":void 0}}};ce.forEach([\"delete\",\"get\",\"head\",\"post\",\"put\",\"patch\"],e=>{yd.headers[e]={}});const N4=ce.toObjectSet([\"age\",\"authorization\",\"content-length\",\"content-type\",\"etag\",\"expires\",\"from\",\"host\",\"if-modified-since\",\"if-unmodified-since\",\"last-modified\",\"location\",\"max-forwards\",\"proxy-authorization\",\"referer\",\"retry-after\",\"user-agent\"]),M4=e=>{const t={};let n,r,s;return e&&e.split(`\n`).forEach(function(l){s=l.indexOf(\":\"),n=l.substring(0,s).trim().toLowerCase(),r=l.substring(s+1).trim(),!(!n||t[n]&&N4[n])&&(n===\"set-cookie\"?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+\", \"+r:r)}),t},NC=Symbol(\"internals\");function ru(e){return e&&String(e).trim().toLowerCase()}function fp(e){return e===!1||e==null?e:ce.isArray(e)?e.map(fp):String(e)}function _4(e){const t=Object.create(null),n=/([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}const R4=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function vv(e,t,n,r,s){if(ce.isFunction(r))return r.call(this,t,n);if(s&&(t=n),!!ce.isString(t)){if(ce.isString(r))return t.indexOf(r)!==-1;if(ce.isRegExp(r))return r.test(t)}}function P4(e){return e.trim().toLowerCase().replace(/([a-z\\d])(\\w*)/g,(t,n,r)=>n.toUpperCase()+r)}function O4(e,t){const n=ce.toCamelCase(\" \"+t);[\"get\",\"set\",\"has\"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(s,o,l){return this[r].call(this,t,s,o,l)},configurable:!0})})}let Tr=class{constructor(t){t&&this.set(t)}set(t,n,r){const s=this;function o(u,d,f){const h=ru(d);if(!h)throw new Error(\"header name must be a non-empty string\");const m=ce.findKey(s,h);(!m||s[m]===void 0||f===!0||f===void 0&&s[m]!==!1)&&(s[m||d]=fp(u))}const l=(u,d)=>ce.forEach(u,(f,h)=>o(f,h,d));if(ce.isPlainObject(t)||t instanceof this.constructor)l(t,n);else if(ce.isString(t)&&(t=t.trim())&&!R4(t))l(M4(t),n);else if(ce.isObject(t)&&ce.isIterable(t)){let u={},d,f;for(const h of t){if(!ce.isArray(h))throw TypeError(\"Object iterator must return a key-value pair\");u[f=h[0]]=(d=u[f])?ce.isArray(d)?[...d,h[1]]:[d,h[1]]:h[1]}l(u,n)}else t!=null&&o(n,t,r);return this}get(t,n){if(t=ru(t),t){const r=ce.findKey(this,t);if(r){const s=this[r];if(!n)return s;if(n===!0)return _4(s);if(ce.isFunction(n))return n.call(this,s,r);if(ce.isRegExp(n))return n.exec(s);throw new TypeError(\"parser must be boolean|regexp|function\")}}}has(t,n){if(t=ru(t),t){const r=ce.findKey(this,t);return!!(r&&this[r]!==void 0&&(!n||vv(this,this[r],r,n)))}return!1}delete(t,n){const r=this;let s=!1;function o(l){if(l=ru(l),l){const u=ce.findKey(r,l);u&&(!n||vv(r,r[u],u,n))&&(delete r[u],s=!0)}}return ce.isArray(t)?t.forEach(o):o(t),s}clear(t){const n=Object.keys(this);let r=n.length,s=!1;for(;r--;){const o=n[r];(!t||vv(this,this[o],o,t,!0))&&(delete this[o],s=!0)}return s}normalize(t){const n=this,r={};return ce.forEach(this,(s,o)=>{const l=ce.findKey(r,o);if(l){n[l]=fp(s),delete n[o];return}const u=t?P4(o):String(o).trim();u!==o&&delete n[o],n[u]=fp(s),r[u]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return ce.forEach(this,(r,s)=>{r!=null&&r!==!1&&(n[s]=t&&ce.isArray(r)?r.join(\", \"):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+\": \"+n).join(`\n`)}getSetCookie(){return this.get(\"set-cookie\")||[]}get[Symbol.toStringTag](){return\"AxiosHeaders\"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const r=new this(t);return n.forEach(s=>r.set(s)),r}static accessor(t){const r=(this[NC]=this[NC]={accessors:{}}).accessors,s=this.prototype;function o(l){const u=ru(l);r[u]||(O4(s,l),r[u]=!0)}return ce.isArray(t)?t.forEach(o):o(t),this}};Tr.accessor([\"Content-Type\",\"Content-Length\",\"Accept\",\"Accept-Encoding\",\"User-Agent\",\"Authorization\"]);ce.reduceDescriptors(Tr.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(r){this[n]=r}}});ce.freezeMethods(Tr);function yv(e,t){const n=this||yd,r=t||n,s=Tr.from(r.headers);let o=r.data;return ce.forEach(e,function(u){o=u.call(n,o,s.normalize(),t?t.status:void 0)}),s.normalize(),o}function Gj(e){return!!(e&&e.__CANCEL__)}function rc(e,t,n){vt.call(this,e??\"canceled\",vt.ERR_CANCELED,t,n),this.name=\"CanceledError\"}ce.inherits(rc,vt,{__CANCEL__:!0});function Jj(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new vt(\"Request failed with status code \"+n.status,[vt.ERR_BAD_REQUEST,vt.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function I4(e){const t=/^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(e);return t&&t[1]||\"\"}function A4(e,t){e=e||10;const n=new Array(e),r=new Array(e);let s=0,o=0,l;return t=t!==void 0?t:1e3,function(d){const f=Date.now(),h=r[o];l||(l=f),n[s]=d,r[s]=f;let m=o,g=0;for(;m!==s;)g+=n[m++],m=m%e;if(s=(s+1)%e,s===o&&(o=(o+1)%e),f-l<t)return;const x=h&&f-h;return x?Math.round(g*1e3/x):void 0}}function D4(e,t){let n=0,r=1e3/t,s,o;const l=(f,h=Date.now())=>{n=h,s=null,o&&(clearTimeout(o),o=null),e(...f)};return[(...f)=>{const h=Date.now(),m=h-n;m>=r?l(f,h):(s=f,o||(o=setTimeout(()=>{o=null,l(s)},r-m)))},()=>s&&l(s)]}const Op=(e,t,n=3)=>{let r=0;const s=A4(50,250);return D4(o=>{const l=o.loaded,u=o.lengthComputable?o.total:void 0,d=l-r,f=s(d),h=l<=u;r=l;const m={loaded:l,total:u,progress:u?l/u:void 0,bytes:d,rate:f||void 0,estimated:f&&u&&h?(u-l)/f:void 0,event:o,lengthComputable:u!=null,[t?\"download\":\"upload\"]:!0};e(m)},n)},MC=(e,t)=>{const n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},_C=e=>(...t)=>ce.asap(()=>e(...t)),F4=rr.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,rr.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(rr.origin),rr.navigator&&/(msie|trident)/i.test(rr.navigator.userAgent)):()=>!0,L4=rr.hasStandardBrowserEnv?{write(e,t,n,r,s,o){const l=[e+\"=\"+encodeURIComponent(t)];ce.isNumber(n)&&l.push(\"expires=\"+new Date(n).toGMTString()),ce.isString(r)&&l.push(\"path=\"+r),ce.isString(s)&&l.push(\"domain=\"+s),o===!0&&l.push(\"secure\"),document.cookie=l.join(\"; \")},read(e){const t=document.cookie.match(new RegExp(\"(^|;\\\\s*)(\"+e+\")=([^;]*)\"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,\"\",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function $4(e){return/^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(e)}function B4(e,t){return t?e.replace(/\\/?\\/$/,\"\")+\"/\"+t.replace(/^\\/+/,\"\"):e}function Qj(e,t,n){let r=!$4(t);return e&&(r||n==!1)?B4(e,t):t}const RC=e=>e instanceof Tr?{...e}:e;function Si(e,t){t=t||{};const n={};function r(f,h,m,g){return ce.isPlainObject(f)&&ce.isPlainObject(h)?ce.merge.call({caseless:g},f,h):ce.isPlainObject(h)?ce.merge({},h):ce.isArray(h)?h.slice():h}function s(f,h,m,g){if(ce.isUndefined(h)){if(!ce.isUndefined(f))return r(void 0,f,m,g)}else return r(f,h,m,g)}function o(f,h){if(!ce.isUndefined(h))return r(void 0,h)}function l(f,h){if(ce.isUndefined(h)){if(!ce.isUndefined(f))return r(void 0,f)}else return r(void 0,h)}function u(f,h,m){if(m in t)return r(f,h);if(m in e)return r(void 0,f)}const d={url:o,method:o,data:o,baseURL:l,transformRequest:l,transformResponse:l,paramsSerializer:l,timeout:l,timeoutMessage:l,withCredentials:l,withXSRFToken:l,adapter:l,responseType:l,xsrfCookieName:l,xsrfHeaderName:l,onUploadProgress:l,onDownloadProgress:l,decompress:l,maxContentLength:l,maxBodyLength:l,beforeRedirect:l,transport:l,httpAgent:l,httpsAgent:l,cancelToken:l,socketPath:l,responseEncoding:l,validateStatus:u,headers:(f,h,m)=>s(RC(f),RC(h),m,!0)};return ce.forEach(Object.keys({...e,...t}),function(h){const m=d[h]||s,g=m(e[h],t[h],h);ce.isUndefined(g)&&m!==u||(n[h]=g)}),n}const Zj=e=>{const t=Si({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:s,xsrfCookieName:o,headers:l,auth:u}=t;if(t.headers=l=Tr.from(l),t.url=qj(Qj(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),u&&l.set(\"Authorization\",\"Basic \"+btoa((u.username||\"\")+\":\"+(u.password?unescape(encodeURIComponent(u.password)):\"\"))),ce.isFormData(n)){if(rr.hasStandardBrowserEnv||rr.hasStandardBrowserWebWorkerEnv)l.setContentType(void 0);else if(ce.isFunction(n.getHeaders)){const d=n.getHeaders(),f=[\"content-type\",\"content-length\"];Object.entries(d).forEach(([h,m])=>{f.includes(h.toLowerCase())&&l.set(h,m)})}}if(rr.hasStandardBrowserEnv&&(r&&ce.isFunction(r)&&(r=r(t)),r||r!==!1&&F4(t.url))){const d=s&&o&&L4.read(o);d&&l.set(s,d)}return t},z4=typeof XMLHttpRequest<\"u\",U4=z4&&function(e){return new Promise(function(n,r){const s=Zj(e);let o=s.data;const l=Tr.from(s.headers).normalize();let{responseType:u,onUploadProgress:d,onDownloadProgress:f}=s,h,m,g,x,b;function w(){x&&x(),b&&b(),s.cancelToken&&s.cancelToken.unsubscribe(h),s.signal&&s.signal.removeEventListener(\"abort\",h)}let C=new XMLHttpRequest;C.open(s.method.toUpperCase(),s.url,!0),C.timeout=s.timeout;function k(){if(!C)return;const M=Tr.from(\"getAllResponseHeaders\"in C&&C.getAllResponseHeaders()),R={data:!u||u===\"text\"||u===\"json\"?C.responseText:C.response,status:C.status,statusText:C.statusText,headers:M,config:e,request:C};Jj(function(O){n(O),w()},function(O){r(O),w()},R),C=null}\"onloadend\"in C?C.onloadend=k:C.onreadystatechange=function(){!C||C.readyState!==4||C.status===0&&!(C.responseURL&&C.responseURL.indexOf(\"file:\")===0)||setTimeout(k)},C.onabort=function(){C&&(r(new vt(\"Request aborted\",vt.ECONNABORTED,e,C)),C=null)},C.onerror=function(_){const R=_&&_.message?_.message:\"Network Error\",N=new vt(R,vt.ERR_NETWORK,e,C);N.event=_||null,r(N),C=null},C.ontimeout=function(){let _=s.timeout?\"timeout of \"+s.timeout+\"ms exceeded\":\"timeout exceeded\";const R=s.transitional||Kj;s.timeoutErrorMessage&&(_=s.timeoutErrorMessage),r(new vt(_,R.clarifyTimeoutError?vt.ETIMEDOUT:vt.ECONNABORTED,e,C)),C=null},o===void 0&&l.setContentType(null),\"setRequestHeader\"in C&&ce.forEach(l.toJSON(),function(_,R){C.setRequestHeader(R,_)}),ce.isUndefined(s.withCredentials)||(C.withCredentials=!!s.withCredentials),u&&u!==\"json\"&&(C.responseType=s.responseType),f&&([g,b]=Op(f,!0),C.addEventListener(\"progress\",g)),d&&C.upload&&([m,x]=Op(d),C.upload.addEventListener(\"progress\",m),C.upload.addEventListener(\"loadend\",x)),(s.cancelToken||s.signal)&&(h=M=>{C&&(r(!M||M.type?new rc(null,e,C):M),C.abort(),C=null)},s.cancelToken&&s.cancelToken.subscribe(h),s.signal&&(s.signal.aborted?h():s.signal.addEventListener(\"abort\",h)));const j=I4(s.url);if(j&&rr.protocols.indexOf(j)===-1){r(new vt(\"Unsupported protocol \"+j+\":\",vt.ERR_BAD_REQUEST,e));return}C.send(o||null)})},V4=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let r=new AbortController,s;const o=function(f){if(!s){s=!0,u();const h=f instanceof Error?f:this.reason;r.abort(h instanceof vt?h:new rc(h instanceof Error?h.message:h))}};let l=t&&setTimeout(()=>{l=null,o(new vt(`timeout ${t} of ms exceeded`,vt.ETIMEDOUT))},t);const u=()=>{e&&(l&&clearTimeout(l),l=null,e.forEach(f=>{f.unsubscribe?f.unsubscribe(o):f.removeEventListener(\"abort\",o)}),e=null)};e.forEach(f=>f.addEventListener(\"abort\",o));const{signal:d}=r;return d.unsubscribe=()=>ce.asap(u),d}},H4=function*(e,t){let n=e.byteLength;if(n<t){yield e;return}let r=0,s;for(;r<n;)s=r+t,yield e.slice(r,s),r=s},q4=async function*(e,t){for await(const n of K4(e))yield*H4(n,t)},K4=async function*(e){if(e[Symbol.asyncIterator]){yield*e;return}const t=e.getReader();try{for(;;){const{done:n,value:r}=await t.read();if(n)break;yield r}}finally{await t.cancel()}},PC=(e,t,n,r)=>{const s=q4(e,t);let o=0,l,u=d=>{l||(l=!0,r&&r(d))};return new ReadableStream({async pull(d){try{const{done:f,value:h}=await s.next();if(f){u(),d.close();return}let m=h.byteLength;if(n){let g=o+=m;n(g)}d.enqueue(new Uint8Array(h))}catch(f){throw u(f),f}},cancel(d){return u(d),s.return()}},{highWaterMark:2})},OC=64*1024,{isFunction:Bf}=ce,W4=(({Request:e,Response:t})=>({Request:e,Response:t}))(ce.global),{ReadableStream:IC,TextEncoder:AC}=ce.global,DC=(e,...t)=>{try{return!!e(...t)}catch{return!1}},G4=e=>{e=ce.merge.call({skipUndefined:!0},W4,e);const{fetch:t,Request:n,Response:r}=e,s=t?Bf(t):typeof fetch==\"function\",o=Bf(n),l=Bf(r);if(!s)return!1;const u=s&&Bf(IC),d=s&&(typeof AC==\"function\"?(b=>w=>b.encode(w))(new AC):async b=>new Uint8Array(await new n(b).arrayBuffer())),f=o&&u&&DC(()=>{let b=!1;const w=new n(rr.origin,{body:new IC,method:\"POST\",get duplex(){return b=!0,\"half\"}}).headers.has(\"Content-Type\");return b&&!w}),h=l&&u&&DC(()=>ce.isReadableStream(new r(\"\").body)),m={stream:h&&(b=>b.body)};s&&[\"text\",\"arrayBuffer\",\"blob\",\"formData\",\"stream\"].forEach(b=>{!m[b]&&(m[b]=(w,C)=>{let k=w&&w[b];if(k)return k.call(w);throw new vt(`Response type '${b}' is not supported`,vt.ERR_NOT_SUPPORT,C)})});const g=async b=>{if(b==null)return 0;if(ce.isBlob(b))return b.size;if(ce.isSpecCompliantForm(b))return(await new n(rr.origin,{method:\"POST\",body:b}).arrayBuffer()).byteLength;if(ce.isArrayBufferView(b)||ce.isArrayBuffer(b))return b.byteLength;if(ce.isURLSearchParams(b)&&(b=b+\"\"),ce.isString(b))return(await d(b)).byteLength},x=async(b,w)=>{const C=ce.toFiniteNumber(b.getContentLength());return C??g(w)};return async b=>{let{url:w,method:C,data:k,signal:j,cancelToken:M,timeout:_,onDownloadProgress:R,onUploadProgress:N,responseType:O,headers:D,withCredentials:z=\"same-origin\",fetchOptions:Q}=Zj(b),pe=t||fetch;O=O?(O+\"\").toLowerCase():\"text\";let V=V4([j,M&&M.toAbortSignal()],_),G=null;const W=V&&V.unsubscribe&&(()=>{V.unsubscribe()});let ie;try{if(N&&f&&C!==\"get\"&&C!==\"head\"&&(ie=await x(D,k))!==0){let A=new n(w,{method:\"POST\",body:k,duplex:\"half\"}),F;if(ce.isFormData(k)&&(F=A.headers.get(\"content-type\"))&&D.setContentType(F),A.body){const[fe,te]=MC(ie,Op(_C(N)));k=PC(A.body,OC,fe,te)}}ce.isString(z)||(z=z?\"include\":\"omit\");const re=o&&\"credentials\"in n.prototype,Y={...Q,signal:V,method:C.toUpperCase(),headers:D.normalize().toJSON(),body:k,duplex:\"half\",credentials:re?z:void 0};G=o&&new n(w,Y);let H=await(o?pe(G,Q):pe(w,Y));const q=h&&(O===\"stream\"||O===\"response\");if(h&&(R||q&&W)){const A={};[\"status\",\"statusText\",\"headers\"].forEach(de=>{A[de]=H[de]});const F=ce.toFiniteNumber(H.headers.get(\"content-length\")),[fe,te]=R&&MC(F,Op(_C(R),!0))||[];H=new r(PC(H.body,OC,fe,()=>{te&&te(),W&&W()}),A)}O=O||\"text\";let he=await m[ce.findKey(m,O)||\"text\"](H,b);return!q&&W&&W(),await new Promise((A,F)=>{Jj(A,F,{data:he,headers:Tr.from(H.headers),status:H.status,statusText:H.statusText,config:b,request:G})})}catch(re){throw W&&W(),re&&re.name===\"TypeError\"&&/Load failed|fetch/i.test(re.message)?Object.assign(new vt(\"Network Error\",vt.ERR_NETWORK,b,G),{cause:re.cause||re}):vt.from(re,re&&re.code,b,G)}}},J4=new Map,Yj=e=>{let t=e?e.env:{};const{fetch:n,Request:r,Response:s}=t,o=[r,s,n];let l=o.length,u=l,d,f,h=J4;for(;u--;)d=o[u],f=h.get(d),f===void 0&&h.set(d,f=u?new Map:G4(t)),h=f;return f};Yj();const Dy={http:f4,xhr:U4,fetch:{get:Yj}};ce.forEach(Dy,(e,t)=>{if(e){try{Object.defineProperty(e,\"name\",{value:t})}catch{}Object.defineProperty(e,\"adapterName\",{value:t})}});const FC=e=>`- ${e}`,Q4=e=>ce.isFunction(e)||e===null||e===!1,Xj={getAdapter:(e,t)=>{e=ce.isArray(e)?e:[e];const{length:n}=e;let r,s;const o={};for(let l=0;l<n;l++){r=e[l];let u;if(s=r,!Q4(r)&&(s=Dy[(u=String(r)).toLowerCase()],s===void 0))throw new vt(`Unknown adapter '${u}'`);if(s&&(ce.isFunction(s)||(s=s.get(t))))break;o[u||\"#\"+l]=s}if(!s){const l=Object.entries(o).map(([d,f])=>`adapter ${d} `+(f===!1?\"is not supported by the environment\":\"is not available in the build\"));let u=n?l.length>1?`since :\n`+l.map(FC).join(`\n`):\" \"+FC(l[0]):\"as no adapter specified\";throw new vt(\"There is no suitable adapter to dispatch the request \"+u,\"ERR_NOT_SUPPORT\")}return s},adapters:Dy};function bv(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new rc(null,e)}function LC(e){return bv(e),e.headers=Tr.from(e.headers),e.data=yv.call(e,e.transformRequest),[\"post\",\"put\",\"patch\"].indexOf(e.method)!==-1&&e.headers.setContentType(\"application/x-www-form-urlencoded\",!1),Xj.getAdapter(e.adapter||yd.adapter,e)(e).then(function(r){return bv(e),r.data=yv.call(e,e.transformResponse,r),r.headers=Tr.from(r.headers),r},function(r){return Gj(r)||(bv(e),r&&r.response&&(r.response.data=yv.call(e,e.transformResponse,r.response),r.response.headers=Tr.from(r.response.headers))),Promise.reject(r)})}const eT=\"1.12.2\",Eh={};[\"object\",\"boolean\",\"number\",\"function\",\"string\",\"symbol\"].forEach((e,t)=>{Eh[e]=function(r){return typeof r===e||\"a\"+(t<1?\"n \":\" \")+e}});const $C={};Eh.transitional=function(t,n,r){function s(o,l){return\"[Axios v\"+eT+\"] Transitional option '\"+o+\"'\"+l+(r?\". \"+r:\"\")}return(o,l,u)=>{if(t===!1)throw new vt(s(l,\" has been removed\"+(n?\" in \"+n:\"\")),vt.ERR_DEPRECATED);return n&&!$C[l]&&($C[l]=!0,console.warn(s(l,\" has been deprecated since v\"+n+\" and will be removed in the near future\"))),t?t(o,l,u):!0}};Eh.spelling=function(t){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${t}`),!0)};function Z4(e,t,n){if(typeof e!=\"object\")throw new vt(\"options must be an object\",vt.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let s=r.length;for(;s-- >0;){const o=r[s],l=t[o];if(l){const u=e[o],d=u===void 0||l(u,o,e);if(d!==!0)throw new vt(\"option \"+o+\" must be \"+d,vt.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new vt(\"Unknown option \"+o,vt.ERR_BAD_OPTION)}}const pp={assertOptions:Z4,validators:Eh},$s=pp.validators;let hi=class{constructor(t){this.defaults=t||{},this.interceptors={request:new TC,response:new TC}}async request(t,n){try{return await this._request(t,n)}catch(r){if(r instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const o=s.stack?s.stack.replace(/^.+\\n/,\"\"):\"\";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\\n.+\\n/,\"\"))&&(r.stack+=`\n`+o):r.stack=o}catch{}}throw r}}_request(t,n){typeof t==\"string\"?(n=n||{},n.url=t):n=t||{},n=Si(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:o}=n;r!==void 0&&pp.assertOptions(r,{silentJSONParsing:$s.transitional($s.boolean),forcedJSONParsing:$s.transitional($s.boolean),clarifyTimeoutError:$s.transitional($s.boolean)},!1),s!=null&&(ce.isFunction(s)?n.paramsSerializer={serialize:s}:pp.assertOptions(s,{encode:$s.function,serialize:$s.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),pp.assertOptions(n,{baseUrl:$s.spelling(\"baseURL\"),withXsrfToken:$s.spelling(\"withXSRFToken\")},!0),n.method=(n.method||this.defaults.method||\"get\").toLowerCase();let l=o&&ce.merge(o.common,o[n.method]);o&&ce.forEach([\"delete\",\"get\",\"head\",\"post\",\"put\",\"patch\",\"common\"],b=>{delete o[b]}),n.headers=Tr.concat(l,o);const u=[];let d=!0;this.interceptors.request.forEach(function(w){typeof w.runWhen==\"function\"&&w.runWhen(n)===!1||(d=d&&w.synchronous,u.unshift(w.fulfilled,w.rejected))});const f=[];this.interceptors.response.forEach(function(w){f.push(w.fulfilled,w.rejected)});let h,m=0,g;if(!d){const b=[LC.bind(this),void 0];for(b.unshift(...u),b.push(...f),g=b.length,h=Promise.resolve(n);m<g;)h=h.then(b[m++],b[m++]);return h}g=u.length;let x=n;for(;m<g;){const b=u[m++],w=u[m++];try{x=b(x)}catch(C){w.call(this,C);break}}try{h=LC.call(this,x)}catch(b){return Promise.reject(b)}for(m=0,g=f.length;m<g;)h=h.then(f[m++],f[m++]);return h}getUri(t){t=Si(this.defaults,t);const n=Qj(t.baseURL,t.url,t.allowAbsoluteUrls);return qj(n,t.params,t.paramsSerializer)}};ce.forEach([\"delete\",\"get\",\"head\",\"options\"],function(t){hi.prototype[t]=function(n,r){return this.request(Si(r||{},{method:t,url:n,data:(r||{}).data}))}});ce.forEach([\"post\",\"put\",\"patch\"],function(t){function n(r){return function(o,l,u){return this.request(Si(u||{},{method:t,headers:r?{\"Content-Type\":\"multipart/form-data\"}:{},url:o,data:l}))}}hi.prototype[t]=n(),hi.prototype[t+\"Form\"]=n(!0)});let Y4=class tT{constructor(t){if(typeof t!=\"function\")throw new TypeError(\"executor must be a function.\");let n;this.promise=new Promise(function(o){n=o});const r=this;this.promise.then(s=>{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](s);r._listeners=null}),this.promise.then=s=>{let o;const l=new Promise(u=>{r.subscribe(u),o=u}).then(s);return l.cancel=function(){r.unsubscribe(o)},l},t(function(o,l,u){r.reason||(r.reason=new rc(o,l,u),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new tT(function(s){t=s}),cancel:t}}};function X4(e){return function(n){return e.apply(null,n)}}function e$(e){return ce.isObject(e)&&e.isAxiosError===!0}const Fy={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Fy).forEach(([e,t])=>{Fy[t]=e});function nT(e){const t=new hi(e),n=Oj(hi.prototype.request,t);return ce.extend(n,hi.prototype,t,{allOwnKeys:!0}),ce.extend(n,t,null,{allOwnKeys:!0}),n.create=function(s){return nT(Si(e,s))},n}const sn=nT(yd);sn.Axios=hi;sn.CanceledError=rc;sn.CancelToken=Y4;sn.isCancel=Gj;sn.VERSION=eT;sn.toFormData=Ch;sn.AxiosError=vt;sn.Cancel=sn.CanceledError;sn.all=function(t){return Promise.all(t)};sn.spread=X4;sn.isAxiosError=e$;sn.mergeConfig=Si;sn.AxiosHeaders=Tr;sn.formToJSON=e=>Wj(ce.isHTMLForm(e)?new FormData(e):e);sn.getAdapter=Xj.getAdapter;sn.HttpStatusCode=Fy;sn.default=sn;const{Axios:aie,AxiosError:iie,CanceledError:lie,isCancel:cie,CancelToken:uie,VERSION:die,all:fie,Cancel:pie,isAxiosError:rT,spread:hie,toFormData:gie,AxiosHeaders:mie,HttpStatusCode:vie,formToJSON:yie,getAdapter:bie,mergeConfig:xie}=sn,t$=e=>[\"auth\",\"verifyServer\",JSON.stringify(e)],sT=async({url:e})=>(await sn.get(`${e}/`)).data,n$=e=>{const{url:t,...n}=e;return mt({...n,queryKey:t$({url:t}),queryFn:()=>sT({url:t}),enabled:!!t})};function r$(e,t){typeof e==\"function\"?e(t):e!=null&&(e.current=t)}function kh(...e){return t=>e.forEach(n=>r$(n,t))}function Rt(...e){return y.useCallback(kh(...e),e)}var No=y.forwardRef((e,t)=>{const{children:n,...r}=e,s=y.Children.toArray(n),o=s.find(o$);if(o){const l=o.props.children,u=s.map(d=>d===o?y.Children.count(l)>1?y.Children.only(null):y.isValidElement(l)?l.props.children:null:d);return i.jsx(Ly,{...r,ref:t,children:y.isValidElement(l)?y.cloneElement(l,void 0,u):null})}return i.jsx(Ly,{...r,ref:t,children:n})});No.displayName=\"Slot\";var Ly=y.forwardRef((e,t)=>{const{children:n,...r}=e;if(y.isValidElement(n)){const s=i$(n);return y.cloneElement(n,{...a$(r,n.props),ref:t?kh(t,s):s})}return y.Children.count(n)>1?y.Children.only(null):null});Ly.displayName=\"SlotClone\";var s$=({children:e})=>i.jsx(i.Fragment,{children:e});function o$(e){return y.isValidElement(e)&&e.type===s$}function a$(e,t){const n={...t};for(const r in t){const s=e[r],o=t[r];/^on[A-Z]/.test(r)?s&&o?n[r]=(...u)=>{o(...u),s(...u)}:s&&(n[r]=s):r===\"style\"?n[r]={...s,...o}:r===\"className\"&&(n[r]=[s,o].filter(Boolean).join(\" \"))}return{...e,...n}}function i$(e){let t=Object.getOwnPropertyDescriptor(e.props,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function oT(e){var t,n,r=\"\";if(typeof e==\"string\"||typeof e==\"number\")r+=e;else if(typeof e==\"object\")if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=oT(e[t]))&&(r&&(r+=\" \"),r+=n);else for(t in e)e[t]&&(r&&(r+=\" \"),r+=t);return r}function l$(){for(var e,t,n=0,r=\"\";n<arguments.length;)(e=arguments[n++])&&(t=oT(e))&&(r&&(r+=\" \"),r+=t);return r}const BC=e=>typeof e==\"boolean\"?\"\".concat(e):e===0?\"0\":e,zC=l$,jh=(e,t)=>n=>{var r;if(t?.variants==null)return zC(e,n?.class,n?.className);const{variants:s,defaultVariants:o}=t,l=Object.keys(s).map(f=>{const h=n?.[f],m=o?.[f];if(h===null)return null;const g=BC(h)||BC(m);return s[f][g]}),u=n&&Object.entries(n).reduce((f,h)=>{let[m,g]=h;return g===void 0||(f[m]=g),f},{}),d=t==null||(r=t.compoundVariants)===null||r===void 0?void 0:r.reduce((f,h)=>{let{class:m,className:g,...x}=h;return Object.entries(x).every(b=>{let[w,C]=b;return Array.isArray(C)?C.includes({...o,...u}[w]):{...o,...u}[w]===C})?[...f,m,g]:f},[]);return zC(e,l,d,n?.class,n?.className)},Ub=\"-\";function c$(e){const t=d$(e),{conflictingClassGroups:n,conflictingClassGroupModifiers:r}=e;function s(l){const u=l.split(Ub);return u[0]===\"\"&&u.length!==1&&u.shift(),aT(u,t)||u$(l)}function o(l,u){const d=n[l]||[];return u&&r[l]?[...d,...r[l]]:d}return{getClassGroupId:s,getConflictingClassGroupIds:o}}function aT(e,t){if(e.length===0)return t.classGroupId;const n=e[0],r=t.nextPart.get(n),s=r?aT(e.slice(1),r):void 0;if(s)return s;if(t.validators.length===0)return;const o=e.join(Ub);return t.validators.find(({validator:l})=>l(o))?.classGroupId}const UC=/^\\[(.+)\\]$/;function u$(e){if(UC.test(e)){const t=UC.exec(e)[1],n=t?.substring(0,t.indexOf(\":\"));if(n)return\"arbitrary..\"+n}}function d$(e){const{theme:t,prefix:n}=e,r={nextPart:new Map,validators:[]};return p$(Object.entries(e.classGroups),n).forEach(([o,l])=>{$y(l,r,o,t)}),r}function $y(e,t,n,r){e.forEach(s=>{if(typeof s==\"string\"){const o=s===\"\"?t:VC(t,s);o.classGroupId=n;return}if(typeof s==\"function\"){if(f$(s)){$y(s(r),t,n,r);return}t.validators.push({validator:s,classGroupId:n});return}Object.entries(s).forEach(([o,l])=>{$y(l,VC(t,o),n,r)})})}function VC(e,t){let n=e;return t.split(Ub).forEach(r=>{n.nextPart.has(r)||n.nextPart.set(r,{nextPart:new Map,validators:[]}),n=n.nextPart.get(r)}),n}function f$(e){return e.isThemeGetter}function p$(e,t){return t?e.map(([n,r])=>{const s=r.map(o=>typeof o==\"string\"?t+o:typeof o==\"object\"?Object.fromEntries(Object.entries(o).map(([l,u])=>[t+l,u])):o);return[n,s]}):e}function h$(e){if(e<1)return{get:()=>{},set:()=>{}};let t=0,n=new Map,r=new Map;function s(o,l){n.set(o,l),t++,t>e&&(t=0,r=n,n=new Map)}return{get(o){let l=n.get(o);if(l!==void 0)return l;if((l=r.get(o))!==void 0)return s(o,l),l},set(o,l){n.has(o)?n.set(o,l):s(o,l)}}}const iT=\"!\";function g$(e){const{separator:t,experimentalParseClassName:n}=e,r=t.length===1,s=t[0],o=t.length;function l(u){const d=[];let f=0,h=0,m;for(let C=0;C<u.length;C++){let k=u[C];if(f===0){if(k===s&&(r||u.slice(C,C+o)===t)){d.push(u.slice(h,C)),h=C+o;continue}if(k===\"/\"){m=C;continue}}k===\"[\"?f++:k===\"]\"&&f--}const g=d.length===0?u:u.substring(h),x=g.startsWith(iT),b=x?g.substring(1):g,w=m&&m>h?m-h:void 0;return{modifiers:d,hasImportantModifier:x,baseClassName:b,maybePostfixModifierPosition:w}}return n?function(d){return n({className:d,parseClassName:l})}:l}function m$(e){if(e.length<=1)return e;const t=[];let n=[];return e.forEach(r=>{r[0]===\"[\"?(t.push(...n.sort(),r),n=[]):n.push(r)}),t.push(...n.sort()),t}function v$(e){return{cache:h$(e.cacheSize),parseClassName:g$(e),...c$(e)}}const y$=/\\s+/;function b$(e,t){const{parseClassName:n,getClassGroupId:r,getConflictingClassGroupIds:s}=t,o=new Set;return e.trim().split(y$).map(l=>{const{modifiers:u,hasImportantModifier:d,baseClassName:f,maybePostfixModifierPosition:h}=n(l);let m=!!h,g=r(m?f.substring(0,h):f);if(!g){if(!m)return{isTailwindClass:!1,originalClassName:l};if(g=r(f),!g)return{isTailwindClass:!1,originalClassName:l};m=!1}const x=m$(u).join(\":\");return{isTailwindClass:!0,modifierId:d?x+iT:x,classGroupId:g,originalClassName:l,hasPostfixModifier:m}}).reverse().filter(l=>{if(!l.isTailwindClass)return!0;const{modifierId:u,classGroupId:d,hasPostfixModifier:f}=l,h=u+d;return o.has(h)?!1:(o.add(h),s(d,f).forEach(m=>o.add(u+m)),!0)}).reverse().map(l=>l.originalClassName).join(\" \")}function x$(){let e=0,t,n,r=\"\";for(;e<arguments.length;)(t=arguments[e++])&&(n=lT(t))&&(r&&(r+=\" \"),r+=n);return r}function lT(e){if(typeof e==\"string\")return e;let t,n=\"\";for(let r=0;r<e.length;r++)e[r]&&(t=lT(e[r]))&&(n&&(n+=\" \"),n+=t);return n}function w$(e,...t){let n,r,s,o=l;function l(d){const f=t.reduce((h,m)=>m(h),e());return n=v$(f),r=n.cache.get,s=n.cache.set,o=u,u(d)}function u(d){const f=r(d);if(f)return f;const h=b$(d,n);return s(d,h),h}return function(){return o(x$.apply(null,arguments))}}function nn(e){const t=n=>n[e]||[];return t.isThemeGetter=!0,t}const cT=/^\\[(?:([a-z-]+):)?(.+)\\]$/i,S$=/^\\d+\\/\\d+$/,C$=new Set([\"px\",\"full\",\"screen\"]),E$=/^(\\d+(\\.\\d+)?)?(xs|sm|md|lg|xl)$/,k$=/\\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\\b(calc|min|max|clamp)\\(.+\\)|^0$/,j$=/^(rgba?|hsla?|hwb|(ok)?(lab|lch))\\(.+\\)$/,T$=/^(inset_)?-?((\\d+)?\\.?(\\d+)[a-z]+|0)_-?((\\d+)?\\.?(\\d+)[a-z]+|0)/,N$=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\\(.+\\)$/;function ho(e){return ci(e)||C$.has(e)||S$.test(e)}function ca(e){return sc(e,\"length\",D$)}function ci(e){return!!e&&!Number.isNaN(Number(e))}function zf(e){return sc(e,\"number\",ci)}function su(e){return!!e&&Number.isInteger(Number(e))}function M$(e){return e.endsWith(\"%\")&&ci(e.slice(0,-1))}function xt(e){return cT.test(e)}function ua(e){return E$.test(e)}const _$=new Set([\"length\",\"size\",\"percentage\"]);function R$(e){return sc(e,_$,uT)}function P$(e){return sc(e,\"position\",uT)}const O$=new Set([\"image\",\"url\"]);function I$(e){return sc(e,O$,L$)}function A$(e){return sc(e,\"\",F$)}function ou(){return!0}function sc(e,t,n){const r=cT.exec(e);return r?r[1]?typeof t==\"string\"?r[1]===t:t.has(r[1]):n(r[2]):!1}function D$(e){return k$.test(e)&&!j$.test(e)}function uT(){return!1}function F$(e){return T$.test(e)}function L$(e){return N$.test(e)}function $$(){const e=nn(\"colors\"),t=nn(\"spacing\"),n=nn(\"blur\"),r=nn(\"brightness\"),s=nn(\"borderColor\"),o=nn(\"borderRadius\"),l=nn(\"borderSpacing\"),u=nn(\"borderWidth\"),d=nn(\"contrast\"),f=nn(\"grayscale\"),h=nn(\"hueRotate\"),m=nn(\"invert\"),g=nn(\"gap\"),x=nn(\"gradientColorStops\"),b=nn(\"gradientColorStopPositions\"),w=nn(\"inset\"),C=nn(\"margin\"),k=nn(\"opacity\"),j=nn(\"padding\"),M=nn(\"saturate\"),_=nn(\"scale\"),R=nn(\"sepia\"),N=nn(\"skew\"),O=nn(\"space\"),D=nn(\"translate\"),z=()=>[\"auto\",\"contain\",\"none\"],Q=()=>[\"auto\",\"hidden\",\"clip\",\"visible\",\"scroll\"],pe=()=>[\"auto\",xt,t],V=()=>[xt,t],G=()=>[\"\",ho,ca],W=()=>[\"auto\",ci,xt],ie=()=>[\"bottom\",\"center\",\"left\",\"left-bottom\",\"left-top\",\"right\",\"right-bottom\",\"right-top\",\"top\"],re=()=>[\"solid\",\"dashed\",\"dotted\",\"double\",\"none\"],Y=()=>[\"normal\",\"multiply\",\"screen\",\"overlay\",\"darken\",\"lighten\",\"color-dodge\",\"color-burn\",\"hard-light\",\"soft-light\",\"difference\",\"exclusion\",\"hue\",\"saturation\",\"color\",\"luminosity\"],H=()=>[\"start\",\"end\",\"center\",\"between\",\"around\",\"evenly\",\"stretch\"],q=()=>[\"\",\"0\",xt],he=()=>[\"auto\",\"avoid\",\"all\",\"avoid-page\",\"page\",\"left\",\"right\",\"column\"],A=()=>[ci,zf],F=()=>[ci,xt];return{cacheSize:500,separator:\":\",theme:{colors:[ou],spacing:[ho,ca],blur:[\"none\",\"\",ua,xt],brightness:A(),borderColor:[e],borderRadius:[\"none\",\"\",\"full\",ua,xt],borderSpacing:V(),borderWidth:G(),contrast:A(),grayscale:q(),hueRotate:F(),invert:q(),gap:V(),gradientColorStops:[e],gradientColorStopPositions:[M$,ca],inset:pe(),margin:pe(),opacity:A(),padding:V(),saturate:A(),scale:A(),sepia:q(),skew:F(),space:V(),translate:V()},classGroups:{aspect:[{aspect:[\"auto\",\"square\",\"video\",xt]}],container:[\"container\"],columns:[{columns:[ua]}],\"break-after\":[{\"break-after\":he()}],\"break-before\":[{\"break-before\":he()}],\"break-inside\":[{\"break-inside\":[\"auto\",\"avoid\",\"avoid-page\",\"avoid-column\"]}],\"box-decoration\":[{\"box-decoration\":[\"slice\",\"clone\"]}],box:[{box:[\"border\",\"content\"]}],display:[\"block\",\"inline-block\",\"inline\",\"flex\",\"inline-flex\",\"table\",\"inline-table\",\"table-caption\",\"table-cell\",\"table-column\",\"table-column-group\",\"table-footer-group\",\"table-header-group\",\"table-row-group\",\"table-row\",\"flow-root\",\"grid\",\"inline-grid\",\"contents\",\"list-item\",\"hidden\"],float:[{float:[\"right\",\"left\",\"none\",\"start\",\"end\"]}],clear:[{clear:[\"left\",\"right\",\"both\",\"none\",\"start\",\"end\"]}],isolation:[\"isolate\",\"isolation-auto\"],\"object-fit\":[{object:[\"contain\",\"cover\",\"fill\",\"none\",\"scale-down\"]}],\"object-position\":[{object:[...ie(),xt]}],overflow:[{overflow:Q()}],\"overflow-x\":[{\"overflow-x\":Q()}],\"overflow-y\":[{\"overflow-y\":Q()}],overscroll:[{overscroll:z()}],\"overscroll-x\":[{\"overscroll-x\":z()}],\"overscroll-y\":[{\"overscroll-y\":z()}],position:[\"static\",\"fixed\",\"absolute\",\"relative\",\"sticky\"],inset:[{inset:[w]}],\"inset-x\":[{\"inset-x\":[w]}],\"inset-y\":[{\"inset-y\":[w]}],start:[{start:[w]}],end:[{end:[w]}],top:[{top:[w]}],right:[{right:[w]}],bottom:[{bottom:[w]}],left:[{left:[w]}],visibility:[\"visible\",\"invisible\",\"collapse\"],z:[{z:[\"auto\",su,xt]}],basis:[{basis:pe()}],\"flex-direction\":[{flex:[\"row\",\"row-reverse\",\"col\",\"col-reverse\"]}],\"flex-wrap\":[{flex:[\"wrap\",\"wrap-reverse\",\"nowrap\"]}],flex:[{flex:[\"1\",\"auto\",\"initial\",\"none\",xt]}],grow:[{grow:q()}],shrink:[{shrink:q()}],order:[{order:[\"first\",\"last\",\"none\",su,xt]}],\"grid-cols\":[{\"grid-cols\":[ou]}],\"col-start-end\":[{col:[\"auto\",{span:[\"full\",su,xt]},xt]}],\"col-start\":[{\"col-start\":W()}],\"col-end\":[{\"col-end\":W()}],\"grid-rows\":[{\"grid-rows\":[ou]}],\"row-start-end\":[{row:[\"auto\",{span:[su,xt]},xt]}],\"row-start\":[{\"row-start\":W()}],\"row-end\":[{\"row-end\":W()}],\"grid-flow\":[{\"grid-flow\":[\"row\",\"col\",\"dense\",\"row-dense\",\"col-dense\"]}],\"auto-cols\":[{\"auto-cols\":[\"auto\",\"min\",\"max\",\"fr\",xt]}],\"auto-rows\":[{\"auto-rows\":[\"auto\",\"min\",\"max\",\"fr\",xt]}],gap:[{gap:[g]}],\"gap-x\":[{\"gap-x\":[g]}],\"gap-y\":[{\"gap-y\":[g]}],\"justify-content\":[{justify:[\"normal\",...H()]}],\"justify-items\":[{\"justify-items\":[\"start\",\"end\",\"center\",\"stretch\"]}],\"justify-self\":[{\"justify-self\":[\"auto\",\"start\",\"end\",\"center\",\"stretch\"]}],\"align-content\":[{content:[\"normal\",...H(),\"baseline\"]}],\"align-items\":[{items:[\"start\",\"end\",\"center\",\"baseline\",\"stretch\"]}],\"align-self\":[{self:[\"auto\",\"start\",\"end\",\"center\",\"stretch\",\"baseline\"]}],\"place-content\":[{\"place-content\":[...H(),\"baseline\"]}],\"place-items\":[{\"place-items\":[\"start\",\"end\",\"center\",\"baseline\",\"stretch\"]}],\"place-self\":[{\"place-self\":[\"auto\",\"start\",\"end\",\"center\",\"stretch\"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[C]}],mx:[{mx:[C]}],my:[{my:[C]}],ms:[{ms:[C]}],me:[{me:[C]}],mt:[{mt:[C]}],mr:[{mr:[C]}],mb:[{mb:[C]}],ml:[{ml:[C]}],\"space-x\":[{\"space-x\":[O]}],\"space-x-reverse\":[\"space-x-reverse\"],\"space-y\":[{\"space-y\":[O]}],\"space-y-reverse\":[\"space-y-reverse\"],w:[{w:[\"auto\",\"min\",\"max\",\"fit\",\"svw\",\"lvw\",\"dvw\",xt,t]}],\"min-w\":[{\"min-w\":[xt,t,\"min\",\"max\",\"fit\"]}],\"max-w\":[{\"max-w\":[xt,t,\"none\",\"full\",\"min\",\"max\",\"fit\",\"prose\",{screen:[ua]},ua]}],h:[{h:[xt,t,\"auto\",\"min\",\"max\",\"fit\",\"svh\",\"lvh\",\"dvh\"]}],\"min-h\":[{\"min-h\":[xt,t,\"min\",\"max\",\"fit\",\"svh\",\"lvh\",\"dvh\"]}],\"max-h\":[{\"max-h\":[xt,t,\"min\",\"max\",\"fit\",\"svh\",\"lvh\",\"dvh\"]}],size:[{size:[xt,t,\"auto\",\"min\",\"max\",\"fit\"]}],\"font-size\":[{text:[\"base\",ua,ca]}],\"font-smoothing\":[\"antialiased\",\"subpixel-antialiased\"],\"font-style\":[\"italic\",\"not-italic\"],\"font-weight\":[{font:[\"thin\",\"extralight\",\"light\",\"normal\",\"medium\",\"semibold\",\"bold\",\"extrabold\",\"black\",zf]}],\"font-family\":[{font:[ou]}],\"fvn-normal\":[\"normal-nums\"],\"fvn-ordinal\":[\"ordinal\"],\"fvn-slashed-zero\":[\"slashed-zero\"],\"fvn-figure\":[\"lining-nums\",\"oldstyle-nums\"],\"fvn-spacing\":[\"proportional-nums\",\"tabular-nums\"],\"fvn-fraction\":[\"diagonal-fractions\",\"stacked-fractons\"],tracking:[{tracking:[\"tighter\",\"tight\",\"normal\",\"wide\",\"wider\",\"widest\",xt]}],\"line-clamp\":[{\"line-clamp\":[\"none\",ci,zf]}],leading:[{leading:[\"none\",\"tight\",\"snug\",\"normal\",\"relaxed\",\"loose\",ho,xt]}],\"list-image\":[{\"list-image\":[\"none\",xt]}],\"list-style-type\":[{list:[\"none\",\"disc\",\"decimal\",xt]}],\"list-style-position\":[{list:[\"inside\",\"outside\"]}],\"placeholder-color\":[{placeholder:[e]}],\"placeholder-opacity\":[{\"placeholder-opacity\":[k]}],\"text-alignment\":[{text:[\"left\",\"center\",\"right\",\"justify\",\"start\",\"end\"]}],\"text-color\":[{text:[e]}],\"text-opacity\":[{\"text-opacity\":[k]}],\"text-decoration\":[\"underline\",\"overline\",\"line-through\",\"no-underline\"],\"text-decoration-style\":[{decoration:[...re(),\"wavy\"]}],\"text-decoration-thickness\":[{decoration:[\"auto\",\"from-font\",ho,ca]}],\"underline-offset\":[{\"underline-offset\":[\"auto\",ho,xt]}],\"text-decoration-color\":[{decoration:[e]}],\"text-transform\":[\"uppercase\",\"lowercase\",\"capitalize\",\"normal-case\"],\"text-overflow\":[\"truncate\",\"text-ellipsis\",\"text-clip\"],\"text-wrap\":[{text:[\"wrap\",\"nowrap\",\"balance\",\"pretty\"]}],indent:[{indent:V()}],\"vertical-align\":[{align:[\"baseline\",\"top\",\"middle\",\"bottom\",\"text-top\",\"text-bottom\",\"sub\",\"super\",xt]}],whitespace:[{whitespace:[\"normal\",\"nowrap\",\"pre\",\"pre-line\",\"pre-wrap\",\"break-spaces\"]}],break:[{break:[\"normal\",\"words\",\"all\",\"keep\"]}],hyphens:[{hyphens:[\"none\",\"manual\",\"auto\"]}],content:[{content:[\"none\",xt]}],\"bg-attachment\":[{bg:[\"fixed\",\"local\",\"scroll\"]}],\"bg-clip\":[{\"bg-clip\":[\"border\",\"padding\",\"content\",\"text\"]}],\"bg-opacity\":[{\"bg-opacity\":[k]}],\"bg-origin\":[{\"bg-origin\":[\"border\",\"padding\",\"content\"]}],\"bg-position\":[{bg:[...ie(),P$]}],\"bg-repeat\":[{bg:[\"no-repeat\",{repeat:[\"\",\"x\",\"y\",\"round\",\"space\"]}]}],\"bg-size\":[{bg:[\"auto\",\"cover\",\"contain\",R$]}],\"bg-image\":[{bg:[\"none\",{\"gradient-to\":[\"t\",\"tr\",\"r\",\"br\",\"b\",\"bl\",\"l\",\"tl\"]},I$]}],\"bg-color\":[{bg:[e]}],\"gradient-from-pos\":[{from:[b]}],\"gradient-via-pos\":[{via:[b]}],\"gradient-to-pos\":[{to:[b]}],\"gradient-from\":[{from:[x]}],\"gradient-via\":[{via:[x]}],\"gradient-to\":[{to:[x]}],rounded:[{rounded:[o]}],\"rounded-s\":[{\"rounded-s\":[o]}],\"rounded-e\":[{\"rounded-e\":[o]}],\"rounded-t\":[{\"rounded-t\":[o]}],\"rounded-r\":[{\"rounded-r\":[o]}],\"rounded-b\":[{\"rounded-b\":[o]}],\"rounded-l\":[{\"rounded-l\":[o]}],\"rounded-ss\":[{\"rounded-ss\":[o]}],\"rounded-se\":[{\"rounded-se\":[o]}],\"rounded-ee\":[{\"rounded-ee\":[o]}],\"rounded-es\":[{\"rounded-es\":[o]}],\"rounded-tl\":[{\"rounded-tl\":[o]}],\"rounded-tr\":[{\"rounded-tr\":[o]}],\"rounded-br\":[{\"rounded-br\":[o]}],\"rounded-bl\":[{\"rounded-bl\":[o]}],\"border-w\":[{border:[u]}],\"border-w-x\":[{\"border-x\":[u]}],\"border-w-y\":[{\"border-y\":[u]}],\"border-w-s\":[{\"border-s\":[u]}],\"border-w-e\":[{\"border-e\":[u]}],\"border-w-t\":[{\"border-t\":[u]}],\"border-w-r\":[{\"border-r\":[u]}],\"border-w-b\":[{\"border-b\":[u]}],\"border-w-l\":[{\"border-l\":[u]}],\"border-opacity\":[{\"border-opacity\":[k]}],\"border-style\":[{border:[...re(),\"hidden\"]}],\"divide-x\":[{\"divide-x\":[u]}],\"divide-x-reverse\":[\"divide-x-reverse\"],\"divide-y\":[{\"divide-y\":[u]}],\"divide-y-reverse\":[\"divide-y-reverse\"],\"divide-opacity\":[{\"divide-opacity\":[k]}],\"divide-style\":[{divide:re()}],\"border-color\":[{border:[s]}],\"border-color-x\":[{\"border-x\":[s]}],\"border-color-y\":[{\"border-y\":[s]}],\"border-color-t\":[{\"border-t\":[s]}],\"border-color-r\":[{\"border-r\":[s]}],\"border-color-b\":[{\"border-b\":[s]}],\"border-color-l\":[{\"border-l\":[s]}],\"divide-color\":[{divide:[s]}],\"outline-style\":[{outline:[\"\",...re()]}],\"outline-offset\":[{\"outline-offset\":[ho,xt]}],\"outline-w\":[{outline:[ho,ca]}],\"outline-color\":[{outline:[e]}],\"ring-w\":[{ring:G()}],\"ring-w-inset\":[\"ring-inset\"],\"ring-color\":[{ring:[e]}],\"ring-opacity\":[{\"ring-opacity\":[k]}],\"ring-offset-w\":[{\"ring-offset\":[ho,ca]}],\"ring-offset-color\":[{\"ring-offset\":[e]}],shadow:[{shadow:[\"\",\"inner\",\"none\",ua,A$]}],\"shadow-color\":[{shadow:[ou]}],opacity:[{opacity:[k]}],\"mix-blend\":[{\"mix-blend\":[...Y(),\"plus-lighter\",\"plus-darker\"]}],\"bg-blend\":[{\"bg-blend\":Y()}],filter:[{filter:[\"\",\"none\"]}],blur:[{blur:[n]}],brightness:[{brightness:[r]}],contrast:[{contrast:[d]}],\"drop-shadow\":[{\"drop-shadow\":[\"\",\"none\",ua,xt]}],grayscale:[{grayscale:[f]}],\"hue-rotate\":[{\"hue-rotate\":[h]}],invert:[{invert:[m]}],saturate:[{saturate:[M]}],sepia:[{sepia:[R]}],\"backdrop-filter\":[{\"backdrop-filter\":[\"\",\"none\"]}],\"backdrop-blur\":[{\"backdrop-blur\":[n]}],\"backdrop-brightness\":[{\"backdrop-brightness\":[r]}],\"backdrop-contrast\":[{\"backdrop-contrast\":[d]}],\"backdrop-grayscale\":[{\"backdrop-grayscale\":[f]}],\"backdrop-hue-rotate\":[{\"backdrop-hue-rotate\":[h]}],\"backdrop-invert\":[{\"backdrop-invert\":[m]}],\"backdrop-opacity\":[{\"backdrop-opacity\":[k]}],\"backdrop-saturate\":[{\"backdrop-saturate\":[M]}],\"backdrop-sepia\":[{\"backdrop-sepia\":[R]}],\"border-collapse\":[{border:[\"collapse\",\"separate\"]}],\"border-spacing\":[{\"border-spacing\":[l]}],\"border-spacing-x\":[{\"border-spacing-x\":[l]}],\"border-spacing-y\":[{\"border-spacing-y\":[l]}],\"table-layout\":[{table:[\"auto\",\"fixed\"]}],caption:[{caption:[\"top\",\"bottom\"]}],transition:[{transition:[\"none\",\"all\",\"\",\"colors\",\"opacity\",\"shadow\",\"transform\",xt]}],duration:[{duration:F()}],ease:[{ease:[\"linear\",\"in\",\"out\",\"in-out\",xt]}],delay:[{delay:F()}],animate:[{animate:[\"none\",\"spin\",\"ping\",\"pulse\",\"bounce\",xt]}],transform:[{transform:[\"\",\"gpu\",\"none\"]}],scale:[{scale:[_]}],\"scale-x\":[{\"scale-x\":[_]}],\"scale-y\":[{\"scale-y\":[_]}],rotate:[{rotate:[su,xt]}],\"translate-x\":[{\"translate-x\":[D]}],\"translate-y\":[{\"translate-y\":[D]}],\"skew-x\":[{\"skew-x\":[N]}],\"skew-y\":[{\"skew-y\":[N]}],\"transform-origin\":[{origin:[\"center\",\"top\",\"top-right\",\"right\",\"bottom-right\",\"bottom\",\"bottom-left\",\"left\",\"top-left\",xt]}],accent:[{accent:[\"auto\",e]}],appearance:[{appearance:[\"none\",\"auto\"]}],cursor:[{cursor:[\"auto\",\"default\",\"pointer\",\"wait\",\"text\",\"move\",\"help\",\"not-allowed\",\"none\",\"context-menu\",\"progress\",\"cell\",\"crosshair\",\"vertical-text\",\"alias\",\"copy\",\"no-drop\",\"grab\",\"grabbing\",\"all-scroll\",\"col-resize\",\"row-resize\",\"n-resize\",\"e-resize\",\"s-resize\",\"w-resize\",\"ne-resize\",\"nw-resize\",\"se-resize\",\"sw-resize\",\"ew-resize\",\"ns-resize\",\"nesw-resize\",\"nwse-resize\",\"zoom-in\",\"zoom-out\",xt]}],\"caret-color\":[{caret:[e]}],\"pointer-events\":[{\"pointer-events\":[\"none\",\"auto\"]}],resize:[{resize:[\"none\",\"y\",\"x\",\"\"]}],\"scroll-behavior\":[{scroll:[\"auto\",\"smooth\"]}],\"scroll-m\":[{\"scroll-m\":V()}],\"scroll-mx\":[{\"scroll-mx\":V()}],\"scroll-my\":[{\"scroll-my\":V()}],\"scroll-ms\":[{\"scroll-ms\":V()}],\"scroll-me\":[{\"scroll-me\":V()}],\"scroll-mt\":[{\"scroll-mt\":V()}],\"scroll-mr\":[{\"scroll-mr\":V()}],\"scroll-mb\":[{\"scroll-mb\":V()}],\"scroll-ml\":[{\"scroll-ml\":V()}],\"scroll-p\":[{\"scroll-p\":V()}],\"scroll-px\":[{\"scroll-px\":V()}],\"scroll-py\":[{\"scroll-py\":V()}],\"scroll-ps\":[{\"scroll-ps\":V()}],\"scroll-pe\":[{\"scroll-pe\":V()}],\"scroll-pt\":[{\"scroll-pt\":V()}],\"scroll-pr\":[{\"scroll-pr\":V()}],\"scroll-pb\":[{\"scroll-pb\":V()}],\"scroll-pl\":[{\"scroll-pl\":V()}],\"snap-align\":[{snap:[\"start\",\"end\",\"center\",\"align-none\"]}],\"snap-stop\":[{snap:[\"normal\",\"always\"]}],\"snap-type\":[{snap:[\"none\",\"x\",\"y\",\"both\"]}],\"snap-strictness\":[{snap:[\"mandatory\",\"proximity\"]}],touch:[{touch:[\"auto\",\"none\",\"manipulation\"]}],\"touch-x\":[{\"touch-pan\":[\"x\",\"left\",\"right\"]}],\"touch-y\":[{\"touch-pan\":[\"y\",\"up\",\"down\"]}],\"touch-pz\":[\"touch-pinch-zoom\"],select:[{select:[\"none\",\"text\",\"all\",\"auto\"]}],\"will-change\":[{\"will-change\":[\"auto\",\"scroll\",\"contents\",\"transform\",xt]}],fill:[{fill:[e,\"none\"]}],\"stroke-w\":[{stroke:[ho,ca,zf]}],stroke:[{stroke:[e,\"none\"]}],sr:[\"sr-only\",\"not-sr-only\"],\"forced-color-adjust\":[{\"forced-color-adjust\":[\"auto\",\"none\"]}]},conflictingClassGroups:{overflow:[\"overflow-x\",\"overflow-y\"],overscroll:[\"overscroll-x\",\"overscroll-y\"],inset:[\"inset-x\",\"inset-y\",\"start\",\"end\",\"top\",\"right\",\"bottom\",\"left\"],\"inset-x\":[\"right\",\"left\"],\"inset-y\":[\"top\",\"bottom\"],flex:[\"basis\",\"grow\",\"shrink\"],gap:[\"gap-x\",\"gap-y\"],p:[\"px\",\"py\",\"ps\",\"pe\",\"pt\",\"pr\",\"pb\",\"pl\"],px:[\"pr\",\"pl\"],py:[\"pt\",\"pb\"],m:[\"mx\",\"my\",\"ms\",\"me\",\"mt\",\"mr\",\"mb\",\"ml\"],mx:[\"mr\",\"ml\"],my:[\"mt\",\"mb\"],size:[\"w\",\"h\"],\"font-size\":[\"leading\"],\"fvn-normal\":[\"fvn-ordinal\",\"fvn-slashed-zero\",\"fvn-figure\",\"fvn-spacing\",\"fvn-fraction\"],\"fvn-ordinal\":[\"fvn-normal\"],\"fvn-slashed-zero\":[\"fvn-normal\"],\"fvn-figure\":[\"fvn-normal\"],\"fvn-spacing\":[\"fvn-normal\"],\"fvn-fraction\":[\"fvn-normal\"],\"line-clamp\":[\"display\",\"overflow\"],rounded:[\"rounded-s\",\"rounded-e\",\"rounded-t\",\"rounded-r\",\"rounded-b\",\"rounded-l\",\"rounded-ss\",\"rounded-se\",\"rounded-ee\",\"rounded-es\",\"rounded-tl\",\"rounded-tr\",\"rounded-br\",\"rounded-bl\"],\"rounded-s\":[\"rounded-ss\",\"rounded-es\"],\"rounded-e\":[\"rounded-se\",\"rounded-ee\"],\"rounded-t\":[\"rounded-tl\",\"rounded-tr\"],\"rounded-r\":[\"rounded-tr\",\"rounded-br\"],\"rounded-b\":[\"rounded-br\",\"rounded-bl\"],\"rounded-l\":[\"rounded-tl\",\"rounded-bl\"],\"border-spacing\":[\"border-spacing-x\",\"border-spacing-y\"],\"border-w\":[\"border-w-s\",\"border-w-e\",\"border-w-t\",\"border-w-r\",\"border-w-b\",\"border-w-l\"],\"border-w-x\":[\"border-w-r\",\"border-w-l\"],\"border-w-y\":[\"border-w-t\",\"border-w-b\"],\"border-color\":[\"border-color-t\",\"border-color-r\",\"border-color-b\",\"border-color-l\"],\"border-color-x\":[\"border-color-r\",\"border-color-l\"],\"border-color-y\":[\"border-color-t\",\"border-color-b\"],\"scroll-m\":[\"scroll-mx\",\"scroll-my\",\"scroll-ms\",\"scroll-me\",\"scroll-mt\",\"scroll-mr\",\"scroll-mb\",\"scroll-ml\"],\"scroll-mx\":[\"scroll-mr\",\"scroll-ml\"],\"scroll-my\":[\"scroll-mt\",\"scroll-mb\"],\"scroll-p\":[\"scroll-px\",\"scroll-py\",\"scroll-ps\",\"scroll-pe\",\"scroll-pt\",\"scroll-pr\",\"scroll-pb\",\"scroll-pl\"],\"scroll-px\":[\"scroll-pr\",\"scroll-pl\"],\"scroll-py\":[\"scroll-pt\",\"scroll-pb\"],touch:[\"touch-x\",\"touch-y\",\"touch-pz\"],\"touch-x\":[\"touch\"],\"touch-y\":[\"touch\"],\"touch-pz\":[\"touch\"]},conflictingClassGroupModifiers:{\"font-size\":[\"leading\"]}}}const B$=w$($$);function Ie(...e){return B$(wo(e))}const z$=jh(\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\",{variants:{variant:{default:\"bg-primary text-primary-foreground hover:bg-primary/90\",destructive:\"bg-destructive text-destructive-foreground hover:bg-destructive/90\",outline:\"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",secondary:\"bg-secondary text-secondary-foreground hover:bg-secondary/80\",warning:\"bg-amber-600 shadow-sm hover:bg-amber-600/90 data-active:bg-amber-600/90 text-foreground\",ghost:\"hover:bg-accent hover:text-accent-foreground\",link:\"text-primary underline-offset-4 hover:underline\"},size:{default:\"h-10 px-4 py-2\",sm:\"h-9 rounded-md px-3\",lg:\"h-11 rounded-md px-8\",icon:\"h-10 w-10\"}},defaultVariants:{variant:\"default\",size:\"default\"}}),se=y.forwardRef(({className:e,variant:t,size:n,asChild:r=!1,...s},o)=>{const l=r?No:\"button\";return i.jsx(l,{className:Ie(z$({variant:t,size:n,className:e})),ref:o,...s})});se.displayName=\"Button\";function Vb(){const{t:e}=Ve(),t=dr(jn.API_URL),{data:n}=n$({url:t}),r=y.useMemo(()=>n?.clientName,[n]),s=y.useMemo(()=>n?.version,[n]),o=[{name:\"Discord\",url:\"https://evolution-api.com/discord\"},{name:\"Postman\",url:\"https://evolution-api.com/postman\"},{name:\"GitHub\",url:\"https://github.com/EvolutionAPI/evolution-api\"},{name:\"Docs\",url:\"https://doc.evolution-api.com\"}];return i.jsxs(\"footer\",{className:\"flex w-full flex-col items-center justify-between p-6 text-xs text-secondary-foreground sm:flex-row\",children:[i.jsxs(\"div\",{className:\"flex items-center space-x-3 divide-x\",children:[r&&r!==\"\"&&i.jsxs(\"span\",{children:[e(\"footer.clientName\"),\": \",i.jsx(\"strong\",{children:r})]}),s&&s!==\"\"&&i.jsxs(\"span\",{className:\"pl-3\",children:[e(\"footer.version\"),\": \",i.jsx(\"strong\",{children:s})]})]}),i.jsx(\"div\",{className:\"flex gap-2\",children:o.map(l=>i.jsx(se,{variant:\"link\",asChild:!0,size:\"sm\",className:\"text-xs\",children:i.jsx(\"a\",{href:l.url,target:\"_blank\",rel:\"noopener noreferrer\",children:l.name})},l.url))})]})}/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const U$=e=>e.replace(/([a-z0-9])([A-Z])/g,\"$1-$2\").toLowerCase(),dT=(...e)=>e.filter((t,n,r)=>!!t&&r.indexOf(t)===n).join(\" \");/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */var V$={xmlns:\"http://www.w3.org/2000/svg\",width:24,height:24,viewBox:\"0 0 24 24\",fill:\"none\",stroke:\"currentColor\",strokeWidth:2,strokeLinecap:\"round\",strokeLinejoin:\"round\"};/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const H$=y.forwardRef(({color:e=\"currentColor\",size:t=24,strokeWidth:n=2,absoluteStrokeWidth:r,className:s=\"\",children:o,iconNode:l,...u},d)=>y.createElement(\"svg\",{ref:d,...V$,width:t,height:t,stroke:e,strokeWidth:r?Number(n)*24/Number(t):n,className:dT(\"lucide\",s),...u},[...l.map(([f,h])=>y.createElement(f,h)),...Array.isArray(o)?o:[o]]));/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Qe=(e,t)=>{const n=y.forwardRef(({className:r,...s},o)=>y.createElement(H$,{ref:o,iconNode:t,className:dT(`lucide-${U$(e)}`,r),...s}));return n.displayName=`${e}`,n};/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const HC=Qe(\"Apple\",[[\"path\",{d:\"M12 20.94c1.5 0 2.75 1.06 4 1.06 3 0 6-8 6-12.22A4.91 4.91 0 0 0 17 5c-2.22 0-4 1.44-5 2-1-.56-2.78-2-5-2a4.9 4.9 0 0 0-5 4.78C2 14 5 22 8 22c1.25 0 2.5-1.06 4-1.06Z\",key:\"3s7exb\"}],[\"path\",{d:\"M10 2c1 .5 2 2 2 5\",key:\"fcco2y\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Th=Qe(\"ArrowRight\",[[\"path\",{d:\"M5 12h14\",key:\"1ays0h\"}],[\"path\",{d:\"m12 5 7 7-7 7\",key:\"xquz4c\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const q$=Qe(\"ArrowUpDown\",[[\"path\",{d:\"m21 16-4 4-4-4\",key:\"f6ql7i\"}],[\"path\",{d:\"M17 20V4\",key:\"1ejh1v\"}],[\"path\",{d:\"m3 8 4-4 4 4\",key:\"11wl7u\"}],[\"path\",{d:\"M7 4v16\",key:\"1glfcx\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const K$=Qe(\"Car\",[[\"path\",{d:\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\",key:\"5owen\"}],[\"circle\",{cx:\"7\",cy:\"17\",r:\"2\",key:\"u2ysq9\"}],[\"path\",{d:\"M9 17h6\",key:\"r8uit2\"}],[\"circle\",{cx:\"17\",cy:\"17\",r:\"2\",key:\"axvx0g\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const fT=Qe(\"Check\",[[\"path\",{d:\"M20 6 9 17l-5-5\",key:\"1gmf2c\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Nh=Qe(\"ChevronDown\",[[\"path\",{d:\"m6 9 6 6 6-6\",key:\"qrunsl\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const W$=Qe(\"ChevronRight\",[[\"path\",{d:\"m9 18 6-6-6-6\",key:\"mthhwq\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const G$=Qe(\"ChevronUp\",[[\"path\",{d:\"m18 15-6-6-6 6\",key:\"153udz\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const J$=Qe(\"ChevronsUpDown\",[[\"path\",{d:\"m7 15 5 5 5-5\",key:\"1hf1tw\"}],[\"path\",{d:\"m7 9 5-5 5 5\",key:\"sgt6xg\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Q$=Qe(\"CircleHelp\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}],[\"path\",{d:\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\",key:\"1u773s\"}],[\"path\",{d:\"M12 17h.01\",key:\"p32p05\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Oi=Qe(\"CircleStop\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}],[\"rect\",{width:\"6\",height:\"6\",x:\"9\",y:\"9\",key:\"1wrtvo\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const pT=Qe(\"CircleUser\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}],[\"circle\",{cx:\"12\",cy:\"10\",r:\"3\",key:\"ilqhr7\"}],[\"path\",{d:\"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662\",key:\"154egf\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Z$=Qe(\"Circle\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Y$=Qe(\"Club\",[[\"path\",{d:\"M17.28 9.05a5.5 5.5 0 1 0-10.56 0A5.5 5.5 0 1 0 12 17.66a5.5 5.5 0 1 0 5.28-8.6Z\",key:\"27yuqz\"}],[\"path\",{d:\"M12 17.66L12 22\",key:\"ogfahf\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Oo=Qe(\"Cog\",[[\"path\",{d:\"M12 20a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z\",key:\"sobvz5\"}],[\"path\",{d:\"M12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z\",key:\"11i496\"}],[\"path\",{d:\"M12 2v2\",key:\"tus03m\"}],[\"path\",{d:\"M12 22v-2\",key:\"1osdcq\"}],[\"path\",{d:\"m17 20.66-1-1.73\",key:\"eq3orb\"}],[\"path\",{d:\"M11 10.27 7 3.34\",key:\"16pf9h\"}],[\"path\",{d:\"m20.66 17-1.73-1\",key:\"sg0v6f\"}],[\"path\",{d:\"m3.34 7 1.73 1\",key:\"1ulond\"}],[\"path\",{d:\"M14 12h8\",key:\"4f43i9\"}],[\"path\",{d:\"M2 12h2\",key:\"1t8f8n\"}],[\"path\",{d:\"m20.66 7-1.73 1\",key:\"1ow05n\"}],[\"path\",{d:\"m3.34 17 1.73-1\",key:\"nuk764\"}],[\"path\",{d:\"m17 3.34-1 1.73\",key:\"2wel8s\"}],[\"path\",{d:\"m11 13.73-4 6.93\",key:\"794ttg\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const X$=Qe(\"Copy\",[[\"rect\",{width:\"14\",height:\"14\",x:\"8\",y:\"8\",rx:\"2\",ry:\"2\",key:\"17jyea\"}],[\"path\",{d:\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\",key:\"zix9uf\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Ii=Qe(\"Delete\",[[\"path\",{d:\"M10 5a2 2 0 0 0-1.344.519l-6.328 5.74a1 1 0 0 0 0 1.481l6.328 5.741A2 2 0 0 0 10 19h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z\",key:\"1yo7s0\"}],[\"path\",{d:\"m12 9 6 6\",key:\"anjzzh\"}],[\"path\",{d:\"m18 9-6 6\",key:\"1fp51s\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const eB=Qe(\"DoorOpen\",[[\"path\",{d:\"M13 4h3a2 2 0 0 1 2 2v14\",key:\"hrm0s9\"}],[\"path\",{d:\"M2 20h3\",key:\"1gaodv\"}],[\"path\",{d:\"M13 20h9\",key:\"s90cdi\"}],[\"path\",{d:\"M10 12v.01\",key:\"vx6srw\"}],[\"path\",{d:\"M13 4.562v16.157a1 1 0 0 1-1.242.97L5 20V5.562a2 2 0 0 1 1.515-1.94l4-1A2 2 0 0 1 13 4.561Z\",key:\"199qr4\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Pa=Qe(\"Ellipsis\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"1\",key:\"41hilf\"}],[\"circle\",{cx:\"19\",cy:\"12\",r:\"1\",key:\"1wjl8i\"}],[\"circle\",{cx:\"5\",cy:\"12\",r:\"1\",key:\"1pcz8c\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const tB=Qe(\"EyeOff\",[[\"path\",{d:\"M9.88 9.88a3 3 0 1 0 4.24 4.24\",key:\"1jxqfv\"}],[\"path\",{d:\"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68\",key:\"9wicm4\"}],[\"path\",{d:\"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61\",key:\"1jreej\"}],[\"line\",{x1:\"2\",x2:\"22\",y1:\"2\",y2:\"22\",key:\"a6p6uj\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const nB=Qe(\"Eye\",[[\"path\",{d:\"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z\",key:\"rwhkz3\"}],[\"circle\",{cx:\"12\",cy:\"12\",r:\"3\",key:\"1v7zrd\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const rB=Qe(\"FilePlus\",[[\"path\",{d:\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\",key:\"1rqfz7\"}],[\"path\",{d:\"M14 2v4a2 2 0 0 0 2 2h4\",key:\"tnqrlb\"}],[\"path\",{d:\"M9 15h6\",key:\"cctwl0\"}],[\"path\",{d:\"M12 18v-6\",key:\"17g6i2\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const sB=Qe(\"FileQuestion\",[[\"path\",{d:\"M12 17h.01\",key:\"p32p05\"}],[\"path\",{d:\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z\",key:\"1mlx9k\"}],[\"path\",{d:\"M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3\",key:\"mhlwft\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Hb=Qe(\"File\",[[\"path\",{d:\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\",key:\"1rqfz7\"}],[\"path\",{d:\"M14 2v4a2 2 0 0 0 2 2h4\",key:\"tnqrlb\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const oB=Qe(\"Flag\",[[\"path\",{d:\"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z\",key:\"i9b6wo\"}],[\"line\",{x1:\"4\",x2:\"4\",y1:\"22\",y2:\"15\",key:\"1cm3nv\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const aB=Qe(\"Github\",[[\"path\",{d:\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\",key:\"tonef\"}],[\"path\",{d:\"M9 18c-4.51 2-5-2-7-2\",key:\"9comsn\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const iB=Qe(\"Globe\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}],[\"path\",{d:\"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\",key:\"13o1zl\"}],[\"path\",{d:\"M2 12h20\",key:\"9i4pu4\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const lB=Qe(\"GripVertical\",[[\"circle\",{cx:\"9\",cy:\"12\",r:\"1\",key:\"1vctgf\"}],[\"circle\",{cx:\"9\",cy:\"5\",r:\"1\",key:\"hp0tcf\"}],[\"circle\",{cx:\"9\",cy:\"19\",r:\"1\",key:\"fkjjf6\"}],[\"circle\",{cx:\"15\",cy:\"12\",r:\"1\",key:\"1tmaij\"}],[\"circle\",{cx:\"15\",cy:\"5\",r:\"1\",key:\"19l28e\"}],[\"circle\",{cx:\"15\",cy:\"19\",r:\"1\",key:\"f4zoj3\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const cB=Qe(\"Image\",[[\"rect\",{width:\"18\",height:\"18\",x:\"3\",y:\"3\",rx:\"2\",ry:\"2\",key:\"1m3agn\"}],[\"circle\",{cx:\"9\",cy:\"9\",r:\"2\",key:\"af1f0g\"}],[\"path\",{d:\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\",key:\"1xmnt7\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const uB=Qe(\"Images\",[[\"path\",{d:\"M18 22H4a2 2 0 0 1-2-2V6\",key:\"pblm9e\"}],[\"path\",{d:\"m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18\",key:\"nf6bnh\"}],[\"circle\",{cx:\"12\",cy:\"8\",r:\"2\",key:\"1822b1\"}],[\"rect\",{width:\"16\",height:\"16\",x:\"6\",y:\"2\",rx:\"2\",key:\"12espp\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const dB=Qe(\"IterationCcw\",[[\"path\",{d:\"M20 10c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8h8\",key:\"4znkd0\"}],[\"polyline\",{points:\"16 14 20 18 16 22\",key:\"11njsm\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const fB=Qe(\"Languages\",[[\"path\",{d:\"m5 8 6 6\",key:\"1wu5hv\"}],[\"path\",{d:\"m4 14 6-6 2-3\",key:\"1k1g8d\"}],[\"path\",{d:\"M2 5h12\",key:\"or177f\"}],[\"path\",{d:\"M7 2h1\",key:\"1t2jsx\"}],[\"path\",{d:\"m22 22-5-10-5 10\",key:\"don7ne\"}],[\"path\",{d:\"M14 18h6\",key:\"1m8k6r\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const pB=Qe(\"LayoutDashboard\",[[\"rect\",{width:\"7\",height:\"9\",x:\"3\",y:\"3\",rx:\"1\",key:\"10lvy0\"}],[\"rect\",{width:\"7\",height:\"5\",x:\"14\",y:\"3\",rx:\"1\",key:\"16une8\"}],[\"rect\",{width:\"7\",height:\"9\",x:\"14\",y:\"12\",rx:\"1\",key:\"1hutg5\"}],[\"rect\",{width:\"7\",height:\"5\",x:\"3\",y:\"16\",rx:\"1\",key:\"ldoo1y\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const hB=Qe(\"LifeBuoy\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}],[\"path\",{d:\"m4.93 4.93 4.24 4.24\",key:\"1ymg45\"}],[\"path\",{d:\"m14.83 9.17 4.24-4.24\",key:\"1cb5xl\"}],[\"path\",{d:\"m14.83 14.83 4.24 4.24\",key:\"q42g0n\"}],[\"path\",{d:\"m9.17 14.83-4.24 4.24\",key:\"bqpfvv\"}],[\"circle\",{cx:\"12\",cy:\"12\",r:\"4\",key:\"4exip2\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const gB=Qe(\"Lightbulb\",[[\"path\",{d:\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\",key:\"1gvzjb\"}],[\"path\",{d:\"M9 18h6\",key:\"x1upvd\"}],[\"path\",{d:\"M10 22h4\",key:\"ceow96\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Ai=Qe(\"ListCollapse\",[[\"path\",{d:\"m3 10 2.5-2.5L3 5\",key:\"i6eama\"}],[\"path\",{d:\"m3 19 2.5-2.5L3 14\",key:\"w2gmor\"}],[\"path\",{d:\"M10 6h11\",key:\"c7qv1k\"}],[\"path\",{d:\"M10 12h11\",key:\"6m4ad9\"}],[\"path\",{d:\"M10 18h11\",key:\"11hvi2\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const mB=Qe(\"Lock\",[[\"rect\",{width:\"18\",height:\"11\",x:\"3\",y:\"11\",rx:\"2\",ry:\"2\",key:\"1w4ew1\"}],[\"path\",{d:\"M7 11V7a5 5 0 0 1 10 0v4\",key:\"fwvmzm\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const vB=Qe(\"Mail\",[[\"rect\",{width:\"20\",height:\"16\",x:\"2\",y:\"4\",rx:\"2\",key:\"18n3k1\"}],[\"path\",{d:\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\",key:\"1ocrg3\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const yB=Qe(\"MapPin\",[[\"path\",{d:\"M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z\",key:\"2oe9fu\"}],[\"circle\",{cx:\"12\",cy:\"10\",r:\"3\",key:\"ilqhr7\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Bl=Qe(\"MessageCircle\",[[\"path\",{d:\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\",key:\"vv11sd\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const hT=Qe(\"Mic\",[[\"path\",{d:\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\",key:\"131961\"}],[\"path\",{d:\"M19 10v2a7 7 0 0 1-14 0v-2\",key:\"1vc78b\"}],[\"line\",{x1:\"12\",x2:\"12\",y1:\"19\",y2:\"22\",key:\"x3vr5v\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const bB=Qe(\"Moon\",[[\"path\",{d:\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\",key:\"a7tn18\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Di=Qe(\"Pause\",[[\"rect\",{x:\"14\",y:\"4\",width:\"4\",height:\"16\",rx:\"1\",key:\"zuxfzm\"}],[\"rect\",{x:\"6\",y:\"4\",width:\"4\",height:\"16\",rx:\"1\",key:\"1okwgv\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Fi=Qe(\"Play\",[[\"polygon\",{points:\"6 3 20 12 6 21 6 3\",key:\"1oa8hb\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const cs=Qe(\"Plus\",[[\"path\",{d:\"M5 12h14\",key:\"1ays0h\"}],[\"path\",{d:\"M12 5v14\",key:\"s699le\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Ip=Qe(\"RefreshCw\",[[\"path\",{d:\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\",key:\"v9h5vc\"}],[\"path\",{d:\"M21 3v5h-5\",key:\"1q7to0\"}],[\"path\",{d:\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\",key:\"3uifl3\"}],[\"path\",{d:\"M8 16H3v5\",key:\"1cv678\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Li=Qe(\"RotateCcw\",[[\"path\",{d:\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\",key:\"1357e3\"}],[\"path\",{d:\"M3 3v5h5\",key:\"1xhq8a\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const xB=Qe(\"Shield\",[[\"path\",{d:\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",key:\"oel41y\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const gT=Qe(\"Smile\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"10\",key:\"1mglay\"}],[\"path\",{d:\"M8 14s1.5 2 4 2 4-2 4-2\",key:\"1y1vjs\"}],[\"line\",{x1:\"9\",x2:\"9.01\",y1:\"9\",y2:\"9\",key:\"yxxnd0\"}],[\"line\",{x1:\"15\",x2:\"15.01\",y1:\"9\",y2:\"9\",key:\"1p4y9e\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const wB=Qe(\"Sparkle\",[[\"path\",{d:\"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z\",key:\"4pj2yx\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const SB=Qe(\"Square\",[[\"rect\",{width:\"18\",height:\"18\",x:\"3\",y:\"3\",rx:\"2\",key:\"afitv7\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const CB=Qe(\"Sticker\",[[\"path\",{d:\"M15.5 3H5a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2V8.5L15.5 3Z\",key:\"1wis1t\"}],[\"path\",{d:\"M14 3v4a2 2 0 0 0 2 2h4\",key:\"36rjfy\"}],[\"path\",{d:\"M8 13h.01\",key:\"1sbv64\"}],[\"path\",{d:\"M16 13h.01\",key:\"wip0gl\"}],[\"path\",{d:\"M10 16s.8 1 2 1c1.3 0 2-1 2-1\",key:\"1vvgv3\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const EB=Qe(\"Sun\",[[\"circle\",{cx:\"12\",cy:\"12\",r:\"4\",key:\"4exip2\"}],[\"path\",{d:\"M12 2v2\",key:\"tus03m\"}],[\"path\",{d:\"M12 20v2\",key:\"1lh1kg\"}],[\"path\",{d:\"m4.93 4.93 1.41 1.41\",key:\"149t6j\"}],[\"path\",{d:\"m17.66 17.66 1.41 1.41\",key:\"ptbguv\"}],[\"path\",{d:\"M2 12h2\",key:\"1t8f8n\"}],[\"path\",{d:\"M20 12h2\",key:\"1q8mjw\"}],[\"path\",{d:\"m6.34 17.66-1.41 1.41\",key:\"1m8zz5\"}],[\"path\",{d:\"m19.07 4.93-1.41 1.41\",key:\"1shlcs\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const kB=Qe(\"Trash\",[[\"path\",{d:\"M3 6h18\",key:\"d0wm0j\"}],[\"path\",{d:\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\",key:\"4alrt4\"}],[\"path\",{d:\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\",key:\"v07s0e\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const Ap=Qe(\"User\",[[\"path\",{d:\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\",key:\"975kel\"}],[\"circle\",{cx:\"12\",cy:\"7\",r:\"4\",key:\"17ys0d\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const jB=Qe(\"UsersRound\",[[\"path\",{d:\"M18 21a8 8 0 0 0-16 0\",key:\"3ypg7q\"}],[\"circle\",{cx:\"10\",cy:\"8\",r:\"5\",key:\"o932ke\"}],[\"path\",{d:\"M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3\",key:\"10s06x\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const TB=Qe(\"Video\",[[\"path\",{d:\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\",key:\"ftymec\"}],[\"rect\",{x:\"2\",y:\"6\",width:\"14\",height:\"12\",rx:\"2\",key:\"158x01\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const qb=Qe(\"X\",[[\"path\",{d:\"M18 6 6 18\",key:\"1bl5f8\"}],[\"path\",{d:\"m6 6 12 12\",key:\"d8bk6v\"}]]);/**\n * @license lucide-react v0.408.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */const mT=Qe(\"Zap\",[[\"path\",{d:\"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\",key:\"1xq2db\"}]]),Ee=sn.create({timeout:3e4});Ee.interceptors.request.use(async e=>{const t=dr(jn.API_URL);if(t&&(e.baseURL=t.toString()),!e.headers.apiKey||e.headers.apiKey===\"\"){const n=dr(jn.INSTANCE_TOKEN);n&&(e.headers.apikey=`${n}`)}return e},e=>Promise.reject(e));const bd=sn.create({timeout:3e4});bd.interceptors.request.use(async e=>{const t=dr(jn.API_URL);if(t&&(e.baseURL=t.toString()),!e.headers.apiKey||e.headers.apiKey===\"\"){const n=dr(jn.TOKEN);n&&(e.headers.apikey=`${n}`)}return e},e=>Promise.reject(e));const NB=e=>[\"instance\",\"fetchInstance\",JSON.stringify(e)],MB=async({instanceId:e})=>{const t=await bd.get(\"/instance/fetchInstances\",{params:{instanceId:e}});return Array.isArray(t.data)?t.data[0]:t.data},vT=e=>{const{instanceId:t,...n}=e;return mt({...n,queryKey:NB({instanceId:t}),queryFn:()=>MB({instanceId:t}),enabled:!!t})};function Ue(e,t,{checkForDefaultPrevented:n=!0}={}){return function(s){if(e?.(s),n===!1||!s.defaultPrevented)return t?.(s)}}function _B(e,t){const n=y.createContext(t);function r(o){const{children:l,...u}=o,d=y.useMemo(()=>u,Object.values(u));return i.jsx(n.Provider,{value:d,children:l})}function s(o){const l=y.useContext(n);if(l)return l;if(t!==void 0)return t;throw new Error(`\\`${o}\\` must be used within \\`${e}\\``)}return r.displayName=e+\"Provider\",[r,s]}function us(e,t=[]){let n=[];function r(o,l){const u=y.createContext(l),d=n.length;n=[...n,l];function f(m){const{scope:g,children:x,...b}=m,w=g?.[e][d]||u,C=y.useMemo(()=>b,Object.values(b));return i.jsx(w.Provider,{value:C,children:x})}function h(m,g){const x=g?.[e][d]||u,b=y.useContext(x);if(b)return b;if(l!==void 0)return l;throw new Error(`\\`${m}\\` must be used within \\`${o}\\``)}return f.displayName=o+\"Provider\",[f,h]}const s=()=>{const o=n.map(l=>y.createContext(l));return function(u){const d=u?.[e]||o;return y.useMemo(()=>({[`__scope${e}`]:{...u,[e]:d}}),[u,d])}};return s.scopeName=e,[r,RB(s,...t)]}function RB(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const r=e.map(s=>({useScope:s(),scopeName:s.scopeName}));return function(o){const l=r.reduce((u,{useScope:d,scopeName:f})=>{const m=d(o)[`__scope${f}`];return{...u,...m}},{});return y.useMemo(()=>({[`__scope${t.scopeName}`]:l}),[l])}};return n.scopeName=t.scopeName,n}function Rn(e){const t=y.useRef(e);return y.useEffect(()=>{t.current=e}),y.useMemo(()=>(...n)=>t.current?.(...n),[])}function ya({prop:e,defaultProp:t,onChange:n=()=>{}}){const[r,s]=PB({defaultProp:t,onChange:n}),o=e!==void 0,l=o?e:r,u=Rn(n),d=y.useCallback(f=>{if(o){const m=typeof f==\"function\"?f(e):f;m!==e&&u(m)}else s(f)},[o,e,s,u]);return[l,d]}function PB({defaultProp:e,onChange:t}){const n=y.useState(e),[r]=n,s=y.useRef(r),o=Rn(t);return y.useEffect(()=>{s.current!==r&&(o(r),s.current=r)},[r,s,o]),n}var OB=[\"a\",\"button\",\"div\",\"form\",\"h2\",\"h3\",\"img\",\"input\",\"label\",\"li\",\"nav\",\"ol\",\"p\",\"span\",\"svg\",\"ul\"],rt=OB.reduce((e,t)=>{const n=y.forwardRef((r,s)=>{const{asChild:o,...l}=r,u=o?No:t;return typeof window<\"u\"&&(window[Symbol.for(\"radix-ui\")]=!0),i.jsx(u,{...l,ref:s})});return n.displayName=`Primitive.${t}`,{...e,[t]:n}},{});function yT(e,t){e&&Ma.flushSync(()=>e.dispatchEvent(t))}function Kb(e){const t=e+\"CollectionProvider\",[n,r]=us(t),[s,o]=n(t,{collectionRef:{current:null},itemMap:new Map}),l=x=>{const{scope:b,children:w}=x,C=qe.useRef(null),k=qe.useRef(new Map).current;return i.jsx(s,{scope:b,itemMap:k,collectionRef:C,children:w})};l.displayName=t;const u=e+\"CollectionSlot\",d=qe.forwardRef((x,b)=>{const{scope:w,children:C}=x,k=o(u,w),j=Rt(b,k.collectionRef);return i.jsx(No,{ref:j,children:C})});d.displayName=u;const f=e+\"CollectionItemSlot\",h=\"data-radix-collection-item\",m=qe.forwardRef((x,b)=>{const{scope:w,children:C,...k}=x,j=qe.useRef(null),M=Rt(b,j),_=o(f,w);return qe.useEffect(()=>(_.itemMap.set(j,{ref:j,...k}),()=>void _.itemMap.delete(j))),i.jsx(No,{[h]:\"\",ref:M,children:C})});m.displayName=f;function g(x){const b=o(e+\"CollectionConsumer\",x);return qe.useCallback(()=>{const C=b.collectionRef.current;if(!C)return[];const k=Array.from(C.querySelectorAll(`[${h}]`));return Array.from(b.itemMap.values()).sort((_,R)=>k.indexOf(_.ref.current)-k.indexOf(R.ref.current))},[b.collectionRef,b.itemMap])}return[{Provider:l,Slot:d,ItemSlot:m},g,r]}var IB=y.createContext(void 0);function xd(e){const t=y.useContext(IB);return e||t||\"ltr\"}function AB(e,t=globalThis?.document){const n=Rn(e);y.useEffect(()=>{const r=s=>{s.key===\"Escape\"&&n(s)};return t.addEventListener(\"keydown\",r,{capture:!0}),()=>t.removeEventListener(\"keydown\",r,{capture:!0})},[n,t])}var DB=\"DismissableLayer\",By=\"dismissableLayer.update\",FB=\"dismissableLayer.pointerDownOutside\",LB=\"dismissableLayer.focusOutside\",qC,bT=y.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),Mh=y.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:s,onFocusOutside:o,onInteractOutside:l,onDismiss:u,...d}=e,f=y.useContext(bT),[h,m]=y.useState(null),g=h?.ownerDocument??globalThis?.document,[,x]=y.useState({}),b=Rt(t,O=>m(O)),w=Array.from(f.layers),[C]=[...f.layersWithOutsidePointerEventsDisabled].slice(-1),k=w.indexOf(C),j=h?w.indexOf(h):-1,M=f.layersWithOutsidePointerEventsDisabled.size>0,_=j>=k,R=zB(O=>{const D=O.target,z=[...f.branches].some(Q=>Q.contains(D));!_||z||(s?.(O),l?.(O),O.defaultPrevented||u?.())},g),N=UB(O=>{const D=O.target;[...f.branches].some(Q=>Q.contains(D))||(o?.(O),l?.(O),O.defaultPrevented||u?.())},g);return AB(O=>{j===f.layers.size-1&&(r?.(O),!O.defaultPrevented&&u&&(O.preventDefault(),u()))},g),y.useEffect(()=>{if(h)return n&&(f.layersWithOutsidePointerEventsDisabled.size===0&&(qC=g.body.style.pointerEvents,g.body.style.pointerEvents=\"none\"),f.layersWithOutsidePointerEventsDisabled.add(h)),f.layers.add(h),KC(),()=>{n&&f.layersWithOutsidePointerEventsDisabled.size===1&&(g.body.style.pointerEvents=qC)}},[h,g,n,f]),y.useEffect(()=>()=>{h&&(f.layers.delete(h),f.layersWithOutsidePointerEventsDisabled.delete(h),KC())},[h,f]),y.useEffect(()=>{const O=()=>x({});return document.addEventListener(By,O),()=>document.removeEventListener(By,O)},[]),i.jsx(rt.div,{...d,ref:b,style:{pointerEvents:M?_?\"auto\":\"none\":void 0,...e.style},onFocusCapture:Ue(e.onFocusCapture,N.onFocusCapture),onBlurCapture:Ue(e.onBlurCapture,N.onBlurCapture),onPointerDownCapture:Ue(e.onPointerDownCapture,R.onPointerDownCapture)})});Mh.displayName=DB;var $B=\"DismissableLayerBranch\",BB=y.forwardRef((e,t)=>{const n=y.useContext(bT),r=y.useRef(null),s=Rt(t,r);return y.useEffect(()=>{const o=r.current;if(o)return n.branches.add(o),()=>{n.branches.delete(o)}},[n.branches]),i.jsx(rt.div,{...e,ref:s})});BB.displayName=$B;function zB(e,t=globalThis?.document){const n=Rn(e),r=y.useRef(!1),s=y.useRef(()=>{});return y.useEffect(()=>{const o=u=>{if(u.target&&!r.current){let d=function(){xT(FB,n,f,{discrete:!0})};const f={originalEvent:u};u.pointerType===\"touch\"?(t.removeEventListener(\"click\",s.current),s.current=d,t.addEventListener(\"click\",s.current,{once:!0})):d()}else t.removeEventListener(\"click\",s.current);r.current=!1},l=window.setTimeout(()=>{t.addEventListener(\"pointerdown\",o)},0);return()=>{window.clearTimeout(l),t.removeEventListener(\"pointerdown\",o),t.removeEventListener(\"click\",s.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function UB(e,t=globalThis?.document){const n=Rn(e),r=y.useRef(!1);return y.useEffect(()=>{const s=o=>{o.target&&!r.current&&xT(LB,n,{originalEvent:o},{discrete:!1})};return t.addEventListener(\"focusin\",s),()=>t.removeEventListener(\"focusin\",s)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function KC(){const e=new CustomEvent(By);document.dispatchEvent(e)}function xT(e,t,n,{discrete:r}){const s=n.originalEvent.target,o=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&s.addEventListener(e,t,{once:!0}),r?yT(s,o):s.dispatchEvent(o)}var xv=0;function Wb(){y.useEffect(()=>{const e=document.querySelectorAll(\"[data-radix-focus-guard]\");return document.body.insertAdjacentElement(\"afterbegin\",e[0]??WC()),document.body.insertAdjacentElement(\"beforeend\",e[1]??WC()),xv++,()=>{xv===1&&document.querySelectorAll(\"[data-radix-focus-guard]\").forEach(t=>t.remove()),xv--}},[])}function WC(){const e=document.createElement(\"span\");return e.setAttribute(\"data-radix-focus-guard\",\"\"),e.tabIndex=0,e.style.cssText=\"outline: none; opacity: 0; position: fixed; pointer-events: none\",e}var wv=\"focusScope.autoFocusOnMount\",Sv=\"focusScope.autoFocusOnUnmount\",GC={bubbles:!1,cancelable:!0},VB=\"FocusScope\",_h=y.forwardRef((e,t)=>{const{loop:n=!1,trapped:r=!1,onMountAutoFocus:s,onUnmountAutoFocus:o,...l}=e,[u,d]=y.useState(null),f=Rn(s),h=Rn(o),m=y.useRef(null),g=Rt(t,w=>d(w)),x=y.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;y.useEffect(()=>{if(r){let w=function(M){if(x.paused||!u)return;const _=M.target;u.contains(_)?m.current=_:fa(m.current,{select:!0})},C=function(M){if(x.paused||!u)return;const _=M.relatedTarget;_!==null&&(u.contains(_)||fa(m.current,{select:!0}))},k=function(M){if(document.activeElement===document.body)for(const R of M)R.removedNodes.length>0&&fa(u)};document.addEventListener(\"focusin\",w),document.addEventListener(\"focusout\",C);const j=new MutationObserver(k);return u&&j.observe(u,{childList:!0,subtree:!0}),()=>{document.removeEventListener(\"focusin\",w),document.removeEventListener(\"focusout\",C),j.disconnect()}}},[r,u,x.paused]),y.useEffect(()=>{if(u){QC.add(x);const w=document.activeElement;if(!u.contains(w)){const k=new CustomEvent(wv,GC);u.addEventListener(wv,f),u.dispatchEvent(k),k.defaultPrevented||(HB(JB(wT(u)),{select:!0}),document.activeElement===w&&fa(u))}return()=>{u.removeEventListener(wv,f),setTimeout(()=>{const k=new CustomEvent(Sv,GC);u.addEventListener(Sv,h),u.dispatchEvent(k),k.defaultPrevented||fa(w??document.body,{select:!0}),u.removeEventListener(Sv,h),QC.remove(x)},0)}}},[u,f,h,x]);const b=y.useCallback(w=>{if(!n&&!r||x.paused)return;const C=w.key===\"Tab\"&&!w.altKey&&!w.ctrlKey&&!w.metaKey,k=document.activeElement;if(C&&k){const j=w.currentTarget,[M,_]=qB(j);M&&_?!w.shiftKey&&k===_?(w.preventDefault(),n&&fa(M,{select:!0})):w.shiftKey&&k===M&&(w.preventDefault(),n&&fa(_,{select:!0})):k===j&&w.preventDefault()}},[n,r,x.paused]);return i.jsx(rt.div,{tabIndex:-1,...l,ref:g,onKeyDown:b})});_h.displayName=VB;function HB(e,{select:t=!1}={}){const n=document.activeElement;for(const r of e)if(fa(r,{select:t}),document.activeElement!==n)return}function qB(e){const t=wT(e),n=JC(t,e),r=JC(t.reverse(),e);return[n,r]}function wT(e){const t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const s=r.tagName===\"INPUT\"&&r.type===\"hidden\";return r.disabled||r.hidden||s?NodeFilter.FILTER_SKIP:r.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function JC(e,t){for(const n of e)if(!KB(n,{upTo:t}))return n}function KB(e,{upTo:t}){if(getComputedStyle(e).visibility===\"hidden\")return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display===\"none\")return!0;e=e.parentElement}return!1}function WB(e){return e instanceof HTMLInputElement&&\"select\"in e}function fa(e,{select:t=!1}={}){if(e&&e.focus){const n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&WB(e)&&t&&e.select()}}var QC=GB();function GB(){let e=[];return{add(t){const n=e[0];t!==n&&n?.pause(),e=ZC(e,t),e.unshift(t)},remove(t){e=ZC(e,t),e[0]?.resume()}}}function ZC(e,t){const n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function JB(e){return e.filter(t=>t.tagName!==\"A\")}var Ln=globalThis?.document?y.useLayoutEffect:()=>{},QB=Yl.useId||(()=>{}),ZB=0;function Es(e){const[t,n]=y.useState(QB());return Ln(()=>{n(r=>r??String(ZB++))},[e]),t?`radix-${t}`:\"\"}const YB=[\"top\",\"right\",\"bottom\",\"left\"],Hs=Math.min,zr=Math.max,Dp=Math.round,Uf=Math.floor,ba=e=>({x:e,y:e}),XB={left:\"right\",right:\"left\",bottom:\"top\",top:\"bottom\"},e3={start:\"end\",end:\"start\"};function zy(e,t,n){return zr(e,Hs(t,n))}function Mo(e,t){return typeof e==\"function\"?e(t):e}function _o(e){return e.split(\"-\")[0]}function oc(e){return e.split(\"-\")[1]}function Gb(e){return e===\"x\"?\"y\":\"x\"}function Jb(e){return e===\"y\"?\"height\":\"width\"}function xa(e){return[\"top\",\"bottom\"].includes(_o(e))?\"y\":\"x\"}function Qb(e){return Gb(xa(e))}function t3(e,t,n){n===void 0&&(n=!1);const r=oc(e),s=Qb(e),o=Jb(s);let l=s===\"x\"?r===(n?\"end\":\"start\")?\"right\":\"left\":r===\"start\"?\"bottom\":\"top\";return t.reference[o]>t.floating[o]&&(l=Fp(l)),[l,Fp(l)]}function n3(e){const t=Fp(e);return[Uy(e),t,Uy(t)]}function Uy(e){return e.replace(/start|end/g,t=>e3[t])}function r3(e,t,n){const r=[\"left\",\"right\"],s=[\"right\",\"left\"],o=[\"top\",\"bottom\"],l=[\"bottom\",\"top\"];switch(e){case\"top\":case\"bottom\":return n?t?s:r:t?r:s;case\"left\":case\"right\":return t?o:l;default:return[]}}function s3(e,t,n,r){const s=oc(e);let o=r3(_o(e),n===\"start\",r);return s&&(o=o.map(l=>l+\"-\"+s),t&&(o=o.concat(o.map(Uy)))),o}function Fp(e){return e.replace(/left|right|bottom|top/g,t=>XB[t])}function o3(e){return{top:0,right:0,bottom:0,left:0,...e}}function ST(e){return typeof e!=\"number\"?o3(e):{top:e,right:e,bottom:e,left:e}}function Lp(e){const{x:t,y:n,width:r,height:s}=e;return{width:r,height:s,top:n,left:t,right:t+r,bottom:n+s,x:t,y:n}}function YC(e,t,n){let{reference:r,floating:s}=e;const o=xa(t),l=Qb(t),u=Jb(l),d=_o(t),f=o===\"y\",h=r.x+r.width/2-s.width/2,m=r.y+r.height/2-s.height/2,g=r[u]/2-s[u]/2;let x;switch(d){case\"top\":x={x:h,y:r.y-s.height};break;case\"bottom\":x={x:h,y:r.y+r.height};break;case\"right\":x={x:r.x+r.width,y:m};break;case\"left\":x={x:r.x-s.width,y:m};break;default:x={x:r.x,y:r.y}}switch(oc(t)){case\"start\":x[l]-=g*(n&&f?-1:1);break;case\"end\":x[l]+=g*(n&&f?-1:1);break}return x}const a3=async(e,t,n)=>{const{placement:r=\"bottom\",strategy:s=\"absolute\",middleware:o=[],platform:l}=n,u=o.filter(Boolean),d=await(l.isRTL==null?void 0:l.isRTL(t));let f=await l.getElementRects({reference:e,floating:t,strategy:s}),{x:h,y:m}=YC(f,r,d),g=r,x={},b=0;for(let w=0;w<u.length;w++){const{name:C,fn:k}=u[w],{x:j,y:M,data:_,reset:R}=await k({x:h,y:m,initialPlacement:r,placement:g,strategy:s,middlewareData:x,rects:f,platform:l,elements:{reference:e,floating:t}});h=j??h,m=M??m,x={...x,[C]:{...x[C],..._}},R&&b<=50&&(b++,typeof R==\"object\"&&(R.placement&&(g=R.placement),R.rects&&(f=R.rects===!0?await l.getElementRects({reference:e,floating:t,strategy:s}):R.rects),{x:h,y:m}=YC(f,g,d)),w=-1)}return{x:h,y:m,placement:g,strategy:s,middlewareData:x}};async function Bu(e,t){var n;t===void 0&&(t={});const{x:r,y:s,platform:o,rects:l,elements:u,strategy:d}=e,{boundary:f=\"clippingAncestors\",rootBoundary:h=\"viewport\",elementContext:m=\"floating\",altBoundary:g=!1,padding:x=0}=Mo(t,e),b=ST(x),C=u[g?m===\"floating\"?\"reference\":\"floating\":m],k=Lp(await o.getClippingRect({element:(n=await(o.isElement==null?void 0:o.isElement(C)))==null||n?C:C.contextElement||await(o.getDocumentElement==null?void 0:o.getDocumentElement(u.floating)),boundary:f,rootBoundary:h,strategy:d})),j=m===\"floating\"?{x:r,y:s,width:l.floating.width,height:l.floating.height}:l.reference,M=await(o.getOffsetParent==null?void 0:o.getOffsetParent(u.floating)),_=await(o.isElement==null?void 0:o.isElement(M))?await(o.getScale==null?void 0:o.getScale(M))||{x:1,y:1}:{x:1,y:1},R=Lp(o.convertOffsetParentRelativeRectToViewportRelativeRect?await o.convertOffsetParentRelativeRectToViewportRelativeRect({elements:u,rect:j,offsetParent:M,strategy:d}):j);return{top:(k.top-R.top+b.top)/_.y,bottom:(R.bottom-k.bottom+b.bottom)/_.y,left:(k.left-R.left+b.left)/_.x,right:(R.right-k.right+b.right)/_.x}}const i3=e=>({name:\"arrow\",options:e,async fn(t){const{x:n,y:r,placement:s,rects:o,platform:l,elements:u,middlewareData:d}=t,{element:f,padding:h=0}=Mo(e,t)||{};if(f==null)return{};const m=ST(h),g={x:n,y:r},x=Qb(s),b=Jb(x),w=await l.getDimensions(f),C=x===\"y\",k=C?\"top\":\"left\",j=C?\"bottom\":\"right\",M=C?\"clientHeight\":\"clientWidth\",_=o.reference[b]+o.reference[x]-g[x]-o.floating[b],R=g[x]-o.reference[x],N=await(l.getOffsetParent==null?void 0:l.getOffsetParent(f));let O=N?N[M]:0;(!O||!await(l.isElement==null?void 0:l.isElement(N)))&&(O=u.floating[M]||o.floating[b]);const D=_/2-R/2,z=O/2-w[b]/2-1,Q=Hs(m[k],z),pe=Hs(m[j],z),V=Q,G=O-w[b]-pe,W=O/2-w[b]/2+D,ie=zy(V,W,G),re=!d.arrow&&oc(s)!=null&&W!==ie&&o.reference[b]/2-(W<V?Q:pe)-w[b]/2<0,Y=re?W<V?W-V:W-G:0;return{[x]:g[x]+Y,data:{[x]:ie,centerOffset:W-ie-Y,...re&&{alignmentOffset:Y}},reset:re}}}),l3=function(e){return e===void 0&&(e={}),{name:\"flip\",options:e,async fn(t){var n,r;const{placement:s,middlewareData:o,rects:l,initialPlacement:u,platform:d,elements:f}=t,{mainAxis:h=!0,crossAxis:m=!0,fallbackPlacements:g,fallbackStrategy:x=\"bestFit\",fallbackAxisSideDirection:b=\"none\",flipAlignment:w=!0,...C}=Mo(e,t);if((n=o.arrow)!=null&&n.alignmentOffset)return{};const k=_o(s),j=xa(u),M=_o(u)===u,_=await(d.isRTL==null?void 0:d.isRTL(f.floating)),R=g||(M||!w?[Fp(u)]:n3(u)),N=b!==\"none\";!g&&N&&R.push(...s3(u,w,b,_));const O=[u,...R],D=await Bu(t,C),z=[];let Q=((r=o.flip)==null?void 0:r.overflows)||[];if(h&&z.push(D[k]),m){const W=t3(s,l,_);z.push(D[W[0]],D[W[1]])}if(Q=[...Q,{placement:s,overflows:z}],!z.every(W=>W<=0)){var pe,V;const W=(((pe=o.flip)==null?void 0:pe.index)||0)+1,ie=O[W];if(ie)return{data:{index:W,overflows:Q},reset:{placement:ie}};let re=(V=Q.filter(Y=>Y.overflows[0]<=0).sort((Y,H)=>Y.overflows[1]-H.overflows[1])[0])==null?void 0:V.placement;if(!re)switch(x){case\"bestFit\":{var G;const Y=(G=Q.filter(H=>{if(N){const q=xa(H.placement);return q===j||q===\"y\"}return!0}).map(H=>[H.placement,H.overflows.filter(q=>q>0).reduce((q,he)=>q+he,0)]).sort((H,q)=>H[1]-q[1])[0])==null?void 0:G[0];Y&&(re=Y);break}case\"initialPlacement\":re=u;break}if(s!==re)return{reset:{placement:re}}}return{}}}};function XC(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function e1(e){return YB.some(t=>e[t]>=0)}const c3=function(e){return e===void 0&&(e={}),{name:\"hide\",options:e,async fn(t){const{rects:n}=t,{strategy:r=\"referenceHidden\",...s}=Mo(e,t);switch(r){case\"referenceHidden\":{const o=await Bu(t,{...s,elementContext:\"reference\"}),l=XC(o,n.reference);return{data:{referenceHiddenOffsets:l,referenceHidden:e1(l)}}}case\"escaped\":{const o=await Bu(t,{...s,altBoundary:!0}),l=XC(o,n.floating);return{data:{escapedOffsets:l,escaped:e1(l)}}}default:return{}}}}};async function u3(e,t){const{placement:n,platform:r,elements:s}=e,o=await(r.isRTL==null?void 0:r.isRTL(s.floating)),l=_o(n),u=oc(n),d=xa(n)===\"y\",f=[\"left\",\"top\"].includes(l)?-1:1,h=o&&d?-1:1,m=Mo(t,e);let{mainAxis:g,crossAxis:x,alignmentAxis:b}=typeof m==\"number\"?{mainAxis:m,crossAxis:0,alignmentAxis:null}:{mainAxis:0,crossAxis:0,alignmentAxis:null,...m};return u&&typeof b==\"number\"&&(x=u===\"end\"?b*-1:b),d?{x:x*h,y:g*f}:{x:g*f,y:x*h}}const d3=function(e){return e===void 0&&(e=0),{name:\"offset\",options:e,async fn(t){var n,r;const{x:s,y:o,placement:l,middlewareData:u}=t,d=await u3(t,e);return l===((n=u.offset)==null?void 0:n.placement)&&(r=u.arrow)!=null&&r.alignmentOffset?{}:{x:s+d.x,y:o+d.y,data:{...d,placement:l}}}}},f3=function(e){return e===void 0&&(e={}),{name:\"shift\",options:e,async fn(t){const{x:n,y:r,placement:s}=t,{mainAxis:o=!0,crossAxis:l=!1,limiter:u={fn:C=>{let{x:k,y:j}=C;return{x:k,y:j}}},...d}=Mo(e,t),f={x:n,y:r},h=await Bu(t,d),m=xa(_o(s)),g=Gb(m);let x=f[g],b=f[m];if(o){const C=g===\"y\"?\"top\":\"left\",k=g===\"y\"?\"bottom\":\"right\",j=x+h[C],M=x-h[k];x=zy(j,x,M)}if(l){const C=m===\"y\"?\"top\":\"left\",k=m===\"y\"?\"bottom\":\"right\",j=b+h[C],M=b-h[k];b=zy(j,b,M)}const w=u.fn({...t,[g]:x,[m]:b});return{...w,data:{x:w.x-n,y:w.y-r}}}}},p3=function(e){return e===void 0&&(e={}),{options:e,fn(t){const{x:n,y:r,placement:s,rects:o,middlewareData:l}=t,{offset:u=0,mainAxis:d=!0,crossAxis:f=!0}=Mo(e,t),h={x:n,y:r},m=xa(s),g=Gb(m);let x=h[g],b=h[m];const w=Mo(u,t),C=typeof w==\"number\"?{mainAxis:w,crossAxis:0}:{mainAxis:0,crossAxis:0,...w};if(d){const M=g===\"y\"?\"height\":\"width\",_=o.reference[g]-o.floating[M]+C.mainAxis,R=o.reference[g]+o.reference[M]-C.mainAxis;x<_?x=_:x>R&&(x=R)}if(f){var k,j;const M=g===\"y\"?\"width\":\"height\",_=[\"top\",\"left\"].includes(_o(s)),R=o.reference[m]-o.floating[M]+(_&&((k=l.offset)==null?void 0:k[m])||0)+(_?0:C.crossAxis),N=o.reference[m]+o.reference[M]+(_?0:((j=l.offset)==null?void 0:j[m])||0)-(_?C.crossAxis:0);b<R?b=R:b>N&&(b=N)}return{[g]:x,[m]:b}}}},h3=function(e){return e===void 0&&(e={}),{name:\"size\",options:e,async fn(t){const{placement:n,rects:r,platform:s,elements:o}=t,{apply:l=()=>{},...u}=Mo(e,t),d=await Bu(t,u),f=_o(n),h=oc(n),m=xa(n)===\"y\",{width:g,height:x}=r.floating;let b,w;f===\"top\"||f===\"bottom\"?(b=f,w=h===(await(s.isRTL==null?void 0:s.isRTL(o.floating))?\"start\":\"end\")?\"left\":\"right\"):(w=f,b=h===\"end\"?\"top\":\"bottom\");const C=x-d.top-d.bottom,k=g-d.left-d.right,j=Hs(x-d[b],C),M=Hs(g-d[w],k),_=!t.middlewareData.shift;let R=j,N=M;if(m?N=h||_?Hs(M,k):k:R=h||_?Hs(j,C):C,_&&!h){const D=zr(d.left,0),z=zr(d.right,0),Q=zr(d.top,0),pe=zr(d.bottom,0);m?N=g-2*(D!==0||z!==0?D+z:zr(d.left,d.right)):R=x-2*(Q!==0||pe!==0?Q+pe:zr(d.top,d.bottom))}await l({...t,availableWidth:N,availableHeight:R});const O=await s.getDimensions(o.floating);return g!==O.width||x!==O.height?{reset:{rects:!0}}:{}}}};function ac(e){return CT(e)?(e.nodeName||\"\").toLowerCase():\"#document\"}function Vr(e){var t;return(e==null||(t=e.ownerDocument)==null?void 0:t.defaultView)||window}function Io(e){var t;return(t=(CT(e)?e.ownerDocument:e.document)||window.document)==null?void 0:t.documentElement}function CT(e){return e instanceof Node||e instanceof Vr(e).Node}function Gs(e){return e instanceof Element||e instanceof Vr(e).Element}function Js(e){return e instanceof HTMLElement||e instanceof Vr(e).HTMLElement}function t1(e){return typeof ShadowRoot>\"u\"?!1:e instanceof ShadowRoot||e instanceof Vr(e).ShadowRoot}function wd(e){const{overflow:t,overflowX:n,overflowY:r,display:s}=Ns(e);return/auto|scroll|overlay|hidden|clip/.test(t+r+n)&&![\"inline\",\"contents\"].includes(s)}function g3(e){return[\"table\",\"td\",\"th\"].includes(ac(e))}function Rh(e){return[\":popover-open\",\":modal\"].some(t=>{try{return e.matches(t)}catch{return!1}})}function Zb(e){const t=Yb(),n=Ns(e);return n.transform!==\"none\"||n.perspective!==\"none\"||(n.containerType?n.containerType!==\"normal\":!1)||!t&&(n.backdropFilter?n.backdropFilter!==\"none\":!1)||!t&&(n.filter?n.filter!==\"none\":!1)||[\"transform\",\"perspective\",\"filter\"].some(r=>(n.willChange||\"\").includes(r))||[\"paint\",\"layout\",\"strict\",\"content\"].some(r=>(n.contain||\"\").includes(r))}function m3(e){let t=wa(e);for(;Js(t)&&!zl(t);){if(Rh(t))return null;if(Zb(t))return t;t=wa(t)}return null}function Yb(){return typeof CSS>\"u\"||!CSS.supports?!1:CSS.supports(\"-webkit-backdrop-filter\",\"none\")}function zl(e){return[\"html\",\"body\",\"#document\"].includes(ac(e))}function Ns(e){return Vr(e).getComputedStyle(e)}function Ph(e){return Gs(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function wa(e){if(ac(e)===\"html\")return e;const t=e.assignedSlot||e.parentNode||t1(e)&&e.host||Io(e);return t1(t)?t.host:t}function ET(e){const t=wa(e);return zl(t)?e.ownerDocument?e.ownerDocument.body:e.body:Js(t)&&wd(t)?t:ET(t)}function zu(e,t,n){var r;t===void 0&&(t=[]),n===void 0&&(n=!0);const s=ET(e),o=s===((r=e.ownerDocument)==null?void 0:r.body),l=Vr(s);return o?t.concat(l,l.visualViewport||[],wd(s)?s:[],l.frameElement&&n?zu(l.frameElement):[]):t.concat(s,zu(s,[],n))}function kT(e){const t=Ns(e);let n=parseFloat(t.width)||0,r=parseFloat(t.height)||0;const s=Js(e),o=s?e.offsetWidth:n,l=s?e.offsetHeight:r,u=Dp(n)!==o||Dp(r)!==l;return u&&(n=o,r=l),{width:n,height:r,$:u}}function Xb(e){return Gs(e)?e:e.contextElement}function Rl(e){const t=Xb(e);if(!Js(t))return ba(1);const n=t.getBoundingClientRect(),{width:r,height:s,$:o}=kT(t);let l=(o?Dp(n.width):n.width)/r,u=(o?Dp(n.height):n.height)/s;return(!l||!Number.isFinite(l))&&(l=1),(!u||!Number.isFinite(u))&&(u=1),{x:l,y:u}}const v3=ba(0);function jT(e){const t=Vr(e);return!Yb()||!t.visualViewport?v3:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function y3(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==Vr(e)?!1:t}function Ci(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);const s=e.getBoundingClientRect(),o=Xb(e);let l=ba(1);t&&(r?Gs(r)&&(l=Rl(r)):l=Rl(e));const u=y3(o,n,r)?jT(o):ba(0);let d=(s.left+u.x)/l.x,f=(s.top+u.y)/l.y,h=s.width/l.x,m=s.height/l.y;if(o){const g=Vr(o),x=r&&Gs(r)?Vr(r):r;let b=g,w=b.frameElement;for(;w&&r&&x!==b;){const C=Rl(w),k=w.getBoundingClientRect(),j=Ns(w),M=k.left+(w.clientLeft+parseFloat(j.paddingLeft))*C.x,_=k.top+(w.clientTop+parseFloat(j.paddingTop))*C.y;d*=C.x,f*=C.y,h*=C.x,m*=C.y,d+=M,f+=_,b=Vr(w),w=b.frameElement}}return Lp({width:h,height:m,x:d,y:f})}function b3(e){let{elements:t,rect:n,offsetParent:r,strategy:s}=e;const o=s===\"fixed\",l=Io(r),u=t?Rh(t.floating):!1;if(r===l||u&&o)return n;let d={scrollLeft:0,scrollTop:0},f=ba(1);const h=ba(0),m=Js(r);if((m||!m&&!o)&&((ac(r)!==\"body\"||wd(l))&&(d=Ph(r)),Js(r))){const g=Ci(r);f=Rl(r),h.x=g.x+r.clientLeft,h.y=g.y+r.clientTop}return{width:n.width*f.x,height:n.height*f.y,x:n.x*f.x-d.scrollLeft*f.x+h.x,y:n.y*f.y-d.scrollTop*f.y+h.y}}function x3(e){return Array.from(e.getClientRects())}function TT(e){return Ci(Io(e)).left+Ph(e).scrollLeft}function w3(e){const t=Io(e),n=Ph(e),r=e.ownerDocument.body,s=zr(t.scrollWidth,t.clientWidth,r.scrollWidth,r.clientWidth),o=zr(t.scrollHeight,t.clientHeight,r.scrollHeight,r.clientHeight);let l=-n.scrollLeft+TT(e);const u=-n.scrollTop;return Ns(r).direction===\"rtl\"&&(l+=zr(t.clientWidth,r.clientWidth)-s),{width:s,height:o,x:l,y:u}}function S3(e,t){const n=Vr(e),r=Io(e),s=n.visualViewport;let o=r.clientWidth,l=r.clientHeight,u=0,d=0;if(s){o=s.width,l=s.height;const f=Yb();(!f||f&&t===\"fixed\")&&(u=s.offsetLeft,d=s.offsetTop)}return{width:o,height:l,x:u,y:d}}function C3(e,t){const n=Ci(e,!0,t===\"fixed\"),r=n.top+e.clientTop,s=n.left+e.clientLeft,o=Js(e)?Rl(e):ba(1),l=e.clientWidth*o.x,u=e.clientHeight*o.y,d=s*o.x,f=r*o.y;return{width:l,height:u,x:d,y:f}}function n1(e,t,n){let r;if(t===\"viewport\")r=S3(e,n);else if(t===\"document\")r=w3(Io(e));else if(Gs(t))r=C3(t,n);else{const s=jT(e);r={...t,x:t.x-s.x,y:t.y-s.y}}return Lp(r)}function NT(e,t){const n=wa(e);return n===t||!Gs(n)||zl(n)?!1:Ns(n).position===\"fixed\"||NT(n,t)}function E3(e,t){const n=t.get(e);if(n)return n;let r=zu(e,[],!1).filter(u=>Gs(u)&&ac(u)!==\"body\"),s=null;const o=Ns(e).position===\"fixed\";let l=o?wa(e):e;for(;Gs(l)&&!zl(l);){const u=Ns(l),d=Zb(l);!d&&u.position===\"fixed\"&&(s=null),(o?!d&&!s:!d&&u.position===\"static\"&&!!s&&[\"absolute\",\"fixed\"].includes(s.position)||wd(l)&&!d&&NT(e,l))?r=r.filter(h=>h!==l):s=u,l=wa(l)}return t.set(e,r),r}function k3(e){let{element:t,boundary:n,rootBoundary:r,strategy:s}=e;const l=[...n===\"clippingAncestors\"?Rh(t)?[]:E3(t,this._c):[].concat(n),r],u=l[0],d=l.reduce((f,h)=>{const m=n1(t,h,s);return f.top=zr(m.top,f.top),f.right=Hs(m.right,f.right),f.bottom=Hs(m.bottom,f.bottom),f.left=zr(m.left,f.left),f},n1(t,u,s));return{width:d.right-d.left,height:d.bottom-d.top,x:d.left,y:d.top}}function j3(e){const{width:t,height:n}=kT(e);return{width:t,height:n}}function T3(e,t,n){const r=Js(t),s=Io(t),o=n===\"fixed\",l=Ci(e,!0,o,t);let u={scrollLeft:0,scrollTop:0};const d=ba(0);if(r||!r&&!o)if((ac(t)!==\"body\"||wd(s))&&(u=Ph(t)),r){const m=Ci(t,!0,o,t);d.x=m.x+t.clientLeft,d.y=m.y+t.clientTop}else s&&(d.x=TT(s));const f=l.left+u.scrollLeft-d.x,h=l.top+u.scrollTop-d.y;return{x:f,y:h,width:l.width,height:l.height}}function Cv(e){return Ns(e).position===\"static\"}function r1(e,t){return!Js(e)||Ns(e).position===\"fixed\"?null:t?t(e):e.offsetParent}function MT(e,t){const n=Vr(e);if(Rh(e))return n;if(!Js(e)){let s=wa(e);for(;s&&!zl(s);){if(Gs(s)&&!Cv(s))return s;s=wa(s)}return n}let r=r1(e,t);for(;r&&g3(r)&&Cv(r);)r=r1(r,t);return r&&zl(r)&&Cv(r)&&!Zb(r)?n:r||m3(e)||n}const N3=async function(e){const t=this.getOffsetParent||MT,n=this.getDimensions,r=await n(e.floating);return{reference:T3(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:r.width,height:r.height}}};function M3(e){return Ns(e).direction===\"rtl\"}const _3={convertOffsetParentRelativeRectToViewportRelativeRect:b3,getDocumentElement:Io,getClippingRect:k3,getOffsetParent:MT,getElementRects:N3,getClientRects:x3,getDimensions:j3,getScale:Rl,isElement:Gs,isRTL:M3};function R3(e,t){let n=null,r;const s=Io(e);function o(){var u;clearTimeout(r),(u=n)==null||u.disconnect(),n=null}function l(u,d){u===void 0&&(u=!1),d===void 0&&(d=1),o();const{left:f,top:h,width:m,height:g}=e.getBoundingClientRect();if(u||t(),!m||!g)return;const x=Uf(h),b=Uf(s.clientWidth-(f+m)),w=Uf(s.clientHeight-(h+g)),C=Uf(f),j={rootMargin:-x+\"px \"+-b+\"px \"+-w+\"px \"+-C+\"px\",threshold:zr(0,Hs(1,d))||1};let M=!0;function _(R){const N=R[0].intersectionRatio;if(N!==d){if(!M)return l();N?l(!1,N):r=setTimeout(()=>{l(!1,1e-7)},1e3)}M=!1}try{n=new IntersectionObserver(_,{...j,root:s.ownerDocument})}catch{n=new IntersectionObserver(_,j)}n.observe(e)}return l(!0),o}function _T(e,t,n,r){r===void 0&&(r={});const{ancestorScroll:s=!0,ancestorResize:o=!0,elementResize:l=typeof ResizeObserver==\"function\",layoutShift:u=typeof IntersectionObserver==\"function\",animationFrame:d=!1}=r,f=Xb(e),h=s||o?[...f?zu(f):[],...zu(t)]:[];h.forEach(k=>{s&&k.addEventListener(\"scroll\",n,{passive:!0}),o&&k.addEventListener(\"resize\",n)});const m=f&&u?R3(f,n):null;let g=-1,x=null;l&&(x=new ResizeObserver(k=>{let[j]=k;j&&j.target===f&&x&&(x.unobserve(t),cancelAnimationFrame(g),g=requestAnimationFrame(()=>{var M;(M=x)==null||M.observe(t)})),n()}),f&&!d&&x.observe(f),x.observe(t));let b,w=d?Ci(e):null;d&&C();function C(){const k=Ci(e);w&&(k.x!==w.x||k.y!==w.y||k.width!==w.width||k.height!==w.height)&&n(),w=k,b=requestAnimationFrame(C)}return n(),()=>{var k;h.forEach(j=>{s&&j.removeEventListener(\"scroll\",n),o&&j.removeEventListener(\"resize\",n)}),m?.(),(k=x)==null||k.disconnect(),x=null,d&&cancelAnimationFrame(b)}}const P3=d3,O3=f3,I3=l3,A3=h3,D3=c3,s1=i3,F3=p3,L3=(e,t,n)=>{const r=new Map,s={platform:_3,...n},o={...s.platform,_c:r};return a3(e,t,{...s,platform:o})};var hp=typeof document<\"u\"?y.useLayoutEffect:y.useEffect;function $p(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e==\"function\"&&e.toString()===t.toString())return!0;let n,r,s;if(e&&t&&typeof e==\"object\"){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(r=n;r--!==0;)if(!$p(e[r],t[r]))return!1;return!0}if(s=Object.keys(e),n=s.length,n!==Object.keys(t).length)return!1;for(r=n;r--!==0;)if(!{}.hasOwnProperty.call(t,s[r]))return!1;for(r=n;r--!==0;){const o=s[r];if(!(o===\"_owner\"&&e.$$typeof)&&!$p(e[o],t[o]))return!1}return!0}return e!==e&&t!==t}function RT(e){return typeof window>\"u\"?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function o1(e,t){const n=RT(e);return Math.round(t*n)/n}function a1(e){const t=y.useRef(e);return hp(()=>{t.current=e}),t}function PT(e){e===void 0&&(e={});const{placement:t=\"bottom\",strategy:n=\"absolute\",middleware:r=[],platform:s,elements:{reference:o,floating:l}={},transform:u=!0,whileElementsMounted:d,open:f}=e,[h,m]=y.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[g,x]=y.useState(r);$p(g,r)||x(r);const[b,w]=y.useState(null),[C,k]=y.useState(null),j=y.useCallback(Y=>{Y!==N.current&&(N.current=Y,w(Y))},[]),M=y.useCallback(Y=>{Y!==O.current&&(O.current=Y,k(Y))},[]),_=o||b,R=l||C,N=y.useRef(null),O=y.useRef(null),D=y.useRef(h),z=d!=null,Q=a1(d),pe=a1(s),V=y.useCallback(()=>{if(!N.current||!O.current)return;const Y={placement:t,strategy:n,middleware:g};pe.current&&(Y.platform=pe.current),L3(N.current,O.current,Y).then(H=>{const q={...H,isPositioned:!0};G.current&&!$p(D.current,q)&&(D.current=q,Ma.flushSync(()=>{m(q)}))})},[g,t,n,pe]);hp(()=>{f===!1&&D.current.isPositioned&&(D.current.isPositioned=!1,m(Y=>({...Y,isPositioned:!1})))},[f]);const G=y.useRef(!1);hp(()=>(G.current=!0,()=>{G.current=!1}),[]),hp(()=>{if(_&&(N.current=_),R&&(O.current=R),_&&R){if(Q.current)return Q.current(_,R,V);V()}},[_,R,V,Q,z]);const W=y.useMemo(()=>({reference:N,floating:O,setReference:j,setFloating:M}),[j,M]),ie=y.useMemo(()=>({reference:_,floating:R}),[_,R]),re=y.useMemo(()=>{const Y={position:n,left:0,top:0};if(!ie.floating)return Y;const H=o1(ie.floating,h.x),q=o1(ie.floating,h.y);return u?{...Y,transform:\"translate(\"+H+\"px, \"+q+\"px)\",...RT(ie.floating)>=1.5&&{willChange:\"transform\"}}:{position:n,left:H,top:q}},[n,u,ie.floating,h.x,h.y]);return y.useMemo(()=>({...h,update:V,refs:W,elements:ie,floatingStyles:re}),[h,V,W,ie,re])}const $3=e=>{function t(n){return{}.hasOwnProperty.call(n,\"current\")}return{name:\"arrow\",options:e,fn(n){const{element:r,padding:s}=typeof e==\"function\"?e(n):e;return r&&t(r)?r.current!=null?s1({element:r.current,padding:s}).fn(n):{}:r?s1({element:r,padding:s}).fn(n):{}}}},OT=(e,t)=>({...P3(e),options:[e,t]}),IT=(e,t)=>({...O3(e),options:[e,t]}),AT=(e,t)=>({...F3(e),options:[e,t]}),DT=(e,t)=>({...I3(e),options:[e,t]}),FT=(e,t)=>({...A3(e),options:[e,t]}),LT=(e,t)=>({...D3(e),options:[e,t]}),$T=(e,t)=>({...$3(e),options:[e,t]});var B3=\"Arrow\",BT=y.forwardRef((e,t)=>{const{children:n,width:r=10,height:s=5,...o}=e;return i.jsx(rt.svg,{...o,ref:t,width:r,height:s,viewBox:\"0 0 30 10\",preserveAspectRatio:\"none\",children:e.asChild?n:i.jsx(\"polygon\",{points:\"0,0 30,0 15,10\"})})});BT.displayName=B3;var z3=BT;function zT(e){const[t,n]=y.useState(void 0);return Ln(()=>{if(e){n({width:e.offsetWidth,height:e.offsetHeight});const r=new ResizeObserver(s=>{if(!Array.isArray(s)||!s.length)return;const o=s[0];let l,u;if(\"borderBoxSize\"in o){const d=o.borderBoxSize,f=Array.isArray(d)?d[0]:d;l=f.inlineSize,u=f.blockSize}else l=e.offsetWidth,u=e.offsetHeight;n({width:l,height:u})});return r.observe(e,{box:\"border-box\"}),()=>r.unobserve(e)}else n(void 0)},[e]),t}var ex=\"Popper\",[UT,Oh]=us(ex),[U3,VT]=UT(ex),HT=e=>{const{__scopePopper:t,children:n}=e,[r,s]=y.useState(null);return i.jsx(U3,{scope:t,anchor:r,onAnchorChange:s,children:n})};HT.displayName=ex;var qT=\"PopperAnchor\",KT=y.forwardRef((e,t)=>{const{__scopePopper:n,virtualRef:r,...s}=e,o=VT(qT,n),l=y.useRef(null),u=Rt(t,l);return y.useEffect(()=>{o.onAnchorChange(r?.current||l.current)}),r?null:i.jsx(rt.div,{...s,ref:u})});KT.displayName=qT;var tx=\"PopperContent\",[V3,H3]=UT(tx),WT=y.forwardRef((e,t)=>{const{__scopePopper:n,side:r=\"bottom\",sideOffset:s=0,align:o=\"center\",alignOffset:l=0,arrowPadding:u=0,avoidCollisions:d=!0,collisionBoundary:f=[],collisionPadding:h=0,sticky:m=\"partial\",hideWhenDetached:g=!1,updatePositionStrategy:x=\"optimized\",onPlaced:b,...w}=e,C=VT(tx,n),[k,j]=y.useState(null),M=Rt(t,Z=>j(Z)),[_,R]=y.useState(null),N=zT(_),O=N?.width??0,D=N?.height??0,z=r+(o!==\"center\"?\"-\"+o:\"\"),Q=typeof h==\"number\"?h:{top:0,right:0,bottom:0,left:0,...h},pe=Array.isArray(f)?f:[f],V=pe.length>0,G={padding:Q,boundary:pe.filter(K3),altBoundary:V},{refs:W,floatingStyles:ie,placement:re,isPositioned:Y,middlewareData:H}=PT({strategy:\"fixed\",placement:z,whileElementsMounted:(...Z)=>_T(...Z,{animationFrame:x===\"always\"}),elements:{reference:C.anchor},middleware:[OT({mainAxis:s+D,alignmentAxis:l}),d&&IT({mainAxis:!0,crossAxis:!1,limiter:m===\"partial\"?AT():void 0,...G}),d&&DT({...G}),FT({...G,apply:({elements:Z,rects:ye,availableWidth:Re,availableHeight:$e})=>{const{width:Ye,height:Fe}=ye.reference,ft=Z.floating.style;ft.setProperty(\"--radix-popper-available-width\",`${Re}px`),ft.setProperty(\"--radix-popper-available-height\",`${$e}px`),ft.setProperty(\"--radix-popper-anchor-width\",`${Ye}px`),ft.setProperty(\"--radix-popper-anchor-height\",`${Fe}px`)}}),_&&$T({element:_,padding:u}),W3({arrowWidth:O,arrowHeight:D}),g&&LT({strategy:\"referenceHidden\",...G})]}),[q,he]=QT(re),A=Rn(b);Ln(()=>{Y&&A?.()},[Y,A]);const F=H.arrow?.x,fe=H.arrow?.y,te=H.arrow?.centerOffset!==0,[de,ge]=y.useState();return Ln(()=>{k&&ge(window.getComputedStyle(k).zIndex)},[k]),i.jsx(\"div\",{ref:W.setFloating,\"data-radix-popper-content-wrapper\":\"\",style:{...ie,transform:Y?ie.transform:\"translate(0, -200%)\",minWidth:\"max-content\",zIndex:de,\"--radix-popper-transform-origin\":[H.transformOrigin?.x,H.transformOrigin?.y].join(\" \"),...H.hide?.referenceHidden&&{visibility:\"hidden\",pointerEvents:\"none\"}},dir:e.dir,children:i.jsx(V3,{scope:n,placedSide:q,onArrowChange:R,arrowX:F,arrowY:fe,shouldHideArrow:te,children:i.jsx(rt.div,{\"data-side\":q,\"data-align\":he,...w,ref:M,style:{...w.style,animation:Y?void 0:\"none\"}})})})});WT.displayName=tx;var GT=\"PopperArrow\",q3={top:\"bottom\",right:\"left\",bottom:\"top\",left:\"right\"},JT=y.forwardRef(function(t,n){const{__scopePopper:r,...s}=t,o=H3(GT,r),l=q3[o.placedSide];return i.jsx(\"span\",{ref:o.onArrowChange,style:{position:\"absolute\",left:o.arrowX,top:o.arrowY,[l]:0,transformOrigin:{top:\"\",right:\"0 0\",bottom:\"center 0\",left:\"100% 0\"}[o.placedSide],transform:{top:\"translateY(100%)\",right:\"translateY(50%) rotate(90deg) translateX(-50%)\",bottom:\"rotate(180deg)\",left:\"translateY(50%) rotate(-90deg) translateX(50%)\"}[o.placedSide],visibility:o.shouldHideArrow?\"hidden\":void 0},children:i.jsx(z3,{...s,ref:n,style:{...s.style,display:\"block\"}})})});JT.displayName=GT;function K3(e){return e!==null}var W3=e=>({name:\"transformOrigin\",options:e,fn(t){const{placement:n,rects:r,middlewareData:s}=t,l=s.arrow?.centerOffset!==0,u=l?0:e.arrowWidth,d=l?0:e.arrowHeight,[f,h]=QT(n),m={start:\"0%\",center:\"50%\",end:\"100%\"}[h],g=(s.arrow?.x??0)+u/2,x=(s.arrow?.y??0)+d/2;let b=\"\",w=\"\";return f===\"bottom\"?(b=l?m:`${g}px`,w=`${-d}px`):f===\"top\"?(b=l?m:`${g}px`,w=`${r.floating.height+d}px`):f===\"right\"?(b=`${-d}px`,w=l?m:`${x}px`):f===\"left\"&&(b=`${r.floating.width+d}px`,w=l?m:`${x}px`),{data:{x:b,y:w}}}});function QT(e){const[t,n=\"center\"]=e.split(\"-\");return[t,n]}var ZT=HT,YT=KT,XT=WT,eN=JT,G3=\"Portal\",Ih=y.forwardRef((e,t)=>{const{container:n,...r}=e,[s,o]=y.useState(!1);Ln(()=>o(!0),[]);const l=n||s&&globalThis?.document?.body;return l?Ib.createPortal(i.jsx(rt.div,{...r,ref:t}),l):null});Ih.displayName=G3;function J3(e,t){return y.useReducer((n,r)=>t[n][r]??n,e)}var Mr=e=>{const{present:t,children:n}=e,r=Q3(t),s=typeof n==\"function\"?n({present:r.isPresent}):y.Children.only(n),o=Rt(r.ref,Z3(s));return typeof n==\"function\"||r.isPresent?y.cloneElement(s,{ref:o}):null};Mr.displayName=\"Presence\";function Q3(e){const[t,n]=y.useState(),r=y.useRef({}),s=y.useRef(e),o=y.useRef(\"none\"),l=e?\"mounted\":\"unmounted\",[u,d]=J3(l,{mounted:{UNMOUNT:\"unmounted\",ANIMATION_OUT:\"unmountSuspended\"},unmountSuspended:{MOUNT:\"mounted\",ANIMATION_END:\"unmounted\"},unmounted:{MOUNT:\"mounted\"}});return y.useEffect(()=>{const f=Vf(r.current);o.current=u===\"mounted\"?f:\"none\"},[u]),Ln(()=>{const f=r.current,h=s.current;if(h!==e){const g=o.current,x=Vf(f);e?d(\"MOUNT\"):x===\"none\"||f?.display===\"none\"?d(\"UNMOUNT\"):d(h&&g!==x?\"ANIMATION_OUT\":\"UNMOUNT\"),s.current=e}},[e,d]),Ln(()=>{if(t){const f=m=>{const x=Vf(r.current).includes(m.animationName);m.target===t&&x&&Ma.flushSync(()=>d(\"ANIMATION_END\"))},h=m=>{m.target===t&&(o.current=Vf(r.current))};return t.addEventListener(\"animationstart\",h),t.addEventListener(\"animationcancel\",f),t.addEventListener(\"animationend\",f),()=>{t.removeEventListener(\"animationstart\",h),t.removeEventListener(\"animationcancel\",f),t.removeEventListener(\"animationend\",f)}}else d(\"ANIMATION_END\")},[t,d]),{isPresent:[\"mounted\",\"unmountSuspended\"].includes(u),ref:y.useCallback(f=>{f&&(r.current=getComputedStyle(f)),n(f)},[])}}function Vf(e){return e?.animationName||\"none\"}function Z3(e){let t=Object.getOwnPropertyDescriptor(e.props,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Ev=\"rovingFocusGroup.onEntryFocus\",Y3={bubbles:!1,cancelable:!0},Ah=\"RovingFocusGroup\",[Vy,tN,X3]=Kb(Ah),[ez,Dh]=us(Ah,[X3]),[tz,nz]=ez(Ah),nN=y.forwardRef((e,t)=>i.jsx(Vy.Provider,{scope:e.__scopeRovingFocusGroup,children:i.jsx(Vy.Slot,{scope:e.__scopeRovingFocusGroup,children:i.jsx(rz,{...e,ref:t})})}));nN.displayName=Ah;var rz=y.forwardRef((e,t)=>{const{__scopeRovingFocusGroup:n,orientation:r,loop:s=!1,dir:o,currentTabStopId:l,defaultCurrentTabStopId:u,onCurrentTabStopIdChange:d,onEntryFocus:f,preventScrollOnEntryFocus:h=!1,...m}=e,g=y.useRef(null),x=Rt(t,g),b=xd(o),[w=null,C]=ya({prop:l,defaultProp:u,onChange:d}),[k,j]=y.useState(!1),M=Rn(f),_=tN(n),R=y.useRef(!1),[N,O]=y.useState(0);return y.useEffect(()=>{const D=g.current;if(D)return D.addEventListener(Ev,M),()=>D.removeEventListener(Ev,M)},[M]),i.jsx(tz,{scope:n,orientation:r,dir:b,loop:s,currentTabStopId:w,onItemFocus:y.useCallback(D=>C(D),[C]),onItemShiftTab:y.useCallback(()=>j(!0),[]),onFocusableItemAdd:y.useCallback(()=>O(D=>D+1),[]),onFocusableItemRemove:y.useCallback(()=>O(D=>D-1),[]),children:i.jsx(rt.div,{tabIndex:k||N===0?-1:0,\"data-orientation\":r,...m,ref:x,style:{outline:\"none\",...e.style},onMouseDown:Ue(e.onMouseDown,()=>{R.current=!0}),onFocus:Ue(e.onFocus,D=>{const z=!R.current;if(D.target===D.currentTarget&&z&&!k){const Q=new CustomEvent(Ev,Y3);if(D.currentTarget.dispatchEvent(Q),!Q.defaultPrevented){const pe=_().filter(re=>re.focusable),V=pe.find(re=>re.active),G=pe.find(re=>re.id===w),ie=[V,G,...pe].filter(Boolean).map(re=>re.ref.current);oN(ie,h)}}R.current=!1}),onBlur:Ue(e.onBlur,()=>j(!1))})})}),rN=\"RovingFocusGroupItem\",sN=y.forwardRef((e,t)=>{const{__scopeRovingFocusGroup:n,focusable:r=!0,active:s=!1,tabStopId:o,...l}=e,u=Es(),d=o||u,f=nz(rN,n),h=f.currentTabStopId===d,m=tN(n),{onFocusableItemAdd:g,onFocusableItemRemove:x}=f;return y.useEffect(()=>{if(r)return g(),()=>x()},[r,g,x]),i.jsx(Vy.ItemSlot,{scope:n,id:d,focusable:r,active:s,children:i.jsx(rt.span,{tabIndex:h?0:-1,\"data-orientation\":f.orientation,...l,ref:t,onMouseDown:Ue(e.onMouseDown,b=>{r?f.onItemFocus(d):b.preventDefault()}),onFocus:Ue(e.onFocus,()=>f.onItemFocus(d)),onKeyDown:Ue(e.onKeyDown,b=>{if(b.key===\"Tab\"&&b.shiftKey){f.onItemShiftTab();return}if(b.target!==b.currentTarget)return;const w=az(b,f.orientation,f.dir);if(w!==void 0){if(b.metaKey||b.ctrlKey||b.altKey||b.shiftKey)return;b.preventDefault();let k=m().filter(j=>j.focusable).map(j=>j.ref.current);if(w===\"last\")k.reverse();else if(w===\"prev\"||w===\"next\"){w===\"prev\"&&k.reverse();const j=k.indexOf(b.currentTarget);k=f.loop?iz(k,j+1):k.slice(j+1)}setTimeout(()=>oN(k))}})})})});sN.displayName=rN;var sz={ArrowLeft:\"prev\",ArrowUp:\"prev\",ArrowRight:\"next\",ArrowDown:\"next\",PageUp:\"first\",Home:\"first\",PageDown:\"last\",End:\"last\"};function oz(e,t){return t!==\"rtl\"?e:e===\"ArrowLeft\"?\"ArrowRight\":e===\"ArrowRight\"?\"ArrowLeft\":e}function az(e,t,n){const r=oz(e.key,n);if(!(t===\"vertical\"&&[\"ArrowLeft\",\"ArrowRight\"].includes(r))&&!(t===\"horizontal\"&&[\"ArrowUp\",\"ArrowDown\"].includes(r)))return sz[r]}function oN(e,t=!1){const n=document.activeElement;for(const r of e)if(r===n||(r.focus({preventScroll:t}),document.activeElement!==n))return}function iz(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var aN=nN,iN=sN,lz=function(e){if(typeof document>\"u\")return null;var t=Array.isArray(e)?e[0]:e;return t.ownerDocument.body},pl=new WeakMap,Hf=new WeakMap,qf={},kv=0,lN=function(e){return e&&(e.host||lN(e.parentNode))},cz=function(e,t){return t.map(function(n){if(e.contains(n))return n;var r=lN(n);return r&&e.contains(r)?r:(console.error(\"aria-hidden\",n,\"in not contained inside\",e,\". Doing nothing\"),null)}).filter(function(n){return!!n})},uz=function(e,t,n,r){var s=cz(t,Array.isArray(e)?e:[e]);qf[n]||(qf[n]=new WeakMap);var o=qf[n],l=[],u=new Set,d=new Set(s),f=function(m){!m||u.has(m)||(u.add(m),f(m.parentNode))};s.forEach(f);var h=function(m){!m||d.has(m)||Array.prototype.forEach.call(m.children,function(g){if(u.has(g))h(g);else try{var x=g.getAttribute(r),b=x!==null&&x!==\"false\",w=(pl.get(g)||0)+1,C=(o.get(g)||0)+1;pl.set(g,w),o.set(g,C),l.push(g),w===1&&b&&Hf.set(g,!0),C===1&&g.setAttribute(n,\"true\"),b||g.setAttribute(r,\"true\")}catch(k){console.error(\"aria-hidden: cannot operate on \",g,k)}})};return h(t),u.clear(),kv++,function(){l.forEach(function(m){var g=pl.get(m)-1,x=o.get(m)-1;pl.set(m,g),o.set(m,x),g||(Hf.has(m)||m.removeAttribute(r),Hf.delete(m)),x||m.removeAttribute(n)}),kv--,kv||(pl=new WeakMap,pl=new WeakMap,Hf=new WeakMap,qf={})}},nx=function(e,t,n){n===void 0&&(n=\"data-aria-hidden\");var r=Array.from(Array.isArray(e)?e:[e]),s=lz(e);return s?(r.push.apply(r,Array.from(s.querySelectorAll(\"[aria-live]\"))),uz(r,s,n,\"aria-hidden\")):function(){return null}},zs=function(){return zs=Object.assign||function(t){for(var n,r=1,s=arguments.length;r<s;r++){n=arguments[r];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},zs.apply(this,arguments)};function cN(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols==\"function\")for(var s=0,r=Object.getOwnPropertySymbols(e);s<r.length;s++)t.indexOf(r[s])<0&&Object.prototype.propertyIsEnumerable.call(e,r[s])&&(n[r[s]]=e[r[s]]);return n}function dz(e,t,n){if(n||arguments.length===2)for(var r=0,s=t.length,o;r<s;r++)(o||!(r in t))&&(o||(o=Array.prototype.slice.call(t,0,r)),o[r]=t[r]);return e.concat(o||Array.prototype.slice.call(t))}var gp=\"right-scroll-bar-position\",mp=\"width-before-scroll-bar\",fz=\"with-scroll-bars-hidden\",pz=\"--removed-body-scroll-bar-size\";function jv(e,t){return typeof e==\"function\"?e(t):e&&(e.current=t),e}function hz(e,t){var n=y.useState(function(){return{value:e,callback:t,facade:{get current(){return n.value},set current(r){var s=n.value;s!==r&&(n.value=r,n.callback(r,s))}}}})[0];return n.callback=t,n.facade}var gz=typeof window<\"u\"?y.useLayoutEffect:y.useEffect,i1=new WeakMap;function mz(e,t){var n=hz(null,function(r){return e.forEach(function(s){return jv(s,r)})});return gz(function(){var r=i1.get(n);if(r){var s=new Set(r),o=new Set(e),l=n.current;s.forEach(function(u){o.has(u)||jv(u,null)}),o.forEach(function(u){s.has(u)||jv(u,l)})}i1.set(n,e)},[e]),n}function vz(e){return e}function yz(e,t){t===void 0&&(t=vz);var n=[],r=!1,s={read:function(){if(r)throw new Error(\"Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.\");return n.length?n[n.length-1]:e},useMedium:function(o){var l=t(o,r);return n.push(l),function(){n=n.filter(function(u){return u!==l})}},assignSyncMedium:function(o){for(r=!0;n.length;){var l=n;n=[],l.forEach(o)}n={push:function(u){return o(u)},filter:function(){return n}}},assignMedium:function(o){r=!0;var l=[];if(n.length){var u=n;n=[],u.forEach(o),l=n}var d=function(){var h=l;l=[],h.forEach(o)},f=function(){return Promise.resolve().then(d)};f(),n={push:function(h){l.push(h),f()},filter:function(h){return l=l.filter(h),n}}}};return s}function bz(e){e===void 0&&(e={});var t=yz(null);return t.options=zs({async:!0,ssr:!1},e),t}var uN=function(e){var t=e.sideCar,n=cN(e,[\"sideCar\"]);if(!t)throw new Error(\"Sidecar: please provide `sideCar` property to import the right car\");var r=t.read();if(!r)throw new Error(\"Sidecar medium not found\");return y.createElement(r,zs({},n))};uN.isSideCarExport=!0;function xz(e,t){return e.useMedium(t),uN}var dN=bz(),Tv=function(){},Fh=y.forwardRef(function(e,t){var n=y.useRef(null),r=y.useState({onScrollCapture:Tv,onWheelCapture:Tv,onTouchMoveCapture:Tv}),s=r[0],o=r[1],l=e.forwardProps,u=e.children,d=e.className,f=e.removeScrollBar,h=e.enabled,m=e.shards,g=e.sideCar,x=e.noIsolation,b=e.inert,w=e.allowPinchZoom,C=e.as,k=C===void 0?\"div\":C,j=e.gapMode,M=cN(e,[\"forwardProps\",\"children\",\"className\",\"removeScrollBar\",\"enabled\",\"shards\",\"sideCar\",\"noIsolation\",\"inert\",\"allowPinchZoom\",\"as\",\"gapMode\"]),_=g,R=mz([n,t]),N=zs(zs({},M),s);return y.createElement(y.Fragment,null,h&&y.createElement(_,{sideCar:dN,removeScrollBar:f,shards:m,noIsolation:x,inert:b,setCallbacks:o,allowPinchZoom:!!w,lockRef:n,gapMode:j}),l?y.cloneElement(y.Children.only(u),zs(zs({},N),{ref:R})):y.createElement(k,zs({},N,{className:d,ref:R}),u))});Fh.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1};Fh.classNames={fullWidth:mp,zeroRight:gp};var wz=function(){if(typeof __webpack_nonce__<\"u\")return __webpack_nonce__};function Sz(){if(!document)return null;var e=document.createElement(\"style\");e.type=\"text/css\";var t=wz();return t&&e.setAttribute(\"nonce\",t),e}function Cz(e,t){e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}function Ez(e){var t=document.head||document.getElementsByTagName(\"head\")[0];t.appendChild(e)}var kz=function(){var e=0,t=null;return{add:function(n){e==0&&(t=Sz())&&(Cz(t,n),Ez(t)),e++},remove:function(){e--,!e&&t&&(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},jz=function(){var e=kz();return function(t,n){y.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},fN=function(){var e=jz(),t=function(n){var r=n.styles,s=n.dynamic;return e(r,s),null};return t},Tz={left:0,top:0,right:0,gap:0},Nv=function(e){return parseInt(e||\"\",10)||0},Nz=function(e){var t=window.getComputedStyle(document.body),n=t[e===\"padding\"?\"paddingLeft\":\"marginLeft\"],r=t[e===\"padding\"?\"paddingTop\":\"marginTop\"],s=t[e===\"padding\"?\"paddingRight\":\"marginRight\"];return[Nv(n),Nv(r),Nv(s)]},Mz=function(e){if(e===void 0&&(e=\"margin\"),typeof window>\"u\")return Tz;var t=Nz(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},_z=fN(),Pl=\"data-scroll-locked\",Rz=function(e,t,n,r){var s=e.left,o=e.top,l=e.right,u=e.gap;return n===void 0&&(n=\"margin\"),`\n  .`.concat(fz,` {\n   overflow: hidden `).concat(r,`;\n   padding-right: `).concat(u,\"px \").concat(r,`;\n  }\n  body[`).concat(Pl,`] {\n    overflow: hidden `).concat(r,`;\n    overscroll-behavior: contain;\n    `).concat([t&&\"position: relative \".concat(r,\";\"),n===\"margin\"&&`\n    padding-left: `.concat(s,`px;\n    padding-top: `).concat(o,`px;\n    padding-right: `).concat(l,`px;\n    margin-left:0;\n    margin-top:0;\n    margin-right: `).concat(u,\"px \").concat(r,`;\n    `),n===\"padding\"&&\"padding-right: \".concat(u,\"px \").concat(r,\";\")].filter(Boolean).join(\"\"),`\n  }\n  \n  .`).concat(gp,` {\n    right: `).concat(u,\"px \").concat(r,`;\n  }\n  \n  .`).concat(mp,` {\n    margin-right: `).concat(u,\"px \").concat(r,`;\n  }\n  \n  .`).concat(gp,\" .\").concat(gp,` {\n    right: 0 `).concat(r,`;\n  }\n  \n  .`).concat(mp,\" .\").concat(mp,` {\n    margin-right: 0 `).concat(r,`;\n  }\n  \n  body[`).concat(Pl,`] {\n    `).concat(pz,\": \").concat(u,`px;\n  }\n`)},l1=function(){var e=parseInt(document.body.getAttribute(Pl)||\"0\",10);return isFinite(e)?e:0},Pz=function(){y.useEffect(function(){return document.body.setAttribute(Pl,(l1()+1).toString()),function(){var e=l1()-1;e<=0?document.body.removeAttribute(Pl):document.body.setAttribute(Pl,e.toString())}},[])},Oz=function(e){var t=e.noRelative,n=e.noImportant,r=e.gapMode,s=r===void 0?\"margin\":r;Pz();var o=y.useMemo(function(){return Mz(s)},[s]);return y.createElement(_z,{styles:Rz(o,!t,s,n?\"\":\"!important\")})},Hy=!1;if(typeof window<\"u\")try{var Kf=Object.defineProperty({},\"passive\",{get:function(){return Hy=!0,!0}});window.addEventListener(\"test\",Kf,Kf),window.removeEventListener(\"test\",Kf,Kf)}catch{Hy=!1}var hl=Hy?{passive:!1}:!1,Iz=function(e){return e.tagName===\"TEXTAREA\"},pN=function(e,t){var n=window.getComputedStyle(e);return n[t]!==\"hidden\"&&!(n.overflowY===n.overflowX&&!Iz(e)&&n[t]===\"visible\")},Az=function(e){return pN(e,\"overflowY\")},Dz=function(e){return pN(e,\"overflowX\")},c1=function(e,t){var n=t.ownerDocument,r=t;do{typeof ShadowRoot<\"u\"&&r instanceof ShadowRoot&&(r=r.host);var s=hN(e,r);if(s){var o=gN(e,r),l=o[1],u=o[2];if(l>u)return!0}r=r.parentNode}while(r&&r!==n.body);return!1},Fz=function(e){var t=e.scrollTop,n=e.scrollHeight,r=e.clientHeight;return[t,n,r]},Lz=function(e){var t=e.scrollLeft,n=e.scrollWidth,r=e.clientWidth;return[t,n,r]},hN=function(e,t){return e===\"v\"?Az(t):Dz(t)},gN=function(e,t){return e===\"v\"?Fz(t):Lz(t)},$z=function(e,t){return e===\"h\"&&t===\"rtl\"?-1:1},Bz=function(e,t,n,r,s){var o=$z(e,window.getComputedStyle(t).direction),l=o*r,u=n.target,d=t.contains(u),f=!1,h=l>0,m=0,g=0;do{var x=gN(e,u),b=x[0],w=x[1],C=x[2],k=w-C-o*b;(b||k)&&hN(e,u)&&(m+=k,g+=b),u instanceof ShadowRoot?u=u.host:u=u.parentNode}while(!d&&u!==document.body||d&&(t.contains(u)||t===u));return(h&&Math.abs(m)<1||!h&&Math.abs(g)<1)&&(f=!0),f},Wf=function(e){return\"changedTouches\"in e?[e.changedTouches[0].clientX,e.changedTouches[0].clientY]:[0,0]},u1=function(e){return[e.deltaX,e.deltaY]},d1=function(e){return e&&\"current\"in e?e.current:e},zz=function(e,t){return e[0]===t[0]&&e[1]===t[1]},Uz=function(e){return`\n  .block-interactivity-`.concat(e,` {pointer-events: none;}\n  .allow-interactivity-`).concat(e,` {pointer-events: all;}\n`)},Vz=0,gl=[];function Hz(e){var t=y.useRef([]),n=y.useRef([0,0]),r=y.useRef(),s=y.useState(Vz++)[0],o=y.useState(fN)[0],l=y.useRef(e);y.useEffect(function(){l.current=e},[e]),y.useEffect(function(){if(e.inert){document.body.classList.add(\"block-interactivity-\".concat(s));var w=dz([e.lockRef.current],(e.shards||[]).map(d1),!0).filter(Boolean);return w.forEach(function(C){return C.classList.add(\"allow-interactivity-\".concat(s))}),function(){document.body.classList.remove(\"block-interactivity-\".concat(s)),w.forEach(function(C){return C.classList.remove(\"allow-interactivity-\".concat(s))})}}},[e.inert,e.lockRef.current,e.shards]);var u=y.useCallback(function(w,C){if(\"touches\"in w&&w.touches.length===2)return!l.current.allowPinchZoom;var k=Wf(w),j=n.current,M=\"deltaX\"in w?w.deltaX:j[0]-k[0],_=\"deltaY\"in w?w.deltaY:j[1]-k[1],R,N=w.target,O=Math.abs(M)>Math.abs(_)?\"h\":\"v\";if(\"touches\"in w&&O===\"h\"&&N.type===\"range\")return!1;var D=c1(O,N);if(!D)return!0;if(D?R=O:(R=O===\"v\"?\"h\":\"v\",D=c1(O,N)),!D)return!1;if(!r.current&&\"changedTouches\"in w&&(M||_)&&(r.current=R),!R)return!0;var z=r.current||R;return Bz(z,C,w,z===\"h\"?M:_)},[]),d=y.useCallback(function(w){var C=w;if(!(!gl.length||gl[gl.length-1]!==o)){var k=\"deltaY\"in C?u1(C):Wf(C),j=t.current.filter(function(R){return R.name===C.type&&(R.target===C.target||C.target===R.shadowParent)&&zz(R.delta,k)})[0];if(j&&j.should){C.cancelable&&C.preventDefault();return}if(!j){var M=(l.current.shards||[]).map(d1).filter(Boolean).filter(function(R){return R.contains(C.target)}),_=M.length>0?u(C,M[0]):!l.current.noIsolation;_&&C.cancelable&&C.preventDefault()}}},[]),f=y.useCallback(function(w,C,k,j){var M={name:w,delta:C,target:k,should:j,shadowParent:qz(k)};t.current.push(M),setTimeout(function(){t.current=t.current.filter(function(_){return _!==M})},1)},[]),h=y.useCallback(function(w){n.current=Wf(w),r.current=void 0},[]),m=y.useCallback(function(w){f(w.type,u1(w),w.target,u(w,e.lockRef.current))},[]),g=y.useCallback(function(w){f(w.type,Wf(w),w.target,u(w,e.lockRef.current))},[]);y.useEffect(function(){return gl.push(o),e.setCallbacks({onScrollCapture:m,onWheelCapture:m,onTouchMoveCapture:g}),document.addEventListener(\"wheel\",d,hl),document.addEventListener(\"touchmove\",d,hl),document.addEventListener(\"touchstart\",h,hl),function(){gl=gl.filter(function(w){return w!==o}),document.removeEventListener(\"wheel\",d,hl),document.removeEventListener(\"touchmove\",d,hl),document.removeEventListener(\"touchstart\",h,hl)}},[]);var x=e.removeScrollBar,b=e.inert;return y.createElement(y.Fragment,null,b?y.createElement(o,{styles:Uz(s)}):null,x?y.createElement(Oz,{gapMode:e.gapMode}):null)}function qz(e){for(var t=null;e!==null;)e instanceof ShadowRoot&&(t=e.host,e=e.host),e=e.parentNode;return t}const Kz=xz(dN,Hz);var Lh=y.forwardRef(function(e,t){return y.createElement(Fh,zs({},e,{ref:t,sideCar:Kz}))});Lh.classNames=Fh.classNames;var qy=[\"Enter\",\" \"],Wz=[\"ArrowDown\",\"PageUp\",\"Home\"],mN=[\"ArrowUp\",\"PageDown\",\"End\"],Gz=[...Wz,...mN],Jz={ltr:[...qy,\"ArrowRight\"],rtl:[...qy,\"ArrowLeft\"]},Qz={ltr:[\"ArrowLeft\"],rtl:[\"ArrowRight\"]},Sd=\"Menu\",[Uu,Zz,Yz]=Kb(Sd),[$i,vN]=us(Sd,[Yz,Oh,Dh]),$h=Oh(),yN=Dh(),[Xz,Bi]=$i(Sd),[eU,Cd]=$i(Sd),bN=e=>{const{__scopeMenu:t,open:n=!1,children:r,dir:s,onOpenChange:o,modal:l=!0}=e,u=$h(t),[d,f]=y.useState(null),h=y.useRef(!1),m=Rn(o),g=xd(s);return y.useEffect(()=>{const x=()=>{h.current=!0,document.addEventListener(\"pointerdown\",b,{capture:!0,once:!0}),document.addEventListener(\"pointermove\",b,{capture:!0,once:!0})},b=()=>h.current=!1;return document.addEventListener(\"keydown\",x,{capture:!0}),()=>{document.removeEventListener(\"keydown\",x,{capture:!0}),document.removeEventListener(\"pointerdown\",b,{capture:!0}),document.removeEventListener(\"pointermove\",b,{capture:!0})}},[]),i.jsx(ZT,{...u,children:i.jsx(Xz,{scope:t,open:n,onOpenChange:m,content:d,onContentChange:f,children:i.jsx(eU,{scope:t,onClose:y.useCallback(()=>m(!1),[m]),isUsingKeyboardRef:h,dir:g,modal:l,children:r})})})};bN.displayName=Sd;var tU=\"MenuAnchor\",rx=y.forwardRef((e,t)=>{const{__scopeMenu:n,...r}=e,s=$h(n);return i.jsx(YT,{...s,...r,ref:t})});rx.displayName=tU;var sx=\"MenuPortal\",[nU,xN]=$i(sx,{forceMount:void 0}),wN=e=>{const{__scopeMenu:t,forceMount:n,children:r,container:s}=e,o=Bi(sx,t);return i.jsx(nU,{scope:t,forceMount:n,children:i.jsx(Mr,{present:n||o.open,children:i.jsx(Ih,{asChild:!0,container:s,children:r})})})};wN.displayName=sx;var is=\"MenuContent\",[rU,ox]=$i(is),SN=y.forwardRef((e,t)=>{const n=xN(is,e.__scopeMenu),{forceMount:r=n.forceMount,...s}=e,o=Bi(is,e.__scopeMenu),l=Cd(is,e.__scopeMenu);return i.jsx(Uu.Provider,{scope:e.__scopeMenu,children:i.jsx(Mr,{present:r||o.open,children:i.jsx(Uu.Slot,{scope:e.__scopeMenu,children:l.modal?i.jsx(sU,{...s,ref:t}):i.jsx(oU,{...s,ref:t})})})})}),sU=y.forwardRef((e,t)=>{const n=Bi(is,e.__scopeMenu),r=y.useRef(null),s=Rt(t,r);return y.useEffect(()=>{const o=r.current;if(o)return nx(o)},[]),i.jsx(ax,{...e,ref:s,trapFocus:n.open,disableOutsidePointerEvents:n.open,disableOutsideScroll:!0,onFocusOutside:Ue(e.onFocusOutside,o=>o.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:()=>n.onOpenChange(!1)})}),oU=y.forwardRef((e,t)=>{const n=Bi(is,e.__scopeMenu);return i.jsx(ax,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:()=>n.onOpenChange(!1)})}),ax=y.forwardRef((e,t)=>{const{__scopeMenu:n,loop:r=!1,trapFocus:s,onOpenAutoFocus:o,onCloseAutoFocus:l,disableOutsidePointerEvents:u,onEntryFocus:d,onEscapeKeyDown:f,onPointerDownOutside:h,onFocusOutside:m,onInteractOutside:g,onDismiss:x,disableOutsideScroll:b,...w}=e,C=Bi(is,n),k=Cd(is,n),j=$h(n),M=yN(n),_=Zz(n),[R,N]=y.useState(null),O=y.useRef(null),D=Rt(t,O,C.onContentChange),z=y.useRef(0),Q=y.useRef(\"\"),pe=y.useRef(0),V=y.useRef(null),G=y.useRef(\"right\"),W=y.useRef(0),ie=b?Lh:y.Fragment,re=b?{as:No,allowPinchZoom:!0}:void 0,Y=q=>{const he=Q.current+q,A=_().filter(Z=>!Z.disabled),F=document.activeElement,fe=A.find(Z=>Z.ref.current===F)?.textValue,te=A.map(Z=>Z.textValue),de=vU(te,he,fe),ge=A.find(Z=>Z.textValue===de)?.ref.current;(function Z(ye){Q.current=ye,window.clearTimeout(z.current),ye!==\"\"&&(z.current=window.setTimeout(()=>Z(\"\"),1e3))})(he),ge&&setTimeout(()=>ge.focus())};y.useEffect(()=>()=>window.clearTimeout(z.current),[]),Wb();const H=y.useCallback(q=>G.current===V.current?.side&&bU(q,V.current?.area),[]);return i.jsx(rU,{scope:n,searchRef:Q,onItemEnter:y.useCallback(q=>{H(q)&&q.preventDefault()},[H]),onItemLeave:y.useCallback(q=>{H(q)||(O.current?.focus(),N(null))},[H]),onTriggerLeave:y.useCallback(q=>{H(q)&&q.preventDefault()},[H]),pointerGraceTimerRef:pe,onPointerGraceIntentChange:y.useCallback(q=>{V.current=q},[]),children:i.jsx(ie,{...re,children:i.jsx(_h,{asChild:!0,trapped:s,onMountAutoFocus:Ue(o,q=>{q.preventDefault(),O.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:l,children:i.jsx(Mh,{asChild:!0,disableOutsidePointerEvents:u,onEscapeKeyDown:f,onPointerDownOutside:h,onFocusOutside:m,onInteractOutside:g,onDismiss:x,children:i.jsx(aN,{asChild:!0,...M,dir:k.dir,orientation:\"vertical\",loop:r,currentTabStopId:R,onCurrentTabStopIdChange:N,onEntryFocus:Ue(d,q=>{k.isUsingKeyboardRef.current||q.preventDefault()}),preventScrollOnEntryFocus:!0,children:i.jsx(XT,{role:\"menu\",\"aria-orientation\":\"vertical\",\"data-state\":LN(C.open),\"data-radix-menu-content\":\"\",dir:k.dir,...j,...w,ref:D,style:{outline:\"none\",...w.style},onKeyDown:Ue(w.onKeyDown,q=>{const A=q.target.closest(\"[data-radix-menu-content]\")===q.currentTarget,F=q.ctrlKey||q.altKey||q.metaKey,fe=q.key.length===1;A&&(q.key===\"Tab\"&&q.preventDefault(),!F&&fe&&Y(q.key));const te=O.current;if(q.target!==te||!Gz.includes(q.key))return;q.preventDefault();const ge=_().filter(Z=>!Z.disabled).map(Z=>Z.ref.current);mN.includes(q.key)&&ge.reverse(),gU(ge)}),onBlur:Ue(e.onBlur,q=>{q.currentTarget.contains(q.target)||(window.clearTimeout(z.current),Q.current=\"\")}),onPointerMove:Ue(e.onPointerMove,Vu(q=>{const he=q.target,A=W.current!==q.clientX;if(q.currentTarget.contains(he)&&A){const F=q.clientX>W.current?\"right\":\"left\";G.current=F,W.current=q.clientX}}))})})})})})})});SN.displayName=is;var aU=\"MenuGroup\",ix=y.forwardRef((e,t)=>{const{__scopeMenu:n,...r}=e;return i.jsx(rt.div,{role:\"group\",...r,ref:t})});ix.displayName=aU;var iU=\"MenuLabel\",CN=y.forwardRef((e,t)=>{const{__scopeMenu:n,...r}=e;return i.jsx(rt.div,{...r,ref:t})});CN.displayName=iU;var Bp=\"MenuItem\",f1=\"menu.itemSelect\",Bh=y.forwardRef((e,t)=>{const{disabled:n=!1,onSelect:r,...s}=e,o=y.useRef(null),l=Cd(Bp,e.__scopeMenu),u=ox(Bp,e.__scopeMenu),d=Rt(t,o),f=y.useRef(!1),h=()=>{const m=o.current;if(!n&&m){const g=new CustomEvent(f1,{bubbles:!0,cancelable:!0});m.addEventListener(f1,x=>r?.(x),{once:!0}),yT(m,g),g.defaultPrevented?f.current=!1:l.onClose()}};return i.jsx(EN,{...s,ref:d,disabled:n,onClick:Ue(e.onClick,h),onPointerDown:m=>{e.onPointerDown?.(m),f.current=!0},onPointerUp:Ue(e.onPointerUp,m=>{f.current||m.currentTarget?.click()}),onKeyDown:Ue(e.onKeyDown,m=>{const g=u.searchRef.current!==\"\";n||g&&m.key===\" \"||qy.includes(m.key)&&(m.currentTarget.click(),m.preventDefault())})})});Bh.displayName=Bp;var EN=y.forwardRef((e,t)=>{const{__scopeMenu:n,disabled:r=!1,textValue:s,...o}=e,l=ox(Bp,n),u=yN(n),d=y.useRef(null),f=Rt(t,d),[h,m]=y.useState(!1),[g,x]=y.useState(\"\");return y.useEffect(()=>{const b=d.current;b&&x((b.textContent??\"\").trim())},[o.children]),i.jsx(Uu.ItemSlot,{scope:n,disabled:r,textValue:s??g,children:i.jsx(iN,{asChild:!0,...u,focusable:!r,children:i.jsx(rt.div,{role:\"menuitem\",\"data-highlighted\":h?\"\":void 0,\"aria-disabled\":r||void 0,\"data-disabled\":r?\"\":void 0,...o,ref:f,onPointerMove:Ue(e.onPointerMove,Vu(b=>{r?l.onItemLeave(b):(l.onItemEnter(b),b.defaultPrevented||b.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:Ue(e.onPointerLeave,Vu(b=>l.onItemLeave(b))),onFocus:Ue(e.onFocus,()=>m(!0)),onBlur:Ue(e.onBlur,()=>m(!1))})})})}),lU=\"MenuCheckboxItem\",kN=y.forwardRef((e,t)=>{const{checked:n=!1,onCheckedChange:r,...s}=e;return i.jsx(_N,{scope:e.__scopeMenu,checked:n,children:i.jsx(Bh,{role:\"menuitemcheckbox\",\"aria-checked\":zp(n)?\"mixed\":n,...s,ref:t,\"data-state\":cx(n),onSelect:Ue(s.onSelect,()=>r?.(zp(n)?!0:!n),{checkForDefaultPrevented:!1})})})});kN.displayName=lU;var jN=\"MenuRadioGroup\",[cU,uU]=$i(jN,{value:void 0,onValueChange:()=>{}}),TN=y.forwardRef((e,t)=>{const{value:n,onValueChange:r,...s}=e,o=Rn(r);return i.jsx(cU,{scope:e.__scopeMenu,value:n,onValueChange:o,children:i.jsx(ix,{...s,ref:t})})});TN.displayName=jN;var NN=\"MenuRadioItem\",MN=y.forwardRef((e,t)=>{const{value:n,...r}=e,s=uU(NN,e.__scopeMenu),o=n===s.value;return i.jsx(_N,{scope:e.__scopeMenu,checked:o,children:i.jsx(Bh,{role:\"menuitemradio\",\"aria-checked\":o,...r,ref:t,\"data-state\":cx(o),onSelect:Ue(r.onSelect,()=>s.onValueChange?.(n),{checkForDefaultPrevented:!1})})})});MN.displayName=NN;var lx=\"MenuItemIndicator\",[_N,dU]=$i(lx,{checked:!1}),RN=y.forwardRef((e,t)=>{const{__scopeMenu:n,forceMount:r,...s}=e,o=dU(lx,n);return i.jsx(Mr,{present:r||zp(o.checked)||o.checked===!0,children:i.jsx(rt.span,{...s,ref:t,\"data-state\":cx(o.checked)})})});RN.displayName=lx;var fU=\"MenuSeparator\",PN=y.forwardRef((e,t)=>{const{__scopeMenu:n,...r}=e;return i.jsx(rt.div,{role:\"separator\",\"aria-orientation\":\"horizontal\",...r,ref:t})});PN.displayName=fU;var pU=\"MenuArrow\",ON=y.forwardRef((e,t)=>{const{__scopeMenu:n,...r}=e,s=$h(n);return i.jsx(eN,{...s,...r,ref:t})});ON.displayName=pU;var hU=\"MenuSub\",[wie,IN]=$i(hU),mu=\"MenuSubTrigger\",AN=y.forwardRef((e,t)=>{const n=Bi(mu,e.__scopeMenu),r=Cd(mu,e.__scopeMenu),s=IN(mu,e.__scopeMenu),o=ox(mu,e.__scopeMenu),l=y.useRef(null),{pointerGraceTimerRef:u,onPointerGraceIntentChange:d}=o,f={__scopeMenu:e.__scopeMenu},h=y.useCallback(()=>{l.current&&window.clearTimeout(l.current),l.current=null},[]);return y.useEffect(()=>h,[h]),y.useEffect(()=>{const m=u.current;return()=>{window.clearTimeout(m),d(null)}},[u,d]),i.jsx(rx,{asChild:!0,...f,children:i.jsx(EN,{id:s.triggerId,\"aria-haspopup\":\"menu\",\"aria-expanded\":n.open,\"aria-controls\":s.contentId,\"data-state\":LN(n.open),...e,ref:kh(t,s.onTriggerChange),onClick:m=>{e.onClick?.(m),!(e.disabled||m.defaultPrevented)&&(m.currentTarget.focus(),n.open||n.onOpenChange(!0))},onPointerMove:Ue(e.onPointerMove,Vu(m=>{o.onItemEnter(m),!m.defaultPrevented&&!e.disabled&&!n.open&&!l.current&&(o.onPointerGraceIntentChange(null),l.current=window.setTimeout(()=>{n.onOpenChange(!0),h()},100))})),onPointerLeave:Ue(e.onPointerLeave,Vu(m=>{h();const g=n.content?.getBoundingClientRect();if(g){const x=n.content?.dataset.side,b=x===\"right\",w=b?-5:5,C=g[b?\"left\":\"right\"],k=g[b?\"right\":\"left\"];o.onPointerGraceIntentChange({area:[{x:m.clientX+w,y:m.clientY},{x:C,y:g.top},{x:k,y:g.top},{x:k,y:g.bottom},{x:C,y:g.bottom}],side:x}),window.clearTimeout(u.current),u.current=window.setTimeout(()=>o.onPointerGraceIntentChange(null),300)}else{if(o.onTriggerLeave(m),m.defaultPrevented)return;o.onPointerGraceIntentChange(null)}})),onKeyDown:Ue(e.onKeyDown,m=>{const g=o.searchRef.current!==\"\";e.disabled||g&&m.key===\" \"||Jz[r.dir].includes(m.key)&&(n.onOpenChange(!0),n.content?.focus(),m.preventDefault())})})})});AN.displayName=mu;var DN=\"MenuSubContent\",FN=y.forwardRef((e,t)=>{const n=xN(is,e.__scopeMenu),{forceMount:r=n.forceMount,...s}=e,o=Bi(is,e.__scopeMenu),l=Cd(is,e.__scopeMenu),u=IN(DN,e.__scopeMenu),d=y.useRef(null),f=Rt(t,d);return i.jsx(Uu.Provider,{scope:e.__scopeMenu,children:i.jsx(Mr,{present:r||o.open,children:i.jsx(Uu.Slot,{scope:e.__scopeMenu,children:i.jsx(ax,{id:u.contentId,\"aria-labelledby\":u.triggerId,...s,ref:f,align:\"start\",side:l.dir===\"rtl\"?\"left\":\"right\",disableOutsidePointerEvents:!1,disableOutsideScroll:!1,trapFocus:!1,onOpenAutoFocus:h=>{l.isUsingKeyboardRef.current&&d.current?.focus(),h.preventDefault()},onCloseAutoFocus:h=>h.preventDefault(),onFocusOutside:Ue(e.onFocusOutside,h=>{h.target!==u.trigger&&o.onOpenChange(!1)}),onEscapeKeyDown:Ue(e.onEscapeKeyDown,h=>{l.onClose(),h.preventDefault()}),onKeyDown:Ue(e.onKeyDown,h=>{const m=h.currentTarget.contains(h.target),g=Qz[l.dir].includes(h.key);m&&g&&(o.onOpenChange(!1),u.trigger?.focus(),h.preventDefault())})})})})})});FN.displayName=DN;function LN(e){return e?\"open\":\"closed\"}function zp(e){return e===\"indeterminate\"}function cx(e){return zp(e)?\"indeterminate\":e?\"checked\":\"unchecked\"}function gU(e){const t=document.activeElement;for(const n of e)if(n===t||(n.focus(),document.activeElement!==t))return}function mU(e,t){return e.map((n,r)=>e[(t+r)%e.length])}function vU(e,t,n){const s=t.length>1&&Array.from(t).every(f=>f===t[0])?t[0]:t,o=n?e.indexOf(n):-1;let l=mU(e,Math.max(o,0));s.length===1&&(l=l.filter(f=>f!==n));const d=l.find(f=>f.toLowerCase().startsWith(s.toLowerCase()));return d!==n?d:void 0}function yU(e,t){const{x:n,y:r}=e;let s=!1;for(let o=0,l=t.length-1;o<t.length;l=o++){const u=t[o].x,d=t[o].y,f=t[l].x,h=t[l].y;d>r!=h>r&&n<(f-u)*(r-d)/(h-d)+u&&(s=!s)}return s}function bU(e,t){if(!t)return!1;const n={x:e.clientX,y:e.clientY};return yU(n,t)}function Vu(e){return t=>t.pointerType===\"mouse\"?e(t):void 0}var xU=bN,wU=rx,SU=wN,CU=SN,EU=ix,kU=CN,jU=Bh,TU=kN,NU=TN,MU=MN,_U=RN,RU=PN,PU=ON,OU=AN,IU=FN,ux=\"DropdownMenu\",[AU]=us(ux,[vN]),pr=vN(),[DU,$N]=AU(ux),dx=e=>{const{__scopeDropdownMenu:t,children:n,dir:r,open:s,defaultOpen:o,onOpenChange:l,modal:u=!0}=e,d=pr(t),f=y.useRef(null),[h=!1,m]=ya({prop:s,defaultProp:o,onChange:l});return i.jsx(DU,{scope:t,triggerId:Es(),triggerRef:f,contentId:Es(),open:h,onOpenChange:m,onOpenToggle:y.useCallback(()=>m(g=>!g),[m]),modal:u,children:i.jsx(xU,{...d,open:h,onOpenChange:m,dir:r,modal:u,children:n})})};dx.displayName=ux;var BN=\"DropdownMenuTrigger\",fx=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,disabled:r=!1,...s}=e,o=$N(BN,n),l=pr(n);return i.jsx(wU,{asChild:!0,...l,children:i.jsx(rt.button,{type:\"button\",id:o.triggerId,\"aria-haspopup\":\"menu\",\"aria-expanded\":o.open,\"aria-controls\":o.open?o.contentId:void 0,\"data-state\":o.open?\"open\":\"closed\",\"data-disabled\":r?\"\":void 0,disabled:r,...s,ref:kh(t,o.triggerRef),onPointerDown:Ue(e.onPointerDown,u=>{!r&&u.button===0&&u.ctrlKey===!1&&(o.onOpenToggle(),o.open||u.preventDefault())}),onKeyDown:Ue(e.onKeyDown,u=>{r||([\"Enter\",\" \"].includes(u.key)&&o.onOpenToggle(),u.key===\"ArrowDown\"&&o.onOpenChange(!0),[\"Enter\",\" \",\"ArrowDown\"].includes(u.key)&&u.preventDefault())})})})});fx.displayName=BN;var FU=\"DropdownMenuPortal\",zN=e=>{const{__scopeDropdownMenu:t,...n}=e,r=pr(t);return i.jsx(SU,{...r,...n})};zN.displayName=FU;var UN=\"DropdownMenuContent\",VN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=$N(UN,n),o=pr(n),l=y.useRef(!1);return i.jsx(CU,{id:s.contentId,\"aria-labelledby\":s.triggerId,...o,...r,ref:t,onCloseAutoFocus:Ue(e.onCloseAutoFocus,u=>{l.current||s.triggerRef.current?.focus(),l.current=!1,u.preventDefault()}),onInteractOutside:Ue(e.onInteractOutside,u=>{const d=u.detail.originalEvent,f=d.button===0&&d.ctrlKey===!0,h=d.button===2||f;(!s.modal||h)&&(l.current=!0)}),style:{...e.style,\"--radix-dropdown-menu-content-transform-origin\":\"var(--radix-popper-transform-origin)\",\"--radix-dropdown-menu-content-available-width\":\"var(--radix-popper-available-width)\",\"--radix-dropdown-menu-content-available-height\":\"var(--radix-popper-available-height)\",\"--radix-dropdown-menu-trigger-width\":\"var(--radix-popper-anchor-width)\",\"--radix-dropdown-menu-trigger-height\":\"var(--radix-popper-anchor-height)\"}})});VN.displayName=UN;var LU=\"DropdownMenuGroup\",$U=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(EU,{...s,...r,ref:t})});$U.displayName=LU;var BU=\"DropdownMenuLabel\",HN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(kU,{...s,...r,ref:t})});HN.displayName=BU;var zU=\"DropdownMenuItem\",qN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(jU,{...s,...r,ref:t})});qN.displayName=zU;var UU=\"DropdownMenuCheckboxItem\",KN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(TU,{...s,...r,ref:t})});KN.displayName=UU;var VU=\"DropdownMenuRadioGroup\",HU=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(NU,{...s,...r,ref:t})});HU.displayName=VU;var qU=\"DropdownMenuRadioItem\",WN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(MU,{...s,...r,ref:t})});WN.displayName=qU;var KU=\"DropdownMenuItemIndicator\",GN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(_U,{...s,...r,ref:t})});GN.displayName=KU;var WU=\"DropdownMenuSeparator\",JN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(RU,{...s,...r,ref:t})});JN.displayName=WU;var GU=\"DropdownMenuArrow\",JU=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(PU,{...s,...r,ref:t})});JU.displayName=GU;var QU=\"DropdownMenuSubTrigger\",QN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(OU,{...s,...r,ref:t})});QN.displayName=QU;var ZU=\"DropdownMenuSubContent\",ZN=y.forwardRef((e,t)=>{const{__scopeDropdownMenu:n,...r}=e,s=pr(n);return i.jsx(IU,{...s,...r,ref:t,style:{...e.style,\"--radix-dropdown-menu-content-transform-origin\":\"var(--radix-popper-transform-origin)\",\"--radix-dropdown-menu-content-available-width\":\"var(--radix-popper-available-width)\",\"--radix-dropdown-menu-content-available-height\":\"var(--radix-popper-available-height)\",\"--radix-dropdown-menu-trigger-width\":\"var(--radix-popper-anchor-width)\",\"--radix-dropdown-menu-trigger-height\":\"var(--radix-popper-anchor-height)\"}})});ZN.displayName=ZU;var YU=dx,XU=fx,e5=zN,YN=VN,XN=HN,eM=qN,tM=KN,nM=WN,rM=GN,Oa=JN,sM=QN,oM=ZN;const Kr=YU,Wr=XU,t5=y.forwardRef(({className:e,inset:t,children:n,...r},s)=>i.jsxs(sM,{ref:s,className:Ie(\"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent\",t&&\"pl-8\",e),...r,children:[n,i.jsx(W$,{className:\"ml-auto h-4 w-4\"})]}));t5.displayName=sM.displayName;const n5=y.forwardRef(({className:e,...t},n)=>i.jsx(oM,{ref:n,className:Ie(\"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",e),...t}));n5.displayName=oM.displayName;const hr=y.forwardRef(({className:e,sideOffset:t=4,...n},r)=>i.jsx(e5,{children:i.jsx(YN,{ref:r,sideOffset:t,className:Ie(\"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",e),...n})}));hr.displayName=YN.displayName;const wt=y.forwardRef(({className:e,inset:t,...n},r)=>i.jsx(eM,{ref:r,className:Ie(\"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",t&&\"pl-8\",e),...n}));wt.displayName=eM.displayName;const aM=y.forwardRef(({className:e,children:t,checked:n,...r},s)=>i.jsxs(tM,{ref:s,className:Ie(\"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",e),checked:n,...r,children:[i.jsx(\"span\",{className:\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\",children:i.jsx(rM,{children:i.jsx(fT,{className:\"h-4 w-4\"})})}),t]}));aM.displayName=tM.displayName;const r5=y.forwardRef(({className:e,children:t,...n},r)=>i.jsxs(nM,{ref:r,className:Ie(\"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",e),...n,children:[i.jsx(\"span\",{className:\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\",children:i.jsx(rM,{children:i.jsx(Z$,{className:\"h-2 w-2 fill-current\"})})}),t]}));r5.displayName=nM.displayName;const Ao=y.forwardRef(({className:e,inset:t,...n},r)=>i.jsx(XN,{ref:r,className:Ie(\"px-2 py-1.5 text-sm font-semibold\",t&&\"pl-8\",e),...n}));Ao.displayName=XN.displayName;const Xs=y.forwardRef(({className:e,...t},n)=>i.jsx(Oa,{ref:n,className:Ie(\"-mx-1 my-1 h-px bg-muted\",e),...t}));Xs.displayName=Oa.displayName;function iM(){const{t:e,i18n:t}=Ve(),n=r=>{t.changeLanguage(r),localStorage.setItem(\"i18nextLng\",r),window.location.reload()};return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"outline\",size:\"icon\",children:[i.jsx(fB,{className:\"h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all\"}),i.jsx(\"span\",{className:\"sr-only\",children:e(\"header.theme.label\")})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(wt,{className:t.language===\"pt-BR\"?\"font-bold\":\"\",onClick:()=>n(\"pt-BR\"),children:e(\"header.language.portuguese\")}),i.jsx(wt,{className:t.language===\"en-US\"?\"font-bold\":\"\",onClick:()=>n(\"en-US\"),children:e(\"header.language.english\")}),i.jsx(wt,{className:t.language===\"es-ES\"?\"font-bold\":\"\",onClick:()=>n(\"es-ES\"),children:e(\"header.language.spanish\")}),i.jsx(wt,{className:t.language===\"fr-FR\"?\"font-bold\":\"\",onClick:()=>n(\"fr-FR\"),children:e(\"header.language.french\")})]})]})}function lM(){const{t:e}=Ve(),{setTheme:t}=tc();return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"outline\",size:\"icon\",children:[i.jsx(EB,{className:\"h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0\"}),i.jsx(bB,{className:\"absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100\"}),i.jsx(\"span\",{className:\"sr-only\",children:e(\"header.theme.label\")})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(wt,{onClick:()=>t(\"light\"),children:e(\"header.theme.light\")}),i.jsx(wt,{onClick:()=>t(\"dark\"),children:e(\"header.theme.dark\")}),i.jsx(wt,{onClick:()=>t(\"system\"),children:e(\"header.theme.system\")})]})]})}var px=\"Avatar\",[s5]=us(px),[o5,cM]=s5(px),uM=y.forwardRef((e,t)=>{const{__scopeAvatar:n,...r}=e,[s,o]=y.useState(\"idle\");return i.jsx(o5,{scope:n,imageLoadingStatus:s,onImageLoadingStatusChange:o,children:i.jsx(rt.span,{...r,ref:t})})});uM.displayName=px;var dM=\"AvatarImage\",fM=y.forwardRef((e,t)=>{const{__scopeAvatar:n,src:r,onLoadingStatusChange:s=()=>{},...o}=e,l=cM(dM,n),u=a5(r),d=Rn(f=>{s(f),l.onImageLoadingStatusChange(f)});return Ln(()=>{u!==\"idle\"&&d(u)},[u,d]),u===\"loaded\"?i.jsx(rt.img,{...o,ref:t,src:r}):null});fM.displayName=dM;var pM=\"AvatarFallback\",hM=y.forwardRef((e,t)=>{const{__scopeAvatar:n,delayMs:r,...s}=e,o=cM(pM,n),[l,u]=y.useState(r===void 0);return y.useEffect(()=>{if(r!==void 0){const d=window.setTimeout(()=>u(!0),r);return()=>window.clearTimeout(d)}},[r]),l&&o.imageLoadingStatus!==\"loaded\"?i.jsx(rt.span,{...s,ref:t}):null});hM.displayName=pM;function a5(e){const[t,n]=y.useState(\"idle\");return Ln(()=>{if(!e){n(\"error\");return}let r=!0;const s=new window.Image,o=l=>()=>{r&&n(l)};return n(\"loading\"),s.onload=o(\"loaded\"),s.onerror=o(\"error\"),s.src=e,()=>{r=!1}},[e]),t}var gM=uM,mM=fM,vM=hM;const Ei=y.forwardRef(({className:e,...t},n)=>i.jsx(gM,{ref:n,className:Ie(\"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full\",e),...t}));Ei.displayName=gM.displayName;const ki=y.forwardRef(({className:e,...t},n)=>i.jsx(mM,{ref:n,className:Ie(\"aspect-square h-full w-full\",e),...t}));ki.displayName=mM.displayName;const Up=y.forwardRef(({className:e,...t},n)=>i.jsx(vM,{ref:n,className:Ie(\"flex h-full w-full items-center justify-center rounded-full bg-muted\",e),...t}));Up.displayName=vM.displayName;var hx=\"Dialog\",[yM]=us(hx),[i5,Ps]=yM(hx),bM=e=>{const{__scopeDialog:t,children:n,open:r,defaultOpen:s,onOpenChange:o,modal:l=!0}=e,u=y.useRef(null),d=y.useRef(null),[f=!1,h]=ya({prop:r,defaultProp:s,onChange:o});return i.jsx(i5,{scope:t,triggerRef:u,contentRef:d,contentId:Es(),titleId:Es(),descriptionId:Es(),open:f,onOpenChange:h,onOpenToggle:y.useCallback(()=>h(m=>!m),[h]),modal:l,children:n})};bM.displayName=hx;var xM=\"DialogTrigger\",wM=y.forwardRef((e,t)=>{const{__scopeDialog:n,...r}=e,s=Ps(xM,n),o=Rt(t,s.triggerRef);return i.jsx(rt.button,{type:\"button\",\"aria-haspopup\":\"dialog\",\"aria-expanded\":s.open,\"aria-controls\":s.contentId,\"data-state\":vx(s.open),...r,ref:o,onClick:Ue(e.onClick,s.onOpenToggle)})});wM.displayName=xM;var gx=\"DialogPortal\",[l5,SM]=yM(gx,{forceMount:void 0}),CM=e=>{const{__scopeDialog:t,forceMount:n,children:r,container:s}=e,o=Ps(gx,t);return i.jsx(l5,{scope:t,forceMount:n,children:y.Children.map(r,l=>i.jsx(Mr,{present:n||o.open,children:i.jsx(Ih,{asChild:!0,container:s,children:l})}))})};CM.displayName=gx;var Vp=\"DialogOverlay\",EM=y.forwardRef((e,t)=>{const n=SM(Vp,e.__scopeDialog),{forceMount:r=n.forceMount,...s}=e,o=Ps(Vp,e.__scopeDialog);return o.modal?i.jsx(Mr,{present:r||o.open,children:i.jsx(c5,{...s,ref:t})}):null});EM.displayName=Vp;var c5=y.forwardRef((e,t)=>{const{__scopeDialog:n,...r}=e,s=Ps(Vp,n);return i.jsx(Lh,{as:No,allowPinchZoom:!0,shards:[s.contentRef],children:i.jsx(rt.div,{\"data-state\":vx(s.open),...r,ref:t,style:{pointerEvents:\"auto\",...r.style}})})}),ji=\"DialogContent\",kM=y.forwardRef((e,t)=>{const n=SM(ji,e.__scopeDialog),{forceMount:r=n.forceMount,...s}=e,o=Ps(ji,e.__scopeDialog);return i.jsx(Mr,{present:r||o.open,children:o.modal?i.jsx(u5,{...s,ref:t}):i.jsx(d5,{...s,ref:t})})});kM.displayName=ji;var u5=y.forwardRef((e,t)=>{const n=Ps(ji,e.__scopeDialog),r=y.useRef(null),s=Rt(t,n.contentRef,r);return y.useEffect(()=>{const o=r.current;if(o)return nx(o)},[]),i.jsx(jM,{...e,ref:s,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:Ue(e.onCloseAutoFocus,o=>{o.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:Ue(e.onPointerDownOutside,o=>{const l=o.detail.originalEvent,u=l.button===0&&l.ctrlKey===!0;(l.button===2||u)&&o.preventDefault()}),onFocusOutside:Ue(e.onFocusOutside,o=>o.preventDefault())})}),d5=y.forwardRef((e,t)=>{const n=Ps(ji,e.__scopeDialog),r=y.useRef(!1),s=y.useRef(!1);return i.jsx(jM,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:o=>{e.onCloseAutoFocus?.(o),o.defaultPrevented||(r.current||n.triggerRef.current?.focus(),o.preventDefault()),r.current=!1,s.current=!1},onInteractOutside:o=>{e.onInteractOutside?.(o),o.defaultPrevented||(r.current=!0,o.detail.originalEvent.type===\"pointerdown\"&&(s.current=!0));const l=o.target;n.triggerRef.current?.contains(l)&&o.preventDefault(),o.detail.originalEvent.type===\"focusin\"&&s.current&&o.preventDefault()}})}),jM=y.forwardRef((e,t)=>{const{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:s,onCloseAutoFocus:o,...l}=e,u=Ps(ji,n),d=y.useRef(null),f=Rt(t,d);return Wb(),i.jsxs(i.Fragment,{children:[i.jsx(_h,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:s,onUnmountAutoFocus:o,children:i.jsx(Mh,{role:\"dialog\",id:u.contentId,\"aria-describedby\":u.descriptionId,\"aria-labelledby\":u.titleId,\"data-state\":vx(u.open),...l,ref:f,onDismiss:()=>u.onOpenChange(!1)})}),i.jsxs(i.Fragment,{children:[i.jsx(f5,{titleId:u.titleId}),i.jsx(h5,{contentRef:d,descriptionId:u.descriptionId})]})]})}),mx=\"DialogTitle\",TM=y.forwardRef((e,t)=>{const{__scopeDialog:n,...r}=e,s=Ps(mx,n);return i.jsx(rt.h2,{id:s.titleId,...r,ref:t})});TM.displayName=mx;var NM=\"DialogDescription\",MM=y.forwardRef((e,t)=>{const{__scopeDialog:n,...r}=e,s=Ps(NM,n);return i.jsx(rt.p,{id:s.descriptionId,...r,ref:t})});MM.displayName=NM;var _M=\"DialogClose\",RM=y.forwardRef((e,t)=>{const{__scopeDialog:n,...r}=e,s=Ps(_M,n);return i.jsx(rt.button,{type:\"button\",...r,ref:t,onClick:Ue(e.onClick,()=>s.onOpenChange(!1))})});RM.displayName=_M;function vx(e){return e?\"open\":\"closed\"}var PM=\"DialogTitleWarning\",[Sie,OM]=_B(PM,{contentName:ji,titleName:mx,docsSlug:\"dialog\"}),f5=({titleId:e})=>{const t=OM(PM),n=`\\`${t.contentName}\\` requires a \\`${t.titleName}\\` for the component to be accessible for screen reader users.\n\nIf you want to hide the \\`${t.titleName}\\`, you can wrap it with our VisuallyHidden component.\n\nFor more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return y.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},p5=\"DialogDescriptionWarning\",h5=({contentRef:e,descriptionId:t})=>{const r=`Warning: Missing \\`Description\\` or \\`aria-describedby={undefined}\\` for {${OM(p5).contentName}}.`;return y.useEffect(()=>{const s=e.current?.getAttribute(\"aria-describedby\");t&&s&&(document.getElementById(t)||console.warn(r))},[r,e,t]),null},g5=bM,m5=wM,v5=CM,IM=EM,AM=kM,DM=TM,FM=MM,LM=RM;const Pt=g5,Bt=m5,y5=v5,$M=LM,BM=y.forwardRef(({className:e,...t},n)=>i.jsx(IM,{ref:n,className:Ie(\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",e),...t}));BM.displayName=IM.displayName;const Nt=y.forwardRef(({className:e,children:t,closeBtn:n=!0,...r},s)=>i.jsx(y5,{children:i.jsx(BM,{className:\"fixed inset-0 grid place-items-center overflow-y-auto\",children:i.jsxs(AM,{ref:s,className:Ie(\"relative z-50 grid w-full max-w-lg gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:m-4 sm:rounded-lg md:w-full\",e),...r,children:[t,n&&i.jsxs(LM,{className:\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\",children:[i.jsx(qb,{className:\"h-4 w-4\"}),i.jsx(\"span\",{className:\"sr-only\",children:\"Close\"})]})]})})}));Nt.displayName=AM.displayName;const Mt=({className:e,...t})=>i.jsx(\"div\",{className:Ie(\"flex flex-col space-y-1.5 text-center sm:text-left\",e),...t});Mt.displayName=\"DialogHeader\";const Yt=({className:e,...t})=>i.jsx(\"div\",{className:Ie(\"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",e),...t});Yt.displayName=\"DialogFooter\";const zt=y.forwardRef(({className:e,...t},n)=>i.jsx(DM,{ref:n,className:Ie(\"text-lg font-semibold leading-none tracking-tight\",e),...t}));zt.displayName=DM.displayName;const eo=y.forwardRef(({className:e,...t},n)=>i.jsx(FM,{ref:n,className:Ie(\"text-sm text-muted-foreground\",e),...t}));eo.displayName=FM.displayName;function zM({instanceId:e}){const[t,n]=y.useState(!1),r=dn(),{theme:s}=tc(),o=()=>{Pj(),r(\"/manager/login\")},l=()=>{r(\"/manager/\")},{data:u}=vT({instanceId:e});return i.jsxs(\"header\",{className:\"flex items-center justify-between px-4 py-2\",children:[i.jsx(Fu,{to:\"/manager\",onClick:l,className:\"flex h-8 items-center gap-4\",children:i.jsx(\"img\",{src:s===\"dark\"?\"https://evolution-api.com/files/evo/evolution-logo-white.svg\":\"https://evolution-api.com/files/evo/evolution-logo.svg\",alt:\"Logo\",className:\"h-full\"})}),i.jsxs(\"div\",{className:\"flex items-center gap-4\",children:[e&&i.jsx(Ei,{className:\"h-8 w-8\",children:i.jsx(ki,{src:u?.profilePicUrl||\"/assets/images/evolution-logo.png\",alt:u?.name})}),i.jsx(iM,{}),i.jsx(lM,{}),i.jsx(se,{onClick:()=>n(!0),variant:\"destructive\",size:\"icon\",children:i.jsx(eB,{size:\"18\"})})]}),t&&i.jsx(Pt,{onOpenChange:n,open:t,children:i.jsxs(Nt,{children:[i.jsx($M,{}),i.jsx(Mt,{children:\"Deseja realmente sair?\"}),i.jsx(Yt,{children:i.jsxs(\"div\",{className:\"flex items-center gap-4\",children:[i.jsx(se,{onClick:()=>n(!1),size:\"sm\",variant:\"outline\",children:\"Cancelar\"}),i.jsx(se,{onClick:o,variant:\"destructive\",children:\"Sair\"})]})})]})})]})}const UM=y.createContext(null),ct=()=>{const e=y.useContext(UM);if(!e)throw new Error(\"useInstance must be used within an InstanceProvider\");return e},VM=({children:e})=>{const t=ls(),[n,r]=y.useState(null),{data:s,refetch:o}=vT({instanceId:n});return y.useEffect(()=>{t.instanceId?r(t.instanceId):r(null)},[t]),i.jsx(UM.Provider,{value:{instance:s??null,reloadInstance:async()=>{await o()}},children:e})};var yx=\"Collapsible\",[b5]=us(yx),[x5,bx]=b5(yx),HM=y.forwardRef((e,t)=>{const{__scopeCollapsible:n,open:r,defaultOpen:s,disabled:o,onOpenChange:l,...u}=e,[d=!1,f]=ya({prop:r,defaultProp:s,onChange:l});return i.jsx(x5,{scope:n,disabled:o,contentId:Es(),open:d,onOpenToggle:y.useCallback(()=>f(h=>!h),[f]),children:i.jsx(rt.div,{\"data-state\":wx(d),\"data-disabled\":o?\"\":void 0,...u,ref:t})})});HM.displayName=yx;var qM=\"CollapsibleTrigger\",KM=y.forwardRef((e,t)=>{const{__scopeCollapsible:n,...r}=e,s=bx(qM,n);return i.jsx(rt.button,{type:\"button\",\"aria-controls\":s.contentId,\"aria-expanded\":s.open||!1,\"data-state\":wx(s.open),\"data-disabled\":s.disabled?\"\":void 0,disabled:s.disabled,...r,ref:t,onClick:Ue(e.onClick,s.onOpenToggle)})});KM.displayName=qM;var xx=\"CollapsibleContent\",WM=y.forwardRef((e,t)=>{const{forceMount:n,...r}=e,s=bx(xx,e.__scopeCollapsible);return i.jsx(Mr,{present:n||s.open,children:({present:o})=>i.jsx(w5,{...r,ref:t,present:o})})});WM.displayName=xx;var w5=y.forwardRef((e,t)=>{const{__scopeCollapsible:n,present:r,children:s,...o}=e,l=bx(xx,n),[u,d]=y.useState(r),f=y.useRef(null),h=Rt(t,f),m=y.useRef(0),g=m.current,x=y.useRef(0),b=x.current,w=l.open||u,C=y.useRef(w),k=y.useRef();return y.useEffect(()=>{const j=requestAnimationFrame(()=>C.current=!1);return()=>cancelAnimationFrame(j)},[]),Ln(()=>{const j=f.current;if(j){k.current=k.current||{transitionDuration:j.style.transitionDuration,animationName:j.style.animationName},j.style.transitionDuration=\"0s\",j.style.animationName=\"none\";const M=j.getBoundingClientRect();m.current=M.height,x.current=M.width,C.current||(j.style.transitionDuration=k.current.transitionDuration,j.style.animationName=k.current.animationName),d(r)}},[l.open,r]),i.jsx(rt.div,{\"data-state\":wx(l.open),\"data-disabled\":l.disabled?\"\":void 0,id:l.contentId,hidden:!w,...o,ref:h,style:{\"--radix-collapsible-content-height\":g?`${g}px`:void 0,\"--radix-collapsible-content-width\":b?`${b}px`:void 0,...e.style},children:w&&s})});function wx(e){return e?\"open\":\"closed\"}var S5=HM;const C5=S5,E5=KM,k5=WM;function j5(){const{t:e}=Ve(),t=y.useMemo(()=>[{id:\"dashboard\",title:e(\"sidebar.dashboard\"),icon:pB,path:\"dashboard\"},{id:\"chat\",title:e(\"sidebar.chat\"),icon:Bl,path:\"chat\"},{navLabel:!0,title:e(\"sidebar.configurations\"),icon:Oo,children:[{id:\"settings\",title:e(\"sidebar.settings\"),path:\"settings\"},{id:\"proxy\",title:e(\"sidebar.proxy\"),path:\"proxy\"}]},{title:e(\"sidebar.events\"),icon:dB,children:[{id:\"webhook\",title:e(\"sidebar.webhook\"),path:\"webhook\"},{id:\"websocket\",title:e(\"sidebar.websocket\"),path:\"websocket\"},{id:\"rabbitmq\",title:e(\"sidebar.rabbitmq\"),path:\"rabbitmq\"},{id:\"sqs\",title:e(\"sidebar.sqs\"),path:\"sqs\"}]},{title:e(\"sidebar.integrations\"),icon:mT,children:[{id:\"evoai\",title:e(\"sidebar.evoai\"),path:\"evoai\"},{id:\"n8n\",title:e(\"sidebar.n8n\"),path:\"n8n\"},{id:\"evolutionBot\",title:e(\"sidebar.evolutionBot\"),path:\"evolutionBot\"},{id:\"chatwoot\",title:e(\"sidebar.chatwoot\"),path:\"chatwoot\"},{id:\"typebot\",title:e(\"sidebar.typebot\"),path:\"typebot\"},{id:\"openai\",title:e(\"sidebar.openai\"),path:\"openai\"},{id:\"dify\",title:e(\"sidebar.dify\"),path:\"dify\"},{id:\"flowise\",title:e(\"sidebar.flowise\"),path:\"flowise\"}]},{id:\"documentation\",title:e(\"sidebar.documentation\"),icon:sB,link:\"https://doc.evolution-api.com\",divider:!0},{id:\"postman\",title:e(\"sidebar.postman\"),icon:Q$,link:\"https://evolution-api.com/postman\"},{id:\"discord\",title:e(\"sidebar.discord\"),icon:Bl,link:\"https://evolution-api.com/discord\"},{id:\"support-premium\",title:e(\"sidebar.supportPremium\"),icon:hB,link:\"https://evolution-api.com/suporte-pro\"}],[e]),n=dn(),{pathname:r}=Pi(),{instance:s}=ct(),o=u=>{!u||!s||(u.path&&n(`/manager/instance/${s.id}/${u.path}`),u.link&&window.open(u.link,\"_blank\"))},l=y.useMemo(()=>t.map(u=>({...u,children:\"children\"in u?u.children?.map(d=>({...d,isActive:\"path\"in d?r.includes(d.path):!1})):void 0,isActive:\"path\"in u&&u.path?r.includes(u.path):!1})).map(u=>({...u,isActive:u.isActive||\"children\"in u&&u.children?.some(d=>d.isActive)})),[t,r]);return i.jsx(\"ul\",{className:\"flex h-full w-full flex-col gap-2 border-r border-border px-2\",children:l.map(u=>i.jsx(\"li\",{className:\"divider\"in u?\"mt-auto\":void 0,children:u.children?i.jsxs(C5,{defaultOpen:u.isActive,children:[i.jsx(E5,{asChild:!0,children:i.jsxs(se,{className:Ie(\"flex w-full items-center justify-start gap-2\"),variant:u.isActive?\"secondary\":\"link\",children:[u.icon&&i.jsx(u.icon,{size:\"15\"}),i.jsx(\"span\",{children:u.title}),i.jsx(Nh,{size:\"15\",className:\"ml-auto\"})]})}),i.jsx(k5,{children:i.jsx(\"ul\",{className:\"my-4 ml-6 flex flex-col gap-2 text-sm\",children:u.children.map(d=>i.jsx(\"li\",{children:i.jsx(\"button\",{onClick:()=>o(d),className:Ie(d.isActive?\"text-foreground\":\"text-muted-foreground\"),children:i.jsx(\"span\",{className:\"nav-label\",children:d.title})})},d.id))})})]}):i.jsxs(se,{className:Ie(\"relative flex w-full items-center justify-start gap-2\",u.isActive&&\"pointer-events-none\"),variant:u.isActive?\"secondary\":\"link\",children:[\"link\"in u&&i.jsx(\"a\",{href:u.link,target:\"_blank\",rel:\"noreferrer\",className:\"absolute inset-0 h-full w-full\"}),\"path\"in u&&i.jsx(Fu,{to:`/manager/instance/${s?.id}/${u.path}`,className:\"absolute inset-0 h-full w-full\"}),u.icon&&i.jsx(u.icon,{size:\"15\"}),i.jsx(\"span\",{children:u.title})]})},u.title))})}function Ky(e,[t,n]){return Math.min(n,Math.max(t,e))}function T5(e,t){return y.useReducer((n,r)=>t[n][r]??n,e)}var Sx=\"ScrollArea\",[GM]=us(Sx),[N5,ds]=GM(Sx),JM=y.forwardRef((e,t)=>{const{__scopeScrollArea:n,type:r=\"hover\",dir:s,scrollHideDelay:o=600,...l}=e,[u,d]=y.useState(null),[f,h]=y.useState(null),[m,g]=y.useState(null),[x,b]=y.useState(null),[w,C]=y.useState(null),[k,j]=y.useState(0),[M,_]=y.useState(0),[R,N]=y.useState(!1),[O,D]=y.useState(!1),z=Rt(t,pe=>d(pe)),Q=xd(s);return i.jsx(N5,{scope:n,type:r,dir:Q,scrollHideDelay:o,scrollArea:u,viewport:f,onViewportChange:h,content:m,onContentChange:g,scrollbarX:x,onScrollbarXChange:b,scrollbarXEnabled:R,onScrollbarXEnabledChange:N,scrollbarY:w,onScrollbarYChange:C,scrollbarYEnabled:O,onScrollbarYEnabledChange:D,onCornerWidthChange:j,onCornerHeightChange:_,children:i.jsx(rt.div,{dir:Q,...l,ref:z,style:{position:\"relative\",\"--radix-scroll-area-corner-width\":k+\"px\",\"--radix-scroll-area-corner-height\":M+\"px\",...e.style}})})});JM.displayName=Sx;var QM=\"ScrollAreaViewport\",ZM=y.forwardRef((e,t)=>{const{__scopeScrollArea:n,children:r,nonce:s,...o}=e,l=ds(QM,n),u=y.useRef(null),d=Rt(t,u,l.onViewportChange);return i.jsxs(i.Fragment,{children:[i.jsx(\"style\",{dangerouslySetInnerHTML:{__html:\"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}\"},nonce:s}),i.jsx(rt.div,{\"data-radix-scroll-area-viewport\":\"\",...o,ref:d,style:{overflowX:l.scrollbarXEnabled?\"scroll\":\"hidden\",overflowY:l.scrollbarYEnabled?\"scroll\":\"hidden\",...e.style},children:i.jsx(\"div\",{ref:l.onContentChange,style:{minWidth:\"100%\",display:\"table\"},children:r})})]})});ZM.displayName=QM;var to=\"ScrollAreaScrollbar\",Cx=y.forwardRef((e,t)=>{const{forceMount:n,...r}=e,s=ds(to,e.__scopeScrollArea),{onScrollbarXEnabledChange:o,onScrollbarYEnabledChange:l}=s,u=e.orientation===\"horizontal\";return y.useEffect(()=>(u?o(!0):l(!0),()=>{u?o(!1):l(!1)}),[u,o,l]),s.type===\"hover\"?i.jsx(M5,{...r,ref:t,forceMount:n}):s.type===\"scroll\"?i.jsx(_5,{...r,ref:t,forceMount:n}):s.type===\"auto\"?i.jsx(YM,{...r,ref:t,forceMount:n}):s.type===\"always\"?i.jsx(Ex,{...r,ref:t}):null});Cx.displayName=to;var M5=y.forwardRef((e,t)=>{const{forceMount:n,...r}=e,s=ds(to,e.__scopeScrollArea),[o,l]=y.useState(!1);return y.useEffect(()=>{const u=s.scrollArea;let d=0;if(u){const f=()=>{window.clearTimeout(d),l(!0)},h=()=>{d=window.setTimeout(()=>l(!1),s.scrollHideDelay)};return u.addEventListener(\"pointerenter\",f),u.addEventListener(\"pointerleave\",h),()=>{window.clearTimeout(d),u.removeEventListener(\"pointerenter\",f),u.removeEventListener(\"pointerleave\",h)}}},[s.scrollArea,s.scrollHideDelay]),i.jsx(Mr,{present:n||o,children:i.jsx(YM,{\"data-state\":o?\"visible\":\"hidden\",...r,ref:t})})}),_5=y.forwardRef((e,t)=>{const{forceMount:n,...r}=e,s=ds(to,e.__scopeScrollArea),o=e.orientation===\"horizontal\",l=Uh(()=>d(\"SCROLL_END\"),100),[u,d]=T5(\"hidden\",{hidden:{SCROLL:\"scrolling\"},scrolling:{SCROLL_END:\"idle\",POINTER_ENTER:\"interacting\"},interacting:{SCROLL:\"interacting\",POINTER_LEAVE:\"idle\"},idle:{HIDE:\"hidden\",SCROLL:\"scrolling\",POINTER_ENTER:\"interacting\"}});return y.useEffect(()=>{if(u===\"idle\"){const f=window.setTimeout(()=>d(\"HIDE\"),s.scrollHideDelay);return()=>window.clearTimeout(f)}},[u,s.scrollHideDelay,d]),y.useEffect(()=>{const f=s.viewport,h=o?\"scrollLeft\":\"scrollTop\";if(f){let m=f[h];const g=()=>{const x=f[h];m!==x&&(d(\"SCROLL\"),l()),m=x};return f.addEventListener(\"scroll\",g),()=>f.removeEventListener(\"scroll\",g)}},[s.viewport,o,d,l]),i.jsx(Mr,{present:n||u!==\"hidden\",children:i.jsx(Ex,{\"data-state\":u===\"hidden\"?\"hidden\":\"visible\",...r,ref:t,onPointerEnter:Ue(e.onPointerEnter,()=>d(\"POINTER_ENTER\")),onPointerLeave:Ue(e.onPointerLeave,()=>d(\"POINTER_LEAVE\"))})})}),YM=y.forwardRef((e,t)=>{const n=ds(to,e.__scopeScrollArea),{forceMount:r,...s}=e,[o,l]=y.useState(!1),u=e.orientation===\"horizontal\",d=Uh(()=>{if(n.viewport){const f=n.viewport.offsetWidth<n.viewport.scrollWidth,h=n.viewport.offsetHeight<n.viewport.scrollHeight;l(u?f:h)}},10);return Ul(n.viewport,d),Ul(n.content,d),i.jsx(Mr,{present:r||o,children:i.jsx(Ex,{\"data-state\":o?\"visible\":\"hidden\",...s,ref:t})})}),Ex=y.forwardRef((e,t)=>{const{orientation:n=\"vertical\",...r}=e,s=ds(to,e.__scopeScrollArea),o=y.useRef(null),l=y.useRef(0),[u,d]=y.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),f=r_(u.viewport,u.content),h={...r,sizes:u,onSizesChange:d,hasThumb:f>0&&f<1,onThumbChange:g=>o.current=g,onThumbPointerUp:()=>l.current=0,onThumbPointerDown:g=>l.current=g};function m(g,x){return D5(g,l.current,u,x)}return n===\"horizontal\"?i.jsx(R5,{...h,ref:t,onThumbPositionChange:()=>{if(s.viewport&&o.current){const g=s.viewport.scrollLeft,x=p1(g,u,s.dir);o.current.style.transform=`translate3d(${x}px, 0, 0)`}},onWheelScroll:g=>{s.viewport&&(s.viewport.scrollLeft=g)},onDragScroll:g=>{s.viewport&&(s.viewport.scrollLeft=m(g,s.dir))}}):n===\"vertical\"?i.jsx(P5,{...h,ref:t,onThumbPositionChange:()=>{if(s.viewport&&o.current){const g=s.viewport.scrollTop,x=p1(g,u);o.current.style.transform=`translate3d(0, ${x}px, 0)`}},onWheelScroll:g=>{s.viewport&&(s.viewport.scrollTop=g)},onDragScroll:g=>{s.viewport&&(s.viewport.scrollTop=m(g))}}):null}),R5=y.forwardRef((e,t)=>{const{sizes:n,onSizesChange:r,...s}=e,o=ds(to,e.__scopeScrollArea),[l,u]=y.useState(),d=y.useRef(null),f=Rt(t,d,o.onScrollbarXChange);return y.useEffect(()=>{d.current&&u(getComputedStyle(d.current))},[d]),i.jsx(e_,{\"data-orientation\":\"horizontal\",...s,ref:f,sizes:n,style:{bottom:0,left:o.dir===\"rtl\"?\"var(--radix-scroll-area-corner-width)\":0,right:o.dir===\"ltr\"?\"var(--radix-scroll-area-corner-width)\":0,\"--radix-scroll-area-thumb-width\":zh(n)+\"px\",...e.style},onThumbPointerDown:h=>e.onThumbPointerDown(h.x),onDragScroll:h=>e.onDragScroll(h.x),onWheelScroll:(h,m)=>{if(o.viewport){const g=o.viewport.scrollLeft+h.deltaX;e.onWheelScroll(g),o_(g,m)&&h.preventDefault()}},onResize:()=>{d.current&&o.viewport&&l&&r({content:o.viewport.scrollWidth,viewport:o.viewport.offsetWidth,scrollbar:{size:d.current.clientWidth,paddingStart:qp(l.paddingLeft),paddingEnd:qp(l.paddingRight)}})}})}),P5=y.forwardRef((e,t)=>{const{sizes:n,onSizesChange:r,...s}=e,o=ds(to,e.__scopeScrollArea),[l,u]=y.useState(),d=y.useRef(null),f=Rt(t,d,o.onScrollbarYChange);return y.useEffect(()=>{d.current&&u(getComputedStyle(d.current))},[d]),i.jsx(e_,{\"data-orientation\":\"vertical\",...s,ref:f,sizes:n,style:{top:0,right:o.dir===\"ltr\"?0:void 0,left:o.dir===\"rtl\"?0:void 0,bottom:\"var(--radix-scroll-area-corner-height)\",\"--radix-scroll-area-thumb-height\":zh(n)+\"px\",...e.style},onThumbPointerDown:h=>e.onThumbPointerDown(h.y),onDragScroll:h=>e.onDragScroll(h.y),onWheelScroll:(h,m)=>{if(o.viewport){const g=o.viewport.scrollTop+h.deltaY;e.onWheelScroll(g),o_(g,m)&&h.preventDefault()}},onResize:()=>{d.current&&o.viewport&&l&&r({content:o.viewport.scrollHeight,viewport:o.viewport.offsetHeight,scrollbar:{size:d.current.clientHeight,paddingStart:qp(l.paddingTop),paddingEnd:qp(l.paddingBottom)}})}})}),[O5,XM]=GM(to),e_=y.forwardRef((e,t)=>{const{__scopeScrollArea:n,sizes:r,hasThumb:s,onThumbChange:o,onThumbPointerUp:l,onThumbPointerDown:u,onThumbPositionChange:d,onDragScroll:f,onWheelScroll:h,onResize:m,...g}=e,x=ds(to,n),[b,w]=y.useState(null),C=Rt(t,z=>w(z)),k=y.useRef(null),j=y.useRef(\"\"),M=x.viewport,_=r.content-r.viewport,R=Rn(h),N=Rn(d),O=Uh(m,10);function D(z){if(k.current){const Q=z.clientX-k.current.left,pe=z.clientY-k.current.top;f({x:Q,y:pe})}}return y.useEffect(()=>{const z=Q=>{const pe=Q.target;b?.contains(pe)&&R(Q,_)};return document.addEventListener(\"wheel\",z,{passive:!1}),()=>document.removeEventListener(\"wheel\",z,{passive:!1})},[M,b,_,R]),y.useEffect(N,[r,N]),Ul(b,O),Ul(x.content,O),i.jsx(O5,{scope:n,scrollbar:b,hasThumb:s,onThumbChange:Rn(o),onThumbPointerUp:Rn(l),onThumbPositionChange:N,onThumbPointerDown:Rn(u),children:i.jsx(rt.div,{...g,ref:C,style:{position:\"absolute\",...g.style},onPointerDown:Ue(e.onPointerDown,z=>{z.button===0&&(z.target.setPointerCapture(z.pointerId),k.current=b.getBoundingClientRect(),j.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect=\"none\",x.viewport&&(x.viewport.style.scrollBehavior=\"auto\"),D(z))}),onPointerMove:Ue(e.onPointerMove,D),onPointerUp:Ue(e.onPointerUp,z=>{const Q=z.target;Q.hasPointerCapture(z.pointerId)&&Q.releasePointerCapture(z.pointerId),document.body.style.webkitUserSelect=j.current,x.viewport&&(x.viewport.style.scrollBehavior=\"\"),k.current=null})})})}),Hp=\"ScrollAreaThumb\",t_=y.forwardRef((e,t)=>{const{forceMount:n,...r}=e,s=XM(Hp,e.__scopeScrollArea);return i.jsx(Mr,{present:n||s.hasThumb,children:i.jsx(I5,{ref:t,...r})})}),I5=y.forwardRef((e,t)=>{const{__scopeScrollArea:n,style:r,...s}=e,o=ds(Hp,n),l=XM(Hp,n),{onThumbPositionChange:u}=l,d=Rt(t,m=>l.onThumbChange(m)),f=y.useRef(),h=Uh(()=>{f.current&&(f.current(),f.current=void 0)},100);return y.useEffect(()=>{const m=o.viewport;if(m){const g=()=>{if(h(),!f.current){const x=F5(m,u);f.current=x,u()}};return u(),m.addEventListener(\"scroll\",g),()=>m.removeEventListener(\"scroll\",g)}},[o.viewport,h,u]),i.jsx(rt.div,{\"data-state\":l.hasThumb?\"visible\":\"hidden\",...s,ref:d,style:{width:\"var(--radix-scroll-area-thumb-width)\",height:\"var(--radix-scroll-area-thumb-height)\",...r},onPointerDownCapture:Ue(e.onPointerDownCapture,m=>{const x=m.target.getBoundingClientRect(),b=m.clientX-x.left,w=m.clientY-x.top;l.onThumbPointerDown({x:b,y:w})}),onPointerUp:Ue(e.onPointerUp,l.onThumbPointerUp)})});t_.displayName=Hp;var kx=\"ScrollAreaCorner\",n_=y.forwardRef((e,t)=>{const n=ds(kx,e.__scopeScrollArea),r=!!(n.scrollbarX&&n.scrollbarY);return n.type!==\"scroll\"&&r?i.jsx(A5,{...e,ref:t}):null});n_.displayName=kx;var A5=y.forwardRef((e,t)=>{const{__scopeScrollArea:n,...r}=e,s=ds(kx,n),[o,l]=y.useState(0),[u,d]=y.useState(0),f=!!(o&&u);return Ul(s.scrollbarX,()=>{const h=s.scrollbarX?.offsetHeight||0;s.onCornerHeightChange(h),d(h)}),Ul(s.scrollbarY,()=>{const h=s.scrollbarY?.offsetWidth||0;s.onCornerWidthChange(h),l(h)}),f?i.jsx(rt.div,{...r,ref:t,style:{width:o,height:u,position:\"absolute\",right:s.dir===\"ltr\"?0:void 0,left:s.dir===\"rtl\"?0:void 0,bottom:0,...e.style}}):null});function qp(e){return e?parseInt(e,10):0}function r_(e,t){const n=e/t;return isNaN(n)?0:n}function zh(e){const t=r_(e.viewport,e.content),n=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,r=(e.scrollbar.size-n)*t;return Math.max(r,18)}function D5(e,t,n,r=\"ltr\"){const s=zh(n),o=s/2,l=t||o,u=s-l,d=n.scrollbar.paddingStart+l,f=n.scrollbar.size-n.scrollbar.paddingEnd-u,h=n.content-n.viewport,m=r===\"ltr\"?[0,h]:[h*-1,0];return s_([d,f],m)(e)}function p1(e,t,n=\"ltr\"){const r=zh(t),s=t.scrollbar.paddingStart+t.scrollbar.paddingEnd,o=t.scrollbar.size-s,l=t.content-t.viewport,u=o-r,d=n===\"ltr\"?[0,l]:[l*-1,0],f=Ky(e,d);return s_([0,l],[0,u])(f)}function s_(e,t){return n=>{if(e[0]===e[1]||t[0]===t[1])return t[0];const r=(t[1]-t[0])/(e[1]-e[0]);return t[0]+r*(n-e[0])}}function o_(e,t){return e>0&&e<t}var F5=(e,t=()=>{})=>{let n={left:e.scrollLeft,top:e.scrollTop},r=0;return(function s(){const o={left:e.scrollLeft,top:e.scrollTop},l=n.left!==o.left,u=n.top!==o.top;(l||u)&&t(),n=o,r=window.requestAnimationFrame(s)})(),()=>window.cancelAnimationFrame(r)};function Uh(e,t){const n=Rn(e),r=y.useRef(0);return y.useEffect(()=>()=>window.clearTimeout(r.current),[]),y.useCallback(()=>{window.clearTimeout(r.current),r.current=window.setTimeout(n,t)},[n,t])}function Ul(e,t){const n=Rn(t);Ln(()=>{let r=0;if(e){const s=new ResizeObserver(()=>{cancelAnimationFrame(r),r=window.requestAnimationFrame(n)});return s.observe(e),()=>{window.cancelAnimationFrame(r),s.unobserve(e)}}},[e,n])}var a_=JM,L5=ZM,$5=n_;const Wy=y.forwardRef(({className:e,children:t,...n},r)=>i.jsxs(a_,{ref:r,className:Ie(\"relative overflow-hidden\",e),...n,children:[i.jsx(L5,{className:\"h-full w-full rounded-[inherit] [&>div[style]]:!block [&>div[style]]:h-full\",children:t}),i.jsx(i_,{}),i.jsx($5,{})]}));Wy.displayName=a_.displayName;const i_=y.forwardRef(({className:e,orientation:t=\"vertical\",...n},r)=>i.jsx(Cx,{ref:r,orientation:t,className:Ie(\"flex touch-none select-none transition-colors\",t===\"vertical\"&&\"h-full w-2.5 border-l border-l-transparent p-[1px]\",t===\"horizontal\"&&\"h-2.5 border-t border-t-transparent p-[1px]\",e),...n,children:i.jsx(t_,{className:Ie(\"relative rounded-full bg-border\",t===\"vertical\"&&\"flex-1\")})}));i_.displayName=Cx.displayName;function un({children:e}){const{instanceId:t}=ls();return i.jsx(VM,{children:i.jsxs(\"div\",{className:\"flex h-screen flex-col\",children:[i.jsx(zM,{instanceId:t}),i.jsxs(\"div\",{className:\"flex min-h-[calc(100vh_-_56px)] flex-1 flex-col md:flex-row\",children:[i.jsx(Wy,{className:\"mr-2 py-6 md:w-64\",children:i.jsx(\"div\",{className:\"flex h-full\",children:i.jsx(j5,{})})}),i.jsx(Wy,{className:\"w-full\",children:i.jsxs(\"div\",{className:\"flex h-full flex-col\",children:[i.jsx(\"div\",{className:\"my-2 flex flex-1 flex-col gap-2 pl-2 pr-4\",children:e}),i.jsx(Vb,{})]})})]})]})})}function B5({children:e}){return i.jsxs(\"div\",{className:\"flex h-full min-h-screen flex-col\",children:[i.jsx(zM,{}),i.jsx(\"main\",{className:\"flex-1\",children:e}),i.jsx(Vb,{})]})}const z5=jh(\"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",{variants:{variant:{default:\"border-transparent bg-primary text-primary-foreground hover:bg-primary/80\",secondary:\"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80\",destructive:\"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80\",outline:\"text-foreground\",warning:\"border-transparent bg-amber-600 text-amber-100 hover:bg-amber-600/80\"}},defaultVariants:{variant:\"default\"}});function vu({className:e,variant:t,...n}){return i.jsx(\"div\",{className:Ie(z5({variant:t}),e),...n})}function l_({status:e}){const{t}=Ve();return e?e===\"open\"?i.jsx(vu,{children:t(\"status.open\")}):e===\"connecting\"?i.jsx(vu,{variant:\"warning\",children:t(\"status.connecting\")}):e===\"close\"||e===\"closed\"?i.jsx(vu,{variant:\"destructive\",children:t(\"status.closed\")}):i.jsx(vu,{variant:\"secondary\",children:e}):null}const U5=e=>{navigator.clipboard.writeText(e),me.success(\"Copiado para a área de transferência\")};function c_({token:e,className:t}){const[n,r]=y.useState(!1);return i.jsxs(\"div\",{className:Ie(\"flex items-center gap-3 truncate rounded-sm bg-primary/20 px-2 py-1\",t),children:[i.jsx(\"pre\",{className:\"block truncate text-xs\",children:n?e:e?.replace(/\\w/g,\"*\")}),i.jsx(se,{variant:\"ghost\",size:\"icon\",onClick:()=>{U5(e)},children:i.jsx(X$,{size:\"15\"})}),i.jsx(se,{variant:\"ghost\",size:\"icon\",onClick:()=>{r(s=>!s)},children:n?i.jsx(tB,{size:\"15\"}):i.jsx(nB,{size:\"15\"})})]})}const So=y.forwardRef(({className:e,...t},n)=>i.jsx(\"div\",{ref:n,className:Ie(\"flex flex-col rounded-lg border bg-card text-card-foreground shadow-sm\",e),...t}));So.displayName=\"Card\";const Co=y.forwardRef(({className:e,...t},n)=>i.jsx(\"div\",{ref:n,className:Ie(\"flex flex-col space-y-1.5 p-6\",e),...t}));Co.displayName=\"CardHeader\";const gi=y.forwardRef(({className:e,...t},n)=>i.jsx(\"h3\",{ref:n,className:Ie(\"text-2xl font-semibold leading-none tracking-tight\",e),...t}));gi.displayName=\"CardTitle\";const Kp=y.forwardRef(({className:e,...t},n)=>i.jsx(\"p\",{ref:n,className:Ie(\"text-sm text-muted-foreground\",e),...t}));Kp.displayName=\"CardDescription\";const Eo=y.forwardRef(({className:e,...t},n)=>i.jsx(\"div\",{ref:n,className:Ie(\"p-6 pt-0\",e),...t}));Eo.displayName=\"CardContent\";const Vh=y.forwardRef(({className:e,...t},n)=>i.jsx(\"div\",{ref:n,className:Ie(\"flex items-center p-6 pt-0\",e),...t}));Vh.displayName=\"CardFooter\";const u_=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",ne=y.forwardRef(({className:e,type:t,...n},r)=>i.jsx(\"input\",{type:t,className:Ie(u_,e),ref:r,...n}));ne.displayName=\"Input\";const V5=[\"instance\",\"fetchInstances\"],H5=async()=>(await bd.get(\"/instance/fetchInstances\")).data,q5=e=>mt({...e,queryKey:V5,queryFn:()=>H5()});function nt(e,t){const n=Ob(),r=cF({mutationFn:e});return(s,o)=>r.mutateAsync(s,{onSuccess:async(l,u,d)=>{t?.invalidateKeys&&await Promise.all(t.invalidateKeys.map(f=>n.invalidateQueries({queryKey:f}))),o?.onSuccess?.(l,u,d)},onError(l,u,d){o?.onError?.(l,u,d)},onSettled(l,u,d,f){o?.onSettled?.(l,u,d,f)}})}const K5=async e=>(await bd.post(\"/instance/create\",e)).data,W5=async e=>(await Ee.post(`/instance/restart/${e}`)).data,G5=async e=>(await Ee.delete(`/instance/logout/${e}`)).data,J5=async e=>(await bd.delete(`/instance/delete/${e}`)).data,Q5=async({instanceName:e,token:t,number:n})=>(await Ee.get(`/instance/connect/${e}`,{headers:{apikey:t},params:{number:n}})).data,Z5=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/settings/set/${e}`,n,{headers:{apikey:t}})).data;function Hh(){const e=nt(Q5,{invalidateKeys:[[\"instance\",\"fetchInstance\"],[\"instance\",\"fetchInstances\"]]}),t=nt(Z5,{invalidateKeys:[[\"instance\",\"fetchSettings\"]]}),n=nt(J5,{invalidateKeys:[[\"instance\",\"fetchInstance\"],[\"instance\",\"fetchInstances\"]]}),r=nt(G5,{invalidateKeys:[[\"instance\",\"fetchInstance\"],[\"instance\",\"fetchInstances\"]]}),s=nt(W5,{invalidateKeys:[[\"instance\",\"fetchInstance\"],[\"instance\",\"fetchInstances\"]]}),o=nt(K5,{invalidateKeys:[[\"instance\",\"fetchInstances\"]]});return{connect:e,updateSettings:t,deleteInstance:n,logout:r,restart:s,createInstance:o}}var Ed=e=>e.type===\"checkbox\",Tl=e=>e instanceof Date,cr=e=>e==null;const d_=e=>typeof e==\"object\";var $n=e=>!cr(e)&&!Array.isArray(e)&&d_(e)&&!Tl(e),f_=e=>$n(e)&&e.target?Ed(e.target)?e.target.checked:e.target.value:e,Y5=e=>e.substring(0,e.search(/\\.\\d+(\\.|$)/))||e,p_=(e,t)=>e.has(Y5(t)),X5=e=>{const t=e.constructor&&e.constructor.prototype;return $n(t)&&t.hasOwnProperty(\"isPrototypeOf\")},jx=typeof window<\"u\"&&typeof window.HTMLElement<\"u\"&&typeof document<\"u\";function Er(e){let t;const n=Array.isArray(e);if(e instanceof Date)t=new Date(e);else if(e instanceof Set)t=new Set(e);else if(!(jx&&(e instanceof Blob||e instanceof FileList))&&(n||$n(e)))if(t=n?[]:{},!n&&!X5(e))t=e;else for(const r in e)e.hasOwnProperty(r)&&(t[r]=Er(e[r]));else return e;return t}var qh=e=>Array.isArray(e)?e.filter(Boolean):[],wn=e=>e===void 0,_e=(e,t,n)=>{if(!t||!$n(e))return n;const r=qh(t.split(/[,[\\].]+?/)).reduce((s,o)=>cr(s)?s:s[o],e);return wn(r)||r===e?wn(e[t])?n:e[t]:r},Us=e=>typeof e==\"boolean\",Tx=e=>/^\\w*$/.test(e),h_=e=>qh(e.replace(/[\"|']|\\]/g,\"\").split(/\\.|\\[/)),qt=(e,t,n)=>{let r=-1;const s=Tx(t)?[t]:h_(t),o=s.length,l=o-1;for(;++r<o;){const u=s[r];let d=n;if(r!==l){const f=e[u];d=$n(f)||Array.isArray(f)?f:isNaN(+s[r+1])?{}:[]}if(u===\"__proto__\")return;e[u]=d,e=e[u]}return e};const Wp={BLUR:\"blur\",FOCUS_OUT:\"focusout\",CHANGE:\"change\"},Ss={onBlur:\"onBlur\",onChange:\"onChange\",onSubmit:\"onSubmit\",onTouched:\"onTouched\",all:\"all\"},go={max:\"max\",min:\"min\",maxLength:\"maxLength\",minLength:\"minLength\",pattern:\"pattern\",required:\"required\",validate:\"validate\"},g_=qe.createContext(null),Kh=()=>qe.useContext(g_),Gn=e=>{const{children:t,...n}=e;return qe.createElement(g_.Provider,{value:n},t)};var m_=(e,t,n,r=!0)=>{const s={defaultValues:t._defaultValues};for(const o in e)Object.defineProperty(s,o,{get:()=>{const l=o;return t._proxyFormState[l]!==Ss.all&&(t._proxyFormState[l]=!r||Ss.all),n&&(n[l]=!0),e[l]}});return s},Lr=e=>$n(e)&&!Object.keys(e).length,v_=(e,t,n,r)=>{n(e);const{name:s,...o}=e;return Lr(o)||Object.keys(o).length>=Object.keys(t).length||Object.keys(o).find(l=>t[l]===(!r||Ss.all))},ju=e=>Array.isArray(e)?e:[e],y_=(e,t,n)=>!e||!t||e===t||ju(e).some(r=>r&&(n?r===t:r.startsWith(t)||t.startsWith(r)));function Nx(e){const t=qe.useRef(e);t.current=e,qe.useEffect(()=>{const n=!e.disabled&&t.current.subject&&t.current.subject.subscribe({next:t.current.next});return()=>{n&&n.unsubscribe()}},[e.disabled])}function e6(e){const t=Kh(),{control:n=t.control,disabled:r,name:s,exact:o}=e||{},[l,u]=qe.useState(n._formState),d=qe.useRef(!0),f=qe.useRef({isDirty:!1,isLoading:!1,dirtyFields:!1,touchedFields:!1,validatingFields:!1,isValidating:!1,isValid:!1,errors:!1}),h=qe.useRef(s);return h.current=s,Nx({disabled:r,next:m=>d.current&&y_(h.current,m.name,o)&&v_(m,f.current,n._updateFormState)&&u({...n._formState,...m}),subject:n._subjects.state}),qe.useEffect(()=>(d.current=!0,f.current.isValid&&n._updateValid(!0),()=>{d.current=!1}),[n]),m_(l,n,f.current,!1)}var qs=e=>typeof e==\"string\",b_=(e,t,n,r,s)=>qs(e)?(r&&t.watch.add(e),_e(n,e,s)):Array.isArray(e)?e.map(o=>(r&&t.watch.add(o),_e(n,o))):(r&&(t.watchAll=!0),n);function t6(e){const t=Kh(),{control:n=t.control,name:r,defaultValue:s,disabled:o,exact:l}=e||{},u=qe.useRef(r);u.current=r,Nx({disabled:o,subject:n._subjects.values,next:h=>{y_(u.current,h.name,l)&&f(Er(b_(u.current,n._names,h.values||n._formValues,!1,s)))}});const[d,f]=qe.useState(n._getWatch(r,s));return qe.useEffect(()=>n._removeUnmounted()),d}function n6(e){const t=Kh(),{name:n,disabled:r,control:s=t.control,shouldUnregister:o}=e,l=p_(s._names.array,n),u=t6({control:s,name:n,defaultValue:_e(s._formValues,n,_e(s._defaultValues,n,e.defaultValue)),exact:!0}),d=e6({control:s,name:n}),f=qe.useRef(s.register(n,{...e.rules,value:u,...Us(e.disabled)?{disabled:e.disabled}:{}}));return qe.useEffect(()=>{const h=s._options.shouldUnregister||o,m=(g,x)=>{const b=_e(s._fields,g);b&&b._f&&(b._f.mount=x)};if(m(n,!0),h){const g=Er(_e(s._options.defaultValues,n));qt(s._defaultValues,n,g),wn(_e(s._formValues,n))&&qt(s._formValues,n,g)}return()=>{(l?h&&!s._state.action:h)?s.unregister(n):m(n,!1)}},[n,s,l,o]),qe.useEffect(()=>{_e(s._fields,n)&&s._updateDisabledField({disabled:r,fields:s._fields,name:n,value:_e(s._fields,n)._f.value})},[r,n,s]),{field:{name:n,value:u,...Us(r)||d.disabled?{disabled:d.disabled||r}:{},onChange:qe.useCallback(h=>f.current.onChange({target:{value:f_(h),name:n},type:Wp.CHANGE}),[n]),onBlur:qe.useCallback(()=>f.current.onBlur({target:{value:_e(s._formValues,n),name:n},type:Wp.BLUR}),[n,s]),ref:h=>{const m=_e(s._fields,n);m&&h&&(m._f.ref={focus:()=>h.focus(),select:()=>h.select(),setCustomValidity:g=>h.setCustomValidity(g),reportValidity:()=>h.reportValidity()})}},formState:d,fieldState:Object.defineProperties({},{invalid:{enumerable:!0,get:()=>!!_e(d.errors,n)},isDirty:{enumerable:!0,get:()=>!!_e(d.dirtyFields,n)},isTouched:{enumerable:!0,get:()=>!!_e(d.touchedFields,n)},isValidating:{enumerable:!0,get:()=>!!_e(d.validatingFields,n)},error:{enumerable:!0,get:()=>_e(d.errors,n)}})}}const r6=e=>e.render(n6(e));var x_=(e,t,n,r,s)=>t?{...n[e],types:{...n[e]&&n[e].types?n[e].types:{},[r]:s||!0}}:{},h1=e=>({isOnSubmit:!e||e===Ss.onSubmit,isOnBlur:e===Ss.onBlur,isOnChange:e===Ss.onChange,isOnAll:e===Ss.all,isOnTouch:e===Ss.onTouched}),g1=(e,t,n)=>!n&&(t.watchAll||t.watch.has(e)||[...t.watch].some(r=>e.startsWith(r)&&/^\\.\\w+/.test(e.slice(r.length))));const Tu=(e,t,n,r)=>{for(const s of n||Object.keys(e)){const o=_e(e,s);if(o){const{_f:l,...u}=o;if(l){if(l.refs&&l.refs[0]&&t(l.refs[0],s)&&!r)break;if(l.ref&&t(l.ref,l.name)&&!r)break;Tu(u,t)}else $n(u)&&Tu(u,t)}}};var s6=(e,t,n)=>{const r=ju(_e(e,n));return qt(r,\"root\",t[n]),qt(e,n,r),e},Mx=e=>e.type===\"file\",ga=e=>typeof e==\"function\",Gp=e=>{if(!jx)return!1;const t=e?e.ownerDocument:0;return e instanceof(t&&t.defaultView?t.defaultView.HTMLElement:HTMLElement)},vp=e=>qs(e),_x=e=>e.type===\"radio\",Jp=e=>e instanceof RegExp;const m1={value:!1,isValid:!1},v1={value:!0,isValid:!0};var w_=e=>{if(Array.isArray(e)){if(e.length>1){const t=e.filter(n=>n&&n.checked&&!n.disabled).map(n=>n.value);return{value:t,isValid:!!t.length}}return e[0].checked&&!e[0].disabled?e[0].attributes&&!wn(e[0].attributes.value)?wn(e[0].value)||e[0].value===\"\"?v1:{value:e[0].value,isValid:!0}:v1:m1}return m1};const y1={isValid:!1,value:null};var S_=e=>Array.isArray(e)?e.reduce((t,n)=>n&&n.checked&&!n.disabled?{isValid:!0,value:n.value}:t,y1):y1;function b1(e,t,n=\"validate\"){if(vp(e)||Array.isArray(e)&&e.every(vp)||Us(e)&&!e)return{type:n,message:vp(e)?e:\"\",ref:t}}var ml=e=>$n(e)&&!Jp(e)?e:{value:e,message:\"\"},x1=async(e,t,n,r,s)=>{const{ref:o,refs:l,required:u,maxLength:d,minLength:f,min:h,max:m,pattern:g,validate:x,name:b,valueAsNumber:w,mount:C,disabled:k}=e._f,j=_e(t,b);if(!C||k)return{};const M=l?l[0]:o,_=V=>{r&&M.reportValidity&&(M.setCustomValidity(Us(V)?\"\":V||\"\"),M.reportValidity())},R={},N=_x(o),O=Ed(o),D=N||O,z=(w||Mx(o))&&wn(o.value)&&wn(j)||Gp(o)&&o.value===\"\"||j===\"\"||Array.isArray(j)&&!j.length,Q=x_.bind(null,b,n,R),pe=(V,G,W,ie=go.maxLength,re=go.minLength)=>{const Y=V?G:W;R[b]={type:V?ie:re,message:Y,ref:o,...Q(V?ie:re,Y)}};if(s?!Array.isArray(j)||!j.length:u&&(!D&&(z||cr(j))||Us(j)&&!j||O&&!w_(l).isValid||N&&!S_(l).isValid)){const{value:V,message:G}=vp(u)?{value:!!u,message:u}:ml(u);if(V&&(R[b]={type:go.required,message:G,ref:M,...Q(go.required,G)},!n))return _(G),R}if(!z&&(!cr(h)||!cr(m))){let V,G;const W=ml(m),ie=ml(h);if(!cr(j)&&!isNaN(j)){const re=o.valueAsNumber||j&&+j;cr(W.value)||(V=re>W.value),cr(ie.value)||(G=re<ie.value)}else{const re=o.valueAsDate||new Date(j),Y=he=>new Date(new Date().toDateString()+\" \"+he),H=o.type==\"time\",q=o.type==\"week\";qs(W.value)&&j&&(V=H?Y(j)>Y(W.value):q?j>W.value:re>new Date(W.value)),qs(ie.value)&&j&&(G=H?Y(j)<Y(ie.value):q?j<ie.value:re<new Date(ie.value))}if((V||G)&&(pe(!!V,W.message,ie.message,go.max,go.min),!n))return _(R[b].message),R}if((d||f)&&!z&&(qs(j)||s&&Array.isArray(j))){const V=ml(d),G=ml(f),W=!cr(V.value)&&j.length>+V.value,ie=!cr(G.value)&&j.length<+G.value;if((W||ie)&&(pe(W,V.message,G.message),!n))return _(R[b].message),R}if(g&&!z&&qs(j)){const{value:V,message:G}=ml(g);if(Jp(V)&&!j.match(V)&&(R[b]={type:go.pattern,message:G,ref:o,...Q(go.pattern,G)},!n))return _(G),R}if(x){if(ga(x)){const V=await x(j,t),G=b1(V,M);if(G&&(R[b]={...G,...Q(go.validate,G.message)},!n))return _(G.message),R}else if($n(x)){let V={};for(const G in x){if(!Lr(V)&&!n)break;const W=b1(await x[G](j,t),M,G);W&&(V={...W,...Q(G,W.message)},_(W.message),n&&(R[b]=V))}if(!Lr(V)&&(R[b]={ref:M,...V},!n))return R}}return _(!0),R};function o6(e,t){const n=t.slice(0,-1).length;let r=0;for(;r<n;)e=wn(e)?r++:e[t[r++]];return e}function a6(e){for(const t in e)if(e.hasOwnProperty(t)&&!wn(e[t]))return!1;return!0}function Dn(e,t){const n=Array.isArray(t)?t:Tx(t)?[t]:h_(t),r=n.length===1?e:o6(e,n),s=n.length-1,o=n[s];return r&&delete r[o],s!==0&&($n(r)&&Lr(r)||Array.isArray(r)&&a6(r))&&Dn(e,n.slice(0,-1)),e}var Mv=()=>{let e=[];return{get observers(){return e},next:s=>{for(const o of e)o.next&&o.next(s)},subscribe:s=>(e.push(s),{unsubscribe:()=>{e=e.filter(o=>o!==s)}}),unsubscribe:()=>{e=[]}}},Qp=e=>cr(e)||!d_(e);function ui(e,t){if(Qp(e)||Qp(t))return e===t;if(Tl(e)&&Tl(t))return e.getTime()===t.getTime();const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(const s of n){const o=e[s];if(!r.includes(s))return!1;if(s!==\"ref\"){const l=t[s];if(Tl(o)&&Tl(l)||$n(o)&&$n(l)||Array.isArray(o)&&Array.isArray(l)?!ui(o,l):o!==l)return!1}}return!0}var C_=e=>e.type===\"select-multiple\",i6=e=>_x(e)||Ed(e),_v=e=>Gp(e)&&e.isConnected,E_=e=>{for(const t in e)if(ga(e[t]))return!0;return!1};function Zp(e,t={}){const n=Array.isArray(e);if($n(e)||n)for(const r in e)Array.isArray(e[r])||$n(e[r])&&!E_(e[r])?(t[r]=Array.isArray(e[r])?[]:{},Zp(e[r],t[r])):cr(e[r])||(t[r]=!0);return t}function k_(e,t,n){const r=Array.isArray(e);if($n(e)||r)for(const s in e)Array.isArray(e[s])||$n(e[s])&&!E_(e[s])?wn(t)||Qp(n[s])?n[s]=Array.isArray(e[s])?Zp(e[s],[]):{...Zp(e[s])}:k_(e[s],cr(t)?{}:t[s],n[s]):n[s]=!ui(e[s],t[s]);return n}var Gf=(e,t)=>k_(e,t,Zp(t)),j_=(e,{valueAsNumber:t,valueAsDate:n,setValueAs:r})=>wn(e)?e:t?e===\"\"?NaN:e&&+e:n&&qs(e)?new Date(e):r?r(e):e;function Rv(e){const t=e.ref;if(!(e.refs?e.refs.every(n=>n.disabled):t.disabled))return Mx(t)?t.files:_x(t)?S_(e.refs).value:C_(t)?[...t.selectedOptions].map(({value:n})=>n):Ed(t)?w_(e.refs).value:j_(wn(t.value)?e.ref.value:t.value,e)}var l6=(e,t,n,r)=>{const s={};for(const o of e){const l=_e(t,o);l&&qt(s,o,l._f)}return{criteriaMode:n,names:[...e],fields:s,shouldUseNativeValidation:r}},au=e=>wn(e)?e:Jp(e)?e.source:$n(e)?Jp(e.value)?e.value.source:e.value:e,c6=e=>e.mount&&(e.required||e.min||e.max||e.maxLength||e.minLength||e.pattern||e.validate);function w1(e,t,n){const r=_e(e,n);if(r||Tx(n))return{error:r,name:n};const s=n.split(\".\");for(;s.length;){const o=s.join(\".\"),l=_e(t,o),u=_e(e,o);if(l&&!Array.isArray(l)&&n!==o)return{name:n};if(u&&u.type)return{name:o,error:u};s.pop()}return{name:n}}var u6=(e,t,n,r,s)=>s.isOnAll?!1:!n&&s.isOnTouch?!(t||e):(n?r.isOnBlur:s.isOnBlur)?!e:(n?r.isOnChange:s.isOnChange)?e:!0,d6=(e,t)=>!qh(_e(e,t)).length&&Dn(e,t);const f6={mode:Ss.onSubmit,reValidateMode:Ss.onChange,shouldFocusError:!0};function p6(e={}){let t={...f6,...e},n={submitCount:0,isDirty:!1,isLoading:ga(t.defaultValues),isValidating:!1,isSubmitted:!1,isSubmitting:!1,isSubmitSuccessful:!1,isValid:!1,touchedFields:{},dirtyFields:{},validatingFields:{},errors:t.errors||{},disabled:t.disabled||!1},r={},s=$n(t.defaultValues)||$n(t.values)?Er(t.defaultValues||t.values)||{}:{},o=t.shouldUnregister?{}:Er(s),l={action:!1,mount:!1,watch:!1},u={mount:new Set,unMount:new Set,array:new Set,watch:new Set},d,f=0;const h={isDirty:!1,dirtyFields:!1,validatingFields:!1,touchedFields:!1,isValidating:!1,isValid:!1,errors:!1},m={values:Mv(),array:Mv(),state:Mv()},g=h1(t.mode),x=h1(t.reValidateMode),b=t.criteriaMode===Ss.all,w=L=>X=>{clearTimeout(f),f=setTimeout(L,X)},C=async L=>{if(h.isValid||L){const X=t.resolver?Lr((await D()).errors):await Q(r,!0);X!==n.isValid&&m.state.next({isValid:X})}},k=(L,X)=>{(h.isValidating||h.validatingFields)&&((L||Array.from(u.mount)).forEach(ue=>{ue&&(X?qt(n.validatingFields,ue,X):Dn(n.validatingFields,ue))}),m.state.next({validatingFields:n.validatingFields,isValidating:!Lr(n.validatingFields)}))},j=(L,X=[],ue,Ne,je=!0,Se=!0)=>{if(Ne&&ue){if(l.action=!0,Se&&Array.isArray(_e(r,L))){const Be=ue(_e(r,L),Ne.argA,Ne.argB);je&&qt(r,L,Be)}if(Se&&Array.isArray(_e(n.errors,L))){const Be=ue(_e(n.errors,L),Ne.argA,Ne.argB);je&&qt(n.errors,L,Be),d6(n.errors,L)}if(h.touchedFields&&Se&&Array.isArray(_e(n.touchedFields,L))){const Be=ue(_e(n.touchedFields,L),Ne.argA,Ne.argB);je&&qt(n.touchedFields,L,Be)}h.dirtyFields&&(n.dirtyFields=Gf(s,o)),m.state.next({name:L,isDirty:V(L,X),dirtyFields:n.dirtyFields,errors:n.errors,isValid:n.isValid})}else qt(o,L,X)},M=(L,X)=>{qt(n.errors,L,X),m.state.next({errors:n.errors})},_=L=>{n.errors=L,m.state.next({errors:n.errors,isValid:!1})},R=(L,X,ue,Ne)=>{const je=_e(r,L);if(je){const Se=_e(o,L,wn(ue)?_e(s,L):ue);wn(Se)||Ne&&Ne.defaultChecked||X?qt(o,L,X?Se:Rv(je._f)):ie(L,Se),l.mount&&C()}},N=(L,X,ue,Ne,je)=>{let Se=!1,Be=!1;const bt={name:L},Wt=!!(_e(r,L)&&_e(r,L)._f&&_e(r,L)._f.disabled);if(!ue||Ne){h.isDirty&&(Be=n.isDirty,n.isDirty=bt.isDirty=V(),Se=Be!==bt.isDirty);const yn=Wt||ui(_e(s,L),X);Be=!!(!Wt&&_e(n.dirtyFields,L)),yn||Wt?Dn(n.dirtyFields,L):qt(n.dirtyFields,L,!0),bt.dirtyFields=n.dirtyFields,Se=Se||h.dirtyFields&&Be!==!yn}if(ue){const yn=_e(n.touchedFields,L);yn||(qt(n.touchedFields,L,ue),bt.touchedFields=n.touchedFields,Se=Se||h.touchedFields&&yn!==ue)}return Se&&je&&m.state.next(bt),Se?bt:{}},O=(L,X,ue,Ne)=>{const je=_e(n.errors,L),Se=h.isValid&&Us(X)&&n.isValid!==X;if(e.delayError&&ue?(d=w(()=>M(L,ue)),d(e.delayError)):(clearTimeout(f),d=null,ue?qt(n.errors,L,ue):Dn(n.errors,L)),(ue?!ui(je,ue):je)||!Lr(Ne)||Se){const Be={...Ne,...Se&&Us(X)?{isValid:X}:{},errors:n.errors,name:L};n={...n,...Be},m.state.next(Be)}},D=async L=>{k(L,!0);const X=await t.resolver(o,t.context,l6(L||u.mount,r,t.criteriaMode,t.shouldUseNativeValidation));return k(L),X},z=async L=>{const{errors:X}=await D(L);if(L)for(const ue of L){const Ne=_e(X,ue);Ne?qt(n.errors,ue,Ne):Dn(n.errors,ue)}else n.errors=X;return X},Q=async(L,X,ue={valid:!0})=>{for(const Ne in L){const je=L[Ne];if(je){const{_f:Se,...Be}=je;if(Se){const bt=u.array.has(Se.name);k([Ne],!0);const Wt=await x1(je,o,b,t.shouldUseNativeValidation&&!X,bt);if(k([Ne]),Wt[Se.name]&&(ue.valid=!1,X))break;!X&&(_e(Wt,Se.name)?bt?s6(n.errors,Wt,Se.name):qt(n.errors,Se.name,Wt[Se.name]):Dn(n.errors,Se.name))}Be&&await Q(Be,X,ue)}}return ue.valid},pe=()=>{for(const L of u.unMount){const X=_e(r,L);X&&(X._f.refs?X._f.refs.every(ue=>!_v(ue)):!_v(X._f.ref))&&ge(L)}u.unMount=new Set},V=(L,X)=>(L&&X&&qt(o,L,X),!ui(A(),s)),G=(L,X,ue)=>b_(L,u,{...l.mount?o:wn(X)?s:qs(L)?{[L]:X}:X},ue,X),W=L=>qh(_e(l.mount?o:s,L,e.shouldUnregister?_e(s,L,[]):[])),ie=(L,X,ue={})=>{const Ne=_e(r,L);let je=X;if(Ne){const Se=Ne._f;Se&&(!Se.disabled&&qt(o,L,j_(X,Se)),je=Gp(Se.ref)&&cr(X)?\"\":X,C_(Se.ref)?[...Se.ref.options].forEach(Be=>Be.selected=je.includes(Be.value)):Se.refs?Ed(Se.ref)?Se.refs.length>1?Se.refs.forEach(Be=>(!Be.defaultChecked||!Be.disabled)&&(Be.checked=Array.isArray(je)?!!je.find(bt=>bt===Be.value):je===Be.value)):Se.refs[0]&&(Se.refs[0].checked=!!je):Se.refs.forEach(Be=>Be.checked=Be.value===je):Mx(Se.ref)?Se.ref.value=\"\":(Se.ref.value=je,Se.ref.type||m.values.next({name:L,values:{...o}})))}(ue.shouldDirty||ue.shouldTouch)&&N(L,je,ue.shouldTouch,ue.shouldDirty,!0),ue.shouldValidate&&he(L)},re=(L,X,ue)=>{for(const Ne in X){const je=X[Ne],Se=`${L}.${Ne}`,Be=_e(r,Se);(u.array.has(L)||!Qp(je)||Be&&!Be._f)&&!Tl(je)?re(Se,je,ue):ie(Se,je,ue)}},Y=(L,X,ue={})=>{const Ne=_e(r,L),je=u.array.has(L),Se=Er(X);qt(o,L,Se),je?(m.array.next({name:L,values:{...o}}),(h.isDirty||h.dirtyFields)&&ue.shouldDirty&&m.state.next({name:L,dirtyFields:Gf(s,o),isDirty:V(L,Se)})):Ne&&!Ne._f&&!cr(Se)?re(L,Se,ue):ie(L,Se,ue),g1(L,u)&&m.state.next({...n}),m.values.next({name:l.mount?L:void 0,values:{...o}})},H=async L=>{l.mount=!0;const X=L.target;let ue=X.name,Ne=!0;const je=_e(r,ue),Se=()=>X.type?Rv(je._f):f_(L),Be=bt=>{Ne=Number.isNaN(bt)||bt===_e(o,ue,bt)};if(je){let bt,Wt;const yn=Se(),bn=L.type===Wp.BLUR||L.type===Wp.FOCUS_OUT,En=!c6(je._f)&&!t.resolver&&!_e(n.errors,ue)&&!je._f.deps||u6(bn,_e(n.touchedFields,ue),n.isSubmitted,x,g),gr=g1(ue,u,bn);qt(o,ue,yn),bn?(je._f.onBlur&&je._f.onBlur(L),d&&d(0)):je._f.onChange&&je._f.onChange(L);const Qn=N(ue,yn,bn,!1),ro=!Lr(Qn)||gr;if(!bn&&m.values.next({name:ue,type:L.type,values:{...o}}),En)return h.isValid&&C(),ro&&m.state.next({name:ue,...gr?{}:Qn});if(!bn&&gr&&m.state.next({...n}),t.resolver){const{errors:Bn}=await D([ue]);if(Be(yn),Ne){const Te=w1(n.errors,r,ue),ut=w1(Bn,r,Te.name||ue);bt=ut.error,ue=ut.name,Wt=Lr(Bn)}}else k([ue],!0),bt=(await x1(je,o,b,t.shouldUseNativeValidation))[ue],k([ue]),Be(yn),Ne&&(bt?Wt=!1:h.isValid&&(Wt=await Q(r,!0)));Ne&&(je._f.deps&&he(je._f.deps),O(ue,Wt,bt,Qn))}},q=(L,X)=>{if(_e(n.errors,X)&&L.focus)return L.focus(),1},he=async(L,X={})=>{let ue,Ne;const je=ju(L);if(t.resolver){const Se=await z(wn(L)?L:je);ue=Lr(Se),Ne=L?!je.some(Be=>_e(Se,Be)):ue}else L?(Ne=(await Promise.all(je.map(async Se=>{const Be=_e(r,Se);return await Q(Be&&Be._f?{[Se]:Be}:Be)}))).every(Boolean),!(!Ne&&!n.isValid)&&C()):Ne=ue=await Q(r);return m.state.next({...!qs(L)||h.isValid&&ue!==n.isValid?{}:{name:L},...t.resolver||!L?{isValid:ue}:{},errors:n.errors}),X.shouldFocus&&!Ne&&Tu(r,q,L?je:u.mount),Ne},A=L=>{const X={...l.mount?o:s};return wn(L)?X:qs(L)?_e(X,L):L.map(ue=>_e(X,ue))},F=(L,X)=>({invalid:!!_e((X||n).errors,L),isDirty:!!_e((X||n).dirtyFields,L),error:_e((X||n).errors,L),isValidating:!!_e(n.validatingFields,L),isTouched:!!_e((X||n).touchedFields,L)}),fe=L=>{L&&ju(L).forEach(X=>Dn(n.errors,X)),m.state.next({errors:L?n.errors:{}})},te=(L,X,ue)=>{const Ne=(_e(r,L,{_f:{}})._f||{}).ref,je=_e(n.errors,L)||{},{ref:Se,message:Be,type:bt,...Wt}=je;qt(n.errors,L,{...Wt,...X,ref:Ne}),m.state.next({name:L,errors:n.errors,isValid:!1}),ue&&ue.shouldFocus&&Ne&&Ne.focus&&Ne.focus()},de=(L,X)=>ga(L)?m.values.subscribe({next:ue=>L(G(void 0,X),ue)}):G(L,X,!0),ge=(L,X={})=>{for(const ue of L?ju(L):u.mount)u.mount.delete(ue),u.array.delete(ue),X.keepValue||(Dn(r,ue),Dn(o,ue)),!X.keepError&&Dn(n.errors,ue),!X.keepDirty&&Dn(n.dirtyFields,ue),!X.keepTouched&&Dn(n.touchedFields,ue),!X.keepIsValidating&&Dn(n.validatingFields,ue),!t.shouldUnregister&&!X.keepDefaultValue&&Dn(s,ue);m.values.next({values:{...o}}),m.state.next({...n,...X.keepDirty?{isDirty:V()}:{}}),!X.keepIsValid&&C()},Z=({disabled:L,name:X,field:ue,fields:Ne,value:je})=>{if(Us(L)&&l.mount||L){const Se=L?void 0:wn(je)?Rv(ue?ue._f:_e(Ne,X)._f):je;qt(o,X,Se),N(X,Se,!1,!1,!0)}},ye=(L,X={})=>{let ue=_e(r,L);const Ne=Us(X.disabled);return qt(r,L,{...ue||{},_f:{...ue&&ue._f?ue._f:{ref:{name:L}},name:L,mount:!0,...X}}),u.mount.add(L),ue?Z({field:ue,disabled:X.disabled,name:L,value:X.value}):R(L,!0,X.value),{...Ne?{disabled:X.disabled}:{},...t.progressive?{required:!!X.required,min:au(X.min),max:au(X.max),minLength:au(X.minLength),maxLength:au(X.maxLength),pattern:au(X.pattern)}:{},name:L,onChange:H,onBlur:H,ref:je=>{if(je){ye(L,X),ue=_e(r,L);const Se=wn(je.value)&&je.querySelectorAll&&je.querySelectorAll(\"input,select,textarea\")[0]||je,Be=i6(Se),bt=ue._f.refs||[];if(Be?bt.find(Wt=>Wt===Se):Se===ue._f.ref)return;qt(r,L,{_f:{...ue._f,...Be?{refs:[...bt.filter(_v),Se,...Array.isArray(_e(s,L))?[{}]:[]],ref:{type:Se.type,name:L}}:{ref:Se}}}),R(L,!1,void 0,Se)}else ue=_e(r,L,{}),ue._f&&(ue._f.mount=!1),(t.shouldUnregister||X.shouldUnregister)&&!(p_(u.array,L)&&l.action)&&u.unMount.add(L)}}},Re=()=>t.shouldFocusError&&Tu(r,q,u.mount),$e=L=>{Us(L)&&(m.state.next({disabled:L}),Tu(r,(X,ue)=>{const Ne=_e(r,ue);Ne&&(X.disabled=Ne._f.disabled||L,Array.isArray(Ne._f.refs)&&Ne._f.refs.forEach(je=>{je.disabled=Ne._f.disabled||L}))},0,!1))},Ye=(L,X)=>async ue=>{let Ne;ue&&(ue.preventDefault&&ue.preventDefault(),ue.persist&&ue.persist());let je=Er(o);if(m.state.next({isSubmitting:!0}),t.resolver){const{errors:Se,values:Be}=await D();n.errors=Se,je=Be}else await Q(r);if(Dn(n.errors,\"root\"),Lr(n.errors)){m.state.next({errors:{}});try{await L(je,ue)}catch(Se){Ne=Se}}else X&&await X({...n.errors},ue),Re(),setTimeout(Re);if(m.state.next({isSubmitted:!0,isSubmitting:!1,isSubmitSuccessful:Lr(n.errors)&&!Ne,submitCount:n.submitCount+1,errors:n.errors}),Ne)throw Ne},Fe=(L,X={})=>{_e(r,L)&&(wn(X.defaultValue)?Y(L,Er(_e(s,L))):(Y(L,X.defaultValue),qt(s,L,Er(X.defaultValue))),X.keepTouched||Dn(n.touchedFields,L),X.keepDirty||(Dn(n.dirtyFields,L),n.isDirty=X.defaultValue?V(L,Er(_e(s,L))):V()),X.keepError||(Dn(n.errors,L),h.isValid&&C()),m.state.next({...n}))},ft=(L,X={})=>{const ue=L?Er(L):s,Ne=Er(ue),je=Lr(L),Se=je?s:Ne;if(X.keepDefaultValues||(s=ue),!X.keepValues){if(X.keepDirtyValues)for(const Be of u.mount)_e(n.dirtyFields,Be)?qt(Se,Be,_e(o,Be)):Y(Be,_e(Se,Be));else{if(jx&&wn(L))for(const Be of u.mount){const bt=_e(r,Be);if(bt&&bt._f){const Wt=Array.isArray(bt._f.refs)?bt._f.refs[0]:bt._f.ref;if(Gp(Wt)){const yn=Wt.closest(\"form\");if(yn){yn.reset();break}}}}r={}}o=e.shouldUnregister?X.keepDefaultValues?Er(s):{}:Er(Se),m.array.next({values:{...Se}}),m.values.next({values:{...Se}})}u={mount:X.keepDirtyValues?u.mount:new Set,unMount:new Set,array:new Set,watch:new Set,watchAll:!1,focus:\"\"},l.mount=!h.isValid||!!X.keepIsValid||!!X.keepDirtyValues,l.watch=!!e.shouldUnregister,m.state.next({submitCount:X.keepSubmitCount?n.submitCount:0,isDirty:je?!1:X.keepDirty?n.isDirty:!!(X.keepDefaultValues&&!ui(L,s)),isSubmitted:X.keepIsSubmitted?n.isSubmitted:!1,dirtyFields:je?{}:X.keepDirtyValues?X.keepDefaultValues&&o?Gf(s,o):n.dirtyFields:X.keepDefaultValues&&L?Gf(s,L):X.keepDirty?n.dirtyFields:{},touchedFields:X.keepTouched?n.touchedFields:{},errors:X.keepErrors?n.errors:{},isSubmitSuccessful:X.keepIsSubmitSuccessful?n.isSubmitSuccessful:!1,isSubmitting:!1})},ln=(L,X)=>ft(ga(L)?L(o):L,X);return{control:{register:ye,unregister:ge,getFieldState:F,handleSubmit:Ye,setError:te,_executeSchema:D,_getWatch:G,_getDirty:V,_updateValid:C,_removeUnmounted:pe,_updateFieldArray:j,_updateDisabledField:Z,_getFieldArray:W,_reset:ft,_resetDefaultValues:()=>ga(t.defaultValues)&&t.defaultValues().then(L=>{ln(L,t.resetOptions),m.state.next({isLoading:!1})}),_updateFormState:L=>{n={...n,...L}},_disableForm:$e,_subjects:m,_proxyFormState:h,_setErrors:_,get _fields(){return r},get _formValues(){return o},get _state(){return l},set _state(L){l=L},get _defaultValues(){return s},get _names(){return u},set _names(L){u=L},get _formState(){return n},set _formState(L){n=L},get _options(){return t},set _options(L){t={...t,...L}}},trigger:he,register:ye,handleSubmit:Ye,watch:de,setValue:Y,getValues:A,reset:ln,resetField:Fe,clearErrors:fe,unregister:ge,setError:te,setFocus:(L,X={})=>{const ue=_e(r,L),Ne=ue&&ue._f;if(Ne){const je=Ne.refs?Ne.refs[0]:Ne.ref;je.focus&&(je.focus(),X.shouldSelect&&je.select())}},getFieldState:F}}function on(e={}){const t=qe.useRef(),n=qe.useRef(),[r,s]=qe.useState({isDirty:!1,isValidating:!1,isLoading:ga(e.defaultValues),isSubmitted:!1,isSubmitting:!1,isSubmitSuccessful:!1,isValid:!1,submitCount:0,dirtyFields:{},touchedFields:{},validatingFields:{},errors:e.errors||{},disabled:e.disabled||!1,defaultValues:ga(e.defaultValues)?void 0:e.defaultValues});t.current||(t.current={...p6(e),formState:r});const o=t.current.control;return o._options=e,Nx({subject:o._subjects.state,next:l=>{v_(l,o._proxyFormState,o._updateFormState,!0)&&s({...o._formState})}}),qe.useEffect(()=>o._disableForm(e.disabled),[o,e.disabled]),qe.useEffect(()=>{if(o._proxyFormState.isDirty){const l=o._getDirty();l!==r.isDirty&&o._subjects.state.next({isDirty:l})}},[o,r.isDirty]),qe.useEffect(()=>{e.values&&!ui(e.values,n.current)?(o._reset(e.values,o._options.resetOptions),n.current=e.values,s(l=>({...l}))):o._resetDefaultValues()},[e.values,o]),qe.useEffect(()=>{e.errors&&o._setErrors(e.errors)},[e.errors,o]),qe.useEffect(()=>{o._state.mount||(o._updateValid(),o._state.mount=!0),o._state.watch&&(o._state.watch=!1,o._subjects.state.next({...o._formState})),o._removeUnmounted()}),qe.useEffect(()=>{e.shouldUnregister&&o._subjects.values.next({values:o._getWatch()})},[e.shouldUnregister,o]),t.current.formState=m_(r,o),t.current}const S1=(e,t,n)=>{if(e&&\"reportValidity\"in e){const r=_e(n,t);e.setCustomValidity(r&&r.message||\"\"),e.reportValidity()}},T_=(e,t)=>{for(const n in t.fields){const r=t.fields[n];r&&r.ref&&\"reportValidity\"in r.ref?S1(r.ref,n,e):r.refs&&r.refs.forEach(s=>S1(s,n,e))}},h6=(e,t)=>{t.shouldUseNativeValidation&&T_(e,t);const n={};for(const r in e){const s=_e(t.fields,r),o=Object.assign(e[r]||{},{ref:s&&s.ref});if(g6(t.names||Object.keys(e),r)){const l=Object.assign({},_e(n,r));qt(l,\"root\",o),qt(n,r,l)}else qt(n,r,o)}return n},g6=(e,t)=>e.some(n=>n.startsWith(t+\".\"));var m6=function(e,t){for(var n={};e.length;){var r=e[0],s=r.code,o=r.message,l=r.path.join(\".\");if(!n[l])if(\"unionErrors\"in r){var u=r.unionErrors[0].errors[0];n[l]={message:u.message,type:u.code}}else n[l]={message:o,type:s};if(\"unionErrors\"in r&&r.unionErrors.forEach(function(h){return h.errors.forEach(function(m){return e.push(m)})}),t){var d=n[l].types,f=d&&d[r.code];n[l]=x_(l,t,n,s,f?[].concat(f,r.message):r.message)}e.shift()}return n},an=function(e,t,n){return n===void 0&&(n={}),function(r,s,o){try{return Promise.resolve((function(l,u){try{var d=Promise.resolve(e[n.mode===\"sync\"?\"parse\":\"parseAsync\"](r,t)).then(function(f){return o.shouldUseNativeValidation&&T_({},o),{errors:{},values:n.raw?r:f}})}catch(f){return u(f)}return d&&d.then?d.then(void 0,u):d})(0,function(l){if((function(u){return Array.isArray(u?.errors)})(l))return{values:{},errors:h6(m6(l.errors,!o.shouldUseNativeValidation&&o.criteriaMode===\"all\"),o)};throw l}))}catch(l){return Promise.reject(l)}}},Wn=[];for(var Pv=0;Pv<256;++Pv)Wn.push((Pv+256).toString(16).slice(1));function v6(e,t=0){return(Wn[e[t+0]]+Wn[e[t+1]]+Wn[e[t+2]]+Wn[e[t+3]]+\"-\"+Wn[e[t+4]]+Wn[e[t+5]]+\"-\"+Wn[e[t+6]]+Wn[e[t+7]]+\"-\"+Wn[e[t+8]]+Wn[e[t+9]]+\"-\"+Wn[e[t+10]]+Wn[e[t+11]]+Wn[e[t+12]]+Wn[e[t+13]]+Wn[e[t+14]]+Wn[e[t+15]]).toLowerCase()}var Jf,y6=new Uint8Array(16);function b6(){if(!Jf&&(Jf=typeof crypto<\"u\"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!Jf))throw new Error(\"crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported\");return Jf(y6)}var x6=typeof crypto<\"u\"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto);const C1={randomUUID:x6};function E1(e,t,n){if(C1.randomUUID&&!e)return C1.randomUUID();e=e||{};var r=e.random||(e.rng||b6)();return r[6]=r[6]&15|64,r[8]=r[8]&63|128,v6(r)}var Ot;(function(e){e.assertEqual=s=>s;function t(s){}e.assertIs=t;function n(s){throw new Error}e.assertNever=n,e.arrayToEnum=s=>{const o={};for(const l of s)o[l]=l;return o},e.getValidEnumValues=s=>{const o=e.objectKeys(s).filter(u=>typeof s[s[u]]!=\"number\"),l={};for(const u of o)l[u]=s[u];return e.objectValues(l)},e.objectValues=s=>e.objectKeys(s).map(function(o){return s[o]}),e.objectKeys=typeof Object.keys==\"function\"?s=>Object.keys(s):s=>{const o=[];for(const l in s)Object.prototype.hasOwnProperty.call(s,l)&&o.push(l);return o},e.find=(s,o)=>{for(const l of s)if(o(l))return l},e.isInteger=typeof Number.isInteger==\"function\"?s=>Number.isInteger(s):s=>typeof s==\"number\"&&isFinite(s)&&Math.floor(s)===s;function r(s,o=\" | \"){return s.map(l=>typeof l==\"string\"?`'${l}'`:l).join(o)}e.joinValues=r,e.jsonStringifyReplacer=(s,o)=>typeof o==\"bigint\"?o.toString():o})(Ot||(Ot={}));var Gy;(function(e){e.mergeShapes=(t,n)=>({...t,...n})})(Gy||(Gy={}));const Le=Ot.arrayToEnum([\"string\",\"nan\",\"number\",\"integer\",\"float\",\"boolean\",\"date\",\"bigint\",\"symbol\",\"function\",\"undefined\",\"null\",\"array\",\"object\",\"unknown\",\"promise\",\"void\",\"never\",\"map\",\"set\"]),pa=e=>{switch(typeof e){case\"undefined\":return Le.undefined;case\"string\":return Le.string;case\"number\":return isNaN(e)?Le.nan:Le.number;case\"boolean\":return Le.boolean;case\"function\":return Le.function;case\"bigint\":return Le.bigint;case\"symbol\":return Le.symbol;case\"object\":return Array.isArray(e)?Le.array:e===null?Le.null:e.then&&typeof e.then==\"function\"&&e.catch&&typeof e.catch==\"function\"?Le.promise:typeof Map<\"u\"&&e instanceof Map?Le.map:typeof Set<\"u\"&&e instanceof Set?Le.set:typeof Date<\"u\"&&e instanceof Date?Le.date:Le.object;default:return Le.unknown}},Ce=Ot.arrayToEnum([\"invalid_type\",\"invalid_literal\",\"custom\",\"invalid_union\",\"invalid_union_discriminator\",\"invalid_enum_value\",\"unrecognized_keys\",\"invalid_arguments\",\"invalid_return_type\",\"invalid_date\",\"invalid_string\",\"too_small\",\"too_big\",\"invalid_intersection_types\",\"not_multiple_of\",\"not_finite\"]),w6=e=>JSON.stringify(e,null,2).replace(/\"([^\"]+)\":/g,\"$1:\");class Hr extends Error{constructor(t){super(),this.issues=[],this.addIssue=r=>{this.issues=[...this.issues,r]},this.addIssues=(r=[])=>{this.issues=[...this.issues,...r]};const n=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,n):this.__proto__=n,this.name=\"ZodError\",this.issues=t}get errors(){return this.issues}format(t){const n=t||function(o){return o.message},r={_errors:[]},s=o=>{for(const l of o.issues)if(l.code===\"invalid_union\")l.unionErrors.map(s);else if(l.code===\"invalid_return_type\")s(l.returnTypeError);else if(l.code===\"invalid_arguments\")s(l.argumentsError);else if(l.path.length===0)r._errors.push(n(l));else{let u=r,d=0;for(;d<l.path.length;){const f=l.path[d];d===l.path.length-1?(u[f]=u[f]||{_errors:[]},u[f]._errors.push(n(l))):u[f]=u[f]||{_errors:[]},u=u[f],d++}}};return s(this),r}static assert(t){if(!(t instanceof Hr))throw new Error(`Not a ZodError: ${t}`)}toString(){return this.message}get message(){return JSON.stringify(this.issues,Ot.jsonStringifyReplacer,2)}get isEmpty(){return this.issues.length===0}flatten(t=n=>n.message){const n={},r=[];for(const s of this.issues)s.path.length>0?(n[s.path[0]]=n[s.path[0]]||[],n[s.path[0]].push(t(s))):r.push(t(s));return{formErrors:r,fieldErrors:n}}get formErrors(){return this.flatten()}}Hr.create=e=>new Hr(e);const Vl=(e,t)=>{let n;switch(e.code){case Ce.invalid_type:e.received===Le.undefined?n=\"Required\":n=`Expected ${e.expected}, received ${e.received}`;break;case Ce.invalid_literal:n=`Invalid literal value, expected ${JSON.stringify(e.expected,Ot.jsonStringifyReplacer)}`;break;case Ce.unrecognized_keys:n=`Unrecognized key(s) in object: ${Ot.joinValues(e.keys,\", \")}`;break;case Ce.invalid_union:n=\"Invalid input\";break;case Ce.invalid_union_discriminator:n=`Invalid discriminator value. Expected ${Ot.joinValues(e.options)}`;break;case Ce.invalid_enum_value:n=`Invalid enum value. Expected ${Ot.joinValues(e.options)}, received '${e.received}'`;break;case Ce.invalid_arguments:n=\"Invalid function arguments\";break;case Ce.invalid_return_type:n=\"Invalid function return type\";break;case Ce.invalid_date:n=\"Invalid date\";break;case Ce.invalid_string:typeof e.validation==\"object\"?\"includes\"in e.validation?(n=`Invalid input: must include \"${e.validation.includes}\"`,typeof e.validation.position==\"number\"&&(n=`${n} at one or more positions greater than or equal to ${e.validation.position}`)):\"startsWith\"in e.validation?n=`Invalid input: must start with \"${e.validation.startsWith}\"`:\"endsWith\"in e.validation?n=`Invalid input: must end with \"${e.validation.endsWith}\"`:Ot.assertNever(e.validation):e.validation!==\"regex\"?n=`Invalid ${e.validation}`:n=\"Invalid\";break;case Ce.too_small:e.type===\"array\"?n=`Array must contain ${e.exact?\"exactly\":e.inclusive?\"at least\":\"more than\"} ${e.minimum} element(s)`:e.type===\"string\"?n=`String must contain ${e.exact?\"exactly\":e.inclusive?\"at least\":\"over\"} ${e.minimum} character(s)`:e.type===\"number\"?n=`Number must be ${e.exact?\"exactly equal to \":e.inclusive?\"greater than or equal to \":\"greater than \"}${e.minimum}`:e.type===\"date\"?n=`Date must be ${e.exact?\"exactly equal to \":e.inclusive?\"greater than or equal to \":\"greater than \"}${new Date(Number(e.minimum))}`:n=\"Invalid input\";break;case Ce.too_big:e.type===\"array\"?n=`Array must contain ${e.exact?\"exactly\":e.inclusive?\"at most\":\"less than\"} ${e.maximum} element(s)`:e.type===\"string\"?n=`String must contain ${e.exact?\"exactly\":e.inclusive?\"at most\":\"under\"} ${e.maximum} character(s)`:e.type===\"number\"?n=`Number must be ${e.exact?\"exactly\":e.inclusive?\"less than or equal to\":\"less than\"} ${e.maximum}`:e.type===\"bigint\"?n=`BigInt must be ${e.exact?\"exactly\":e.inclusive?\"less than or equal to\":\"less than\"} ${e.maximum}`:e.type===\"date\"?n=`Date must be ${e.exact?\"exactly\":e.inclusive?\"smaller than or equal to\":\"smaller than\"} ${new Date(Number(e.maximum))}`:n=\"Invalid input\";break;case Ce.custom:n=\"Invalid input\";break;case Ce.invalid_intersection_types:n=\"Intersection results could not be merged\";break;case Ce.not_multiple_of:n=`Number must be a multiple of ${e.multipleOf}`;break;case Ce.not_finite:n=\"Number must be finite\";break;default:n=t.defaultError,Ot.assertNever(e)}return{message:n}};let N_=Vl;function S6(e){N_=e}function Yp(){return N_}const Xp=e=>{const{data:t,path:n,errorMaps:r,issueData:s}=e,o=[...n,...s.path||[]],l={...s,path:o};if(s.message!==void 0)return{...s,path:o,message:s.message};let u=\"\";const d=r.filter(f=>!!f).slice().reverse();for(const f of d)u=f(l,{data:t,defaultError:u}).message;return{...s,path:o,message:u}},C6=[];function Ae(e,t){const n=Yp(),r=Xp({issueData:t,data:e.data,path:e.path,errorMaps:[e.common.contextualErrorMap,e.schemaErrorMap,n,n===Vl?void 0:Vl].filter(s=>!!s)});e.common.issues.push(r)}class sr{constructor(){this.value=\"valid\"}dirty(){this.value===\"valid\"&&(this.value=\"dirty\")}abort(){this.value!==\"aborted\"&&(this.value=\"aborted\")}static mergeArray(t,n){const r=[];for(const s of n){if(s.status===\"aborted\")return lt;s.status===\"dirty\"&&t.dirty(),r.push(s.value)}return{status:t.value,value:r}}static async mergeObjectAsync(t,n){const r=[];for(const s of n){const o=await s.key,l=await s.value;r.push({key:o,value:l})}return sr.mergeObjectSync(t,r)}static mergeObjectSync(t,n){const r={};for(const s of n){const{key:o,value:l}=s;if(o.status===\"aborted\"||l.status===\"aborted\")return lt;o.status===\"dirty\"&&t.dirty(),l.status===\"dirty\"&&t.dirty(),o.value!==\"__proto__\"&&(typeof l.value<\"u\"||s.alwaysSet)&&(r[o.value]=l.value)}return{status:t.value,value:r}}}const lt=Object.freeze({status:\"aborted\"}),Nl=e=>({status:\"dirty\",value:e}),fr=e=>({status:\"valid\",value:e}),Jy=e=>e.status===\"aborted\",Qy=e=>e.status===\"dirty\",Hu=e=>e.status===\"valid\",qu=e=>typeof Promise<\"u\"&&e instanceof Promise;function eh(e,t,n,r){if(typeof t==\"function\"?e!==t||!0:!t.has(e))throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");return t.get(e)}function M_(e,t,n,r,s){if(typeof t==\"function\"?e!==t||!0:!t.has(e))throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");return t.set(e,n),n}var Ze;(function(e){e.errToObj=t=>typeof t==\"string\"?{message:t}:t||{},e.toString=t=>typeof t==\"string\"?t:t?.message})(Ze||(Ze={}));var yu,bu;class Qs{constructor(t,n,r,s){this._cachedPath=[],this.parent=t,this.data=n,this._path=r,this._key=s}get path(){return this._cachedPath.length||(this._key instanceof Array?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}}const k1=(e,t)=>{if(Hu(t))return{success:!0,data:t.value};if(!e.common.issues.length)throw new Error(\"Validation failed but no issues detected.\");return{success:!1,get error(){if(this._error)return this._error;const n=new Hr(e.common.issues);return this._error=n,this._error}}};function yt(e){if(!e)return{};const{errorMap:t,invalid_type_error:n,required_error:r,description:s}=e;if(t&&(n||r))throw new Error(`Can't use \"invalid_type_error\" or \"required_error\" in conjunction with custom error map.`);return t?{errorMap:t,description:s}:{errorMap:(l,u)=>{var d,f;const{message:h}=e;return l.code===\"invalid_enum_value\"?{message:h??u.defaultError}:typeof u.data>\"u\"?{message:(d=h??r)!==null&&d!==void 0?d:u.defaultError}:l.code!==\"invalid_type\"?{message:u.defaultError}:{message:(f=h??n)!==null&&f!==void 0?f:u.defaultError}},description:s}}class St{constructor(t){this.spa=this.safeParseAsync,this._def=t,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this)}get description(){return this._def.description}_getType(t){return pa(t.data)}_getOrReturnCtx(t,n){return n||{common:t.parent.common,data:t.data,parsedType:pa(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}_processInputParams(t){return{status:new sr,ctx:{common:t.parent.common,data:t.data,parsedType:pa(t.data),schemaErrorMap:this._def.errorMap,path:t.path,parent:t.parent}}}_parseSync(t){const n=this._parse(t);if(qu(n))throw new Error(\"Synchronous parse encountered promise.\");return n}_parseAsync(t){const n=this._parse(t);return Promise.resolve(n)}parse(t,n){const r=this.safeParse(t,n);if(r.success)return r.data;throw r.error}safeParse(t,n){var r;const s={common:{issues:[],async:(r=n?.async)!==null&&r!==void 0?r:!1,contextualErrorMap:n?.errorMap},path:n?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:pa(t)},o=this._parseSync({data:t,path:s.path,parent:s});return k1(s,o)}async parseAsync(t,n){const r=await this.safeParseAsync(t,n);if(r.success)return r.data;throw r.error}async safeParseAsync(t,n){const r={common:{issues:[],contextualErrorMap:n?.errorMap,async:!0},path:n?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:t,parsedType:pa(t)},s=this._parse({data:t,path:r.path,parent:r}),o=await(qu(s)?s:Promise.resolve(s));return k1(r,o)}refine(t,n){const r=s=>typeof n==\"string\"||typeof n>\"u\"?{message:n}:typeof n==\"function\"?n(s):n;return this._refinement((s,o)=>{const l=t(s),u=()=>o.addIssue({code:Ce.custom,...r(s)});return typeof Promise<\"u\"&&l instanceof Promise?l.then(d=>d?!0:(u(),!1)):l?!0:(u(),!1)})}refinement(t,n){return this._refinement((r,s)=>t(r)?!0:(s.addIssue(typeof n==\"function\"?n(r,s):n),!1))}_refinement(t){return new Ms({schema:this,typeName:it.ZodEffects,effect:{type:\"refinement\",refinement:t}})}superRefine(t){return this._refinement(t)}optional(){return Ws.create(this,this._def)}nullable(){return ka.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return ks.create(this,this._def)}promise(){return ql.create(this,this._def)}or(t){return Ju.create([this,t],this._def)}and(t){return Qu.create(this,t,this._def)}transform(t){return new Ms({...yt(this._def),schema:this,typeName:it.ZodEffects,effect:{type:\"transform\",transform:t}})}default(t){const n=typeof t==\"function\"?t:()=>t;return new td({...yt(this._def),innerType:this,defaultValue:n,typeName:it.ZodDefault})}brand(){return new Rx({typeName:it.ZodBranded,type:this,...yt(this._def)})}catch(t){const n=typeof t==\"function\"?t:()=>t;return new nd({...yt(this._def),innerType:this,catchValue:n,typeName:it.ZodCatch})}describe(t){const n=this.constructor;return new n({...this._def,description:t})}pipe(t){return kd.create(this,t)}readonly(){return rd.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}}const E6=/^c[^\\s-]{8,}$/i,k6=/^[0-9a-z]+$/,j6=/^[0-9A-HJKMNP-TV-Z]{26}$/,T6=/^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i,N6=/^[a-z0-9_-]{21}$/i,M6=/^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/,_6=/^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i,R6=\"^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$\";let Ov;const P6=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,O6=/^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/,I6=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,__=\"((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))\",A6=new RegExp(`^${__}$`);function R_(e){let t=\"([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d\";return e.precision?t=`${t}\\\\.\\\\d{${e.precision}}`:e.precision==null&&(t=`${t}(\\\\.\\\\d+)?`),t}function D6(e){return new RegExp(`^${R_(e)}$`)}function P_(e){let t=`${__}T${R_(e)}`;const n=[];return n.push(e.local?\"Z?\":\"Z\"),e.offset&&n.push(\"([+-]\\\\d{2}:?\\\\d{2})\"),t=`${t}(${n.join(\"|\")})`,new RegExp(`^${t}$`)}function F6(e,t){return!!((t===\"v4\"||!t)&&P6.test(e)||(t===\"v6\"||!t)&&O6.test(e))}class Cs extends St{_parse(t){if(this._def.coerce&&(t.data=String(t.data)),this._getType(t)!==Le.string){const o=this._getOrReturnCtx(t);return Ae(o,{code:Ce.invalid_type,expected:Le.string,received:o.parsedType}),lt}const r=new sr;let s;for(const o of this._def.checks)if(o.kind===\"min\")t.data.length<o.value&&(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),r.dirty());else if(o.kind===\"max\")t.data.length>o.value&&(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!1,message:o.message}),r.dirty());else if(o.kind===\"length\"){const l=t.data.length>o.value,u=t.data.length<o.value;(l||u)&&(s=this._getOrReturnCtx(t,s),l?Ae(s,{code:Ce.too_big,maximum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}):u&&Ae(s,{code:Ce.too_small,minimum:o.value,type:\"string\",inclusive:!0,exact:!0,message:o.message}),r.dirty())}else if(o.kind===\"email\")_6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"email\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"emoji\")Ov||(Ov=new RegExp(R6,\"u\")),Ov.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"emoji\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"uuid\")T6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"uuid\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"nanoid\")N6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"nanoid\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"cuid\")E6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"cuid\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"cuid2\")k6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"cuid2\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"ulid\")j6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"ulid\",code:Ce.invalid_string,message:o.message}),r.dirty());else if(o.kind===\"url\")try{new URL(t.data)}catch{s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"url\",code:Ce.invalid_string,message:o.message}),r.dirty()}else o.kind===\"regex\"?(o.regex.lastIndex=0,o.regex.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"regex\",code:Ce.invalid_string,message:o.message}),r.dirty())):o.kind===\"trim\"?t.data=t.data.trim():o.kind===\"includes\"?t.data.includes(o.value,o.position)||(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.invalid_string,validation:{includes:o.value,position:o.position},message:o.message}),r.dirty()):o.kind===\"toLowerCase\"?t.data=t.data.toLowerCase():o.kind===\"toUpperCase\"?t.data=t.data.toUpperCase():o.kind===\"startsWith\"?t.data.startsWith(o.value)||(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.invalid_string,validation:{startsWith:o.value},message:o.message}),r.dirty()):o.kind===\"endsWith\"?t.data.endsWith(o.value)||(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.invalid_string,validation:{endsWith:o.value},message:o.message}),r.dirty()):o.kind===\"datetime\"?P_(o).test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.invalid_string,validation:\"datetime\",message:o.message}),r.dirty()):o.kind===\"date\"?A6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.invalid_string,validation:\"date\",message:o.message}),r.dirty()):o.kind===\"time\"?D6(o).test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.invalid_string,validation:\"time\",message:o.message}),r.dirty()):o.kind===\"duration\"?M6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"duration\",code:Ce.invalid_string,message:o.message}),r.dirty()):o.kind===\"ip\"?F6(t.data,o.version)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"ip\",code:Ce.invalid_string,message:o.message}),r.dirty()):o.kind===\"base64\"?I6.test(t.data)||(s=this._getOrReturnCtx(t,s),Ae(s,{validation:\"base64\",code:Ce.invalid_string,message:o.message}),r.dirty()):Ot.assertNever(o);return{status:r.value,value:t.data}}_regex(t,n,r){return this.refinement(s=>t.test(s),{validation:n,code:Ce.invalid_string,...Ze.errToObj(r)})}_addCheck(t){return new Cs({...this._def,checks:[...this._def.checks,t]})}email(t){return this._addCheck({kind:\"email\",...Ze.errToObj(t)})}url(t){return this._addCheck({kind:\"url\",...Ze.errToObj(t)})}emoji(t){return this._addCheck({kind:\"emoji\",...Ze.errToObj(t)})}uuid(t){return this._addCheck({kind:\"uuid\",...Ze.errToObj(t)})}nanoid(t){return this._addCheck({kind:\"nanoid\",...Ze.errToObj(t)})}cuid(t){return this._addCheck({kind:\"cuid\",...Ze.errToObj(t)})}cuid2(t){return this._addCheck({kind:\"cuid2\",...Ze.errToObj(t)})}ulid(t){return this._addCheck({kind:\"ulid\",...Ze.errToObj(t)})}base64(t){return this._addCheck({kind:\"base64\",...Ze.errToObj(t)})}ip(t){return this._addCheck({kind:\"ip\",...Ze.errToObj(t)})}datetime(t){var n,r;return typeof t==\"string\"?this._addCheck({kind:\"datetime\",precision:null,offset:!1,local:!1,message:t}):this._addCheck({kind:\"datetime\",precision:typeof t?.precision>\"u\"?null:t?.precision,offset:(n=t?.offset)!==null&&n!==void 0?n:!1,local:(r=t?.local)!==null&&r!==void 0?r:!1,...Ze.errToObj(t?.message)})}date(t){return this._addCheck({kind:\"date\",message:t})}time(t){return typeof t==\"string\"?this._addCheck({kind:\"time\",precision:null,message:t}):this._addCheck({kind:\"time\",precision:typeof t?.precision>\"u\"?null:t?.precision,...Ze.errToObj(t?.message)})}duration(t){return this._addCheck({kind:\"duration\",...Ze.errToObj(t)})}regex(t,n){return this._addCheck({kind:\"regex\",regex:t,...Ze.errToObj(n)})}includes(t,n){return this._addCheck({kind:\"includes\",value:t,position:n?.position,...Ze.errToObj(n?.message)})}startsWith(t,n){return this._addCheck({kind:\"startsWith\",value:t,...Ze.errToObj(n)})}endsWith(t,n){return this._addCheck({kind:\"endsWith\",value:t,...Ze.errToObj(n)})}min(t,n){return this._addCheck({kind:\"min\",value:t,...Ze.errToObj(n)})}max(t,n){return this._addCheck({kind:\"max\",value:t,...Ze.errToObj(n)})}length(t,n){return this._addCheck({kind:\"length\",value:t,...Ze.errToObj(n)})}nonempty(t){return this.min(1,Ze.errToObj(t))}trim(){return new Cs({...this._def,checks:[...this._def.checks,{kind:\"trim\"}]})}toLowerCase(){return new Cs({...this._def,checks:[...this._def.checks,{kind:\"toLowerCase\"}]})}toUpperCase(){return new Cs({...this._def,checks:[...this._def.checks,{kind:\"toUpperCase\"}]})}get isDatetime(){return!!this._def.checks.find(t=>t.kind===\"datetime\")}get isDate(){return!!this._def.checks.find(t=>t.kind===\"date\")}get isTime(){return!!this._def.checks.find(t=>t.kind===\"time\")}get isDuration(){return!!this._def.checks.find(t=>t.kind===\"duration\")}get isEmail(){return!!this._def.checks.find(t=>t.kind===\"email\")}get isURL(){return!!this._def.checks.find(t=>t.kind===\"url\")}get isEmoji(){return!!this._def.checks.find(t=>t.kind===\"emoji\")}get isUUID(){return!!this._def.checks.find(t=>t.kind===\"uuid\")}get isNANOID(){return!!this._def.checks.find(t=>t.kind===\"nanoid\")}get isCUID(){return!!this._def.checks.find(t=>t.kind===\"cuid\")}get isCUID2(){return!!this._def.checks.find(t=>t.kind===\"cuid2\")}get isULID(){return!!this._def.checks.find(t=>t.kind===\"ulid\")}get isIP(){return!!this._def.checks.find(t=>t.kind===\"ip\")}get isBase64(){return!!this._def.checks.find(t=>t.kind===\"base64\")}get minLength(){let t=null;for(const n of this._def.checks)n.kind===\"min\"&&(t===null||n.value>t)&&(t=n.value);return t}get maxLength(){let t=null;for(const n of this._def.checks)n.kind===\"max\"&&(t===null||n.value<t)&&(t=n.value);return t}}Cs.create=e=>{var t;return new Cs({checks:[],typeName:it.ZodString,coerce:(t=e?.coerce)!==null&&t!==void 0?t:!1,...yt(e)})};function L6(e,t){const n=(e.toString().split(\".\")[1]||\"\").length,r=(t.toString().split(\".\")[1]||\"\").length,s=n>r?n:r,o=parseInt(e.toFixed(s).replace(\".\",\"\")),l=parseInt(t.toFixed(s).replace(\".\",\"\"));return o%l/Math.pow(10,s)}class Sa extends St{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(t){if(this._def.coerce&&(t.data=Number(t.data)),this._getType(t)!==Le.number){const o=this._getOrReturnCtx(t);return Ae(o,{code:Ce.invalid_type,expected:Le.number,received:o.parsedType}),lt}let r;const s=new sr;for(const o of this._def.checks)o.kind===\"int\"?Ot.isInteger(t.data)||(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.invalid_type,expected:\"integer\",received:\"float\",message:o.message}),s.dirty()):o.kind===\"min\"?(o.inclusive?t.data<o.value:t.data<=o.value)&&(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.too_small,minimum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),s.dirty()):o.kind===\"max\"?(o.inclusive?t.data>o.value:t.data>=o.value)&&(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.too_big,maximum:o.value,type:\"number\",inclusive:o.inclusive,exact:!1,message:o.message}),s.dirty()):o.kind===\"multipleOf\"?L6(t.data,o.value)!==0&&(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.not_multiple_of,multipleOf:o.value,message:o.message}),s.dirty()):o.kind===\"finite\"?Number.isFinite(t.data)||(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.not_finite,message:o.message}),s.dirty()):Ot.assertNever(o);return{status:s.value,value:t.data}}gte(t,n){return this.setLimit(\"min\",t,!0,Ze.toString(n))}gt(t,n){return this.setLimit(\"min\",t,!1,Ze.toString(n))}lte(t,n){return this.setLimit(\"max\",t,!0,Ze.toString(n))}lt(t,n){return this.setLimit(\"max\",t,!1,Ze.toString(n))}setLimit(t,n,r,s){return new Sa({...this._def,checks:[...this._def.checks,{kind:t,value:n,inclusive:r,message:Ze.toString(s)}]})}_addCheck(t){return new Sa({...this._def,checks:[...this._def.checks,t]})}int(t){return this._addCheck({kind:\"int\",message:Ze.toString(t)})}positive(t){return this._addCheck({kind:\"min\",value:0,inclusive:!1,message:Ze.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:0,inclusive:!1,message:Ze.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:0,inclusive:!0,message:Ze.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:0,inclusive:!0,message:Ze.toString(t)})}multipleOf(t,n){return this._addCheck({kind:\"multipleOf\",value:t,message:Ze.toString(n)})}finite(t){return this._addCheck({kind:\"finite\",message:Ze.toString(t)})}safe(t){return this._addCheck({kind:\"min\",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:Ze.toString(t)})._addCheck({kind:\"max\",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:Ze.toString(t)})}get minValue(){let t=null;for(const n of this._def.checks)n.kind===\"min\"&&(t===null||n.value>t)&&(t=n.value);return t}get maxValue(){let t=null;for(const n of this._def.checks)n.kind===\"max\"&&(t===null||n.value<t)&&(t=n.value);return t}get isInt(){return!!this._def.checks.find(t=>t.kind===\"int\"||t.kind===\"multipleOf\"&&Ot.isInteger(t.value))}get isFinite(){let t=null,n=null;for(const r of this._def.checks){if(r.kind===\"finite\"||r.kind===\"int\"||r.kind===\"multipleOf\")return!0;r.kind===\"min\"?(n===null||r.value>n)&&(n=r.value):r.kind===\"max\"&&(t===null||r.value<t)&&(t=r.value)}return Number.isFinite(n)&&Number.isFinite(t)}}Sa.create=e=>new Sa({checks:[],typeName:it.ZodNumber,coerce:e?.coerce||!1,...yt(e)});class Ca extends St{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(t){if(this._def.coerce&&(t.data=BigInt(t.data)),this._getType(t)!==Le.bigint){const o=this._getOrReturnCtx(t);return Ae(o,{code:Ce.invalid_type,expected:Le.bigint,received:o.parsedType}),lt}let r;const s=new sr;for(const o of this._def.checks)o.kind===\"min\"?(o.inclusive?t.data<o.value:t.data<=o.value)&&(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.too_small,type:\"bigint\",minimum:o.value,inclusive:o.inclusive,message:o.message}),s.dirty()):o.kind===\"max\"?(o.inclusive?t.data>o.value:t.data>=o.value)&&(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.too_big,type:\"bigint\",maximum:o.value,inclusive:o.inclusive,message:o.message}),s.dirty()):o.kind===\"multipleOf\"?t.data%o.value!==BigInt(0)&&(r=this._getOrReturnCtx(t,r),Ae(r,{code:Ce.not_multiple_of,multipleOf:o.value,message:o.message}),s.dirty()):Ot.assertNever(o);return{status:s.value,value:t.data}}gte(t,n){return this.setLimit(\"min\",t,!0,Ze.toString(n))}gt(t,n){return this.setLimit(\"min\",t,!1,Ze.toString(n))}lte(t,n){return this.setLimit(\"max\",t,!0,Ze.toString(n))}lt(t,n){return this.setLimit(\"max\",t,!1,Ze.toString(n))}setLimit(t,n,r,s){return new Ca({...this._def,checks:[...this._def.checks,{kind:t,value:n,inclusive:r,message:Ze.toString(s)}]})}_addCheck(t){return new Ca({...this._def,checks:[...this._def.checks,t]})}positive(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!1,message:Ze.toString(t)})}negative(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!1,message:Ze.toString(t)})}nonpositive(t){return this._addCheck({kind:\"max\",value:BigInt(0),inclusive:!0,message:Ze.toString(t)})}nonnegative(t){return this._addCheck({kind:\"min\",value:BigInt(0),inclusive:!0,message:Ze.toString(t)})}multipleOf(t,n){return this._addCheck({kind:\"multipleOf\",value:t,message:Ze.toString(n)})}get minValue(){let t=null;for(const n of this._def.checks)n.kind===\"min\"&&(t===null||n.value>t)&&(t=n.value);return t}get maxValue(){let t=null;for(const n of this._def.checks)n.kind===\"max\"&&(t===null||n.value<t)&&(t=n.value);return t}}Ca.create=e=>{var t;return new Ca({checks:[],typeName:it.ZodBigInt,coerce:(t=e?.coerce)!==null&&t!==void 0?t:!1,...yt(e)})};class Ku extends St{_parse(t){if(this._def.coerce&&(t.data=!!t.data),this._getType(t)!==Le.boolean){const r=this._getOrReturnCtx(t);return Ae(r,{code:Ce.invalid_type,expected:Le.boolean,received:r.parsedType}),lt}return fr(t.data)}}Ku.create=e=>new Ku({typeName:it.ZodBoolean,coerce:e?.coerce||!1,...yt(e)});class Ti extends St{_parse(t){if(this._def.coerce&&(t.data=new Date(t.data)),this._getType(t)!==Le.date){const o=this._getOrReturnCtx(t);return Ae(o,{code:Ce.invalid_type,expected:Le.date,received:o.parsedType}),lt}if(isNaN(t.data.getTime())){const o=this._getOrReturnCtx(t);return Ae(o,{code:Ce.invalid_date}),lt}const r=new sr;let s;for(const o of this._def.checks)o.kind===\"min\"?t.data.getTime()<o.value&&(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.too_small,message:o.message,inclusive:!0,exact:!1,minimum:o.value,type:\"date\"}),r.dirty()):o.kind===\"max\"?t.data.getTime()>o.value&&(s=this._getOrReturnCtx(t,s),Ae(s,{code:Ce.too_big,message:o.message,inclusive:!0,exact:!1,maximum:o.value,type:\"date\"}),r.dirty()):Ot.assertNever(o);return{status:r.value,value:new Date(t.data.getTime())}}_addCheck(t){return new Ti({...this._def,checks:[...this._def.checks,t]})}min(t,n){return this._addCheck({kind:\"min\",value:t.getTime(),message:Ze.toString(n)})}max(t,n){return this._addCheck({kind:\"max\",value:t.getTime(),message:Ze.toString(n)})}get minDate(){let t=null;for(const n of this._def.checks)n.kind===\"min\"&&(t===null||n.value>t)&&(t=n.value);return t!=null?new Date(t):null}get maxDate(){let t=null;for(const n of this._def.checks)n.kind===\"max\"&&(t===null||n.value<t)&&(t=n.value);return t!=null?new Date(t):null}}Ti.create=e=>new Ti({checks:[],coerce:e?.coerce||!1,typeName:it.ZodDate,...yt(e)});class th extends St{_parse(t){if(this._getType(t)!==Le.symbol){const r=this._getOrReturnCtx(t);return Ae(r,{code:Ce.invalid_type,expected:Le.symbol,received:r.parsedType}),lt}return fr(t.data)}}th.create=e=>new th({typeName:it.ZodSymbol,...yt(e)});class Wu extends St{_parse(t){if(this._getType(t)!==Le.undefined){const r=this._getOrReturnCtx(t);return Ae(r,{code:Ce.invalid_type,expected:Le.undefined,received:r.parsedType}),lt}return fr(t.data)}}Wu.create=e=>new Wu({typeName:it.ZodUndefined,...yt(e)});class Gu extends St{_parse(t){if(this._getType(t)!==Le.null){const r=this._getOrReturnCtx(t);return Ae(r,{code:Ce.invalid_type,expected:Le.null,received:r.parsedType}),lt}return fr(t.data)}}Gu.create=e=>new Gu({typeName:it.ZodNull,...yt(e)});class Hl extends St{constructor(){super(...arguments),this._any=!0}_parse(t){return fr(t.data)}}Hl.create=e=>new Hl({typeName:it.ZodAny,...yt(e)});class mi extends St{constructor(){super(...arguments),this._unknown=!0}_parse(t){return fr(t.data)}}mi.create=e=>new mi({typeName:it.ZodUnknown,...yt(e)});class Ro extends St{_parse(t){const n=this._getOrReturnCtx(t);return Ae(n,{code:Ce.invalid_type,expected:Le.never,received:n.parsedType}),lt}}Ro.create=e=>new Ro({typeName:it.ZodNever,...yt(e)});class nh extends St{_parse(t){if(this._getType(t)!==Le.undefined){const r=this._getOrReturnCtx(t);return Ae(r,{code:Ce.invalid_type,expected:Le.void,received:r.parsedType}),lt}return fr(t.data)}}nh.create=e=>new nh({typeName:it.ZodVoid,...yt(e)});class ks extends St{_parse(t){const{ctx:n,status:r}=this._processInputParams(t),s=this._def;if(n.parsedType!==Le.array)return Ae(n,{code:Ce.invalid_type,expected:Le.array,received:n.parsedType}),lt;if(s.exactLength!==null){const l=n.data.length>s.exactLength.value,u=n.data.length<s.exactLength.value;(l||u)&&(Ae(n,{code:l?Ce.too_big:Ce.too_small,minimum:u?s.exactLength.value:void 0,maximum:l?s.exactLength.value:void 0,type:\"array\",inclusive:!0,exact:!0,message:s.exactLength.message}),r.dirty())}if(s.minLength!==null&&n.data.length<s.minLength.value&&(Ae(n,{code:Ce.too_small,minimum:s.minLength.value,type:\"array\",inclusive:!0,exact:!1,message:s.minLength.message}),r.dirty()),s.maxLength!==null&&n.data.length>s.maxLength.value&&(Ae(n,{code:Ce.too_big,maximum:s.maxLength.value,type:\"array\",inclusive:!0,exact:!1,message:s.maxLength.message}),r.dirty()),n.common.async)return Promise.all([...n.data].map((l,u)=>s.type._parseAsync(new Qs(n,l,n.path,u)))).then(l=>sr.mergeArray(r,l));const o=[...n.data].map((l,u)=>s.type._parseSync(new Qs(n,l,n.path,u)));return sr.mergeArray(r,o)}get element(){return this._def.type}min(t,n){return new ks({...this._def,minLength:{value:t,message:Ze.toString(n)}})}max(t,n){return new ks({...this._def,maxLength:{value:t,message:Ze.toString(n)}})}length(t,n){return new ks({...this._def,exactLength:{value:t,message:Ze.toString(n)}})}nonempty(t){return this.min(1,t)}}ks.create=(e,t)=>new ks({type:e,minLength:null,maxLength:null,exactLength:null,typeName:it.ZodArray,...yt(t)});function El(e){if(e instanceof gn){const t={};for(const n in e.shape){const r=e.shape[n];t[n]=Ws.create(El(r))}return new gn({...e._def,shape:()=>t})}else return e instanceof ks?new ks({...e._def,type:El(e.element)}):e instanceof Ws?Ws.create(El(e.unwrap())):e instanceof ka?ka.create(El(e.unwrap())):e instanceof Zs?Zs.create(e.items.map(t=>El(t))):e}class gn extends St{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;const t=this._def.shape(),n=Ot.objectKeys(t);return this._cached={shape:t,keys:n}}_parse(t){if(this._getType(t)!==Le.object){const f=this._getOrReturnCtx(t);return Ae(f,{code:Ce.invalid_type,expected:Le.object,received:f.parsedType}),lt}const{status:r,ctx:s}=this._processInputParams(t),{shape:o,keys:l}=this._getCached(),u=[];if(!(this._def.catchall instanceof Ro&&this._def.unknownKeys===\"strip\"))for(const f in s.data)l.includes(f)||u.push(f);const d=[];for(const f of l){const h=o[f],m=s.data[f];d.push({key:{status:\"valid\",value:f},value:h._parse(new Qs(s,m,s.path,f)),alwaysSet:f in s.data})}if(this._def.catchall instanceof Ro){const f=this._def.unknownKeys;if(f===\"passthrough\")for(const h of u)d.push({key:{status:\"valid\",value:h},value:{status:\"valid\",value:s.data[h]}});else if(f===\"strict\")u.length>0&&(Ae(s,{code:Ce.unrecognized_keys,keys:u}),r.dirty());else if(f!==\"strip\")throw new Error(\"Internal ZodObject error: invalid unknownKeys value.\")}else{const f=this._def.catchall;for(const h of u){const m=s.data[h];d.push({key:{status:\"valid\",value:h},value:f._parse(new Qs(s,m,s.path,h)),alwaysSet:h in s.data})}}return s.common.async?Promise.resolve().then(async()=>{const f=[];for(const h of d){const m=await h.key,g=await h.value;f.push({key:m,value:g,alwaysSet:h.alwaysSet})}return f}).then(f=>sr.mergeObjectSync(r,f)):sr.mergeObjectSync(r,d)}get shape(){return this._def.shape()}strict(t){return Ze.errToObj,new gn({...this._def,unknownKeys:\"strict\",...t!==void 0?{errorMap:(n,r)=>{var s,o,l,u;const d=(l=(o=(s=this._def).errorMap)===null||o===void 0?void 0:o.call(s,n,r).message)!==null&&l!==void 0?l:r.defaultError;return n.code===\"unrecognized_keys\"?{message:(u=Ze.errToObj(t).message)!==null&&u!==void 0?u:d}:{message:d}}}:{}})}strip(){return new gn({...this._def,unknownKeys:\"strip\"})}passthrough(){return new gn({...this._def,unknownKeys:\"passthrough\"})}extend(t){return new gn({...this._def,shape:()=>({...this._def.shape(),...t})})}merge(t){return new gn({unknownKeys:t._def.unknownKeys,catchall:t._def.catchall,shape:()=>({...this._def.shape(),...t._def.shape()}),typeName:it.ZodObject})}setKey(t,n){return this.augment({[t]:n})}catchall(t){return new gn({...this._def,catchall:t})}pick(t){const n={};return Ot.objectKeys(t).forEach(r=>{t[r]&&this.shape[r]&&(n[r]=this.shape[r])}),new gn({...this._def,shape:()=>n})}omit(t){const n={};return Ot.objectKeys(this.shape).forEach(r=>{t[r]||(n[r]=this.shape[r])}),new gn({...this._def,shape:()=>n})}deepPartial(){return El(this)}partial(t){const n={};return Ot.objectKeys(this.shape).forEach(r=>{const s=this.shape[r];t&&!t[r]?n[r]=s:n[r]=s.optional()}),new gn({...this._def,shape:()=>n})}required(t){const n={};return Ot.objectKeys(this.shape).forEach(r=>{if(t&&!t[r])n[r]=this.shape[r];else{let o=this.shape[r];for(;o instanceof Ws;)o=o._def.innerType;n[r]=o}}),new gn({...this._def,shape:()=>n})}keyof(){return O_(Ot.objectKeys(this.shape))}}gn.create=(e,t)=>new gn({shape:()=>e,unknownKeys:\"strip\",catchall:Ro.create(),typeName:it.ZodObject,...yt(t)});gn.strictCreate=(e,t)=>new gn({shape:()=>e,unknownKeys:\"strict\",catchall:Ro.create(),typeName:it.ZodObject,...yt(t)});gn.lazycreate=(e,t)=>new gn({shape:e,unknownKeys:\"strip\",catchall:Ro.create(),typeName:it.ZodObject,...yt(t)});class Ju extends St{_parse(t){const{ctx:n}=this._processInputParams(t),r=this._def.options;function s(o){for(const u of o)if(u.result.status===\"valid\")return u.result;for(const u of o)if(u.result.status===\"dirty\")return n.common.issues.push(...u.ctx.common.issues),u.result;const l=o.map(u=>new Hr(u.ctx.common.issues));return Ae(n,{code:Ce.invalid_union,unionErrors:l}),lt}if(n.common.async)return Promise.all(r.map(async o=>{const l={...n,common:{...n.common,issues:[]},parent:null};return{result:await o._parseAsync({data:n.data,path:n.path,parent:l}),ctx:l}})).then(s);{let o;const l=[];for(const d of r){const f={...n,common:{...n.common,issues:[]},parent:null},h=d._parseSync({data:n.data,path:n.path,parent:f});if(h.status===\"valid\")return h;h.status===\"dirty\"&&!o&&(o={result:h,ctx:f}),f.common.issues.length&&l.push(f.common.issues)}if(o)return n.common.issues.push(...o.ctx.common.issues),o.result;const u=l.map(d=>new Hr(d));return Ae(n,{code:Ce.invalid_union,unionErrors:u}),lt}}get options(){return this._def.options}}Ju.create=(e,t)=>new Ju({options:e,typeName:it.ZodUnion,...yt(t)});const mo=e=>e instanceof Yu?mo(e.schema):e instanceof Ms?mo(e.innerType()):e instanceof Xu?[e.value]:e instanceof Ea?e.options:e instanceof ed?Ot.objectValues(e.enum):e instanceof td?mo(e._def.innerType):e instanceof Wu?[void 0]:e instanceof Gu?[null]:e instanceof Ws?[void 0,...mo(e.unwrap())]:e instanceof ka?[null,...mo(e.unwrap())]:e instanceof Rx||e instanceof rd?mo(e.unwrap()):e instanceof nd?mo(e._def.innerType):[];class Wh extends St{_parse(t){const{ctx:n}=this._processInputParams(t);if(n.parsedType!==Le.object)return Ae(n,{code:Ce.invalid_type,expected:Le.object,received:n.parsedType}),lt;const r=this.discriminator,s=n.data[r],o=this.optionsMap.get(s);return o?n.common.async?o._parseAsync({data:n.data,path:n.path,parent:n}):o._parseSync({data:n.data,path:n.path,parent:n}):(Ae(n,{code:Ce.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[r]}),lt)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(t,n,r){const s=new Map;for(const o of n){const l=mo(o.shape[t]);if(!l.length)throw new Error(`A discriminator value for key \\`${t}\\` could not be extracted from all schema options`);for(const u of l){if(s.has(u))throw new Error(`Discriminator property ${String(t)} has duplicate value ${String(u)}`);s.set(u,o)}}return new Wh({typeName:it.ZodDiscriminatedUnion,discriminator:t,options:n,optionsMap:s,...yt(r)})}}function Zy(e,t){const n=pa(e),r=pa(t);if(e===t)return{valid:!0,data:e};if(n===Le.object&&r===Le.object){const s=Ot.objectKeys(t),o=Ot.objectKeys(e).filter(u=>s.indexOf(u)!==-1),l={...e,...t};for(const u of o){const d=Zy(e[u],t[u]);if(!d.valid)return{valid:!1};l[u]=d.data}return{valid:!0,data:l}}else if(n===Le.array&&r===Le.array){if(e.length!==t.length)return{valid:!1};const s=[];for(let o=0;o<e.length;o++){const l=e[o],u=t[o],d=Zy(l,u);if(!d.valid)return{valid:!1};s.push(d.data)}return{valid:!0,data:s}}else return n===Le.date&&r===Le.date&&+e==+t?{valid:!0,data:e}:{valid:!1}}class Qu extends St{_parse(t){const{status:n,ctx:r}=this._processInputParams(t),s=(o,l)=>{if(Jy(o)||Jy(l))return lt;const u=Zy(o.value,l.value);return u.valid?((Qy(o)||Qy(l))&&n.dirty(),{status:n.value,value:u.data}):(Ae(r,{code:Ce.invalid_intersection_types}),lt)};return r.common.async?Promise.all([this._def.left._parseAsync({data:r.data,path:r.path,parent:r}),this._def.right._parseAsync({data:r.data,path:r.path,parent:r})]).then(([o,l])=>s(o,l)):s(this._def.left._parseSync({data:r.data,path:r.path,parent:r}),this._def.right._parseSync({data:r.data,path:r.path,parent:r}))}}Qu.create=(e,t,n)=>new Qu({left:e,right:t,typeName:it.ZodIntersection,...yt(n)});class Zs extends St{_parse(t){const{status:n,ctx:r}=this._processInputParams(t);if(r.parsedType!==Le.array)return Ae(r,{code:Ce.invalid_type,expected:Le.array,received:r.parsedType}),lt;if(r.data.length<this._def.items.length)return Ae(r,{code:Ce.too_small,minimum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),lt;!this._def.rest&&r.data.length>this._def.items.length&&(Ae(r,{code:Ce.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:\"array\"}),n.dirty());const o=[...r.data].map((l,u)=>{const d=this._def.items[u]||this._def.rest;return d?d._parse(new Qs(r,l,r.path,u)):null}).filter(l=>!!l);return r.common.async?Promise.all(o).then(l=>sr.mergeArray(n,l)):sr.mergeArray(n,o)}get items(){return this._def.items}rest(t){return new Zs({...this._def,rest:t})}}Zs.create=(e,t)=>{if(!Array.isArray(e))throw new Error(\"You must pass an array of schemas to z.tuple([ ... ])\");return new Zs({items:e,typeName:it.ZodTuple,rest:null,...yt(t)})};class Zu extends St{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:n,ctx:r}=this._processInputParams(t);if(r.parsedType!==Le.object)return Ae(r,{code:Ce.invalid_type,expected:Le.object,received:r.parsedType}),lt;const s=[],o=this._def.keyType,l=this._def.valueType;for(const u in r.data)s.push({key:o._parse(new Qs(r,u,r.path,u)),value:l._parse(new Qs(r,r.data[u],r.path,u)),alwaysSet:u in r.data});return r.common.async?sr.mergeObjectAsync(n,s):sr.mergeObjectSync(n,s)}get element(){return this._def.valueType}static create(t,n,r){return n instanceof St?new Zu({keyType:t,valueType:n,typeName:it.ZodRecord,...yt(r)}):new Zu({keyType:Cs.create(),valueType:t,typeName:it.ZodRecord,...yt(n)})}}class rh extends St{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(t){const{status:n,ctx:r}=this._processInputParams(t);if(r.parsedType!==Le.map)return Ae(r,{code:Ce.invalid_type,expected:Le.map,received:r.parsedType}),lt;const s=this._def.keyType,o=this._def.valueType,l=[...r.data.entries()].map(([u,d],f)=>({key:s._parse(new Qs(r,u,r.path,[f,\"key\"])),value:o._parse(new Qs(r,d,r.path,[f,\"value\"]))}));if(r.common.async){const u=new Map;return Promise.resolve().then(async()=>{for(const d of l){const f=await d.key,h=await d.value;if(f.status===\"aborted\"||h.status===\"aborted\")return lt;(f.status===\"dirty\"||h.status===\"dirty\")&&n.dirty(),u.set(f.value,h.value)}return{status:n.value,value:u}})}else{const u=new Map;for(const d of l){const f=d.key,h=d.value;if(f.status===\"aborted\"||h.status===\"aborted\")return lt;(f.status===\"dirty\"||h.status===\"dirty\")&&n.dirty(),u.set(f.value,h.value)}return{status:n.value,value:u}}}}rh.create=(e,t,n)=>new rh({valueType:t,keyType:e,typeName:it.ZodMap,...yt(n)});class Ni extends St{_parse(t){const{status:n,ctx:r}=this._processInputParams(t);if(r.parsedType!==Le.set)return Ae(r,{code:Ce.invalid_type,expected:Le.set,received:r.parsedType}),lt;const s=this._def;s.minSize!==null&&r.data.size<s.minSize.value&&(Ae(r,{code:Ce.too_small,minimum:s.minSize.value,type:\"set\",inclusive:!0,exact:!1,message:s.minSize.message}),n.dirty()),s.maxSize!==null&&r.data.size>s.maxSize.value&&(Ae(r,{code:Ce.too_big,maximum:s.maxSize.value,type:\"set\",inclusive:!0,exact:!1,message:s.maxSize.message}),n.dirty());const o=this._def.valueType;function l(d){const f=new Set;for(const h of d){if(h.status===\"aborted\")return lt;h.status===\"dirty\"&&n.dirty(),f.add(h.value)}return{status:n.value,value:f}}const u=[...r.data.values()].map((d,f)=>o._parse(new Qs(r,d,r.path,f)));return r.common.async?Promise.all(u).then(d=>l(d)):l(u)}min(t,n){return new Ni({...this._def,minSize:{value:t,message:Ze.toString(n)}})}max(t,n){return new Ni({...this._def,maxSize:{value:t,message:Ze.toString(n)}})}size(t,n){return this.min(t,n).max(t,n)}nonempty(t){return this.min(1,t)}}Ni.create=(e,t)=>new Ni({valueType:e,minSize:null,maxSize:null,typeName:it.ZodSet,...yt(t)});class Ol extends St{constructor(){super(...arguments),this.validate=this.implement}_parse(t){const{ctx:n}=this._processInputParams(t);if(n.parsedType!==Le.function)return Ae(n,{code:Ce.invalid_type,expected:Le.function,received:n.parsedType}),lt;function r(u,d){return Xp({data:u,path:n.path,errorMaps:[n.common.contextualErrorMap,n.schemaErrorMap,Yp(),Vl].filter(f=>!!f),issueData:{code:Ce.invalid_arguments,argumentsError:d}})}function s(u,d){return Xp({data:u,path:n.path,errorMaps:[n.common.contextualErrorMap,n.schemaErrorMap,Yp(),Vl].filter(f=>!!f),issueData:{code:Ce.invalid_return_type,returnTypeError:d}})}const o={errorMap:n.common.contextualErrorMap},l=n.data;if(this._def.returns instanceof ql){const u=this;return fr(async function(...d){const f=new Hr([]),h=await u._def.args.parseAsync(d,o).catch(x=>{throw f.addIssue(r(d,x)),f}),m=await Reflect.apply(l,this,h);return await u._def.returns._def.type.parseAsync(m,o).catch(x=>{throw f.addIssue(s(m,x)),f})})}else{const u=this;return fr(function(...d){const f=u._def.args.safeParse(d,o);if(!f.success)throw new Hr([r(d,f.error)]);const h=Reflect.apply(l,this,f.data),m=u._def.returns.safeParse(h,o);if(!m.success)throw new Hr([s(h,m.error)]);return m.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...t){return new Ol({...this._def,args:Zs.create(t).rest(mi.create())})}returns(t){return new Ol({...this._def,returns:t})}implement(t){return this.parse(t)}strictImplement(t){return this.parse(t)}static create(t,n,r){return new Ol({args:t||Zs.create([]).rest(mi.create()),returns:n||mi.create(),typeName:it.ZodFunction,...yt(r)})}}class Yu extends St{get schema(){return this._def.getter()}_parse(t){const{ctx:n}=this._processInputParams(t);return this._def.getter()._parse({data:n.data,path:n.path,parent:n})}}Yu.create=(e,t)=>new Yu({getter:e,typeName:it.ZodLazy,...yt(t)});class Xu extends St{_parse(t){if(t.data!==this._def.value){const n=this._getOrReturnCtx(t);return Ae(n,{received:n.data,code:Ce.invalid_literal,expected:this._def.value}),lt}return{status:\"valid\",value:t.data}}get value(){return this._def.value}}Xu.create=(e,t)=>new Xu({value:e,typeName:it.ZodLiteral,...yt(t)});function O_(e,t){return new Ea({values:e,typeName:it.ZodEnum,...yt(t)})}class Ea extends St{constructor(){super(...arguments),yu.set(this,void 0)}_parse(t){if(typeof t.data!=\"string\"){const n=this._getOrReturnCtx(t),r=this._def.values;return Ae(n,{expected:Ot.joinValues(r),received:n.parsedType,code:Ce.invalid_type}),lt}if(eh(this,yu)||M_(this,yu,new Set(this._def.values)),!eh(this,yu).has(t.data)){const n=this._getOrReturnCtx(t),r=this._def.values;return Ae(n,{received:n.data,code:Ce.invalid_enum_value,options:r}),lt}return fr(t.data)}get options(){return this._def.values}get enum(){const t={};for(const n of this._def.values)t[n]=n;return t}get Values(){const t={};for(const n of this._def.values)t[n]=n;return t}get Enum(){const t={};for(const n of this._def.values)t[n]=n;return t}extract(t,n=this._def){return Ea.create(t,{...this._def,...n})}exclude(t,n=this._def){return Ea.create(this.options.filter(r=>!t.includes(r)),{...this._def,...n})}}yu=new WeakMap;Ea.create=O_;class ed extends St{constructor(){super(...arguments),bu.set(this,void 0)}_parse(t){const n=Ot.getValidEnumValues(this._def.values),r=this._getOrReturnCtx(t);if(r.parsedType!==Le.string&&r.parsedType!==Le.number){const s=Ot.objectValues(n);return Ae(r,{expected:Ot.joinValues(s),received:r.parsedType,code:Ce.invalid_type}),lt}if(eh(this,bu)||M_(this,bu,new Set(Ot.getValidEnumValues(this._def.values))),!eh(this,bu).has(t.data)){const s=Ot.objectValues(n);return Ae(r,{received:r.data,code:Ce.invalid_enum_value,options:s}),lt}return fr(t.data)}get enum(){return this._def.values}}bu=new WeakMap;ed.create=(e,t)=>new ed({values:e,typeName:it.ZodNativeEnum,...yt(t)});class ql extends St{unwrap(){return this._def.type}_parse(t){const{ctx:n}=this._processInputParams(t);if(n.parsedType!==Le.promise&&n.common.async===!1)return Ae(n,{code:Ce.invalid_type,expected:Le.promise,received:n.parsedType}),lt;const r=n.parsedType===Le.promise?n.data:Promise.resolve(n.data);return fr(r.then(s=>this._def.type.parseAsync(s,{path:n.path,errorMap:n.common.contextualErrorMap})))}}ql.create=(e,t)=>new ql({type:e,typeName:it.ZodPromise,...yt(t)});class Ms extends St{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===it.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(t){const{status:n,ctx:r}=this._processInputParams(t),s=this._def.effect||null,o={addIssue:l=>{Ae(r,l),l.fatal?n.abort():n.dirty()},get path(){return r.path}};if(o.addIssue=o.addIssue.bind(o),s.type===\"preprocess\"){const l=s.transform(r.data,o);if(r.common.async)return Promise.resolve(l).then(async u=>{if(n.value===\"aborted\")return lt;const d=await this._def.schema._parseAsync({data:u,path:r.path,parent:r});return d.status===\"aborted\"?lt:d.status===\"dirty\"||n.value===\"dirty\"?Nl(d.value):d});{if(n.value===\"aborted\")return lt;const u=this._def.schema._parseSync({data:l,path:r.path,parent:r});return u.status===\"aborted\"?lt:u.status===\"dirty\"||n.value===\"dirty\"?Nl(u.value):u}}if(s.type===\"refinement\"){const l=u=>{const d=s.refinement(u,o);if(r.common.async)return Promise.resolve(d);if(d instanceof Promise)throw new Error(\"Async refinement encountered during synchronous parse operation. Use .parseAsync instead.\");return u};if(r.common.async===!1){const u=this._def.schema._parseSync({data:r.data,path:r.path,parent:r});return u.status===\"aborted\"?lt:(u.status===\"dirty\"&&n.dirty(),l(u.value),{status:n.value,value:u.value})}else return this._def.schema._parseAsync({data:r.data,path:r.path,parent:r}).then(u=>u.status===\"aborted\"?lt:(u.status===\"dirty\"&&n.dirty(),l(u.value).then(()=>({status:n.value,value:u.value}))))}if(s.type===\"transform\")if(r.common.async===!1){const l=this._def.schema._parseSync({data:r.data,path:r.path,parent:r});if(!Hu(l))return l;const u=s.transform(l.value,o);if(u instanceof Promise)throw new Error(\"Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.\");return{status:n.value,value:u}}else return this._def.schema._parseAsync({data:r.data,path:r.path,parent:r}).then(l=>Hu(l)?Promise.resolve(s.transform(l.value,o)).then(u=>({status:n.value,value:u})):l);Ot.assertNever(s)}}Ms.create=(e,t,n)=>new Ms({schema:e,typeName:it.ZodEffects,effect:t,...yt(n)});Ms.createWithPreprocess=(e,t,n)=>new Ms({schema:t,effect:{type:\"preprocess\",transform:e},typeName:it.ZodEffects,...yt(n)});class Ws extends St{_parse(t){return this._getType(t)===Le.undefined?fr(void 0):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}}Ws.create=(e,t)=>new Ws({innerType:e,typeName:it.ZodOptional,...yt(t)});class ka extends St{_parse(t){return this._getType(t)===Le.null?fr(null):this._def.innerType._parse(t)}unwrap(){return this._def.innerType}}ka.create=(e,t)=>new ka({innerType:e,typeName:it.ZodNullable,...yt(t)});class td extends St{_parse(t){const{ctx:n}=this._processInputParams(t);let r=n.data;return n.parsedType===Le.undefined&&(r=this._def.defaultValue()),this._def.innerType._parse({data:r,path:n.path,parent:n})}removeDefault(){return this._def.innerType}}td.create=(e,t)=>new td({innerType:e,typeName:it.ZodDefault,defaultValue:typeof t.default==\"function\"?t.default:()=>t.default,...yt(t)});class nd extends St{_parse(t){const{ctx:n}=this._processInputParams(t),r={...n,common:{...n.common,issues:[]}},s=this._def.innerType._parse({data:r.data,path:r.path,parent:{...r}});return qu(s)?s.then(o=>({status:\"valid\",value:o.status===\"valid\"?o.value:this._def.catchValue({get error(){return new Hr(r.common.issues)},input:r.data})})):{status:\"valid\",value:s.status===\"valid\"?s.value:this._def.catchValue({get error(){return new Hr(r.common.issues)},input:r.data})}}removeCatch(){return this._def.innerType}}nd.create=(e,t)=>new nd({innerType:e,typeName:it.ZodCatch,catchValue:typeof t.catch==\"function\"?t.catch:()=>t.catch,...yt(t)});class sh extends St{_parse(t){if(this._getType(t)!==Le.nan){const r=this._getOrReturnCtx(t);return Ae(r,{code:Ce.invalid_type,expected:Le.nan,received:r.parsedType}),lt}return{status:\"valid\",value:t.data}}}sh.create=e=>new sh({typeName:it.ZodNaN,...yt(e)});const $6=Symbol(\"zod_brand\");class Rx extends St{_parse(t){const{ctx:n}=this._processInputParams(t),r=n.data;return this._def.type._parse({data:r,path:n.path,parent:n})}unwrap(){return this._def.type}}class kd extends St{_parse(t){const{status:n,ctx:r}=this._processInputParams(t);if(r.common.async)return(async()=>{const o=await this._def.in._parseAsync({data:r.data,path:r.path,parent:r});return o.status===\"aborted\"?lt:o.status===\"dirty\"?(n.dirty(),Nl(o.value)):this._def.out._parseAsync({data:o.value,path:r.path,parent:r})})();{const s=this._def.in._parseSync({data:r.data,path:r.path,parent:r});return s.status===\"aborted\"?lt:s.status===\"dirty\"?(n.dirty(),{status:\"dirty\",value:s.value}):this._def.out._parseSync({data:s.value,path:r.path,parent:r})}}static create(t,n){return new kd({in:t,out:n,typeName:it.ZodPipeline})}}class rd extends St{_parse(t){const n=this._def.innerType._parse(t),r=s=>(Hu(s)&&(s.value=Object.freeze(s.value)),s);return qu(n)?n.then(s=>r(s)):r(n)}unwrap(){return this._def.innerType}}rd.create=(e,t)=>new rd({innerType:e,typeName:it.ZodReadonly,...yt(t)});function I_(e,t={},n){return e?Hl.create().superRefine((r,s)=>{var o,l;if(!e(r)){const u=typeof t==\"function\"?t(r):typeof t==\"string\"?{message:t}:t,d=(l=(o=u.fatal)!==null&&o!==void 0?o:n)!==null&&l!==void 0?l:!0,f=typeof u==\"string\"?{message:u}:u;s.addIssue({code:\"custom\",...f,fatal:d})}}):Hl.create()}const B6={object:gn.lazycreate};var it;(function(e){e.ZodString=\"ZodString\",e.ZodNumber=\"ZodNumber\",e.ZodNaN=\"ZodNaN\",e.ZodBigInt=\"ZodBigInt\",e.ZodBoolean=\"ZodBoolean\",e.ZodDate=\"ZodDate\",e.ZodSymbol=\"ZodSymbol\",e.ZodUndefined=\"ZodUndefined\",e.ZodNull=\"ZodNull\",e.ZodAny=\"ZodAny\",e.ZodUnknown=\"ZodUnknown\",e.ZodNever=\"ZodNever\",e.ZodVoid=\"ZodVoid\",e.ZodArray=\"ZodArray\",e.ZodObject=\"ZodObject\",e.ZodUnion=\"ZodUnion\",e.ZodDiscriminatedUnion=\"ZodDiscriminatedUnion\",e.ZodIntersection=\"ZodIntersection\",e.ZodTuple=\"ZodTuple\",e.ZodRecord=\"ZodRecord\",e.ZodMap=\"ZodMap\",e.ZodSet=\"ZodSet\",e.ZodFunction=\"ZodFunction\",e.ZodLazy=\"ZodLazy\",e.ZodLiteral=\"ZodLiteral\",e.ZodEnum=\"ZodEnum\",e.ZodEffects=\"ZodEffects\",e.ZodNativeEnum=\"ZodNativeEnum\",e.ZodOptional=\"ZodOptional\",e.ZodNullable=\"ZodNullable\",e.ZodDefault=\"ZodDefault\",e.ZodCatch=\"ZodCatch\",e.ZodPromise=\"ZodPromise\",e.ZodBranded=\"ZodBranded\",e.ZodPipeline=\"ZodPipeline\",e.ZodReadonly=\"ZodReadonly\"})(it||(it={}));const z6=(e,t={message:`Input not instance of ${e.name}`})=>I_(n=>n instanceof e,t),A_=Cs.create,D_=Sa.create,U6=sh.create,V6=Ca.create,F_=Ku.create,H6=Ti.create,q6=th.create,K6=Wu.create,W6=Gu.create,G6=Hl.create,J6=mi.create,Q6=Ro.create,Z6=nh.create,Y6=ks.create,X6=gn.create,e8=gn.strictCreate,t8=Ju.create,n8=Wh.create,r8=Qu.create,s8=Zs.create,o8=Zu.create,a8=rh.create,i8=Ni.create,l8=Ol.create,c8=Yu.create,u8=Xu.create,d8=Ea.create,f8=ed.create,p8=ql.create,j1=Ms.create,h8=Ws.create,g8=ka.create,m8=Ms.createWithPreprocess,v8=kd.create,y8=()=>A_().optional(),b8=()=>D_().optional(),x8=()=>F_().optional(),w8={string:(e=>Cs.create({...e,coerce:!0})),number:(e=>Sa.create({...e,coerce:!0})),boolean:(e=>Ku.create({...e,coerce:!0})),bigint:(e=>Ca.create({...e,coerce:!0})),date:(e=>Ti.create({...e,coerce:!0}))},S8=lt;var P=Object.freeze({__proto__:null,defaultErrorMap:Vl,setErrorMap:S6,getErrorMap:Yp,makeIssue:Xp,EMPTY_PATH:C6,addIssueToContext:Ae,ParseStatus:sr,INVALID:lt,DIRTY:Nl,OK:fr,isAborted:Jy,isDirty:Qy,isValid:Hu,isAsync:qu,get util(){return Ot},get objectUtil(){return Gy},ZodParsedType:Le,getParsedType:pa,ZodType:St,datetimeRegex:P_,ZodString:Cs,ZodNumber:Sa,ZodBigInt:Ca,ZodBoolean:Ku,ZodDate:Ti,ZodSymbol:th,ZodUndefined:Wu,ZodNull:Gu,ZodAny:Hl,ZodUnknown:mi,ZodNever:Ro,ZodVoid:nh,ZodArray:ks,ZodObject:gn,ZodUnion:Ju,ZodDiscriminatedUnion:Wh,ZodIntersection:Qu,ZodTuple:Zs,ZodRecord:Zu,ZodMap:rh,ZodSet:Ni,ZodFunction:Ol,ZodLazy:Yu,ZodLiteral:Xu,ZodEnum:Ea,ZodNativeEnum:ed,ZodPromise:ql,ZodEffects:Ms,ZodTransformer:Ms,ZodOptional:Ws,ZodNullable:ka,ZodDefault:td,ZodCatch:nd,ZodNaN:sh,BRAND:$6,ZodBranded:Rx,ZodPipeline:kd,ZodReadonly:rd,custom:I_,Schema:St,ZodSchema:St,late:B6,get ZodFirstPartyTypeKind(){return it},coerce:w8,any:G6,array:Y6,bigint:V6,boolean:F_,date:H6,discriminatedUnion:n8,effect:j1,enum:d8,function:l8,instanceof:z6,intersection:r8,lazy:c8,literal:u8,map:a8,nan:U6,nativeEnum:f8,never:Q6,null:W6,nullable:g8,number:D_,object:X6,oboolean:x8,onumber:b8,optional:h8,ostring:y8,pipeline:v8,preprocess:m8,promise:p8,record:o8,set:i8,strictObject:e8,string:A_,symbol:q6,transformer:j1,tuple:s8,undefined:K6,union:t8,unknown:J6,void:Z6,NEVER:S8,ZodIssueCode:Ce,quotelessJson:w6,ZodError:Hr}),L_=y.createContext({dragDropManager:void 0}),os;(function(e){e.SOURCE=\"SOURCE\",e.TARGET=\"TARGET\"})(os||(os={}));function gt(e,t){for(var n=arguments.length,r=new Array(n>2?n-2:0),s=2;s<n;s++)r[s-2]=arguments[s];if(!e){var o;if(t===void 0)o=new Error(\"Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.\");else{var l=0;o=new Error(t.replace(/%s/g,function(){return r[l++]})),o.name=\"Invariant Violation\"}throw o.framesToPop=1,o}}var Px=\"dnd-core/INIT_COORDS\",Gh=\"dnd-core/BEGIN_DRAG\",Ox=\"dnd-core/PUBLISH_DRAG_SOURCE\",Jh=\"dnd-core/HOVER\",Qh=\"dnd-core/DROP\",Zh=\"dnd-core/END_DRAG\";function T1(e,t){return{type:Px,payload:{sourceClientOffset:t||null,clientOffset:e||null}}}function yp(e){\"@babel/helpers - typeof\";return typeof Symbol==\"function\"&&typeof Symbol.iterator==\"symbol\"?yp=function(n){return typeof n}:yp=function(n){return n&&typeof Symbol==\"function\"&&n.constructor===Symbol&&n!==Symbol.prototype?\"symbol\":typeof n},yp(e)}function C8(e,t,n){return t.split(\".\").reduce(function(r,s){return r&&r[s]?r[s]:n||null},e)}function E8(e,t){return e.filter(function(n){return n!==t})}function $_(e){return yp(e)===\"object\"}function k8(e,t){var n=new Map,r=function(l){n.set(l,n.has(l)?n.get(l)+1:1)};e.forEach(r),t.forEach(r);var s=[];return n.forEach(function(o,l){o===1&&s.push(l)}),s}function j8(e,t){return e.filter(function(n){return t.indexOf(n)>-1})}var T8={type:Px,payload:{clientOffset:null,sourceClientOffset:null}};function N8(e){return function(){var n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{publishSource:!0},s=r.publishSource,o=s===void 0?!0:s,l=r.clientOffset,u=r.getSourceClientOffset,d=e.getMonitor(),f=e.getRegistry();e.dispatch(T1(l)),M8(n,d,f);var h=P8(n,d);if(h===null){e.dispatch(T8);return}var m=null;if(l){if(!u)throw new Error(\"getSourceClientOffset must be defined\");_8(u),m=u(h)}e.dispatch(T1(l,m));var g=f.getSource(h),x=g.beginDrag(d,h);if(x!=null){R8(x),f.pinSource(h);var b=f.getSourceType(h);return{type:Gh,payload:{itemType:b,item:x,sourceId:h,clientOffset:l||null,sourceClientOffset:m||null,isSourcePublic:!!o}}}}}function M8(e,t,n){gt(!t.isDragging(),\"Cannot call beginDrag while dragging.\"),e.forEach(function(r){gt(n.getSource(r),\"Expected sourceIds to be registered.\")})}function _8(e){gt(typeof e==\"function\",\"When clientOffset is provided, getSourceClientOffset must be a function.\")}function R8(e){gt($_(e),\"Item must be an object.\")}function P8(e,t){for(var n=null,r=e.length-1;r>=0;r--)if(t.canDragSource(e[r])){n=e[r];break}return n}function O8(e){return function(){var n=e.getMonitor();if(n.isDragging())return{type:Ox}}}function Yy(e,t){return t===null?e===null:Array.isArray(e)?e.some(function(n){return n===t}):e===t}function I8(e){return function(n){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},s=r.clientOffset;A8(n);var o=n.slice(0),l=e.getMonitor(),u=e.getRegistry();D8(o,l,u);var d=l.getItemType();return F8(o,u,d),L8(o,l,u),{type:Jh,payload:{targetIds:o,clientOffset:s||null}}}}function A8(e){gt(Array.isArray(e),\"Expected targetIds to be an array.\")}function D8(e,t,n){gt(t.isDragging(),\"Cannot call hover while not dragging.\"),gt(!t.didDrop(),\"Cannot call hover after drop.\");for(var r=0;r<e.length;r++){var s=e[r];gt(e.lastIndexOf(s)===r,\"Expected targetIds to be unique in the passed array.\");var o=n.getTarget(s);gt(o,\"Expected targetIds to be registered.\")}}function F8(e,t,n){for(var r=e.length-1;r>=0;r--){var s=e[r],o=t.getTargetType(s);Yy(o,n)||e.splice(r,1)}}function L8(e,t,n){e.forEach(function(r){var s=n.getTarget(r);s.hover(t,r)})}function N1(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable})),n.push.apply(n,r)}return n}function M1(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=null?arguments[t]:{};t%2?N1(Object(n),!0).forEach(function(r){$8(e,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):N1(Object(n)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))})}return e}function $8(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function B8(e){return function(){var n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},r=e.getMonitor(),s=e.getRegistry();z8(r);var o=H8(r);o.forEach(function(l,u){var d=U8(l,u,s,r),f={type:Qh,payload:{dropResult:M1(M1({},n),d)}};e.dispatch(f)})}}function z8(e){gt(e.isDragging(),\"Cannot call drop while not dragging.\"),gt(!e.didDrop(),\"Cannot call drop twice during one drag operation.\")}function U8(e,t,n,r){var s=n.getTarget(e),o=s?s.drop(r,e):void 0;return V8(o),typeof o>\"u\"&&(o=t===0?{}:r.getDropResult()),o}function V8(e){gt(typeof e>\"u\"||$_(e),\"Drop result must either be an object or undefined.\")}function H8(e){var t=e.getTargetIds().filter(e.canDropOnTarget,e);return t.reverse(),t}function q8(e){return function(){var n=e.getMonitor(),r=e.getRegistry();K8(n);var s=n.getSourceId();if(s!=null){var o=r.getSource(s,!0);o.endDrag(n,s),r.unpinSource()}return{type:Zh}}}function K8(e){gt(e.isDragging(),\"Cannot call endDrag while not dragging.\")}function W8(e){return{beginDrag:N8(e),publishDragSource:O8(e),hover:I8(e),drop:B8(e),endDrag:q8(e)}}function G8(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function J8(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Q8(e,t,n){return t&&J8(e.prototype,t),e}function iu(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Z8=(function(){function e(t,n){var r=this;G8(this,e),iu(this,\"store\",void 0),iu(this,\"monitor\",void 0),iu(this,\"backend\",void 0),iu(this,\"isSetUp\",!1),iu(this,\"handleRefCountChange\",function(){var s=r.store.getState().refCount>0;r.backend&&(s&&!r.isSetUp?(r.backend.setup(),r.isSetUp=!0):!s&&r.isSetUp&&(r.backend.teardown(),r.isSetUp=!1))}),this.store=t,this.monitor=n,t.subscribe(this.handleRefCountChange)}return Q8(e,[{key:\"receiveBackend\",value:function(n){this.backend=n}},{key:\"getMonitor\",value:function(){return this.monitor}},{key:\"getBackend\",value:function(){return this.backend}},{key:\"getRegistry\",value:function(){return this.monitor.registry}},{key:\"getActions\",value:function(){var n=this,r=this.store.dispatch;function s(l){return function(){for(var u=arguments.length,d=new Array(u),f=0;f<u;f++)d[f]=arguments[f];var h=l.apply(n,d);typeof h<\"u\"&&r(h)}}var o=W8(this);return Object.keys(o).reduce(function(l,u){var d=o[u];return l[u]=s(d),l},{})}},{key:\"dispatch\",value:function(n){this.store.dispatch(n)}}]),e})();function ns(e){return\"Minified Redux error #\"+e+\"; visit https://redux.js.org/Errors?code=\"+e+\" for the full message or use the non-minified dev environment for full errors. \"}var _1=(function(){return typeof Symbol==\"function\"&&Symbol.observable||\"@@observable\"})(),R1=function(){return Math.random().toString(36).substring(7).split(\"\").join(\".\")},P1={INIT:\"@@redux/INIT\"+R1(),REPLACE:\"@@redux/REPLACE\"+R1()};function Y8(e){if(typeof e!=\"object\"||e===null)return!1;for(var t=e;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function B_(e,t,n){var r;if(typeof t==\"function\"&&typeof n==\"function\"||typeof n==\"function\"&&typeof arguments[3]==\"function\")throw new Error(ns(0));if(typeof t==\"function\"&&typeof n>\"u\"&&(n=t,t=void 0),typeof n<\"u\"){if(typeof n!=\"function\")throw new Error(ns(1));return n(B_)(e,t)}if(typeof e!=\"function\")throw new Error(ns(2));var s=e,o=t,l=[],u=l,d=!1;function f(){u===l&&(u=l.slice())}function h(){if(d)throw new Error(ns(3));return o}function m(w){if(typeof w!=\"function\")throw new Error(ns(4));if(d)throw new Error(ns(5));var C=!0;return f(),u.push(w),function(){if(C){if(d)throw new Error(ns(6));C=!1,f();var j=u.indexOf(w);u.splice(j,1),l=null}}}function g(w){if(!Y8(w))throw new Error(ns(7));if(typeof w.type>\"u\")throw new Error(ns(8));if(d)throw new Error(ns(9));try{d=!0,o=s(o,w)}finally{d=!1}for(var C=l=u,k=0;k<C.length;k++){var j=C[k];j()}return w}function x(w){if(typeof w!=\"function\")throw new Error(ns(10));s=w,g({type:P1.REPLACE})}function b(){var w,C=m;return w={subscribe:function(j){if(typeof j!=\"object\"||j===null)throw new Error(ns(11));function M(){j.next&&j.next(h())}M();var _=C(M);return{unsubscribe:_}}},w[_1]=function(){return this},w}return g({type:P1.INIT}),r={dispatch:g,subscribe:m,getState:h,replaceReducer:x},r[_1]=b,r}var X8=function(t,n){return t===n};function eV(e,t){return!e&&!t?!0:!e||!t?!1:e.x===t.x&&e.y===t.y}function tV(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:X8;if(e.length!==t.length)return!1;for(var r=0;r<e.length;++r)if(!n(e[r],t[r]))return!1;return!0}function O1(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable})),n.push.apply(n,r)}return n}function I1(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=null?arguments[t]:{};t%2?O1(Object(n),!0).forEach(function(r){nV(e,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):O1(Object(n)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))})}return e}function nV(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var A1={initialSourceClientOffset:null,initialClientOffset:null,clientOffset:null};function rV(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:A1,t=arguments.length>1?arguments[1]:void 0,n=t.payload;switch(t.type){case Px:case Gh:return{initialSourceClientOffset:n.sourceClientOffset,initialClientOffset:n.clientOffset,clientOffset:n.clientOffset};case Jh:return eV(e.clientOffset,n.clientOffset)?e:I1(I1({},e),{},{clientOffset:n.clientOffset});case Zh:case Qh:return A1;default:return e}}var Ix=\"dnd-core/ADD_SOURCE\",Ax=\"dnd-core/ADD_TARGET\",Dx=\"dnd-core/REMOVE_SOURCE\",Yh=\"dnd-core/REMOVE_TARGET\";function sV(e){return{type:Ix,payload:{sourceId:e}}}function oV(e){return{type:Ax,payload:{targetId:e}}}function aV(e){return{type:Dx,payload:{sourceId:e}}}function iV(e){return{type:Yh,payload:{targetId:e}}}function D1(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable})),n.push.apply(n,r)}return n}function rs(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=null?arguments[t]:{};t%2?D1(Object(n),!0).forEach(function(r){lV(e,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):D1(Object(n)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))})}return e}function lV(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var cV={itemType:null,item:null,sourceId:null,targetIds:[],dropResult:null,didDrop:!1,isSourcePublic:null};function uV(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:cV,t=arguments.length>1?arguments[1]:void 0,n=t.payload;switch(t.type){case Gh:return rs(rs({},e),{},{itemType:n.itemType,item:n.item,sourceId:n.sourceId,isSourcePublic:n.isSourcePublic,dropResult:null,didDrop:!1});case Ox:return rs(rs({},e),{},{isSourcePublic:!0});case Jh:return rs(rs({},e),{},{targetIds:n.targetIds});case Yh:return e.targetIds.indexOf(n.targetId)===-1?e:rs(rs({},e),{},{targetIds:E8(e.targetIds,n.targetId)});case Qh:return rs(rs({},e),{},{dropResult:n.dropResult,didDrop:!0,targetIds:[]});case Zh:return rs(rs({},e),{},{itemType:null,item:null,sourceId:null,dropResult:null,didDrop:!1,isSourcePublic:null,targetIds:[]});default:return e}}function dV(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case Ix:case Ax:return e+1;case Dx:case Yh:return e-1;default:return e}}var oh=[],Fx=[];oh.__IS_NONE__=!0;Fx.__IS_ALL__=!0;function fV(e,t){if(e===oh)return!1;if(e===Fx||typeof t>\"u\")return!0;var n=j8(t,e);return n.length>0}function pV(){var e=arguments.length>1?arguments[1]:void 0;switch(e.type){case Jh:break;case Ix:case Ax:case Yh:case Dx:return oh;case Gh:case Ox:case Zh:case Qh:default:return Fx}var t=e.payload,n=t.targetIds,r=n===void 0?[]:n,s=t.prevTargetIds,o=s===void 0?[]:s,l=k8(r,o),u=l.length>0||!tV(r,o);if(!u)return oh;var d=o[o.length-1],f=r[r.length-1];return d!==f&&(d&&l.push(d),f&&l.push(f)),l}function hV(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0;return e+1}function F1(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable})),n.push.apply(n,r)}return n}function L1(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=null?arguments[t]:{};t%2?F1(Object(n),!0).forEach(function(r){gV(e,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):F1(Object(n)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))})}return e}function gV(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function mV(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;return{dirtyHandlerIds:pV(e.dirtyHandlerIds,{type:t.type,payload:L1(L1({},t.payload),{},{prevTargetIds:C8(e,\"dragOperation.targetIds\",[])})}),dragOffset:rV(e.dragOffset,t),refCount:dV(e.refCount,t),dragOperation:uV(e.dragOperation,t),stateId:hV(e.stateId)}}function vV(e,t){return{x:e.x+t.x,y:e.y+t.y}}function z_(e,t){return{x:e.x-t.x,y:e.y-t.y}}function yV(e){var t=e.clientOffset,n=e.initialClientOffset,r=e.initialSourceClientOffset;return!t||!n||!r?null:z_(vV(t,r),n)}function bV(e){var t=e.clientOffset,n=e.initialClientOffset;return!t||!n?null:z_(t,n)}function xV(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function wV(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function SV(e,t,n){return t&&wV(e.prototype,t),e}function $1(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var CV=(function(){function e(t,n){xV(this,e),$1(this,\"store\",void 0),$1(this,\"registry\",void 0),this.store=t,this.registry=n}return SV(e,[{key:\"subscribeToStateChange\",value:function(n){var r=this,s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{handlerIds:void 0},o=s.handlerIds;gt(typeof n==\"function\",\"listener must be a function.\"),gt(typeof o>\"u\"||Array.isArray(o),\"handlerIds, when specified, must be an array of strings.\");var l=this.store.getState().stateId,u=function(){var f=r.store.getState(),h=f.stateId;try{var m=h===l||h===l+1&&!fV(f.dirtyHandlerIds,o);m||n()}finally{l=h}};return this.store.subscribe(u)}},{key:\"subscribeToOffsetChange\",value:function(n){var r=this;gt(typeof n==\"function\",\"listener must be a function.\");var s=this.store.getState().dragOffset,o=function(){var u=r.store.getState().dragOffset;u!==s&&(s=u,n())};return this.store.subscribe(o)}},{key:\"canDragSource\",value:function(n){if(!n)return!1;var r=this.registry.getSource(n);return gt(r,\"Expected to find a valid source. sourceId=\".concat(n)),this.isDragging()?!1:r.canDrag(this,n)}},{key:\"canDropOnTarget\",value:function(n){if(!n)return!1;var r=this.registry.getTarget(n);if(gt(r,\"Expected to find a valid target. targetId=\".concat(n)),!this.isDragging()||this.didDrop())return!1;var s=this.registry.getTargetType(n),o=this.getItemType();return Yy(s,o)&&r.canDrop(this,n)}},{key:\"isDragging\",value:function(){return!!this.getItemType()}},{key:\"isDraggingSource\",value:function(n){if(!n)return!1;var r=this.registry.getSource(n,!0);if(gt(r,\"Expected to find a valid source. sourceId=\".concat(n)),!this.isDragging()||!this.isSourcePublic())return!1;var s=this.registry.getSourceType(n),o=this.getItemType();return s!==o?!1:r.isDragging(this,n)}},{key:\"isOverTarget\",value:function(n){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{shallow:!1};if(!n)return!1;var s=r.shallow;if(!this.isDragging())return!1;var o=this.registry.getTargetType(n),l=this.getItemType();if(l&&!Yy(o,l))return!1;var u=this.getTargetIds();if(!u.length)return!1;var d=u.indexOf(n);return s?d===u.length-1:d>-1}},{key:\"getItemType\",value:function(){return this.store.getState().dragOperation.itemType}},{key:\"getItem\",value:function(){return this.store.getState().dragOperation.item}},{key:\"getSourceId\",value:function(){return this.store.getState().dragOperation.sourceId}},{key:\"getTargetIds\",value:function(){return this.store.getState().dragOperation.targetIds}},{key:\"getDropResult\",value:function(){return this.store.getState().dragOperation.dropResult}},{key:\"didDrop\",value:function(){return this.store.getState().dragOperation.didDrop}},{key:\"isSourcePublic\",value:function(){return!!this.store.getState().dragOperation.isSourcePublic}},{key:\"getInitialClientOffset\",value:function(){return this.store.getState().dragOffset.initialClientOffset}},{key:\"getInitialSourceClientOffset\",value:function(){return this.store.getState().dragOffset.initialSourceClientOffset}},{key:\"getClientOffset\",value:function(){return this.store.getState().dragOffset.clientOffset}},{key:\"getSourceClientOffset\",value:function(){return yV(this.store.getState().dragOffset)}},{key:\"getDifferenceFromInitialOffset\",value:function(){return bV(this.store.getState().dragOffset)}}]),e})(),EV=0;function kV(){return EV++}function bp(e){\"@babel/helpers - typeof\";return typeof Symbol==\"function\"&&typeof Symbol.iterator==\"symbol\"?bp=function(n){return typeof n}:bp=function(n){return n&&typeof Symbol==\"function\"&&n.constructor===Symbol&&n!==Symbol.prototype?\"symbol\":typeof n},bp(e)}function jV(e){gt(typeof e.canDrag==\"function\",\"Expected canDrag to be a function.\"),gt(typeof e.beginDrag==\"function\",\"Expected beginDrag to be a function.\"),gt(typeof e.endDrag==\"function\",\"Expected endDrag to be a function.\")}function TV(e){gt(typeof e.canDrop==\"function\",\"Expected canDrop to be a function.\"),gt(typeof e.hover==\"function\",\"Expected hover to be a function.\"),gt(typeof e.drop==\"function\",\"Expected beginDrag to be a function.\")}function Xy(e,t){if(t&&Array.isArray(e)){e.forEach(function(n){return Xy(n,!1)});return}gt(typeof e==\"string\"||bp(e)===\"symbol\",t?\"Type can only be a string, a symbol, or an array of either.\":\"Type can only be a string or a symbol.\")}const B1=typeof global<\"u\"?global:self,U_=B1.MutationObserver||B1.WebKitMutationObserver;function V_(e){return function(){const n=setTimeout(s,0),r=setInterval(s,50);function s(){clearTimeout(n),clearInterval(r),e()}}}function NV(e){let t=1;const n=new U_(e),r=document.createTextNode(\"\");return n.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}const MV=typeof U_==\"function\"?NV:V_;class _V{enqueueTask(t){const{queue:n,requestFlush:r}=this;n.length||(r(),this.flushing=!0),n[n.length]=t}constructor(){this.queue=[],this.pendingErrors=[],this.flushing=!1,this.index=0,this.capacity=1024,this.flush=()=>{const{queue:t}=this;for(;this.index<t.length;){const n=this.index;if(this.index++,t[n].call(),this.index>this.capacity){for(let r=0,s=t.length-this.index;r<s;r++)t[r]=t[r+this.index];t.length-=this.index,this.index=0}}t.length=0,this.index=0,this.flushing=!1},this.registerPendingError=t=>{this.pendingErrors.push(t),this.requestErrorThrow()},this.requestFlush=MV(this.flush),this.requestErrorThrow=V_(()=>{if(this.pendingErrors.length)throw this.pendingErrors.shift()})}}class RV{call(){try{this.task&&this.task()}catch(t){this.onError(t)}finally{this.task=null,this.release(this)}}constructor(t,n){this.onError=t,this.release=n,this.task=null}}class PV{create(t){const n=this.freeTasks,r=n.length?n.pop():new RV(this.onError,s=>n[n.length]=s);return r.task=t,r}constructor(t){this.onError=t,this.freeTasks=[]}}const H_=new _V,OV=new PV(H_.registerPendingError);function IV(e){H_.enqueueTask(OV.create(e))}function AV(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function DV(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function FV(e,t,n){return t&&DV(e.prototype,t),e}function vl(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function LV(e,t){return UV(e)||zV(e,t)||BV(e,t)||$V()}function $V(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function BV(e,t){if(e){if(typeof e==\"string\")return z1(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return z1(e,t)}}function z1(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function zV(e,t){var n=e==null?null:typeof Symbol<\"u\"&&e[Symbol.iterator]||e[\"@@iterator\"];if(n!=null){var r=[],s=!0,o=!1,l,u;try{for(n=n.call(e);!(s=(l=n.next()).done)&&(r.push(l.value),!(t&&r.length===t));s=!0);}catch(d){o=!0,u=d}finally{try{!s&&n.return!=null&&n.return()}finally{if(o)throw u}}return r}}function UV(e){if(Array.isArray(e))return e}function VV(e){var t=kV().toString();switch(e){case os.SOURCE:return\"S\".concat(t);case os.TARGET:return\"T\".concat(t);default:throw new Error(\"Unknown Handler Role: \".concat(e))}}function U1(e){switch(e[0]){case\"S\":return os.SOURCE;case\"T\":return os.TARGET;default:gt(!1,\"Cannot parse handler ID: \".concat(e))}}function V1(e,t){var n=e.entries(),r=!1;do{var s=n.next(),o=s.done,l=LV(s.value,2),u=l[1];if(u===t)return!0;r=!!o}while(!r);return!1}var HV=(function(){function e(t){AV(this,e),vl(this,\"types\",new Map),vl(this,\"dragSources\",new Map),vl(this,\"dropTargets\",new Map),vl(this,\"pinnedSourceId\",null),vl(this,\"pinnedSource\",null),vl(this,\"store\",void 0),this.store=t}return FV(e,[{key:\"addSource\",value:function(n,r){Xy(n),jV(r);var s=this.addHandler(os.SOURCE,n,r);return this.store.dispatch(sV(s)),s}},{key:\"addTarget\",value:function(n,r){Xy(n,!0),TV(r);var s=this.addHandler(os.TARGET,n,r);return this.store.dispatch(oV(s)),s}},{key:\"containsHandler\",value:function(n){return V1(this.dragSources,n)||V1(this.dropTargets,n)}},{key:\"getSource\",value:function(n){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;gt(this.isSourceId(n),\"Expected a valid source ID.\");var s=r&&n===this.pinnedSourceId,o=s?this.pinnedSource:this.dragSources.get(n);return o}},{key:\"getTarget\",value:function(n){return gt(this.isTargetId(n),\"Expected a valid target ID.\"),this.dropTargets.get(n)}},{key:\"getSourceType\",value:function(n){return gt(this.isSourceId(n),\"Expected a valid source ID.\"),this.types.get(n)}},{key:\"getTargetType\",value:function(n){return gt(this.isTargetId(n),\"Expected a valid target ID.\"),this.types.get(n)}},{key:\"isSourceId\",value:function(n){var r=U1(n);return r===os.SOURCE}},{key:\"isTargetId\",value:function(n){var r=U1(n);return r===os.TARGET}},{key:\"removeSource\",value:function(n){var r=this;gt(this.getSource(n),\"Expected an existing source.\"),this.store.dispatch(aV(n)),IV(function(){r.dragSources.delete(n),r.types.delete(n)})}},{key:\"removeTarget\",value:function(n){gt(this.getTarget(n),\"Expected an existing target.\"),this.store.dispatch(iV(n)),this.dropTargets.delete(n),this.types.delete(n)}},{key:\"pinSource\",value:function(n){var r=this.getSource(n);gt(r,\"Expected an existing source.\"),this.pinnedSourceId=n,this.pinnedSource=r}},{key:\"unpinSource\",value:function(){gt(this.pinnedSource,\"No source is pinned at the time.\"),this.pinnedSourceId=null,this.pinnedSource=null}},{key:\"addHandler\",value:function(n,r,s){var o=VV(n);return this.types.set(o,r),n===os.SOURCE?this.dragSources.set(o,s):n===os.TARGET&&this.dropTargets.set(o,s),o}}]),e})();function qV(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:void 0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,s=KV(r),o=new CV(s,new HV(s)),l=new Z8(s,o),u=e(l,t,n);return l.receiveBackend(u),l}function KV(e){var t=typeof window<\"u\"&&window.__REDUX_DEVTOOLS_EXTENSION__;return B_(mV,e&&t&&t({name:\"dnd-core\",instanceId:\"dnd-core\"}))}var WV=[\"children\"];function GV(e,t){return YV(e)||ZV(e,t)||QV(e,t)||JV()}function JV(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function QV(e,t){if(e){if(typeof e==\"string\")return H1(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return H1(e,t)}}function H1(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function ZV(e,t){var n=e==null?null:typeof Symbol<\"u\"&&e[Symbol.iterator]||e[\"@@iterator\"];if(n!=null){var r=[],s=!0,o=!1,l,u;try{for(n=n.call(e);!(s=(l=n.next()).done)&&(r.push(l.value),!(t&&r.length===t));s=!0);}catch(d){o=!0,u=d}finally{try{!s&&n.return!=null&&n.return()}finally{if(o)throw u}}return r}}function YV(e){if(Array.isArray(e))return e}function XV(e,t){if(e==null)return{};var n=eH(e,t),r,s;if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(s=0;s<o.length;s++)r=o[s],!(t.indexOf(r)>=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function eH(e,t){if(e==null)return{};var n={},r=Object.keys(e),s,o;for(o=0;o<r.length;o++)s=r[o],!(t.indexOf(s)>=0)&&(n[s]=e[s]);return n}var q1=0,xp=Symbol.for(\"__REACT_DND_CONTEXT_INSTANCE__\"),tH=y.memo(function(t){var n=t.children,r=XV(t,WV),s=nH(r),o=GV(s,2),l=o[0],u=o[1];return y.useEffect(function(){if(u){var d=q_();return++q1,function(){--q1===0&&(d[xp]=null)}}},[]),i.jsx(L_.Provider,Object.assign({value:l},{children:n}),void 0)});function nH(e){if(\"manager\"in e){var t={dragDropManager:e.manager};return[t,!1]}var n=rH(e.backend,e.context,e.options,e.debugMode),r=!e.context;return[n,r]}function rH(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:q_(),n=arguments.length>2?arguments[2]:void 0,r=arguments.length>3?arguments[3]:void 0,s=t;return s[xp]||(s[xp]={dragDropManager:qV(e,t,n,r)}),s[xp]}function q_(){return typeof global<\"u\"?global:window}function sH(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function oH(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function aH(e,t,n){return t&&oH(e.prototype,t),e}function K1(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Iv=!1,Av=!1,iH=(function(){function e(t){sH(this,e),K1(this,\"internalMonitor\",void 0),K1(this,\"sourceId\",null),this.internalMonitor=t.getMonitor()}return aH(e,[{key:\"receiveHandlerId\",value:function(n){this.sourceId=n}},{key:\"getHandlerId\",value:function(){return this.sourceId}},{key:\"canDrag\",value:function(){gt(!Iv,\"You may not call monitor.canDrag() inside your canDrag() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor\");try{return Iv=!0,this.internalMonitor.canDragSource(this.sourceId)}finally{Iv=!1}}},{key:\"isDragging\",value:function(){if(!this.sourceId)return!1;gt(!Av,\"You may not call monitor.isDragging() inside your isDragging() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor\");try{return Av=!0,this.internalMonitor.isDraggingSource(this.sourceId)}finally{Av=!1}}},{key:\"subscribeToStateChange\",value:function(n,r){return this.internalMonitor.subscribeToStateChange(n,r)}},{key:\"isDraggingSource\",value:function(n){return this.internalMonitor.isDraggingSource(n)}},{key:\"isOverTarget\",value:function(n,r){return this.internalMonitor.isOverTarget(n,r)}},{key:\"getTargetIds\",value:function(){return this.internalMonitor.getTargetIds()}},{key:\"isSourcePublic\",value:function(){return this.internalMonitor.isSourcePublic()}},{key:\"getSourceId\",value:function(){return this.internalMonitor.getSourceId()}},{key:\"subscribeToOffsetChange\",value:function(n){return this.internalMonitor.subscribeToOffsetChange(n)}},{key:\"canDragSource\",value:function(n){return this.internalMonitor.canDragSource(n)}},{key:\"canDropOnTarget\",value:function(n){return this.internalMonitor.canDropOnTarget(n)}},{key:\"getItemType\",value:function(){return this.internalMonitor.getItemType()}},{key:\"getItem\",value:function(){return this.internalMonitor.getItem()}},{key:\"getDropResult\",value:function(){return this.internalMonitor.getDropResult()}},{key:\"didDrop\",value:function(){return this.internalMonitor.didDrop()}},{key:\"getInitialClientOffset\",value:function(){return this.internalMonitor.getInitialClientOffset()}},{key:\"getInitialSourceClientOffset\",value:function(){return this.internalMonitor.getInitialSourceClientOffset()}},{key:\"getSourceClientOffset\",value:function(){return this.internalMonitor.getSourceClientOffset()}},{key:\"getClientOffset\",value:function(){return this.internalMonitor.getClientOffset()}},{key:\"getDifferenceFromInitialOffset\",value:function(){return this.internalMonitor.getDifferenceFromInitialOffset()}}]),e})();function lH(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function cH(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function uH(e,t,n){return t&&cH(e.prototype,t),e}function W1(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Dv=!1,dH=(function(){function e(t){lH(this,e),W1(this,\"internalMonitor\",void 0),W1(this,\"targetId\",null),this.internalMonitor=t.getMonitor()}return uH(e,[{key:\"receiveHandlerId\",value:function(n){this.targetId=n}},{key:\"getHandlerId\",value:function(){return this.targetId}},{key:\"subscribeToStateChange\",value:function(n,r){return this.internalMonitor.subscribeToStateChange(n,r)}},{key:\"canDrop\",value:function(){if(!this.targetId)return!1;gt(!Dv,\"You may not call monitor.canDrop() inside your canDrop() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drop-target-monitor\");try{return Dv=!0,this.internalMonitor.canDropOnTarget(this.targetId)}finally{Dv=!1}}},{key:\"isOver\",value:function(n){return this.targetId?this.internalMonitor.isOverTarget(this.targetId,n):!1}},{key:\"getItemType\",value:function(){return this.internalMonitor.getItemType()}},{key:\"getItem\",value:function(){return this.internalMonitor.getItem()}},{key:\"getDropResult\",value:function(){return this.internalMonitor.getDropResult()}},{key:\"didDrop\",value:function(){return this.internalMonitor.didDrop()}},{key:\"getInitialClientOffset\",value:function(){return this.internalMonitor.getInitialClientOffset()}},{key:\"getInitialSourceClientOffset\",value:function(){return this.internalMonitor.getInitialSourceClientOffset()}},{key:\"getSourceClientOffset\",value:function(){return this.internalMonitor.getSourceClientOffset()}},{key:\"getClientOffset\",value:function(){return this.internalMonitor.getClientOffset()}},{key:\"getDifferenceFromInitialOffset\",value:function(){return this.internalMonitor.getDifferenceFromInitialOffset()}}]),e})();function fH(e){if(typeof e.type!=\"string\"){var t=e.type.displayName||e.type.name||\"the component\";throw new Error(\"Only native element nodes can now be passed to React DnD connectors.\"+\"You can either wrap \".concat(t,\" into a <div>, or turn it into a \")+\"drag source or a drop target itself.\")}}function pH(e){return function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:null,n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;if(!y.isValidElement(t)){var r=t;return e(r,n),r}var s=t;fH(s);var o=n?function(l){return e(l,n)}:e;return hH(s,o)}}function K_(e){var t={};return Object.keys(e).forEach(function(n){var r=e[n];if(n.endsWith(\"Ref\"))t[n]=e[n];else{var s=pH(r);t[n]=function(){return s}}}),t}function G1(e,t){typeof e==\"function\"?e(t):e.current=t}function hH(e,t){var n=e.ref;return gt(typeof n!=\"string\",\"Cannot connect React DnD to an element with an existing string ref. Please convert it to use a callback ref instead, or wrap it into a <span> or <div>. Read more: https://reactjs.org/docs/refs-and-the-dom.html#callback-refs\"),n?y.cloneElement(e,{ref:function(s){G1(n,s),G1(t,s)}}):y.cloneElement(e,{ref:t})}function wp(e){\"@babel/helpers - typeof\";return typeof Symbol==\"function\"&&typeof Symbol.iterator==\"symbol\"?wp=function(n){return typeof n}:wp=function(n){return n&&typeof Symbol==\"function\"&&n.constructor===Symbol&&n!==Symbol.prototype?\"symbol\":typeof n},wp(e)}function eb(e){return e!==null&&wp(e)===\"object\"&&Object.prototype.hasOwnProperty.call(e,\"current\")}function tb(e,t,n,r){var s=void 0;if(s!==void 0)return!!s;if(e===t)return!0;if(typeof e!=\"object\"||!e||typeof t!=\"object\"||!t)return!1;var o=Object.keys(e),l=Object.keys(t);if(o.length!==l.length)return!1;for(var u=Object.prototype.hasOwnProperty.bind(t),d=0;d<o.length;d++){var f=o[d];if(!u(f))return!1;var h=e[f],m=t[f];if(s=void 0,s===!1||s===void 0&&h!==m)return!1}return!0}function gH(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function mH(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function vH(e,t,n){return t&&mH(e.prototype,t),e}function tr(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var yH=(function(){function e(t){var n=this;gH(this,e),tr(this,\"hooks\",K_({dragSource:function(s,o){n.clearDragSource(),n.dragSourceOptions=o||null,eb(s)?n.dragSourceRef=s:n.dragSourceNode=s,n.reconnectDragSource()},dragPreview:function(s,o){n.clearDragPreview(),n.dragPreviewOptions=o||null,eb(s)?n.dragPreviewRef=s:n.dragPreviewNode=s,n.reconnectDragPreview()}})),tr(this,\"handlerId\",null),tr(this,\"dragSourceRef\",null),tr(this,\"dragSourceNode\",void 0),tr(this,\"dragSourceOptionsInternal\",null),tr(this,\"dragSourceUnsubscribe\",void 0),tr(this,\"dragPreviewRef\",null),tr(this,\"dragPreviewNode\",void 0),tr(this,\"dragPreviewOptionsInternal\",null),tr(this,\"dragPreviewUnsubscribe\",void 0),tr(this,\"lastConnectedHandlerId\",null),tr(this,\"lastConnectedDragSource\",null),tr(this,\"lastConnectedDragSourceOptions\",null),tr(this,\"lastConnectedDragPreview\",null),tr(this,\"lastConnectedDragPreviewOptions\",null),tr(this,\"backend\",void 0),this.backend=t}return vH(e,[{key:\"receiveHandlerId\",value:function(n){this.handlerId!==n&&(this.handlerId=n,this.reconnect())}},{key:\"connectTarget\",get:function(){return this.dragSource}},{key:\"dragSourceOptions\",get:function(){return this.dragSourceOptionsInternal},set:function(n){this.dragSourceOptionsInternal=n}},{key:\"dragPreviewOptions\",get:function(){return this.dragPreviewOptionsInternal},set:function(n){this.dragPreviewOptionsInternal=n}},{key:\"reconnect\",value:function(){this.reconnectDragSource(),this.reconnectDragPreview()}},{key:\"reconnectDragSource\",value:function(){var n=this.dragSource,r=this.didHandlerIdChange()||this.didConnectedDragSourceChange()||this.didDragSourceOptionsChange();if(r&&this.disconnectDragSource(),!!this.handlerId){if(!n){this.lastConnectedDragSource=n;return}r&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDragSource=n,this.lastConnectedDragSourceOptions=this.dragSourceOptions,this.dragSourceUnsubscribe=this.backend.connectDragSource(this.handlerId,n,this.dragSourceOptions))}}},{key:\"reconnectDragPreview\",value:function(){var n=this.dragPreview,r=this.didHandlerIdChange()||this.didConnectedDragPreviewChange()||this.didDragPreviewOptionsChange();if(r&&this.disconnectDragPreview(),!!this.handlerId){if(!n){this.lastConnectedDragPreview=n;return}r&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDragPreview=n,this.lastConnectedDragPreviewOptions=this.dragPreviewOptions,this.dragPreviewUnsubscribe=this.backend.connectDragPreview(this.handlerId,n,this.dragPreviewOptions))}}},{key:\"didHandlerIdChange\",value:function(){return this.lastConnectedHandlerId!==this.handlerId}},{key:\"didConnectedDragSourceChange\",value:function(){return this.lastConnectedDragSource!==this.dragSource}},{key:\"didConnectedDragPreviewChange\",value:function(){return this.lastConnectedDragPreview!==this.dragPreview}},{key:\"didDragSourceOptionsChange\",value:function(){return!tb(this.lastConnectedDragSourceOptions,this.dragSourceOptions)}},{key:\"didDragPreviewOptionsChange\",value:function(){return!tb(this.lastConnectedDragPreviewOptions,this.dragPreviewOptions)}},{key:\"disconnectDragSource\",value:function(){this.dragSourceUnsubscribe&&(this.dragSourceUnsubscribe(),this.dragSourceUnsubscribe=void 0)}},{key:\"disconnectDragPreview\",value:function(){this.dragPreviewUnsubscribe&&(this.dragPreviewUnsubscribe(),this.dragPreviewUnsubscribe=void 0,this.dragPreviewNode=null,this.dragPreviewRef=null)}},{key:\"dragSource\",get:function(){return this.dragSourceNode||this.dragSourceRef&&this.dragSourceRef.current}},{key:\"dragPreview\",get:function(){return this.dragPreviewNode||this.dragPreviewRef&&this.dragPreviewRef.current}},{key:\"clearDragSource\",value:function(){this.dragSourceNode=null,this.dragSourceRef=null}},{key:\"clearDragPreview\",value:function(){this.dragPreviewNode=null,this.dragPreviewRef=null}}]),e})();function bH(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function xH(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function wH(e,t,n){return t&&xH(e.prototype,t),e}function Bs(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var SH=(function(){function e(t){var n=this;bH(this,e),Bs(this,\"hooks\",K_({dropTarget:function(s,o){n.clearDropTarget(),n.dropTargetOptions=o,eb(s)?n.dropTargetRef=s:n.dropTargetNode=s,n.reconnect()}})),Bs(this,\"handlerId\",null),Bs(this,\"dropTargetRef\",null),Bs(this,\"dropTargetNode\",void 0),Bs(this,\"dropTargetOptionsInternal\",null),Bs(this,\"unsubscribeDropTarget\",void 0),Bs(this,\"lastConnectedHandlerId\",null),Bs(this,\"lastConnectedDropTarget\",null),Bs(this,\"lastConnectedDropTargetOptions\",null),Bs(this,\"backend\",void 0),this.backend=t}return wH(e,[{key:\"connectTarget\",get:function(){return this.dropTarget}},{key:\"reconnect\",value:function(){var n=this.didHandlerIdChange()||this.didDropTargetChange()||this.didOptionsChange();n&&this.disconnectDropTarget();var r=this.dropTarget;if(this.handlerId){if(!r){this.lastConnectedDropTarget=r;return}n&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDropTarget=r,this.lastConnectedDropTargetOptions=this.dropTargetOptions,this.unsubscribeDropTarget=this.backend.connectDropTarget(this.handlerId,r,this.dropTargetOptions))}}},{key:\"receiveHandlerId\",value:function(n){n!==this.handlerId&&(this.handlerId=n,this.reconnect())}},{key:\"dropTargetOptions\",get:function(){return this.dropTargetOptionsInternal},set:function(n){this.dropTargetOptionsInternal=n}},{key:\"didHandlerIdChange\",value:function(){return this.lastConnectedHandlerId!==this.handlerId}},{key:\"didDropTargetChange\",value:function(){return this.lastConnectedDropTarget!==this.dropTarget}},{key:\"didOptionsChange\",value:function(){return!tb(this.lastConnectedDropTargetOptions,this.dropTargetOptions)}},{key:\"disconnectDropTarget\",value:function(){this.unsubscribeDropTarget&&(this.unsubscribeDropTarget(),this.unsubscribeDropTarget=void 0)}},{key:\"dropTarget\",get:function(){return this.dropTargetNode||this.dropTargetRef&&this.dropTargetRef.current}},{key:\"clearDropTarget\",value:function(){this.dropTargetRef=null,this.dropTargetNode=null}}]),e})();function CH(e,t,n){var r=n.getRegistry(),s=r.addTarget(e,t);return[s,function(){return r.removeTarget(s)}]}function EH(e,t,n){var r=n.getRegistry(),s=r.addSource(e,t);return[s,function(){return r.removeSource(s)}]}var Mi=typeof window<\"u\"?y.useLayoutEffect:y.useEffect;function Sp(e){\"@babel/helpers - typeof\";return typeof Symbol==\"function\"&&typeof Symbol.iterator==\"symbol\"?Sp=function(n){return typeof n}:Sp=function(n){return n&&typeof Symbol==\"function\"&&n.constructor===Symbol&&n!==Symbol.prototype?\"symbol\":typeof n},Sp(e)}function kH(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function jH(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function TH(e,t,n){return t&&jH(e.prototype,t),e}function Fv(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var NH=(function(){function e(t,n,r){kH(this,e),Fv(this,\"spec\",void 0),Fv(this,\"monitor\",void 0),Fv(this,\"connector\",void 0),this.spec=t,this.monitor=n,this.connector=r}return TH(e,[{key:\"beginDrag\",value:function(){var n,r=this.spec,s=this.monitor,o=null;return Sp(r.item)===\"object\"?o=r.item:typeof r.item==\"function\"?o=r.item(s):o={},(n=o)!==null&&n!==void 0?n:null}},{key:\"canDrag\",value:function(){var n=this.spec,r=this.monitor;return typeof n.canDrag==\"boolean\"?n.canDrag:typeof n.canDrag==\"function\"?n.canDrag(r):!0}},{key:\"isDragging\",value:function(n,r){var s=this.spec,o=this.monitor,l=s.isDragging;return l?l(o):r===n.getSourceId()}},{key:\"endDrag\",value:function(){var n=this.spec,r=this.monitor,s=this.connector,o=n.end;o&&o(r.getItem(),r),s.reconnect()}}]),e})();function MH(e,t,n){var r=y.useMemo(function(){return new NH(e,t,n)},[t,n]);return y.useEffect(function(){r.spec=e},[e]),r}function ic(){var e=y.useContext(L_),t=e.dragDropManager;return gt(t!=null,\"Expected drag drop context\"),t}function _H(e){return y.useMemo(function(){var t=e.type;return gt(t!=null,\"spec.type must be defined\"),t},[e])}function RH(e,t){return AH(e)||IH(e,t)||OH(e,t)||PH()}function PH(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function OH(e,t){if(e){if(typeof e==\"string\")return J1(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return J1(e,t)}}function J1(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function IH(e,t){var n=e==null?null:typeof Symbol<\"u\"&&e[Symbol.iterator]||e[\"@@iterator\"];if(n!=null){var r=[],s=!0,o=!1,l,u;try{for(n=n.call(e);!(s=(l=n.next()).done)&&(r.push(l.value),!(t&&r.length===t));s=!0);}catch(d){o=!0,u=d}finally{try{!s&&n.return!=null&&n.return()}finally{if(o)throw u}}return r}}function AH(e){if(Array.isArray(e))return e}function DH(e,t,n){var r=ic(),s=MH(e,t,n),o=_H(e);Mi(function(){if(o!=null){var u=EH(o,s,r),d=RH(u,2),f=d[0],h=d[1];return t.receiveHandlerId(f),n.receiveHandlerId(f),h}},[r,t,n,s,o])}function FH(e){return zH(e)||BH(e)||$H(e)||LH()}function LH(){throw new TypeError(`Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function $H(e,t){if(e){if(typeof e==\"string\")return nb(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return nb(e,t)}}function BH(e){if(typeof Symbol<\"u\"&&e[Symbol.iterator]!=null||e[\"@@iterator\"]!=null)return Array.from(e)}function zH(e){if(Array.isArray(e))return nb(e)}function nb(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function W_(e,t){var n=FH(t||[]);return t==null&&typeof e!=\"function\"&&n.push(e),y.useMemo(function(){return typeof e==\"function\"?e():e},n)}function UH(){var e=ic();return y.useMemo(function(){return new iH(e)},[e])}function VH(e,t){var n=ic(),r=y.useMemo(function(){return new yH(n.getBackend())},[n]);return Mi(function(){return r.dragSourceOptions=e||null,r.reconnect(),function(){return r.disconnectDragSource()}},[r,e]),Mi(function(){return r.dragPreviewOptions=t||null,r.reconnect(),function(){return r.disconnectDragPreview()}},[r,t]),r}var Lv,Q1;function HH(){return Q1||(Q1=1,Lv=function e(t,n){if(t===n)return!0;if(t&&n&&typeof t==\"object\"&&typeof n==\"object\"){if(t.constructor!==n.constructor)return!1;var r,s,o;if(Array.isArray(t)){if(r=t.length,r!=n.length)return!1;for(s=r;s--!==0;)if(!e(t[s],n[s]))return!1;return!0}if(t.constructor===RegExp)return t.source===n.source&&t.flags===n.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===n.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===n.toString();if(o=Object.keys(t),r=o.length,r!==Object.keys(n).length)return!1;for(s=r;s--!==0;)if(!Object.prototype.hasOwnProperty.call(n,o[s]))return!1;for(s=r;s--!==0;){var l=o[s];if(!e(t[l],n[l]))return!1}return!0}return t!==t&&n!==n}),Lv}var qH=HH();const KH=fd(qH);function WH(e,t){return ZH(e)||QH(e,t)||JH(e,t)||GH()}function GH(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function JH(e,t){if(e){if(typeof e==\"string\")return Z1(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Z1(e,t)}}function Z1(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function QH(e,t){var n=e==null?null:typeof Symbol<\"u\"&&e[Symbol.iterator]||e[\"@@iterator\"];if(n!=null){var r=[],s=!0,o=!1,l,u;try{for(n=n.call(e);!(s=(l=n.next()).done)&&(r.push(l.value),!(t&&r.length===t));s=!0);}catch(d){o=!0,u=d}finally{try{!s&&n.return!=null&&n.return()}finally{if(o)throw u}}return r}}function ZH(e){if(Array.isArray(e))return e}function YH(e,t,n){var r=y.useState(function(){return t(e)}),s=WH(r,2),o=s[0],l=s[1],u=y.useCallback(function(){var d=t(e);KH(o,d)||(l(d),n&&n())},[o,e,n]);return Mi(u),[o,u]}function XH(e,t){return rq(e)||nq(e,t)||tq(e,t)||eq()}function eq(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function tq(e,t){if(e){if(typeof e==\"string\")return Y1(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Y1(e,t)}}function Y1(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function nq(e,t){var n=e==null?null:typeof Symbol<\"u\"&&e[Symbol.iterator]||e[\"@@iterator\"];if(n!=null){var r=[],s=!0,o=!1,l,u;try{for(n=n.call(e);!(s=(l=n.next()).done)&&(r.push(l.value),!(t&&r.length===t));s=!0);}catch(d){o=!0,u=d}finally{try{!s&&n.return!=null&&n.return()}finally{if(o)throw u}}return r}}function rq(e){if(Array.isArray(e))return e}function sq(e,t,n){var r=YH(e,t,n),s=XH(r,2),o=s[0],l=s[1];return Mi(function(){var d=e.getHandlerId();if(d!=null)return e.subscribeToStateChange(l,{handlerIds:[d]})},[e,l]),o}function G_(e,t,n){return sq(t,e||function(){return{}},function(){return n.reconnect()})}function oq(e){return y.useMemo(function(){return e.hooks.dragSource()},[e])}function aq(e){return y.useMemo(function(){return e.hooks.dragPreview()},[e])}function iq(e,t){var n=W_(e,t);gt(!n.begin,\"useDrag::spec.begin was deprecated in v14. Replace spec.begin() with spec.item(). (see more here - https://react-dnd.github.io/react-dnd/docs/api/use-drag)\");var r=UH(),s=VH(n.options,n.previewOptions);return DH(n,r,s),[G_(n.collect,r,s),oq(s),aq(s)]}function lq(e){var t=e.accept;return y.useMemo(function(){return gt(e.accept!=null,\"accept must be defined\"),Array.isArray(t)?t:[t]},[t])}function cq(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function uq(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function dq(e,t,n){return t&&uq(e.prototype,t),e}function X1(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var fq=(function(){function e(t,n){cq(this,e),X1(this,\"spec\",void 0),X1(this,\"monitor\",void 0),this.spec=t,this.monitor=n}return dq(e,[{key:\"canDrop\",value:function(){var n=this.spec,r=this.monitor;return n.canDrop?n.canDrop(r.getItem(),r):!0}},{key:\"hover\",value:function(){var n=this.spec,r=this.monitor;n.hover&&n.hover(r.getItem(),r)}},{key:\"drop\",value:function(){var n=this.spec,r=this.monitor;if(n.drop)return n.drop(r.getItem(),r)}}]),e})();function pq(e,t){var n=y.useMemo(function(){return new fq(e,t)},[t]);return y.useEffect(function(){n.spec=e},[e]),n}function hq(e,t){return yq(e)||vq(e,t)||mq(e,t)||gq()}function gq(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function mq(e,t){if(e){if(typeof e==\"string\")return eE(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===\"Object\"&&e.constructor&&(n=e.constructor.name),n===\"Map\"||n===\"Set\")return Array.from(e);if(n===\"Arguments\"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return eE(e,t)}}function eE(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function vq(e,t){var n=e==null?null:typeof Symbol<\"u\"&&e[Symbol.iterator]||e[\"@@iterator\"];if(n!=null){var r=[],s=!0,o=!1,l,u;try{for(n=n.call(e);!(s=(l=n.next()).done)&&(r.push(l.value),!(t&&r.length===t));s=!0);}catch(d){o=!0,u=d}finally{try{!s&&n.return!=null&&n.return()}finally{if(o)throw u}}return r}}function yq(e){if(Array.isArray(e))return e}function bq(e,t,n){var r=ic(),s=pq(e,t),o=lq(e);Mi(function(){var u=CH(o,s,r),d=hq(u,2),f=d[0],h=d[1];return t.receiveHandlerId(f),n.receiveHandlerId(f),h},[r,t,s,n,o.map(function(l){return l.toString()}).join(\"|\")])}function xq(){var e=ic();return y.useMemo(function(){return new dH(e)},[e])}function wq(e){var t=ic(),n=y.useMemo(function(){return new SH(t.getBackend())},[t]);return Mi(function(){return n.dropTargetOptions=e||null,n.reconnect(),function(){return n.disconnectDropTarget()}},[e]),n}function Sq(e){return y.useMemo(function(){return e.hooks.dropTarget()},[e])}function Cq(e,t){var n=W_(e,t),r=xq(),s=wq(n.options);return bq(n,r,s),[G_(n.collect,r,s),Sq(s)]}function J_(e){var t=null,n=function(){return t==null&&(t=e()),t};return n}function Eq(e,t){return e.filter(function(n){return n!==t})}function kq(e,t){var n=new Set,r=function(l){return n.add(l)};e.forEach(r),t.forEach(r);var s=[];return n.forEach(function(o){return s.push(o)}),s}function jq(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function Tq(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Nq(e,t,n){return t&&Tq(e.prototype,t),e}function tE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Mq=(function(){function e(t){jq(this,e),tE(this,\"entered\",[]),tE(this,\"isNodeInDocument\",void 0),this.isNodeInDocument=t}return Nq(e,[{key:\"enter\",value:function(n){var r=this,s=this.entered.length,o=function(u){return r.isNodeInDocument(u)&&(!u.contains||u.contains(n))};return this.entered=kq(this.entered.filter(o),[n]),s===0&&this.entered.length>0}},{key:\"leave\",value:function(n){var r=this.entered.length;return this.entered=Eq(this.entered.filter(this.isNodeInDocument),n),r>0&&this.entered.length===0}},{key:\"reset\",value:function(){this.entered=[]}}]),e})(),_q=J_(function(){return/firefox/i.test(navigator.userAgent)}),Q_=J_(function(){return!!window.safari});function Rq(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function Pq(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Oq(e,t,n){return t&&Pq(e.prototype,t),e}function lu(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var nE=(function(){function e(t,n){Rq(this,e),lu(this,\"xs\",void 0),lu(this,\"ys\",void 0),lu(this,\"c1s\",void 0),lu(this,\"c2s\",void 0),lu(this,\"c3s\",void 0);for(var r=t.length,s=[],o=0;o<r;o++)s.push(o);s.sort(function(D,z){return t[D]<t[z]?-1:1});for(var l=[],u=[],d,f,h=0;h<r-1;h++)d=t[h+1]-t[h],f=n[h+1]-n[h],l.push(d),u.push(f/d);for(var m=[u[0]],g=0;g<l.length-1;g++){var x=u[g],b=u[g+1];if(x*b<=0)m.push(0);else{d=l[g];var w=l[g+1],C=d+w;m.push(3*C/((C+w)/x+(C+d)/b))}}m.push(u[u.length-1]);for(var k=[],j=[],M,_=0;_<m.length-1;_++){M=u[_];var R=m[_],N=1/l[_],O=R+m[_+1]-M-M;k.push((M-R-O)*N),j.push(O*N*N)}this.xs=t,this.ys=n,this.c1s=m,this.c2s=k,this.c3s=j}return Oq(e,[{key:\"interpolate\",value:function(n){var r=this.xs,s=this.ys,o=this.c1s,l=this.c2s,u=this.c3s,d=r.length-1;if(n===r[d])return s[d];for(var f=0,h=u.length-1,m;f<=h;){m=Math.floor(.5*(f+h));var g=r[m];if(g<n)f=m+1;else if(g>n)h=m-1;else return s[m]}d=Math.max(0,h);var x=n-r[d],b=x*x;return s[d]+o[d]*x+l[d]*b+u[d]*x*b}}]),e})(),Iq=1;function Z_(e){var t=e.nodeType===Iq?e:e.parentElement;if(!t)return null;var n=t.getBoundingClientRect(),r=n.top,s=n.left;return{x:s,y:r}}function Qf(e){return{x:e.clientX,y:e.clientY}}function Aq(e){var t;return e.nodeName===\"IMG\"&&(_q()||!((t=document.documentElement)!==null&&t!==void 0&&t.contains(e)))}function Dq(e,t,n,r){var s=e?t.width:n,o=e?t.height:r;return Q_()&&e&&(o/=window.devicePixelRatio,s/=window.devicePixelRatio),{dragPreviewWidth:s,dragPreviewHeight:o}}function Fq(e,t,n,r,s){var o=Aq(t),l=o?e:t,u=Z_(l),d={x:n.x-u.x,y:n.y-u.y},f=e.offsetWidth,h=e.offsetHeight,m=r.anchorX,g=r.anchorY,x=Dq(o,t,f,h),b=x.dragPreviewWidth,w=x.dragPreviewHeight,C=function(){var O=new nE([0,.5,1],[d.y,d.y/h*w,d.y+w-h]),D=O.interpolate(g);return Q_()&&o&&(D+=(window.devicePixelRatio-1)*w),D},k=function(){var O=new nE([0,.5,1],[d.x,d.x/f*b,d.x+b-f]);return O.interpolate(m)},j=s.offsetX,M=s.offsetY,_=j===0||j,R=M===0||M;return{x:_?j:k(),y:R?M:C()}}var Y_=\"__NATIVE_FILE__\",X_=\"__NATIVE_URL__\",eR=\"__NATIVE_TEXT__\",tR=\"__NATIVE_HTML__\";const rE=Object.freeze(Object.defineProperty({__proto__:null,FILE:Y_,HTML:tR,TEXT:eR,URL:X_},Symbol.toStringTag,{value:\"Module\"}));function $v(e,t,n){var r=t.reduce(function(s,o){return s||e.getData(o)},\"\");return r??n}var yl;function Zf(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var rb=(yl={},Zf(yl,Y_,{exposeProperties:{files:function(t){return Array.prototype.slice.call(t.files)},items:function(t){return t.items},dataTransfer:function(t){return t}},matchesTypes:[\"Files\"]}),Zf(yl,tR,{exposeProperties:{html:function(t,n){return $v(t,n,\"\")},dataTransfer:function(t){return t}},matchesTypes:[\"Html\",\"text/html\"]}),Zf(yl,X_,{exposeProperties:{urls:function(t,n){return $v(t,n,\"\").split(`\n`)},dataTransfer:function(t){return t}},matchesTypes:[\"Url\",\"text/uri-list\"]}),Zf(yl,eR,{exposeProperties:{text:function(t,n){return $v(t,n,\"\")},dataTransfer:function(t){return t}},matchesTypes:[\"Text\",\"text/plain\"]}),yl);function Lq(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function $q(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Bq(e,t,n){return t&&$q(e.prototype,t),e}function sE(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var zq=(function(){function e(t){Lq(this,e),sE(this,\"item\",void 0),sE(this,\"config\",void 0),this.config=t,this.item={},this.initializeExposedProperties()}return Bq(e,[{key:\"initializeExposedProperties\",value:function(){var n=this;Object.keys(this.config.exposeProperties).forEach(function(r){Object.defineProperty(n.item,r,{configurable:!0,enumerable:!0,get:function(){return console.warn(`Browser doesn't allow reading \"`.concat(r,'\" until the drop event.')),null}})})}},{key:\"loadDataTransfer\",value:function(n){var r=this;if(n){var s={};Object.keys(this.config.exposeProperties).forEach(function(o){s[o]={value:r.config.exposeProperties[o](n,r.config.matchesTypes),configurable:!0,enumerable:!0}}),Object.defineProperties(this.item,s)}}},{key:\"canDrag\",value:function(){return!0}},{key:\"beginDrag\",value:function(){return this.item}},{key:\"isDragging\",value:function(n,r){return r===n.getSourceId()}},{key:\"endDrag\",value:function(){}}]),e})();function Uq(e,t){var n=new zq(rb[e]);return n.loadDataTransfer(t),n}function Bv(e){if(!e)return null;var t=Array.prototype.slice.call(e.types||[]);return Object.keys(rb).filter(function(n){var r=rb[n].matchesTypes;return r.some(function(s){return t.indexOf(s)>-1})})[0]||null}function Vq(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function Hq(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function qq(e,t,n){return t&&Hq(e.prototype,t),e}function zv(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Kq=(function(){function e(t,n){Vq(this,e),zv(this,\"ownerDocument\",null),zv(this,\"globalContext\",void 0),zv(this,\"optionsArgs\",void 0),this.globalContext=t,this.optionsArgs=n}return qq(e,[{key:\"window\",get:function(){if(this.globalContext)return this.globalContext;if(typeof window<\"u\")return window}},{key:\"document\",get:function(){var n;return(n=this.globalContext)!==null&&n!==void 0&&n.document?this.globalContext.document:this.window?this.window.document:void 0}},{key:\"rootElement\",get:function(){var n;return((n=this.optionsArgs)===null||n===void 0?void 0:n.rootElement)||this.window}}]),e})();function oE(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable})),n.push.apply(n,r)}return n}function aE(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]!=null?arguments[t]:{};t%2?oE(Object(n),!0).forEach(function(r){jt(e,r,n[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):oE(Object(n)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))})}return e}function Wq(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function Gq(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function Jq(e,t,n){return t&&Gq(e.prototype,t),e}function jt(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Qq=(function(){function e(t,n,r){var s=this;Wq(this,e),jt(this,\"options\",void 0),jt(this,\"actions\",void 0),jt(this,\"monitor\",void 0),jt(this,\"registry\",void 0),jt(this,\"enterLeaveCounter\",void 0),jt(this,\"sourcePreviewNodes\",new Map),jt(this,\"sourcePreviewNodeOptions\",new Map),jt(this,\"sourceNodes\",new Map),jt(this,\"sourceNodeOptions\",new Map),jt(this,\"dragStartSourceIds\",null),jt(this,\"dropTargetIds\",[]),jt(this,\"dragEnterTargetIds\",[]),jt(this,\"currentNativeSource\",null),jt(this,\"currentNativeHandle\",null),jt(this,\"currentDragSourceNode\",null),jt(this,\"altKeyPressed\",!1),jt(this,\"mouseMoveTimeoutTimer\",null),jt(this,\"asyncEndDragFrameId\",null),jt(this,\"dragOverTargetIds\",null),jt(this,\"lastClientOffset\",null),jt(this,\"hoverRafId\",null),jt(this,\"getSourceClientOffset\",function(o){var l=s.sourceNodes.get(o);return l&&Z_(l)||null}),jt(this,\"endDragNativeItem\",function(){s.isDraggingNativeItem()&&(s.actions.endDrag(),s.currentNativeHandle&&s.registry.removeSource(s.currentNativeHandle),s.currentNativeHandle=null,s.currentNativeSource=null)}),jt(this,\"isNodeInDocument\",function(o){return!!(o&&s.document&&s.document.body&&s.document.body.contains(o))}),jt(this,\"endDragIfSourceWasRemovedFromDOM\",function(){var o=s.currentDragSourceNode;o==null||s.isNodeInDocument(o)||s.clearCurrentDragSourceNode()&&s.monitor.isDragging()&&s.actions.endDrag()}),jt(this,\"handleTopDragStartCapture\",function(){s.clearCurrentDragSourceNode(),s.dragStartSourceIds=[]}),jt(this,\"handleTopDragStart\",function(o){if(!o.defaultPrevented){var l=s.dragStartSourceIds;s.dragStartSourceIds=null;var u=Qf(o);s.monitor.isDragging()&&s.actions.endDrag(),s.actions.beginDrag(l||[],{publishSource:!1,getSourceClientOffset:s.getSourceClientOffset,clientOffset:u});var d=o.dataTransfer,f=Bv(d);if(s.monitor.isDragging()){if(d&&typeof d.setDragImage==\"function\"){var h=s.monitor.getSourceId(),m=s.sourceNodes.get(h),g=s.sourcePreviewNodes.get(h)||m;if(g){var x=s.getCurrentSourcePreviewNodeOptions(),b=x.anchorX,w=x.anchorY,C=x.offsetX,k=x.offsetY,j={anchorX:b,anchorY:w},M={offsetX:C,offsetY:k},_=Fq(m,g,u,j,M);d.setDragImage(g,_.x,_.y)}}try{d?.setData(\"application/json\",{})}catch{}s.setCurrentDragSourceNode(o.target);var R=s.getCurrentSourcePreviewNodeOptions(),N=R.captureDraggingState;N?s.actions.publishDragSource():setTimeout(function(){return s.actions.publishDragSource()},0)}else if(f)s.beginDragNativeItem(f);else{if(d&&!d.types&&(o.target&&!o.target.hasAttribute||!o.target.hasAttribute(\"draggable\")))return;o.preventDefault()}}}),jt(this,\"handleTopDragEndCapture\",function(){s.clearCurrentDragSourceNode()&&s.monitor.isDragging()&&s.actions.endDrag()}),jt(this,\"handleTopDragEnterCapture\",function(o){s.dragEnterTargetIds=[];var l=s.enterLeaveCounter.enter(o.target);if(!(!l||s.monitor.isDragging())){var u=o.dataTransfer,d=Bv(u);d&&s.beginDragNativeItem(d,u)}}),jt(this,\"handleTopDragEnter\",function(o){var l=s.dragEnterTargetIds;if(s.dragEnterTargetIds=[],!!s.monitor.isDragging()){s.altKeyPressed=o.altKey,l.length>0&&s.actions.hover(l,{clientOffset:Qf(o)});var u=l.some(function(d){return s.monitor.canDropOnTarget(d)});u&&(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect=s.getCurrentDropEffect()))}}),jt(this,\"handleTopDragOverCapture\",function(){s.dragOverTargetIds=[]}),jt(this,\"handleTopDragOver\",function(o){var l=s.dragOverTargetIds;if(s.dragOverTargetIds=[],!s.monitor.isDragging()){o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect=\"none\");return}s.altKeyPressed=o.altKey,s.lastClientOffset=Qf(o),s.hoverRafId===null&&typeof requestAnimationFrame<\"u\"&&(s.hoverRafId=requestAnimationFrame(function(){s.monitor.isDragging()&&s.actions.hover(l||[],{clientOffset:s.lastClientOffset}),s.hoverRafId=null}));var u=(l||[]).some(function(d){return s.monitor.canDropOnTarget(d)});u?(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect=s.getCurrentDropEffect())):s.isDraggingNativeItem()?o.preventDefault():(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect=\"none\"))}),jt(this,\"handleTopDragLeaveCapture\",function(o){s.isDraggingNativeItem()&&o.preventDefault();var l=s.enterLeaveCounter.leave(o.target);l&&s.isDraggingNativeItem()&&setTimeout(function(){return s.endDragNativeItem()},0)}),jt(this,\"handleTopDropCapture\",function(o){if(s.dropTargetIds=[],s.isDraggingNativeItem()){var l;o.preventDefault(),(l=s.currentNativeSource)===null||l===void 0||l.loadDataTransfer(o.dataTransfer)}else Bv(o.dataTransfer)&&o.preventDefault();s.enterLeaveCounter.reset()}),jt(this,\"handleTopDrop\",function(o){var l=s.dropTargetIds;s.dropTargetIds=[],s.actions.hover(l,{clientOffset:Qf(o)}),s.actions.drop({dropEffect:s.getCurrentDropEffect()}),s.isDraggingNativeItem()?s.endDragNativeItem():s.monitor.isDragging()&&s.actions.endDrag()}),jt(this,\"handleSelectStart\",function(o){var l=o.target;typeof l.dragDrop==\"function\"&&(l.tagName===\"INPUT\"||l.tagName===\"SELECT\"||l.tagName===\"TEXTAREA\"||l.isContentEditable||(o.preventDefault(),l.dragDrop()))}),this.options=new Kq(n,r),this.actions=t.getActions(),this.monitor=t.getMonitor(),this.registry=t.getRegistry(),this.enterLeaveCounter=new Mq(this.isNodeInDocument)}return Jq(e,[{key:\"profile\",value:function(){var n,r;return{sourcePreviewNodes:this.sourcePreviewNodes.size,sourcePreviewNodeOptions:this.sourcePreviewNodeOptions.size,sourceNodeOptions:this.sourceNodeOptions.size,sourceNodes:this.sourceNodes.size,dragStartSourceIds:((n=this.dragStartSourceIds)===null||n===void 0?void 0:n.length)||0,dropTargetIds:this.dropTargetIds.length,dragEnterTargetIds:this.dragEnterTargetIds.length,dragOverTargetIds:((r=this.dragOverTargetIds)===null||r===void 0?void 0:r.length)||0}}},{key:\"window\",get:function(){return this.options.window}},{key:\"document\",get:function(){return this.options.document}},{key:\"rootElement\",get:function(){return this.options.rootElement}},{key:\"setup\",value:function(){var n=this.rootElement;if(n!==void 0){if(n.__isReactDndBackendSetUp)throw new Error(\"Cannot have two HTML5 backends at the same time.\");n.__isReactDndBackendSetUp=!0,this.addEventListeners(n)}}},{key:\"teardown\",value:function(){var n=this.rootElement;if(n!==void 0&&(n.__isReactDndBackendSetUp=!1,this.removeEventListeners(this.rootElement),this.clearCurrentDragSourceNode(),this.asyncEndDragFrameId)){var r;(r=this.window)===null||r===void 0||r.cancelAnimationFrame(this.asyncEndDragFrameId)}}},{key:\"connectDragPreview\",value:function(n,r,s){var o=this;return this.sourcePreviewNodeOptions.set(n,s),this.sourcePreviewNodes.set(n,r),function(){o.sourcePreviewNodes.delete(n),o.sourcePreviewNodeOptions.delete(n)}}},{key:\"connectDragSource\",value:function(n,r,s){var o=this;this.sourceNodes.set(n,r),this.sourceNodeOptions.set(n,s);var l=function(f){return o.handleDragStart(f,n)},u=function(f){return o.handleSelectStart(f)};return r.setAttribute(\"draggable\",\"true\"),r.addEventListener(\"dragstart\",l),r.addEventListener(\"selectstart\",u),function(){o.sourceNodes.delete(n),o.sourceNodeOptions.delete(n),r.removeEventListener(\"dragstart\",l),r.removeEventListener(\"selectstart\",u),r.setAttribute(\"draggable\",\"false\")}}},{key:\"connectDropTarget\",value:function(n,r){var s=this,o=function(f){return s.handleDragEnter(f,n)},l=function(f){return s.handleDragOver(f,n)},u=function(f){return s.handleDrop(f,n)};return r.addEventListener(\"dragenter\",o),r.addEventListener(\"dragover\",l),r.addEventListener(\"drop\",u),function(){r.removeEventListener(\"dragenter\",o),r.removeEventListener(\"dragover\",l),r.removeEventListener(\"drop\",u)}}},{key:\"addEventListeners\",value:function(n){n.addEventListener&&(n.addEventListener(\"dragstart\",this.handleTopDragStart),n.addEventListener(\"dragstart\",this.handleTopDragStartCapture,!0),n.addEventListener(\"dragend\",this.handleTopDragEndCapture,!0),n.addEventListener(\"dragenter\",this.handleTopDragEnter),n.addEventListener(\"dragenter\",this.handleTopDragEnterCapture,!0),n.addEventListener(\"dragleave\",this.handleTopDragLeaveCapture,!0),n.addEventListener(\"dragover\",this.handleTopDragOver),n.addEventListener(\"dragover\",this.handleTopDragOverCapture,!0),n.addEventListener(\"drop\",this.handleTopDrop),n.addEventListener(\"drop\",this.handleTopDropCapture,!0))}},{key:\"removeEventListeners\",value:function(n){n.removeEventListener&&(n.removeEventListener(\"dragstart\",this.handleTopDragStart),n.removeEventListener(\"dragstart\",this.handleTopDragStartCapture,!0),n.removeEventListener(\"dragend\",this.handleTopDragEndCapture,!0),n.removeEventListener(\"dragenter\",this.handleTopDragEnter),n.removeEventListener(\"dragenter\",this.handleTopDragEnterCapture,!0),n.removeEventListener(\"dragleave\",this.handleTopDragLeaveCapture,!0),n.removeEventListener(\"dragover\",this.handleTopDragOver),n.removeEventListener(\"dragover\",this.handleTopDragOverCapture,!0),n.removeEventListener(\"drop\",this.handleTopDrop),n.removeEventListener(\"drop\",this.handleTopDropCapture,!0))}},{key:\"getCurrentSourceNodeOptions\",value:function(){var n=this.monitor.getSourceId(),r=this.sourceNodeOptions.get(n);return aE({dropEffect:this.altKeyPressed?\"copy\":\"move\"},r||{})}},{key:\"getCurrentDropEffect\",value:function(){return this.isDraggingNativeItem()?\"copy\":this.getCurrentSourceNodeOptions().dropEffect}},{key:\"getCurrentSourcePreviewNodeOptions\",value:function(){var n=this.monitor.getSourceId(),r=this.sourcePreviewNodeOptions.get(n);return aE({anchorX:.5,anchorY:.5,captureDraggingState:!1},r||{})}},{key:\"isDraggingNativeItem\",value:function(){var n=this.monitor.getItemType();return Object.keys(rE).some(function(r){return rE[r]===n})}},{key:\"beginDragNativeItem\",value:function(n,r){this.clearCurrentDragSourceNode(),this.currentNativeSource=Uq(n,r),this.currentNativeHandle=this.registry.addSource(n,this.currentNativeSource),this.actions.beginDrag([this.currentNativeHandle])}},{key:\"setCurrentDragSourceNode\",value:function(n){var r=this;this.clearCurrentDragSourceNode(),this.currentDragSourceNode=n;var s=1e3;this.mouseMoveTimeoutTimer=setTimeout(function(){var o;return(o=r.rootElement)===null||o===void 0?void 0:o.addEventListener(\"mousemove\",r.endDragIfSourceWasRemovedFromDOM,!0)},s)}},{key:\"clearCurrentDragSourceNode\",value:function(){if(this.currentDragSourceNode){if(this.currentDragSourceNode=null,this.rootElement){var n;(n=this.window)===null||n===void 0||n.clearTimeout(this.mouseMoveTimeoutTimer||void 0),this.rootElement.removeEventListener(\"mousemove\",this.endDragIfSourceWasRemovedFromDOM,!0)}return this.mouseMoveTimeoutTimer=null,!0}return!1}},{key:\"handleDragStart\",value:function(n,r){n.defaultPrevented||(this.dragStartSourceIds||(this.dragStartSourceIds=[]),this.dragStartSourceIds.unshift(r))}},{key:\"handleDragEnter\",value:function(n,r){this.dragEnterTargetIds.unshift(r)}},{key:\"handleDragOver\",value:function(n,r){this.dragOverTargetIds===null&&(this.dragOverTargetIds=[]),this.dragOverTargetIds.unshift(r)}},{key:\"handleDrop\",value:function(n,r){this.dropTargetIds.unshift(r)}}]),e})(),Zq=function(t,n,r){return new Qq(t,n,r)},Yq=Object.create,nR=Object.defineProperty,Xq=Object.getOwnPropertyDescriptor,rR=Object.getOwnPropertyNames,e7=Object.getPrototypeOf,t7=Object.prototype.hasOwnProperty,n7=(e,t)=>function(){return t||(0,e[rR(e)[0]])((t={exports:{}}).exports,t),t.exports},r7=(e,t,n,r)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let s of rR(t))!t7.call(e,s)&&s!==n&&nR(e,s,{get:()=>t[s],enumerable:!(r=Xq(t,s))||r.enumerable});return e},sR=(e,t,n)=>(n=e!=null?Yq(e7(e)):{},r7(nR(n,\"default\",{value:e,enumerable:!0}),e)),oR=n7({\"node_modules/classnames/index.js\"(e,t){(function(){var n={}.hasOwnProperty;function r(){for(var s=[],o=0;o<arguments.length;o++){var l=arguments[o];if(l){var u=typeof l;if(u===\"string\"||u===\"number\")s.push(l);else if(Array.isArray(l)){if(l.length){var d=r.apply(null,l);d&&s.push(d)}}else if(u===\"object\"){if(l.toString!==Object.prototype.toString&&!l.toString.toString().includes(\"[native code]\")){s.push(l.toString());continue}for(var f in l)n.call(l,f)&&l[f]&&s.push(f)}}}return s.join(\" \")}typeof t<\"u\"&&t.exports?(r.default=r,t.exports=r):typeof define==\"function\"&&typeof define.amd==\"object\"&&define.amd?define(\"classnames\",[],function(){return r}):window.classNames=r})()}}),Il={ENTER:[10,13],TAB:9,BACKSPACE:8,UP_ARROW:38,DOWN_ARROW:40,SPACE:32},Vs={ENTER:\"Enter\",TAB:\"Tab\",COMMA:\",\",SPACE:\" \",SEMICOLON:\";\"},s7=\"Press enter to add new tag\",o7=\"text\",iE={tags:\"ReactTags__tags\",tagInput:\"ReactTags__tagInput\",tagInputField:\"ReactTags__tagInputField\",selected:\"ReactTags__selected\",tag:\"ReactTags__tag\",remove:\"ReactTags__remove\",suggestions:\"ReactTags__suggestions\",activeSuggestion:\"ReactTags__activeSuggestion\",editTagInput:\"ReactTags__editTagInput\",editTagInputField:\"ReactTags__editTagInputField\",clearAll:\"ReactTags__clearAll\"},cu={INLINE:\"inline\",TOP:\"top\",BOTTOM:\"bottom\"},lE={TAG_LIMIT:\"Tag limit reached!\"},a7=typeof global==\"object\"&&global&&global.Object===Object&&global,aR=a7,i7=typeof self==\"object\"&&self&&self.Object===Object&&self,l7=aR||i7||Function(\"return this\")(),Do=l7,c7=Do.Symbol,ja=c7,iR=Object.prototype,u7=iR.hasOwnProperty,d7=iR.toString,uu=ja?ja.toStringTag:void 0;function f7(e){var t=u7.call(e,uu),n=e[uu];try{e[uu]=void 0;var r=!0}catch{}var s=d7.call(e);return r&&(t?e[uu]=n:delete e[uu]),s}var p7=f7,h7=Object.prototype,g7=h7.toString;function m7(e){return g7.call(e)}var v7=m7,y7=\"[object Null]\",b7=\"[object Undefined]\",cE=ja?ja.toStringTag:void 0;function x7(e){return e==null?e===void 0?b7:y7:cE&&cE in Object(e)?p7(e):v7(e)}var lc=x7;function w7(e){return e!=null&&typeof e==\"object\"}var Kl=w7,S7=\"[object Symbol]\";function C7(e){return typeof e==\"symbol\"||Kl(e)&&lc(e)==S7}var E7=C7;function k7(e,t){for(var n=-1,r=e==null?0:e.length,s=Array(r);++n<r;)s[n]=t(e[n],n,e);return s}var j7=k7,T7=Array.isArray,sd=T7,uE=ja?ja.prototype:void 0,dE=uE?uE.toString:void 0;function lR(e){if(typeof e==\"string\")return e;if(sd(e))return j7(e,lR)+\"\";if(E7(e))return dE?dE.call(e):\"\";var t=e+\"\";return t==\"0\"&&1/e==-1/0?\"-0\":t}var N7=lR;function M7(e){var t=typeof e;return e!=null&&(t==\"object\"||t==\"function\")}var cR=M7,_7=\"[object AsyncFunction]\",R7=\"[object Function]\",P7=\"[object GeneratorFunction]\",O7=\"[object Proxy]\";function I7(e){if(!cR(e))return!1;var t=lc(e);return t==R7||t==P7||t==_7||t==O7}var uR=I7,A7=Do[\"__core-js_shared__\"],Uv=A7,fE=(function(){var e=/[^.]+$/.exec(Uv&&Uv.keys&&Uv.keys.IE_PROTO||\"\");return e?\"Symbol(src)_1.\"+e:\"\"})();function D7(e){return!!fE&&fE in e}var F7=D7,L7=Function.prototype,$7=L7.toString;function B7(e){if(e!=null){try{return $7.call(e)}catch{}try{return e+\"\"}catch{}}return\"\"}var zi=B7,z7=/[\\\\^$.*+?()[\\]{}|]/g,U7=/^\\[object .+?Constructor\\]$/,V7=Function.prototype,H7=Object.prototype,q7=V7.toString,K7=H7.hasOwnProperty,W7=RegExp(\"^\"+q7.call(K7).replace(z7,\"\\\\$&\").replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\");function G7(e){if(!cR(e)||F7(e))return!1;var t=uR(e)?W7:U7;return t.test(zi(e))}var J7=G7;function Q7(e,t){return e?.[t]}var Z7=Q7;function Y7(e,t){var n=Z7(e,t);return J7(n)?n:void 0}var cc=Y7,X7=cc(Do,\"WeakMap\"),sb=X7;function eK(){}var tK=eK;function nK(e,t,n,r){for(var s=e.length,o=n+(r?1:-1);r?o--:++o<s;)if(t(e[o],o,e))return o;return-1}var rK=nK;function sK(e){return e!==e}var oK=sK;function aK(e,t,n){for(var r=n-1,s=e.length;++r<s;)if(e[r]===t)return r;return-1}var iK=aK;function lK(e,t,n){return t===t?iK(e,t,n):rK(e,oK,n)}var cK=lK;function uK(e,t){var n=e==null?0:e.length;return!!n&&cK(e,t,0)>-1}var dK=uK,fK=9007199254740991,pK=/^(?:0|[1-9]\\d*)$/;function hK(e,t){var n=typeof e;return t=t??fK,!!t&&(n==\"number\"||n!=\"symbol\"&&pK.test(e))&&e>-1&&e%1==0&&e<t}var gK=hK;function mK(e,t){return e===t||e!==e&&t!==t}var dR=mK,vK=9007199254740991;function yK(e){return typeof e==\"number\"&&e>-1&&e%1==0&&e<=vK}var fR=yK;function bK(e){return e!=null&&fR(e.length)&&!uR(e)}var xK=bK,wK=Object.prototype;function SK(e){var t=e&&e.constructor,n=typeof t==\"function\"&&t.prototype||wK;return e===n}var CK=SK;function EK(e,t){for(var n=-1,r=Array(e);++n<e;)r[n]=t(n);return r}var kK=EK,jK=\"[object Arguments]\";function TK(e){return Kl(e)&&lc(e)==jK}var pE=TK,pR=Object.prototype,NK=pR.hasOwnProperty,MK=pR.propertyIsEnumerable,_K=pE((function(){return arguments})())?pE:function(e){return Kl(e)&&NK.call(e,\"callee\")&&!MK.call(e,\"callee\")},RK=_K;function PK(){return!1}var OK=PK,hR=typeof ko==\"object\"&&ko&&!ko.nodeType&&ko,hE=hR&&typeof jo==\"object\"&&jo&&!jo.nodeType&&jo,IK=hE&&hE.exports===hR,gE=IK?Do.Buffer:void 0,AK=gE?gE.isBuffer:void 0,DK=AK||OK,ob=DK,FK=\"[object Arguments]\",LK=\"[object Array]\",$K=\"[object Boolean]\",BK=\"[object Date]\",zK=\"[object Error]\",UK=\"[object Function]\",VK=\"[object Map]\",HK=\"[object Number]\",qK=\"[object Object]\",KK=\"[object RegExp]\",WK=\"[object Set]\",GK=\"[object String]\",JK=\"[object WeakMap]\",QK=\"[object ArrayBuffer]\",ZK=\"[object DataView]\",YK=\"[object Float32Array]\",XK=\"[object Float64Array]\",eW=\"[object Int8Array]\",tW=\"[object Int16Array]\",nW=\"[object Int32Array]\",rW=\"[object Uint8Array]\",sW=\"[object Uint8ClampedArray]\",oW=\"[object Uint16Array]\",aW=\"[object Uint32Array]\",rn={};rn[YK]=rn[XK]=rn[eW]=rn[tW]=rn[nW]=rn[rW]=rn[sW]=rn[oW]=rn[aW]=!0;rn[FK]=rn[LK]=rn[QK]=rn[$K]=rn[ZK]=rn[BK]=rn[zK]=rn[UK]=rn[VK]=rn[HK]=rn[qK]=rn[KK]=rn[WK]=rn[GK]=rn[JK]=!1;function iW(e){return Kl(e)&&fR(e.length)&&!!rn[lc(e)]}var lW=iW;function cW(e){return function(t){return e(t)}}var uW=cW,gR=typeof ko==\"object\"&&ko&&!ko.nodeType&&ko,Nu=gR&&typeof jo==\"object\"&&jo&&!jo.nodeType&&jo,dW=Nu&&Nu.exports===gR,Vv=dW&&aR.process,fW=(function(){try{var e=Nu&&Nu.require&&Nu.require(\"util\").types;return e||Vv&&Vv.binding&&Vv.binding(\"util\")}catch{}})(),mE=fW,vE=mE&&mE.isTypedArray,pW=vE?uW(vE):lW,mR=pW,hW=Object.prototype,gW=hW.hasOwnProperty;function mW(e,t){var n=sd(e),r=!n&&RK(e),s=!n&&!r&&ob(e),o=!n&&!r&&!s&&mR(e),l=n||r||s||o,u=l?kK(e.length,String):[],d=u.length;for(var f in e)(t||gW.call(e,f))&&!(l&&(f==\"length\"||s&&(f==\"offset\"||f==\"parent\")||o&&(f==\"buffer\"||f==\"byteLength\"||f==\"byteOffset\")||gK(f,d)))&&u.push(f);return u}var vW=mW;function yW(e,t){return function(n){return e(t(n))}}var bW=yW,xW=bW(Object.keys,Object),wW=xW,SW=Object.prototype,CW=SW.hasOwnProperty;function EW(e){if(!CK(e))return wW(e);var t=[];for(var n in Object(e))CW.call(e,n)&&n!=\"constructor\"&&t.push(n);return t}var kW=EW;function jW(e){return xK(e)?vW(e):kW(e)}var TW=jW,NW=cc(Object,\"create\"),od=NW;function MW(){this.__data__=od?od(null):{},this.size=0}var _W=MW;function RW(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var PW=RW,OW=\"__lodash_hash_undefined__\",IW=Object.prototype,AW=IW.hasOwnProperty;function DW(e){var t=this.__data__;if(od){var n=t[e];return n===OW?void 0:n}return AW.call(t,e)?t[e]:void 0}var FW=DW,LW=Object.prototype,$W=LW.hasOwnProperty;function BW(e){var t=this.__data__;return od?t[e]!==void 0:$W.call(t,e)}var zW=BW,UW=\"__lodash_hash_undefined__\";function VW(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=od&&t===void 0?UW:t,this}var HW=VW;function uc(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}uc.prototype.clear=_W;uc.prototype.delete=PW;uc.prototype.get=FW;uc.prototype.has=zW;uc.prototype.set=HW;var yE=uc;function qW(){this.__data__=[],this.size=0}var KW=qW;function WW(e,t){for(var n=e.length;n--;)if(dR(e[n][0],t))return n;return-1}var Xh=WW,GW=Array.prototype,JW=GW.splice;function QW(e){var t=this.__data__,n=Xh(t,e);if(n<0)return!1;var r=t.length-1;return n==r?t.pop():JW.call(t,n,1),--this.size,!0}var ZW=QW;function YW(e){var t=this.__data__,n=Xh(t,e);return n<0?void 0:t[n][1]}var XW=YW;function e9(e){return Xh(this.__data__,e)>-1}var t9=e9;function n9(e,t){var n=this.__data__,r=Xh(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}var r9=n9;function dc(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}dc.prototype.clear=KW;dc.prototype.delete=ZW;dc.prototype.get=XW;dc.prototype.has=t9;dc.prototype.set=r9;var eg=dc,s9=cc(Do,\"Map\"),ad=s9;function o9(){this.size=0,this.__data__={hash:new yE,map:new(ad||eg),string:new yE}}var a9=o9;function i9(e){var t=typeof e;return t==\"string\"||t==\"number\"||t==\"symbol\"||t==\"boolean\"?e!==\"__proto__\":e===null}var l9=i9;function c9(e,t){var n=e.__data__;return l9(t)?n[typeof t==\"string\"?\"string\":\"hash\"]:n.map}var tg=c9;function u9(e){var t=tg(this,e).delete(e);return this.size-=t?1:0,t}var d9=u9;function f9(e){return tg(this,e).get(e)}var p9=f9;function h9(e){return tg(this,e).has(e)}var g9=h9;function m9(e,t){var n=tg(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}var v9=m9;function fc(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}fc.prototype.clear=a9;fc.prototype.delete=d9;fc.prototype.get=p9;fc.prototype.has=g9;fc.prototype.set=v9;var vR=fc;function y9(e){return e==null?\"\":N7(e)}var yR=y9;function b9(e,t){for(var n=-1,r=t.length,s=e.length;++n<r;)e[s+n]=t[n];return e}var x9=b9;function w9(e){return function(t){return e?.[t]}}var S9=w9;function C9(){this.__data__=new eg,this.size=0}var E9=C9;function k9(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}var j9=k9;function T9(e){return this.__data__.get(e)}var N9=T9;function M9(e){return this.__data__.has(e)}var _9=M9,R9=200;function P9(e,t){var n=this.__data__;if(n instanceof eg){var r=n.__data__;if(!ad||r.length<R9-1)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new vR(r)}return n.set(e,t),this.size=n.size,this}var O9=P9;function pc(e){var t=this.__data__=new eg(e);this.size=t.size}pc.prototype.clear=E9;pc.prototype.delete=j9;pc.prototype.get=N9;pc.prototype.has=_9;pc.prototype.set=O9;var Hv=pc;function I9(e,t){for(var n=-1,r=e==null?0:e.length,s=0,o=[];++n<r;){var l=e[n];t(l,n,e)&&(o[s++]=l)}return o}var A9=I9;function D9(){return[]}var F9=D9,L9=Object.prototype,$9=L9.propertyIsEnumerable,bE=Object.getOwnPropertySymbols,B9=bE?function(e){return e==null?[]:(e=Object(e),A9(bE(e),function(t){return $9.call(e,t)}))}:F9,z9=B9;function U9(e,t,n){var r=t(e);return sd(e)?r:x9(r,n(e))}var V9=U9;function H9(e){return V9(e,TW,z9)}var xE=H9,q9=cc(Do,\"DataView\"),ab=q9,K9=cc(Do,\"Promise\"),ib=K9,W9=cc(Do,\"Set\"),Al=W9,wE=\"[object Map]\",G9=\"[object Object]\",SE=\"[object Promise]\",CE=\"[object Set]\",EE=\"[object WeakMap]\",kE=\"[object DataView]\",J9=zi(ab),Q9=zi(ad),Z9=zi(ib),Y9=zi(Al),X9=zi(sb),si=lc;(ab&&si(new ab(new ArrayBuffer(1)))!=kE||ad&&si(new ad)!=wE||ib&&si(ib.resolve())!=SE||Al&&si(new Al)!=CE||sb&&si(new sb)!=EE)&&(si=function(e){var t=lc(e),n=t==G9?e.constructor:void 0,r=n?zi(n):\"\";if(r)switch(r){case J9:return kE;case Q9:return wE;case Z9:return SE;case Y9:return CE;case X9:return EE}return t});var jE=si,eG=Do.Uint8Array,TE=eG,tG=\"__lodash_hash_undefined__\";function nG(e){return this.__data__.set(e,tG),this}var rG=nG;function sG(e){return this.__data__.has(e)}var oG=sG;function ah(e){var t=-1,n=e==null?0:e.length;for(this.__data__=new vR;++t<n;)this.add(e[t])}ah.prototype.add=ah.prototype.push=rG;ah.prototype.has=oG;var bR=ah;function aG(e,t){for(var n=-1,r=e==null?0:e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}var iG=aG;function lG(e,t){return e.has(t)}var xR=lG,cG=1,uG=2;function dG(e,t,n,r,s,o){var l=n&cG,u=e.length,d=t.length;if(u!=d&&!(l&&d>u))return!1;var f=o.get(e),h=o.get(t);if(f&&h)return f==t&&h==e;var m=-1,g=!0,x=n&uG?new bR:void 0;for(o.set(e,t),o.set(t,e);++m<u;){var b=e[m],w=t[m];if(r)var C=l?r(w,b,m,t,e,o):r(b,w,m,e,t,o);if(C!==void 0){if(C)continue;g=!1;break}if(x){if(!iG(t,function(k,j){if(!xR(x,j)&&(b===k||s(b,k,n,r,o)))return x.push(j)})){g=!1;break}}else if(!(b===w||s(b,w,n,r,o))){g=!1;break}}return o.delete(e),o.delete(t),g}var wR=dG;function fG(e){var t=-1,n=Array(e.size);return e.forEach(function(r,s){n[++t]=[s,r]}),n}var pG=fG;function hG(e){var t=-1,n=Array(e.size);return e.forEach(function(r){n[++t]=r}),n}var Lx=hG,gG=1,mG=2,vG=\"[object Boolean]\",yG=\"[object Date]\",bG=\"[object Error]\",xG=\"[object Map]\",wG=\"[object Number]\",SG=\"[object RegExp]\",CG=\"[object Set]\",EG=\"[object String]\",kG=\"[object Symbol]\",jG=\"[object ArrayBuffer]\",TG=\"[object DataView]\",NE=ja?ja.prototype:void 0,qv=NE?NE.valueOf:void 0;function NG(e,t,n,r,s,o,l){switch(n){case TG:if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case jG:return!(e.byteLength!=t.byteLength||!o(new TE(e),new TE(t)));case vG:case yG:case wG:return dR(+e,+t);case bG:return e.name==t.name&&e.message==t.message;case SG:case EG:return e==t+\"\";case xG:var u=pG;case CG:var d=r&gG;if(u||(u=Lx),e.size!=t.size&&!d)return!1;var f=l.get(e);if(f)return f==t;r|=mG,l.set(e,t);var h=wR(u(e),u(t),r,s,o,l);return l.delete(e),h;case kG:if(qv)return qv.call(e)==qv.call(t)}return!1}var MG=NG,_G=1,RG=Object.prototype,PG=RG.hasOwnProperty;function OG(e,t,n,r,s,o){var l=n&_G,u=xE(e),d=u.length,f=xE(t),h=f.length;if(d!=h&&!l)return!1;for(var m=d;m--;){var g=u[m];if(!(l?g in t:PG.call(t,g)))return!1}var x=o.get(e),b=o.get(t);if(x&&b)return x==t&&b==e;var w=!0;o.set(e,t),o.set(t,e);for(var C=l;++m<d;){g=u[m];var k=e[g],j=t[g];if(r)var M=l?r(j,k,g,t,e,o):r(k,j,g,e,t,o);if(!(M===void 0?k===j||s(k,j,n,r,o):M)){w=!1;break}C||(C=g==\"constructor\")}if(w&&!C){var _=e.constructor,R=t.constructor;_!=R&&\"constructor\"in e&&\"constructor\"in t&&!(typeof _==\"function\"&&_ instanceof _&&typeof R==\"function\"&&R instanceof R)&&(w=!1)}return o.delete(e),o.delete(t),w}var IG=OG,AG=1,ME=\"[object Arguments]\",_E=\"[object Array]\",Yf=\"[object Object]\",DG=Object.prototype,RE=DG.hasOwnProperty;function FG(e,t,n,r,s,o){var l=sd(e),u=sd(t),d=l?_E:jE(e),f=u?_E:jE(t);d=d==ME?Yf:d,f=f==ME?Yf:f;var h=d==Yf,m=f==Yf,g=d==f;if(g&&ob(e)){if(!ob(t))return!1;l=!0,h=!1}if(g&&!h)return o||(o=new Hv),l||mR(e)?wR(e,t,n,r,s,o):MG(e,t,d,n,r,s,o);if(!(n&AG)){var x=h&&RE.call(e,\"__wrapped__\"),b=m&&RE.call(t,\"__wrapped__\");if(x||b){var w=x?e.value():e,C=b?t.value():t;return o||(o=new Hv),s(w,C,n,r,o)}}return g?(o||(o=new Hv),IG(e,t,n,r,s,o)):!1}var LG=FG;function SR(e,t,n,r,s){return e===t?!0:e==null||t==null||!Kl(e)&&!Kl(t)?e!==e&&t!==t:LG(e,t,n,r,SR,s)}var $G=SR;function BG(e,t,n){for(var r=-1,s=e==null?0:e.length;++r<s;)if(n(t,e[r]))return!0;return!1}var zG=BG,UG={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#39;\"},VG=S9(UG),HG=VG,CR=/[&<>\"']/g,qG=RegExp(CR.source);function KG(e){return e=yR(e),e&&qG.test(e)?e.replace(CR,HG):e}var WG=KG,ER=/[\\\\^$.*+?()[\\]{}|]/g,GG=RegExp(ER.source);function JG(e){return e=yR(e),e&&GG.test(e)?e.replace(ER,\"\\\\$&\"):e}var QG=JG;function ZG(e,t){return $G(e,t)}var YG=ZG,XG=1/0,eJ=Al&&1/Lx(new Al([,-0]))[1]==XG?function(e){return new Al(e)}:tK,tJ=eJ,nJ=200;function rJ(e,t,n){var r=-1,s=dK,o=e.length,l=!0,u=[],d=u;if(n)l=!1,s=zG;else if(o>=nJ){var f=t?null:tJ(e);if(f)return Lx(f);l=!1,s=xR,d=new bR}else d=t?[]:u;e:for(;++r<o;){var h=e[r],m=t?t(h):h;if(h=n||h!==0?h:0,l&&m===m){for(var g=d.length;g--;)if(d[g]===m)continue e;t&&d.push(m),u.push(h)}else s(d,m,n)||(d!==u&&d.push(m),u.push(h))}return u}var sJ=rJ;function oJ(e){return e&&e.length?sJ(e):[]}var aJ=oJ,iJ=e=>i.jsx(\"button\",{className:e.classNames.clearAll,onClick:e.onClick,children:\"Clear all\"}),lJ=iJ,cJ=(e,t)=>{const n=t.offsetHeight,r=e.offsetHeight,s=e.offsetTop-t.scrollTop;s+r>=n?t.scrollTop+=s-n+r:s<0&&(t.scrollTop+=s)},lb=(e,t,n,r)=>typeof r==\"function\"?r(e):e.length>=t&&n,uJ=e=>{const t=y.createRef(),{labelField:n,minQueryLength:r,isFocused:s,classNames:o,selectedIndex:l,query:u}=e;y.useEffect(()=>{if(!t.current)return;const m=t.current.querySelector(`.${o.activeSuggestion}`);m&&cJ(m,t.current)},[l]);const d=(m,g)=>{const x=g.trim().replace(/[-\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\"),{[n]:b}=m;return{__html:b.replace(RegExp(x,\"gi\"),w=>`<mark>${WG(w)}</mark>`)}},f=(m,g)=>typeof e.renderSuggestion==\"function\"?e.renderSuggestion(m,g):i.jsx(\"span\",{dangerouslySetInnerHTML:d(m,g)}),h=e.suggestions.map((m,g)=>i.jsx(\"li\",{onMouseDown:e.handleClick.bind(null,g),onTouchStart:e.handleClick.bind(null,g),onMouseOver:e.handleHover.bind(null,g),className:g===e.selectedIndex?e.classNames.activeSuggestion:\"\",children:f(m,e.query)},g));return h.length===0||!lb(u,r||2,s,e.shouldRenderSuggestions)?null:i.jsx(\"div\",{ref:t,className:o.suggestions,\"data-testid\":\"suggestions\",children:i.jsxs(\"ul\",{children:[\" \",h,\" \"]})})},dJ=(e,t)=>{const{query:n,minQueryLength:r=2,isFocused:s,suggestions:o}=t;return!!(e.isFocused===s&&YG(e.suggestions,o)&&lb(n,r,s,t.shouldRenderSuggestions)===lb(e.query,e.minQueryLength??2,e.isFocused,e.shouldRenderSuggestions)&&e.selectedIndex===t.selectedIndex)},fJ=y.memo(uJ,dJ),pJ=fJ,hJ=sR(oR()),gJ=sR(oR());function mJ(e){const t=e.map(r=>{const s=r-48*Math.floor(r/48);return String.fromCharCode(96<=r?s:r)}).join(\"\"),n=QG(t);return new RegExp(`[${n}]+`)}function vJ(e){switch(e){case Vs.ENTER:return[10,13];case Vs.TAB:return 9;case Vs.COMMA:return 188;case Vs.SPACE:return 32;case Vs.SEMICOLON:return 186;default:return 0}}function PE(e){const{moveTag:t,readOnly:n,allowDragDrop:r}=e;return t!==void 0&&!n&&r}function yJ(e){const{readOnly:t,allowDragDrop:n}=e;return!t&&n}var bJ=e=>{const{readOnly:t,removeComponent:n,onRemove:r,className:s,tag:o,index:l}=e,u=f=>{if(Il.ENTER.includes(f.keyCode)||f.keyCode===Il.SPACE){f.preventDefault(),f.stopPropagation();return}f.keyCode===Il.BACKSPACE&&r(f)};if(t)return i.jsx(\"span\",{});const d=`Tag at index ${l} with value ${o.id} focussed. Press backspace to remove`;if(n){const f=n;return i.jsx(f,{\"data-testid\":\"remove\",onRemove:r,onKeyDown:u,className:s,\"aria-label\":d,tag:o,index:l})}return i.jsx(\"button\",{\"data-testid\":\"remove\",onClick:r,onKeyDown:u,className:s,type:\"button\",\"aria-label\":d,children:i.jsx(\"svg\",{xmlns:\"http://www.w3.org/2000/svg\",viewBox:\"0 0 512 512\",height:\"12\",width:\"12\",fill:\"#fff\",children:i.jsx(\"path\",{d:\"M376.6 84.5c11.3-13.6 9.5-33.8-4.1-45.1s-33.8-9.5-45.1 4.1L192 206 56.6 43.5C45.3 29.9 25.1 28.1 11.5 39.4S-3.9 70.9 7.4 84.5L150.3 256 7.4 427.5c-11.3 13.6-9.5 33.8 4.1 45.1s33.8 9.5 45.1-4.1L192 306 327.4 468.5c11.3 13.6 31.5 15.4 45.1 4.1s15.4-31.5 4.1-45.1L233.7 256 376.6 84.5z\"})})})},xJ=bJ,OE={TAG:\"tag\"},wJ=e=>{const t=y.useRef(null),{readOnly:n=!1,tag:r,classNames:s,index:o,moveTag:l,allowDragDrop:u=!0,labelField:d=\"text\",tags:f}=e,[{isDragging:h},m]=iq(()=>({type:OE.TAG,collect:C=>({isDragging:!!C.isDragging()}),item:e,canDrag:()=>PE({moveTag:l,readOnly:n,allowDragDrop:u})}),[f]),[,g]=Cq(()=>({accept:OE.TAG,drop:C=>{const k=C.index,j=o;k!==j&&e?.moveTag?.(k,j)},canDrop:C=>yJ(C)}),[f]);m(g(t));const x=e.tag[d],{className:b=\"\"}=r,w=h?0:1;return i.jsxs(\"span\",{ref:t,className:(0,gJ.default)(\"tag-wrapper\",s.tag,b),style:{opacity:w,cursor:PE({moveTag:l,readOnly:n,allowDragDrop:u})?\"move\":\"auto\"},\"data-testid\":\"tag\",onClick:e.onTagClicked,onTouchStart:e.onTagClicked,children:[x,i.jsx(xJ,{tag:e.tag,className:s.remove,removeComponent:e.removeComponent,onRemove:e.onDelete,readOnly:n,index:o})]})},SJ=e=>{const{autofocus:t,autoFocus:n,readOnly:r,labelField:s,allowDeleteFromEmptyInput:o,allowAdditionFromPaste:l,allowDragDrop:u,minQueryLength:d,shouldRenderSuggestions:f,removeComponent:h,autocomplete:m,inline:g,maxTags:x,allowUnique:b,editable:w,placeholder:C,delimiters:k,separators:j,tags:M,inputFieldPosition:_,inputProps:R,classNames:N,maxLength:O,inputValue:D,clearAll:z}=e,[Q,pe]=y.useState(e.suggestions),[V,G]=y.useState(\"\"),[W,ie]=y.useState(!1),[re,Y]=y.useState(-1),[H,q]=y.useState(!1),[he,A]=y.useState(\"\"),[F,fe]=y.useState(-1),[te,de]=y.useState(\"\"),ge=y.createRef(),Z=y.useRef(null),ye=y.useRef(null);y.useEffect(()=>{k.length&&console.warn(\"[Deprecation] The delimiters prop is deprecated and will be removed in v7.x.x, please use separators instead. If you have any concerns regarding this, please share your thoughts in https://github.com/react-tags/react-tags/issues/960\")},[]),y.useEffect(()=>{typeof g<\"u\"&&console.warn(\"[Deprecation] The inline attribute is deprecated and will be removed in v7.x.x, please use inputFieldPosition instead.\")},[g]),y.useEffect(()=>{typeof t<\"u\"&&console.warn(\"[Deprecated] autofocus prop will be removed in 7.x so please migrate to autoFocus prop.\"),(t||n&&t!==!1)&&!r&&Ye()},[n,n,r]),y.useEffect(()=>{vn()},[V,e.suggestions]);const Re=Te=>{let ut=e.suggestions.slice();if(b){const mr=M.map(vr=>vr.id.trim().toLowerCase());ut=ut.filter(vr=>!mr.includes(vr.id.toLowerCase()))}if(e.handleFilterSuggestions)return e.handleFilterSuggestions(Te,ut);const It=ut.filter(mr=>$e(Te,mr)===0),Tn=ut.filter(mr=>$e(Te,mr)>0);return It.concat(Tn)},$e=(Te,ut)=>ut[s].toLowerCase().indexOf(Te.toLowerCase()),Ye=()=>{G(\"\"),Z.current&&(Z.current.value=\"\",Z.current.focus())},Fe=(Te,ut)=>{ut.preventDefault(),ut.stopPropagation();const It=M.slice();It.length!==0&&(de(\"\"),e?.handleDelete?.(Te,ut),ft(Te,It))},ft=(Te,ut)=>{if(!ge?.current)return;const It=ge.current.querySelectorAll(\".ReactTags__remove\");let Tn=\"\";Te===0&&ut.length>1?(Tn=`Tag at index ${Te} with value ${ut[Te].id} deleted. Tag at index 0 with value ${ut[1].id} focussed. Press backspace to remove`,It[0].focus()):Te>0?(Tn=`Tag at index ${Te} with value ${ut[Te].id} deleted. Tag at index ${Te-1} with value ${ut[Te-1].id} focussed. Press backspace to remove`,It[Te-1].focus()):(Tn=`Tag at index ${Te} with value ${ut[Te].id} deleted. Input focussed. Press enter to add a new tag`,Z.current?.focus()),A(Tn)},ln=(Te,ut,It)=>{r||(w&&(fe(Te),G(ut[s]),ye.current?.focus()),e.handleTagClick?.(Te,It))},Sn=Te=>{e.handleInputChange&&e.handleInputChange(Te.target.value,Te);const ut=Te.target.value.trim();G(ut)},vn=()=>{const Te=Re(V);pe(Te),Y(re>=Te.length?Te.length-1:re)},Cn=Te=>{const ut=Te.target.value;e.handleInputFocus&&e.handleInputFocus(ut,Te),ie(!0)},L=Te=>{const ut=Te.target.value;e.handleInputBlur&&(e.handleInputBlur(ut,Te),Z.current&&(Z.current.value=\"\")),ie(!1),fe(-1)},X=Te=>{if(Te.key===\"Escape\"&&(Te.preventDefault(),Te.stopPropagation(),Y(-1),q(!1),pe([]),fe(-1)),(j.indexOf(Te.key)!==-1||k.indexOf(Te.keyCode)!==-1)&&!Te.shiftKey){(Te.keyCode!==Il.TAB||V!==\"\")&&Te.preventDefault();const ut=H&&re!==-1?Q[re]:{id:V.trim(),[s]:V.trim(),className:\"\"};Object.keys(ut)&&je(ut)}Te.key===\"Backspace\"&&V===\"\"&&(o||_===cu.INLINE)&&Fe(M.length-1,Te),Te.keyCode===Il.UP_ARROW&&(Te.preventDefault(),Y(re<=0?Q.length-1:re-1),q(!0)),Te.keyCode===Il.DOWN_ARROW&&(Te.preventDefault(),q(!0),Q.length===0?Y(-1):Y((re+1)%Q.length))},ue=()=>x&&M.length>=x,Ne=Te=>{if(!l)return;if(ue()){de(lE.TAG_LIMIT),Ye();return}de(\"\"),Te.preventDefault();const ut=Te.clipboardData||window.clipboardData,It=ut.getData(\"text\"),{maxLength:Tn=It.length}=e,mr=Math.min(Tn,It.length),vr=ut.getData(\"text\").substr(0,mr);let Gr=k;j.length&&(Gr=[],j.forEach(Rr=>{const Uo=vJ(Rr);Array.isArray(Uo)?Gr=[...Gr,...Uo]:Gr.push(Uo)}));const Jr=mJ(Gr),_r=vr.split(Jr).map(Rr=>Rr.trim());aJ(_r).forEach(Rr=>je({id:Rr.trim(),[s]:Rr.trim(),className:\"\"}))},je=Te=>{if(!Te.id||!Te[s])return;if(F===-1){if(ue()){de(lE.TAG_LIMIT),Ye();return}de(\"\")}const ut=M.map(It=>It.id.toLowerCase());if(!(b&&ut.indexOf(Te.id.trim().toLowerCase())>=0)){if(m){const It=Re(Te[s]);console.warn(\"[Deprecation] The autocomplete prop will be removed in 7.x to simplify the integration and make it more intutive. If you have any concerns regarding this, please share your thoughts in https://github.com/react-tags/react-tags/issues/949\"),(m===1&&It.length===1||m===!0&&It.length)&&(Te=It[0])}F!==-1&&e.onTagUpdate?e.onTagUpdate(F,Te):e?.handleAddition?.(Te),G(\"\"),q(!1),Y(-1),fe(-1),Ye()}},Se=Te=>{je(Q[Te])},Be=()=>{e.onClearAll&&e.onClearAll(),de(\"\"),Ye()},bt=Te=>{Y(Te),q(!0)},Wt=(Te,ut)=>{const It=M[Te];e?.handleDrag?.(It,Te,ut)},bn=(()=>{const Te={...iE,...e.classNames};return M.map((ut,It)=>i.jsx(y.Fragment,{children:F===It?i.jsx(\"div\",{className:Te.editTagInput,children:i.jsx(\"input\",{ref:Tn=>{ye.current=Tn},onFocus:Cn,value:V,onChange:Sn,onKeyDown:X,onBlur:L,className:Te.editTagInputField,onPaste:Ne,\"data-testid\":\"tag-edit\"})}):i.jsx(wJ,{index:It,tag:ut,tags:M,labelField:s,onDelete:Tn=>Fe(It,Tn),moveTag:u?Wt:void 0,removeComponent:h,onTagClicked:Tn=>ln(It,ut,Tn),readOnly:r,classNames:Te,allowDragDrop:u})},It))})(),En={...iE,...N},{name:gr,id:Qn}=e,ro=g===!1?cu.BOTTOM:_,Bn=r?null:i.jsxs(\"div\",{className:En.tagInput,children:[i.jsx(\"input\",{...R,ref:Te=>{Z.current=Te},className:En.tagInputField,type:\"text\",placeholder:C,\"aria-label\":C,onFocus:Cn,onBlur:L,onChange:Sn,onKeyDown:X,onPaste:Ne,name:gr,id:Qn,maxLength:O,value:D,\"data-automation\":\"input\",\"data-testid\":\"input\"}),i.jsx(pJ,{query:V.trim(),suggestions:Q,labelField:s,selectedIndex:re,handleClick:Se,handleHover:bt,minQueryLength:d,shouldRenderSuggestions:f,isFocused:W,classNames:En,renderSuggestion:e.renderSuggestion}),z&&M.length>0&&i.jsx(lJ,{classNames:En,onClick:Be}),te&&i.jsxs(\"div\",{\"data-testid\":\"error\",className:\"ReactTags__error\",children:[i.jsx(\"svg\",{xmlns:\"http://www.w3.org/2000/svg\",viewBox:\"0 0 512 512\",height:\"24\",width:\"24\",fill:\"#e03131\",children:i.jsx(\"path\",{d:\"M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"})}),te]})]});return i.jsxs(\"div\",{className:(0,hJ.default)(En.tags,\"react-tags-wrapper\"),ref:ge,children:[i.jsx(\"p\",{role:\"alert\",className:\"sr-only\",style:{position:\"absolute\",overflow:\"hidden\",clip:\"rect(0 0 0 0)\",margin:\"-1px\",padding:0,width:\"1px\",height:\"1px\",border:0},children:he}),ro===cu.TOP&&Bn,i.jsxs(\"div\",{className:En.selected,children:[bn,ro===cu.INLINE&&Bn]}),ro===cu.BOTTOM&&Bn]})},CJ=SJ,EJ=e=>{const{placeholder:t=s7,labelField:n=o7,suggestions:r=[],delimiters:s=[],separators:o=e.delimiters?.length?[]:[Vs.ENTER,Vs.TAB],autofocus:l,autoFocus:u=!0,inline:d,inputFieldPosition:f=\"inline\",allowDeleteFromEmptyInput:h=!1,allowAdditionFromPaste:m=!0,autocomplete:g=!1,readOnly:x=!1,allowUnique:b=!0,allowDragDrop:w=!0,tags:C=[],inputProps:k={},editable:j=!1,clearAll:M=!1,handleDelete:_,handleAddition:R,onTagUpdate:N,handleDrag:O,handleFilterSuggestions:D,handleTagClick:z,handleInputChange:Q,handleInputFocus:pe,handleInputBlur:V,minQueryLength:G,shouldRenderSuggestions:W,removeComponent:ie,onClearAll:re,classNames:Y,name:H,id:q,maxLength:he,inputValue:A,maxTags:F,renderSuggestion:fe}=e;return i.jsx(CJ,{placeholder:t,labelField:n,suggestions:r,delimiters:s,separators:o,autofocus:l,autoFocus:u,inline:d,inputFieldPosition:f,allowDeleteFromEmptyInput:h,allowAdditionFromPaste:m,autocomplete:g,readOnly:x,allowUnique:b,allowDragDrop:w,tags:C,inputProps:k,editable:j,clearAll:M,handleDelete:_,handleAddition:R,onTagUpdate:N,handleDrag:O,handleFilterSuggestions:D,handleTagClick:z,handleInputChange:Q,handleInputFocus:pe,handleInputBlur:V,minQueryLength:G,shouldRenderSuggestions:W,removeComponent:ie,onClearAll:re,classNames:Y,name:H,id:q,maxLength:he,inputValue:A,maxTags:F,renderSuggestion:fe})},kJ=({...e})=>i.jsx(tH,{backend:Zq,children:i.jsx(EJ,{...e})});/*! Bundled license information:\n\nclassnames/index.js:\n  (*!\n  \tCopyright (c) 2018 Jed Watson.\n  \tLicensed under the MIT License (MIT), see\n  \thttp://jedwatson.github.io/classnames\n  *)\n\nlodash-es/lodash.js:\n  (**\n   * @license\n   * Lodash (Custom Build) <https://lodash.com/>\n   * Build: `lodash modularize exports=\"es\" -o ./`\n   * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>\n   * Released under MIT license <https://lodash.com/license>\n   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n   *)\n*/var jJ=\"Label\",kR=y.forwardRef((e,t)=>i.jsx(rt.label,{...e,ref:t,onMouseDown:n=>{n.target.closest(\"button, input, select, textarea\")||(e.onMouseDown?.(n),!n.defaultPrevented&&n.detail>1&&n.preventDefault())}}));kR.displayName=jJ;var jR=kR;const TJ=jh(\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"),TR=y.forwardRef(({className:e,...t},n)=>i.jsx(jR,{ref:n,className:Ie(TJ(),e),...t}));TR.displayName=jR.displayName;function NR(e){const t=y.useRef({value:e,previous:e});return y.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}var NJ=\"VisuallyHidden\",MR=y.forwardRef((e,t)=>i.jsx(rt.span,{...e,ref:t,style:{position:\"absolute\",border:0,width:1,height:1,padding:0,margin:-1,overflow:\"hidden\",clip:\"rect(0, 0, 0, 0)\",whiteSpace:\"nowrap\",wordWrap:\"normal\",...e.style}}));MR.displayName=NJ;var MJ=[\" \",\"Enter\",\"ArrowUp\",\"ArrowDown\"],_J=[\" \",\"Enter\"],jd=\"Select\",[ng,rg,RJ]=Kb(jd),[hc]=us(jd,[RJ,Oh]),sg=Oh(),[PJ,Ia]=hc(jd),[OJ,IJ]=hc(jd),_R=e=>{const{__scopeSelect:t,children:n,open:r,defaultOpen:s,onOpenChange:o,value:l,defaultValue:u,onValueChange:d,dir:f,name:h,autoComplete:m,disabled:g,required:x}=e,b=sg(t),[w,C]=y.useState(null),[k,j]=y.useState(null),[M,_]=y.useState(!1),R=xd(f),[N=!1,O]=ya({prop:r,defaultProp:s,onChange:o}),[D,z]=ya({prop:l,defaultProp:u,onChange:d}),Q=y.useRef(null),pe=w?!!w.closest(\"form\"):!0,[V,G]=y.useState(new Set),W=Array.from(V).map(ie=>ie.props.value).join(\";\");return i.jsx(ZT,{...b,children:i.jsxs(PJ,{required:x,scope:t,trigger:w,onTriggerChange:C,valueNode:k,onValueNodeChange:j,valueNodeHasChildren:M,onValueNodeHasChildrenChange:_,contentId:Es(),value:D,onValueChange:z,open:N,onOpenChange:O,dir:R,triggerPointerDownPosRef:Q,disabled:g,children:[i.jsx(ng.Provider,{scope:t,children:i.jsx(OJ,{scope:e.__scopeSelect,onNativeOptionAdd:y.useCallback(ie=>{G(re=>new Set(re).add(ie))},[]),onNativeOptionRemove:y.useCallback(ie=>{G(re=>{const Y=new Set(re);return Y.delete(ie),Y})},[]),children:n})}),pe?i.jsxs(tP,{\"aria-hidden\":!0,required:x,tabIndex:-1,name:h,autoComplete:m,value:D,onChange:ie=>z(ie.target.value),disabled:g,children:[D===void 0?i.jsx(\"option\",{value:\"\"}):null,Array.from(V)]},W):null]})})};_R.displayName=jd;var RR=\"SelectTrigger\",PR=y.forwardRef((e,t)=>{const{__scopeSelect:n,disabled:r=!1,...s}=e,o=sg(n),l=Ia(RR,n),u=l.disabled||r,d=Rt(t,l.onTriggerChange),f=rg(n),[h,m,g]=nP(b=>{const w=f().filter(j=>!j.disabled),C=w.find(j=>j.value===l.value),k=rP(w,b,C);k!==void 0&&l.onValueChange(k.value)}),x=()=>{u||(l.onOpenChange(!0),g())};return i.jsx(YT,{asChild:!0,...o,children:i.jsx(rt.button,{type:\"button\",role:\"combobox\",\"aria-controls\":l.contentId,\"aria-expanded\":l.open,\"aria-required\":l.required,\"aria-autocomplete\":\"none\",dir:l.dir,\"data-state\":l.open?\"open\":\"closed\",disabled:u,\"data-disabled\":u?\"\":void 0,\"data-placeholder\":eP(l.value)?\"\":void 0,...s,ref:d,onClick:Ue(s.onClick,b=>{b.currentTarget.focus()}),onPointerDown:Ue(s.onPointerDown,b=>{const w=b.target;w.hasPointerCapture(b.pointerId)&&w.releasePointerCapture(b.pointerId),b.button===0&&b.ctrlKey===!1&&(x(),l.triggerPointerDownPosRef.current={x:Math.round(b.pageX),y:Math.round(b.pageY)},b.preventDefault())}),onKeyDown:Ue(s.onKeyDown,b=>{const w=h.current!==\"\";!(b.ctrlKey||b.altKey||b.metaKey)&&b.key.length===1&&m(b.key),!(w&&b.key===\" \")&&MJ.includes(b.key)&&(x(),b.preventDefault())})})})});PR.displayName=RR;var OR=\"SelectValue\",IR=y.forwardRef((e,t)=>{const{__scopeSelect:n,className:r,style:s,children:o,placeholder:l=\"\",...u}=e,d=Ia(OR,n),{onValueNodeHasChildrenChange:f}=d,h=o!==void 0,m=Rt(t,d.onValueNodeChange);return Ln(()=>{f(h)},[f,h]),i.jsx(rt.span,{...u,ref:m,style:{pointerEvents:\"none\"},children:eP(d.value)?i.jsx(i.Fragment,{children:l}):o})});IR.displayName=OR;var AJ=\"SelectIcon\",AR=y.forwardRef((e,t)=>{const{__scopeSelect:n,children:r,...s}=e;return i.jsx(rt.span,{\"aria-hidden\":!0,...s,ref:t,children:r||\"▼\"})});AR.displayName=AJ;var DJ=\"SelectPortal\",DR=e=>i.jsx(Ih,{asChild:!0,...e});DR.displayName=DJ;var _i=\"SelectContent\",FR=y.forwardRef((e,t)=>{const n=Ia(_i,e.__scopeSelect),[r,s]=y.useState();if(Ln(()=>{s(new DocumentFragment)},[]),!n.open){const o=r;return o?Ma.createPortal(i.jsx(LR,{scope:e.__scopeSelect,children:i.jsx(ng.Slot,{scope:e.__scopeSelect,children:i.jsx(\"div\",{children:e.children})})}),o):null}return i.jsx($R,{...e,ref:t})});FR.displayName=_i;var vo=10,[LR,Aa]=hc(_i),FJ=\"SelectContentImpl\",$R=y.forwardRef((e,t)=>{const{__scopeSelect:n,position:r=\"item-aligned\",onCloseAutoFocus:s,onEscapeKeyDown:o,onPointerDownOutside:l,side:u,sideOffset:d,align:f,alignOffset:h,arrowPadding:m,collisionBoundary:g,collisionPadding:x,sticky:b,hideWhenDetached:w,avoidCollisions:C,...k}=e,j=Ia(_i,n),[M,_]=y.useState(null),[R,N]=y.useState(null),O=Rt(t,Z=>_(Z)),[D,z]=y.useState(null),[Q,pe]=y.useState(null),V=rg(n),[G,W]=y.useState(!1),ie=y.useRef(!1);y.useEffect(()=>{if(M)return nx(M)},[M]),Wb();const re=y.useCallback(Z=>{const[ye,...Re]=V().map(Fe=>Fe.ref.current),[$e]=Re.slice(-1),Ye=document.activeElement;for(const Fe of Z)if(Fe===Ye||(Fe?.scrollIntoView({block:\"nearest\"}),Fe===ye&&R&&(R.scrollTop=0),Fe===$e&&R&&(R.scrollTop=R.scrollHeight),Fe?.focus(),document.activeElement!==Ye))return},[V,R]),Y=y.useCallback(()=>re([D,M]),[re,D,M]);y.useEffect(()=>{G&&Y()},[G,Y]);const{onOpenChange:H,triggerPointerDownPosRef:q}=j;y.useEffect(()=>{if(M){let Z={x:0,y:0};const ye=$e=>{Z={x:Math.abs(Math.round($e.pageX)-(q.current?.x??0)),y:Math.abs(Math.round($e.pageY)-(q.current?.y??0))}},Re=$e=>{Z.x<=10&&Z.y<=10?$e.preventDefault():M.contains($e.target)||H(!1),document.removeEventListener(\"pointermove\",ye),q.current=null};return q.current!==null&&(document.addEventListener(\"pointermove\",ye),document.addEventListener(\"pointerup\",Re,{capture:!0,once:!0})),()=>{document.removeEventListener(\"pointermove\",ye),document.removeEventListener(\"pointerup\",Re,{capture:!0})}}},[M,H,q]),y.useEffect(()=>{const Z=()=>H(!1);return window.addEventListener(\"blur\",Z),window.addEventListener(\"resize\",Z),()=>{window.removeEventListener(\"blur\",Z),window.removeEventListener(\"resize\",Z)}},[H]);const[he,A]=nP(Z=>{const ye=V().filter(Ye=>!Ye.disabled),Re=ye.find(Ye=>Ye.ref.current===document.activeElement),$e=rP(ye,Z,Re);$e&&setTimeout(()=>$e.ref.current.focus())}),F=y.useCallback((Z,ye,Re)=>{const $e=!ie.current&&!Re;(j.value!==void 0&&j.value===ye||$e)&&(z(Z),$e&&(ie.current=!0))},[j.value]),fe=y.useCallback(()=>M?.focus(),[M]),te=y.useCallback((Z,ye,Re)=>{const $e=!ie.current&&!Re;(j.value!==void 0&&j.value===ye||$e)&&pe(Z)},[j.value]),de=r===\"popper\"?cb:BR,ge=de===cb?{side:u,sideOffset:d,align:f,alignOffset:h,arrowPadding:m,collisionBoundary:g,collisionPadding:x,sticky:b,hideWhenDetached:w,avoidCollisions:C}:{};return i.jsx(LR,{scope:n,content:M,viewport:R,onViewportChange:N,itemRefCallback:F,selectedItem:D,onItemLeave:fe,itemTextRefCallback:te,focusSelectedItem:Y,selectedItemText:Q,position:r,isPositioned:G,searchRef:he,children:i.jsx(Lh,{as:No,allowPinchZoom:!0,children:i.jsx(_h,{asChild:!0,trapped:j.open,onMountAutoFocus:Z=>{Z.preventDefault()},onUnmountAutoFocus:Ue(s,Z=>{j.trigger?.focus({preventScroll:!0}),Z.preventDefault()}),children:i.jsx(Mh,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:o,onPointerDownOutside:l,onFocusOutside:Z=>Z.preventDefault(),onDismiss:()=>j.onOpenChange(!1),children:i.jsx(de,{role:\"listbox\",id:j.contentId,\"data-state\":j.open?\"open\":\"closed\",dir:j.dir,onContextMenu:Z=>Z.preventDefault(),...k,...ge,onPlaced:()=>W(!0),ref:O,style:{display:\"flex\",flexDirection:\"column\",outline:\"none\",...k.style},onKeyDown:Ue(k.onKeyDown,Z=>{const ye=Z.ctrlKey||Z.altKey||Z.metaKey;if(Z.key===\"Tab\"&&Z.preventDefault(),!ye&&Z.key.length===1&&A(Z.key),[\"ArrowUp\",\"ArrowDown\",\"Home\",\"End\"].includes(Z.key)){let $e=V().filter(Ye=>!Ye.disabled).map(Ye=>Ye.ref.current);if([\"ArrowUp\",\"End\"].includes(Z.key)&&($e=$e.slice().reverse()),[\"ArrowUp\",\"ArrowDown\"].includes(Z.key)){const Ye=Z.target,Fe=$e.indexOf(Ye);$e=$e.slice(Fe+1)}setTimeout(()=>re($e)),Z.preventDefault()}})})})})})})});$R.displayName=FJ;var LJ=\"SelectItemAlignedPosition\",BR=y.forwardRef((e,t)=>{const{__scopeSelect:n,onPlaced:r,...s}=e,o=Ia(_i,n),l=Aa(_i,n),[u,d]=y.useState(null),[f,h]=y.useState(null),m=Rt(t,O=>h(O)),g=rg(n),x=y.useRef(!1),b=y.useRef(!0),{viewport:w,selectedItem:C,selectedItemText:k,focusSelectedItem:j}=l,M=y.useCallback(()=>{if(o.trigger&&o.valueNode&&u&&f&&w&&C&&k){const O=o.trigger.getBoundingClientRect(),D=f.getBoundingClientRect(),z=o.valueNode.getBoundingClientRect(),Q=k.getBoundingClientRect();if(o.dir!==\"rtl\"){const Ye=Q.left-D.left,Fe=z.left-Ye,ft=O.left-Fe,ln=O.width+ft,Sn=Math.max(ln,D.width),vn=window.innerWidth-vo,Cn=Ky(Fe,[vo,vn-Sn]);u.style.minWidth=ln+\"px\",u.style.left=Cn+\"px\"}else{const Ye=D.right-Q.right,Fe=window.innerWidth-z.right-Ye,ft=window.innerWidth-O.right-Fe,ln=O.width+ft,Sn=Math.max(ln,D.width),vn=window.innerWidth-vo,Cn=Ky(Fe,[vo,vn-Sn]);u.style.minWidth=ln+\"px\",u.style.right=Cn+\"px\"}const pe=g(),V=window.innerHeight-vo*2,G=w.scrollHeight,W=window.getComputedStyle(f),ie=parseInt(W.borderTopWidth,10),re=parseInt(W.paddingTop,10),Y=parseInt(W.borderBottomWidth,10),H=parseInt(W.paddingBottom,10),q=ie+re+G+H+Y,he=Math.min(C.offsetHeight*5,q),A=window.getComputedStyle(w),F=parseInt(A.paddingTop,10),fe=parseInt(A.paddingBottom,10),te=O.top+O.height/2-vo,de=V-te,ge=C.offsetHeight/2,Z=C.offsetTop+ge,ye=ie+re+Z,Re=q-ye;if(ye<=te){const Ye=C===pe[pe.length-1].ref.current;u.style.bottom=\"0px\";const Fe=f.clientHeight-w.offsetTop-w.offsetHeight,ft=Math.max(de,ge+(Ye?fe:0)+Fe+Y),ln=ye+ft;u.style.height=ln+\"px\"}else{const Ye=C===pe[0].ref.current;u.style.top=\"0px\";const ft=Math.max(te,ie+w.offsetTop+(Ye?F:0)+ge)+Re;u.style.height=ft+\"px\",w.scrollTop=ye-te+w.offsetTop}u.style.margin=`${vo}px 0`,u.style.minHeight=he+\"px\",u.style.maxHeight=V+\"px\",r?.(),requestAnimationFrame(()=>x.current=!0)}},[g,o.trigger,o.valueNode,u,f,w,C,k,o.dir,r]);Ln(()=>M(),[M]);const[_,R]=y.useState();Ln(()=>{f&&R(window.getComputedStyle(f).zIndex)},[f]);const N=y.useCallback(O=>{O&&b.current===!0&&(M(),j?.(),b.current=!1)},[M,j]);return i.jsx(BJ,{scope:n,contentWrapper:u,shouldExpandOnScrollRef:x,onScrollButtonChange:N,children:i.jsx(\"div\",{ref:d,style:{display:\"flex\",flexDirection:\"column\",position:\"fixed\",zIndex:_},children:i.jsx(rt.div,{...s,ref:m,style:{boxSizing:\"border-box\",maxHeight:\"100%\",...s.style}})})})});BR.displayName=LJ;var $J=\"SelectPopperPosition\",cb=y.forwardRef((e,t)=>{const{__scopeSelect:n,align:r=\"start\",collisionPadding:s=vo,...o}=e,l=sg(n);return i.jsx(XT,{...l,...o,ref:t,align:r,collisionPadding:s,style:{boxSizing:\"border-box\",...o.style,\"--radix-select-content-transform-origin\":\"var(--radix-popper-transform-origin)\",\"--radix-select-content-available-width\":\"var(--radix-popper-available-width)\",\"--radix-select-content-available-height\":\"var(--radix-popper-available-height)\",\"--radix-select-trigger-width\":\"var(--radix-popper-anchor-width)\",\"--radix-select-trigger-height\":\"var(--radix-popper-anchor-height)\"}})});cb.displayName=$J;var[BJ,$x]=hc(_i,{}),ub=\"SelectViewport\",zR=y.forwardRef((e,t)=>{const{__scopeSelect:n,nonce:r,...s}=e,o=Aa(ub,n),l=$x(ub,n),u=Rt(t,o.onViewportChange),d=y.useRef(0);return i.jsxs(i.Fragment,{children:[i.jsx(\"style\",{dangerouslySetInnerHTML:{__html:\"[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}\"},nonce:r}),i.jsx(ng.Slot,{scope:n,children:i.jsx(rt.div,{\"data-radix-select-viewport\":\"\",role:\"presentation\",...s,ref:u,style:{position:\"relative\",flex:1,overflow:\"auto\",...s.style},onScroll:Ue(s.onScroll,f=>{const h=f.currentTarget,{contentWrapper:m,shouldExpandOnScrollRef:g}=l;if(g?.current&&m){const x=Math.abs(d.current-h.scrollTop);if(x>0){const b=window.innerHeight-vo*2,w=parseFloat(m.style.minHeight),C=parseFloat(m.style.height),k=Math.max(w,C);if(k<b){const j=k+x,M=Math.min(b,j),_=j-M;m.style.height=M+\"px\",m.style.bottom===\"0px\"&&(h.scrollTop=_>0?_:0,m.style.justifyContent=\"flex-end\")}}}d.current=h.scrollTop})})})]})});zR.displayName=ub;var UR=\"SelectGroup\",[zJ,UJ]=hc(UR),VJ=y.forwardRef((e,t)=>{const{__scopeSelect:n,...r}=e,s=Es();return i.jsx(zJ,{scope:n,id:s,children:i.jsx(rt.div,{role:\"group\",\"aria-labelledby\":s,...r,ref:t})})});VJ.displayName=UR;var VR=\"SelectLabel\",HR=y.forwardRef((e,t)=>{const{__scopeSelect:n,...r}=e,s=UJ(VR,n);return i.jsx(rt.div,{id:s.id,...r,ref:t})});HR.displayName=VR;var ih=\"SelectItem\",[HJ,qR]=hc(ih),KR=y.forwardRef((e,t)=>{const{__scopeSelect:n,value:r,disabled:s=!1,textValue:o,...l}=e,u=Ia(ih,n),d=Aa(ih,n),f=u.value===r,[h,m]=y.useState(o??\"\"),[g,x]=y.useState(!1),b=Rt(t,k=>d.itemRefCallback?.(k,r,s)),w=Es(),C=()=>{s||(u.onValueChange(r),u.onOpenChange(!1))};if(r===\"\")throw new Error(\"A <Select.Item /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder.\");return i.jsx(HJ,{scope:n,value:r,disabled:s,textId:w,isSelected:f,onItemTextChange:y.useCallback(k=>{m(j=>j||(k?.textContent??\"\").trim())},[]),children:i.jsx(ng.ItemSlot,{scope:n,value:r,disabled:s,textValue:h,children:i.jsx(rt.div,{role:\"option\",\"aria-labelledby\":w,\"data-highlighted\":g?\"\":void 0,\"aria-selected\":f&&g,\"data-state\":f?\"checked\":\"unchecked\",\"aria-disabled\":s||void 0,\"data-disabled\":s?\"\":void 0,tabIndex:s?void 0:-1,...l,ref:b,onFocus:Ue(l.onFocus,()=>x(!0)),onBlur:Ue(l.onBlur,()=>x(!1)),onPointerUp:Ue(l.onPointerUp,C),onPointerMove:Ue(l.onPointerMove,k=>{s?d.onItemLeave?.():k.currentTarget.focus({preventScroll:!0})}),onPointerLeave:Ue(l.onPointerLeave,k=>{k.currentTarget===document.activeElement&&d.onItemLeave?.()}),onKeyDown:Ue(l.onKeyDown,k=>{d.searchRef?.current!==\"\"&&k.key===\" \"||(_J.includes(k.key)&&C(),k.key===\" \"&&k.preventDefault())})})})})});KR.displayName=ih;var xu=\"SelectItemText\",WR=y.forwardRef((e,t)=>{const{__scopeSelect:n,className:r,style:s,...o}=e,l=Ia(xu,n),u=Aa(xu,n),d=qR(xu,n),f=IJ(xu,n),[h,m]=y.useState(null),g=Rt(t,k=>m(k),d.onItemTextChange,k=>u.itemTextRefCallback?.(k,d.value,d.disabled)),x=h?.textContent,b=y.useMemo(()=>i.jsx(\"option\",{value:d.value,disabled:d.disabled,children:x},d.value),[d.disabled,d.value,x]),{onNativeOptionAdd:w,onNativeOptionRemove:C}=f;return Ln(()=>(w(b),()=>C(b)),[w,C,b]),i.jsxs(i.Fragment,{children:[i.jsx(rt.span,{id:d.textId,...o,ref:g}),d.isSelected&&l.valueNode&&!l.valueNodeHasChildren?Ma.createPortal(o.children,l.valueNode):null]})});WR.displayName=xu;var GR=\"SelectItemIndicator\",JR=y.forwardRef((e,t)=>{const{__scopeSelect:n,...r}=e;return qR(GR,n).isSelected?i.jsx(rt.span,{\"aria-hidden\":!0,...r,ref:t}):null});JR.displayName=GR;var db=\"SelectScrollUpButton\",QR=y.forwardRef((e,t)=>{const n=Aa(db,e.__scopeSelect),r=$x(db,e.__scopeSelect),[s,o]=y.useState(!1),l=Rt(t,r.onScrollButtonChange);return Ln(()=>{if(n.viewport&&n.isPositioned){let u=function(){const f=d.scrollTop>0;o(f)};const d=n.viewport;return u(),d.addEventListener(\"scroll\",u),()=>d.removeEventListener(\"scroll\",u)}},[n.viewport,n.isPositioned]),s?i.jsx(YR,{...e,ref:l,onAutoScroll:()=>{const{viewport:u,selectedItem:d}=n;u&&d&&(u.scrollTop=u.scrollTop-d.offsetHeight)}}):null});QR.displayName=db;var fb=\"SelectScrollDownButton\",ZR=y.forwardRef((e,t)=>{const n=Aa(fb,e.__scopeSelect),r=$x(fb,e.__scopeSelect),[s,o]=y.useState(!1),l=Rt(t,r.onScrollButtonChange);return Ln(()=>{if(n.viewport&&n.isPositioned){let u=function(){const f=d.scrollHeight-d.clientHeight,h=Math.ceil(d.scrollTop)<f;o(h)};const d=n.viewport;return u(),d.addEventListener(\"scroll\",u),()=>d.removeEventListener(\"scroll\",u)}},[n.viewport,n.isPositioned]),s?i.jsx(YR,{...e,ref:l,onAutoScroll:()=>{const{viewport:u,selectedItem:d}=n;u&&d&&(u.scrollTop=u.scrollTop+d.offsetHeight)}}):null});ZR.displayName=fb;var YR=y.forwardRef((e,t)=>{const{__scopeSelect:n,onAutoScroll:r,...s}=e,o=Aa(\"SelectScrollButton\",n),l=y.useRef(null),u=rg(n),d=y.useCallback(()=>{l.current!==null&&(window.clearInterval(l.current),l.current=null)},[]);return y.useEffect(()=>()=>d(),[d]),Ln(()=>{u().find(h=>h.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:\"nearest\"})},[u]),i.jsx(rt.div,{\"aria-hidden\":!0,...s,ref:t,style:{flexShrink:0,...s.style},onPointerDown:Ue(s.onPointerDown,()=>{l.current===null&&(l.current=window.setInterval(r,50))}),onPointerMove:Ue(s.onPointerMove,()=>{o.onItemLeave?.(),l.current===null&&(l.current=window.setInterval(r,50))}),onPointerLeave:Ue(s.onPointerLeave,()=>{d()})})}),qJ=\"SelectSeparator\",XR=y.forwardRef((e,t)=>{const{__scopeSelect:n,...r}=e;return i.jsx(rt.div,{\"aria-hidden\":!0,...r,ref:t})});XR.displayName=qJ;var pb=\"SelectArrow\",KJ=y.forwardRef((e,t)=>{const{__scopeSelect:n,...r}=e,s=sg(n),o=Ia(pb,n),l=Aa(pb,n);return o.open&&l.position===\"popper\"?i.jsx(eN,{...s,...r,ref:t}):null});KJ.displayName=pb;function eP(e){return e===\"\"||e===void 0}var tP=y.forwardRef((e,t)=>{const{value:n,...r}=e,s=y.useRef(null),o=Rt(t,s),l=NR(n);return y.useEffect(()=>{const u=s.current,d=window.HTMLSelectElement.prototype,h=Object.getOwnPropertyDescriptor(d,\"value\").set;if(l!==n&&h){const m=new Event(\"change\",{bubbles:!0});h.call(u,n),u.dispatchEvent(m)}},[l,n]),i.jsx(MR,{asChild:!0,children:i.jsx(\"select\",{...r,ref:o,defaultValue:n})})});tP.displayName=\"BubbleSelect\";function nP(e){const t=Rn(e),n=y.useRef(\"\"),r=y.useRef(0),s=y.useCallback(l=>{const u=n.current+l;t(u),(function d(f){n.current=f,window.clearTimeout(r.current),f!==\"\"&&(r.current=window.setTimeout(()=>d(\"\"),1e3))})(u)},[t]),o=y.useCallback(()=>{n.current=\"\",window.clearTimeout(r.current)},[]);return y.useEffect(()=>()=>window.clearTimeout(r.current),[]),[n,s,o]}function rP(e,t,n){const s=t.length>1&&Array.from(t).every(f=>f===t[0])?t[0]:t,o=n?e.indexOf(n):-1;let l=WJ(e,Math.max(o,0));s.length===1&&(l=l.filter(f=>f!==n));const d=l.find(f=>f.textValue.toLowerCase().startsWith(s.toLowerCase()));return d!==n?d:void 0}function WJ(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var GJ=_R,sP=PR,JJ=IR,QJ=AR,ZJ=DR,oP=FR,YJ=zR,aP=HR,iP=KR,XJ=WR,eQ=JR,lP=QR,cP=ZR,uP=XR;const tQ=GJ,nQ=JJ,dP=y.forwardRef(({className:e,children:t,...n},r)=>i.jsxs(sP,{ref:r,className:Ie(\"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-default disabled:opacity-50 [&>span]:line-clamp-1\",e),...n,children:[t,i.jsx(QJ,{asChild:!0,children:i.jsx(Nh,{className:\"h-4 w-4 opacity-50\"})})]}));dP.displayName=sP.displayName;const fP=y.forwardRef(({className:e,...t},n)=>i.jsx(lP,{ref:n,className:Ie(\"flex cursor-default items-center justify-center py-1\",e),...t,children:i.jsx(G$,{className:\"h-4 w-4\"})}));fP.displayName=lP.displayName;const pP=y.forwardRef(({className:e,...t},n)=>i.jsx(cP,{ref:n,className:Ie(\"flex cursor-default items-center justify-center py-1\",e),...t,children:i.jsx(Nh,{className:\"h-4 w-4\"})}));pP.displayName=cP.displayName;const hP=y.forwardRef(({className:e,children:t,position:n=\"popper\",...r},s)=>i.jsx(ZJ,{children:i.jsxs(oP,{ref:s,className:Ie(\"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",n===\"popper\"&&\"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",e),position:n,...r,children:[i.jsx(fP,{}),i.jsx(YJ,{className:Ie(\"p-1\",n===\"popper\"&&\"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\"),children:t}),i.jsx(pP,{})]})}));hP.displayName=oP.displayName;const rQ=y.forwardRef(({className:e,...t},n)=>i.jsx(aP,{ref:n,className:Ie(\"py-1.5 pl-8 pr-2 text-sm font-semibold\",e),...t}));rQ.displayName=aP.displayName;const gP=y.forwardRef(({className:e,children:t,...n},r)=>i.jsxs(iP,{ref:r,className:Ie(\"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",e),...n,children:[i.jsx(\"span\",{className:\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\",children:i.jsx(eQ,{children:i.jsx(fT,{className:\"h-4 w-4\"})})}),i.jsx(XJ,{children:t})]}));gP.displayName=iP.displayName;const sQ=y.forwardRef(({className:e,...t},n)=>i.jsx(uP,{ref:n,className:Ie(\"-mx-1 my-1 h-px bg-muted\",e),...t}));sQ.displayName=uP.displayName;var Bx=\"Switch\",[oQ]=us(Bx),[aQ,iQ]=oQ(Bx),mP=y.forwardRef((e,t)=>{const{__scopeSwitch:n,name:r,checked:s,defaultChecked:o,required:l,disabled:u,value:d=\"on\",onCheckedChange:f,...h}=e,[m,g]=y.useState(null),x=Rt(t,j=>g(j)),b=y.useRef(!1),w=m?!!m.closest(\"form\"):!0,[C=!1,k]=ya({prop:s,defaultProp:o,onChange:f});return i.jsxs(aQ,{scope:n,checked:C,disabled:u,children:[i.jsx(rt.button,{type:\"button\",role:\"switch\",\"aria-checked\":C,\"aria-required\":l,\"data-state\":bP(C),\"data-disabled\":u?\"\":void 0,disabled:u,value:d,...h,ref:x,onClick:Ue(e.onClick,j=>{k(M=>!M),w&&(b.current=j.isPropagationStopped(),b.current||j.stopPropagation())})}),w&&i.jsx(lQ,{control:m,bubbles:!b.current,name:r,value:d,checked:C,required:l,disabled:u,style:{transform:\"translateX(-100%)\"}})]})});mP.displayName=Bx;var vP=\"SwitchThumb\",yP=y.forwardRef((e,t)=>{const{__scopeSwitch:n,...r}=e,s=iQ(vP,n);return i.jsx(rt.span,{\"data-state\":bP(s.checked),\"data-disabled\":s.disabled?\"\":void 0,...r,ref:t})});yP.displayName=vP;var lQ=e=>{const{control:t,checked:n,bubbles:r=!0,...s}=e,o=y.useRef(null),l=NR(n),u=zT(t);return y.useEffect(()=>{const d=o.current,f=window.HTMLInputElement.prototype,m=Object.getOwnPropertyDescriptor(f,\"checked\").set;if(l!==n&&m){const g=new Event(\"click\",{bubbles:r});m.call(d,n),d.dispatchEvent(g)}},[l,n,r]),i.jsx(\"input\",{type:\"checkbox\",\"aria-hidden\":!0,defaultChecked:n,...s,tabIndex:-1,ref:o,style:{...e.style,...u,position:\"absolute\",pointerEvents:\"none\",opacity:0,margin:0}})};function bP(e){return e?\"checked\":\"unchecked\"}var xP=mP,cQ=yP;const gc=y.forwardRef(({className:e,...t},n)=>i.jsx(xP,{className:Ie(\"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-slate-400\",e),...t,ref:n,children:i.jsx(cQ,{className:Ie(\"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0\")})}));gc.displayName=xP.displayName;const Fo=Gn,wP=y.createContext({}),Lo=({...e})=>i.jsx(wP.Provider,{value:{name:e.name},children:i.jsx(r6,{...e})}),og=()=>{const e=y.useContext(wP),t=y.useContext(SP),{getFieldState:n,formState:r}=Kh(),s=n(e.name,r);if(!e)throw new Error(\"useFormField should be used within <FormField>\");const{id:o}=t;return{id:o,name:e.name,formItemId:`${o}-form-item`,formDescriptionId:`${o}-form-item-description`,formMessageId:`${o}-form-item-message`,...s}},SP=y.createContext({}),no=y.forwardRef(({className:e,...t},n)=>{const r=y.useId();return i.jsx(SP.Provider,{value:{id:r},children:i.jsx(\"div\",{ref:n,className:Ie(\"space-y-2\",e),...t})})});no.displayName=\"FormItem\";const Nr=y.forwardRef(({className:e,...t},n)=>{const{error:r,formItemId:s}=og();return i.jsx(TR,{ref:n,className:Ie(r&&\"text-rose-600\",e),htmlFor:s,...t})});Nr.displayName=\"FormLabel\";const _s=y.forwardRef(({...e},t)=>{const{error:n,formItemId:r,formDescriptionId:s,formMessageId:o}=og();return i.jsx(No,{ref:t,id:r,\"aria-describedby\":n?`${s} ${o}`:`${s}`,\"aria-invalid\":!!n,...e})});_s.displayName=\"FormControl\";const ag=y.forwardRef(({className:e,...t},n)=>{const{formDescriptionId:r}=og();return i.jsx(\"p\",{ref:n,id:r,className:Ie(\"text-sm text-muted-foreground\",e),...t})});ag.displayName=\"FormDescription\";const Td=y.forwardRef(({className:e,children:t,...n},r)=>{const{error:s,formMessageId:o}=og(),l=s?String(s?.message):t;return l?i.jsx(\"p\",{ref:r,id:o,className:Ie(\"text-sm font-medium text-rose-600\",e),...n,children:l}):null});Td.displayName=\"FormMessage\";const le=({name:e,label:t,children:n,required:r,readOnly:s,className:o,...l})=>i.jsx(Lo,{...l,name:e,render:({field:u})=>i.jsxs(no,{className:o,children:[t&&i.jsxs(Nr,{children:[t,r&&i.jsx(\"span\",{className:\"ml-2 text-rose-600\",children:\"*\"})]}),i.jsx(_s,{children:y.isValidElement(n)&&y.cloneElement(n,{...u,value:u.value??\"\",required:r,readOnly:s,checked:u.value,onCheckedChange:u.onChange})}),i.jsx(Td,{})]})}),Pe=({name:e,label:t,required:n,className:r,helper:s,reverse:o,...l})=>i.jsx(Lo,{...l,name:e,render:({field:u})=>i.jsxs(no,{className:Ie(\"flex items-center gap-3\",o&&\"flex-row-reverse justify-end\",r),children:[i.jsx(\"div\",{className:\"flex flex-col gap-2\",children:t&&i.jsxs(Nr,{children:[i.jsxs(\"p\",{className:\"break-all\",children:[t,n&&i.jsx(\"span\",{className:\"ml-2 text-rose-600\",children:\"*\"})]}),s&&i.jsx(ag,{className:\"mt-2\",children:s})]})}),i.jsx(_s,{children:i.jsx(gc,{checked:u.value,onCheckedChange:u.onChange,required:n})}),i.jsx(Td,{})]})}),Jt=({name:e,label:t,helper:n,required:r,options:s,placeholder:o,disabled:l,...u})=>i.jsx(Lo,{...u,name:e,render:({field:d})=>i.jsxs(no,{children:[t&&i.jsxs(Nr,{children:[t,r&&i.jsx(\"span\",{className:\"ml-2 text-rose-600\",children:\"*\"})]}),i.jsx(_s,{children:i.jsxs(tQ,{onValueChange:d.onChange,defaultValue:d.value,disabled:l,children:[i.jsx(_s,{children:i.jsx(dP,{children:i.jsx(nQ,{placeholder:o})})}),i.jsx(hP,{children:s.map(f=>i.jsx(gP,{value:f.value,children:f.label},f.value))})]})}),n&&i.jsx(ag,{children:n}),i.jsx(Td,{})]})}),Da=({name:e,label:t,helper:n,required:r,placeholder:s,...o})=>i.jsx(Lo,{...o,name:e,render:({field:l})=>{let u=[];return Array.isArray(l.value)&&(u=l.value),i.jsxs(no,{children:[t&&i.jsxs(Nr,{children:[t,r&&i.jsx(\"span\",{className:\"ml-2 text-rose-600\",children:\"*\"})]}),i.jsx(_s,{children:i.jsx(kJ,{tags:u.map(d=>({id:d,text:d,className:\"\"})),handleDelete:d=>l.onChange(u.filter((f,h)=>h!==d)),handleAddition:d=>l.onChange([...u,d.id]),inputFieldPosition:\"bottom\",placeholder:s,autoFocus:!1,allowDragDrop:!1,separators:[Vs.ENTER,Vs.TAB,Vs.COMMA],classNames:{tags:\"tagsClass\",tagInput:\"tagInputClass\",tagInputField:u_,selected:\"my-2 flex flex-wrap gap-2\",tag:\"flex items-center gap-2 px-2 py-1 bg-primary/30 rounded-md text-xs\",remove:\"[&>svg]:fill-rose-600 hover:[&>svg]:fill-rose-700\",suggestions:\"suggestionsClass\",activeSuggestion:\"activeSuggestionClass\",editTagInput:\"editTagInputClass\",editTagInputField:\"editTagInputFieldClass\",clearAll:\"clearAllClass\"}})}),n&&i.jsx(ag,{children:n}),i.jsx(Td,{})]})}}),Kv=P.string().optional().transform(e=>e===\"\"?void 0:e),uQ=P.object({name:P.string(),token:Kv,number:Kv,businessId:Kv,integration:P.enum([\"WHATSAPP-BUSINESS\",\"WHATSAPP-BAILEYS\",\"EVOLUTION\"])});function dQ({resetTable:e}){const{t}=Ve(),{createInstance:n}=Hh(),[r,s]=y.useState(!1),o=[{value:\"WHATSAPP-BAILEYS\",label:t(\"instance.form.integration.baileys\")},{value:\"WHATSAPP-BUSINESS\",label:t(\"instance.form.integration.whatsapp\")},{value:\"EVOLUTION\",label:t(\"instance.form.integration.evolution\")}],l=on({resolver:an(uQ),defaultValues:{name:\"\",integration:\"WHATSAPP-BAILEYS\",token:E1().replace(\"-\",\"\").toUpperCase(),number:\"\",businessId:\"\"}}),u=l.watch(\"integration\"),d=async h=>{try{const m={instanceName:h.name,integration:h.integration,token:h.token===\"\"?null:h.token,number:h.number===\"\"?null:h.number,businessId:h.businessId===\"\"?null:h.businessId};await n(m),me.success(t(\"toast.instance.created\")),s(!1),f(),e()}catch(m){console.error(\"Error:\",m),me.error(`Error : ${m?.response?.data?.response?.message}`)}},f=()=>{l.reset({name:\"\",integration:\"WHATSAPP-BAILEYS\",token:E1().replace(\"-\",\"\").toLocaleUpperCase(),number:\"\",businessId:\"\"})};return i.jsxs(Pt,{open:r,onOpenChange:s,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"default\",size:\"sm\",children:[t(\"instance.button.create\"),\" \",i.jsx(cs,{size:\"18\"})]})}),i.jsxs(Nt,{className:\"sm:max-w-[650px]\",onCloseAutoFocus:f,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"instance.modal.title\")})}),i.jsx(Gn,{...l,children:i.jsxs(\"form\",{onSubmit:l.handleSubmit(d),className:\"grid gap-4 py-4\",children:[i.jsx(le,{required:!0,name:\"name\",label:t(\"instance.form.name\"),children:i.jsx(ne,{})}),i.jsx(Jt,{name:\"integration\",label:t(\"instance.form.integration.label\"),options:o}),i.jsx(le,{required:!0,name:\"token\",label:t(\"instance.form.token\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"number\",label:t(\"instance.form.number\"),children:i.jsx(ne,{type:\"tel\"})}),u===\"WHATSAPP-BUSINESS\"&&i.jsx(le,{required:!0,name:\"businessId\",label:t(\"instance.form.businessId\"),children:i.jsx(ne,{})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:t(\"instance.button.save\")})})]})})]})]})}function bo(e,t,{checkForDefaultPrevented:n=!0}={}){return function(s){if(e?.(s),n===!1||!s.defaultPrevented)return t?.(s)}}function IE(e,t){if(typeof e==\"function\")return e(t);e!=null&&(e.current=t)}function CP(...e){return t=>{let n=!1;const r=e.map(s=>{const o=IE(s,t);return!n&&typeof o==\"function\"&&(n=!0),o});if(n)return()=>{for(let s=0;s<r.length;s++){const o=r[s];typeof o==\"function\"?o():IE(e[s],null)}}}}function Ui(...e){return y.useCallback(CP(...e),e)}function EP(e,t=[]){let n=[];function r(o,l){const u=y.createContext(l),d=n.length;n=[...n,l];const f=m=>{const{scope:g,children:x,...b}=m,w=g?.[e]?.[d]||u,C=y.useMemo(()=>b,Object.values(b));return i.jsx(w.Provider,{value:C,children:x})};f.displayName=o+\"Provider\";function h(m,g){const x=g?.[e]?.[d]||u,b=y.useContext(x);if(b)return b;if(l!==void 0)return l;throw new Error(`\\`${m}\\` must be used within \\`${o}\\``)}return[f,h]}const s=()=>{const o=n.map(l=>y.createContext(l));return function(u){const d=u?.[e]||o;return y.useMemo(()=>({[`__scope${e}`]:{...u,[e]:d}}),[u,d])}};return s.scopeName=e,[r,fQ(s,...t)]}function fQ(...e){const t=e[0];if(e.length===1)return t;const n=()=>{const r=e.map(s=>({useScope:s(),scopeName:s.scopeName}));return function(o){const l=r.reduce((u,{useScope:d,scopeName:f})=>{const m=d(o)[`__scope${f}`];return{...u,...m}},{});return y.useMemo(()=>({[`__scope${t.scopeName}`]:l}),[l])}};return n.scopeName=t.scopeName,n}function pQ(e){const t=hQ(e),n=y.forwardRef((r,s)=>{const{children:o,...l}=r,u=y.Children.toArray(o),d=u.find(mQ);if(d){const f=d.props.children,h=u.map(m=>m===d?y.Children.count(f)>1?y.Children.only(null):y.isValidElement(f)?f.props.children:null:m);return i.jsx(t,{...l,ref:s,children:y.isValidElement(f)?y.cloneElement(f,void 0,h):null})}return i.jsx(t,{...l,ref:s,children:o})});return n.displayName=`${e}.Slot`,n}function hQ(e){const t=y.forwardRef((n,r)=>{const{children:s,...o}=n;if(y.isValidElement(s)){const l=yQ(s),u=vQ(o,s.props);return s.type!==y.Fragment&&(u.ref=r?CP(r,l):l),y.cloneElement(s,u)}return y.Children.count(s)>1?y.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var kP=Symbol(\"radix.slottable\");function gQ(e){const t=({children:n})=>i.jsx(i.Fragment,{children:n});return t.displayName=`${e}.Slottable`,t.__radixId=kP,t}function mQ(e){return y.isValidElement(e)&&typeof e.type==\"function\"&&\"__radixId\"in e.type&&e.type.__radixId===kP}function vQ(e,t){const n={...t};for(const r in t){const s=e[r],o=t[r];/^on[A-Z]/.test(r)?s&&o?n[r]=(...u)=>{const d=o(...u);return s(...u),d}:s&&(n[r]=s):r===\"style\"?n[r]={...s,...o}:r===\"className\"&&(n[r]=[s,o].filter(Boolean).join(\" \"))}return{...e,...n}}function yQ(e){let t=Object.getOwnPropertyDescriptor(e.props,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var bQ=[\"a\",\"button\",\"div\",\"form\",\"h2\",\"h3\",\"img\",\"input\",\"label\",\"li\",\"nav\",\"ol\",\"p\",\"select\",\"span\",\"svg\",\"ul\"],Fa=bQ.reduce((e,t)=>{const n=pQ(`Primitive.${t}`),r=y.forwardRef((s,o)=>{const{asChild:l,...u}=s,d=l?n:t;return typeof window<\"u\"&&(window[Symbol.for(\"radix-ui\")]=!0),i.jsx(d,{...u,ref:o})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function xQ(e,t){e&&Ma.flushSync(()=>e.dispatchEvent(t))}function ig(e){const t=y.useRef(e);return y.useEffect(()=>{t.current=e}),y.useMemo(()=>(...n)=>t.current?.(...n),[])}function wQ(e,t=globalThis?.document){const n=ig(e);y.useEffect(()=>{const r=s=>{s.key===\"Escape\"&&n(s)};return t.addEventListener(\"keydown\",r,{capture:!0}),()=>t.removeEventListener(\"keydown\",r,{capture:!0})},[n,t])}var SQ=\"DismissableLayer\",hb=\"dismissableLayer.update\",CQ=\"dismissableLayer.pointerDownOutside\",EQ=\"dismissableLayer.focusOutside\",AE,jP=y.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),TP=y.forwardRef((e,t)=>{const{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:s,onFocusOutside:o,onInteractOutside:l,onDismiss:u,...d}=e,f=y.useContext(jP),[h,m]=y.useState(null),g=h?.ownerDocument??globalThis?.document,[,x]=y.useState({}),b=Ui(t,O=>m(O)),w=Array.from(f.layers),[C]=[...f.layersWithOutsidePointerEventsDisabled].slice(-1),k=w.indexOf(C),j=h?w.indexOf(h):-1,M=f.layersWithOutsidePointerEventsDisabled.size>0,_=j>=k,R=TQ(O=>{const D=O.target,z=[...f.branches].some(Q=>Q.contains(D));!_||z||(s?.(O),l?.(O),O.defaultPrevented||u?.())},g),N=NQ(O=>{const D=O.target;[...f.branches].some(Q=>Q.contains(D))||(o?.(O),l?.(O),O.defaultPrevented||u?.())},g);return wQ(O=>{j===f.layers.size-1&&(r?.(O),!O.defaultPrevented&&u&&(O.preventDefault(),u()))},g),y.useEffect(()=>{if(h)return n&&(f.layersWithOutsidePointerEventsDisabled.size===0&&(AE=g.body.style.pointerEvents,g.body.style.pointerEvents=\"none\"),f.layersWithOutsidePointerEventsDisabled.add(h)),f.layers.add(h),DE(),()=>{n&&f.layersWithOutsidePointerEventsDisabled.size===1&&(g.body.style.pointerEvents=AE)}},[h,g,n,f]),y.useEffect(()=>()=>{h&&(f.layers.delete(h),f.layersWithOutsidePointerEventsDisabled.delete(h),DE())},[h,f]),y.useEffect(()=>{const O=()=>x({});return document.addEventListener(hb,O),()=>document.removeEventListener(hb,O)},[]),i.jsx(Fa.div,{...d,ref:b,style:{pointerEvents:M?_?\"auto\":\"none\":void 0,...e.style},onFocusCapture:bo(e.onFocusCapture,N.onFocusCapture),onBlurCapture:bo(e.onBlurCapture,N.onBlurCapture),onPointerDownCapture:bo(e.onPointerDownCapture,R.onPointerDownCapture)})});TP.displayName=SQ;var kQ=\"DismissableLayerBranch\",jQ=y.forwardRef((e,t)=>{const n=y.useContext(jP),r=y.useRef(null),s=Ui(t,r);return y.useEffect(()=>{const o=r.current;if(o)return n.branches.add(o),()=>{n.branches.delete(o)}},[n.branches]),i.jsx(Fa.div,{...e,ref:s})});jQ.displayName=kQ;function TQ(e,t=globalThis?.document){const n=ig(e),r=y.useRef(!1),s=y.useRef(()=>{});return y.useEffect(()=>{const o=u=>{if(u.target&&!r.current){let d=function(){NP(CQ,n,f,{discrete:!0})};const f={originalEvent:u};u.pointerType===\"touch\"?(t.removeEventListener(\"click\",s.current),s.current=d,t.addEventListener(\"click\",s.current,{once:!0})):d()}else t.removeEventListener(\"click\",s.current);r.current=!1},l=window.setTimeout(()=>{t.addEventListener(\"pointerdown\",o)},0);return()=>{window.clearTimeout(l),t.removeEventListener(\"pointerdown\",o),t.removeEventListener(\"click\",s.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function NQ(e,t=globalThis?.document){const n=ig(e),r=y.useRef(!1);return y.useEffect(()=>{const s=o=>{o.target&&!r.current&&NP(EQ,n,{originalEvent:o},{discrete:!1})};return t.addEventListener(\"focusin\",s),()=>t.removeEventListener(\"focusin\",s)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function DE(){const e=new CustomEvent(hb);document.dispatchEvent(e)}function NP(e,t,n,{discrete:r}){const s=n.originalEvent.target,o=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&s.addEventListener(e,t,{once:!0}),r?xQ(s,o):s.dispatchEvent(o)}var Ta=globalThis?.document?y.useLayoutEffect:()=>{},MQ=Yl[\" useId \".trim().toString()]||(()=>{}),_Q=0;function RQ(e){const[t,n]=y.useState(MQ());return Ta(()=>{n(r=>r??String(_Q++))},[e]),t?`radix-${t}`:\"\"}var PQ=\"Arrow\",MP=y.forwardRef((e,t)=>{const{children:n,width:r=10,height:s=5,...o}=e;return i.jsx(Fa.svg,{...o,ref:t,width:r,height:s,viewBox:\"0 0 30 10\",preserveAspectRatio:\"none\",children:e.asChild?n:i.jsx(\"polygon\",{points:\"0,0 30,0 15,10\"})})});MP.displayName=PQ;var OQ=MP;function IQ(e){const[t,n]=y.useState(void 0);return Ta(()=>{if(e){n({width:e.offsetWidth,height:e.offsetHeight});const r=new ResizeObserver(s=>{if(!Array.isArray(s)||!s.length)return;const o=s[0];let l,u;if(\"borderBoxSize\"in o){const d=o.borderBoxSize,f=Array.isArray(d)?d[0]:d;l=f.inlineSize,u=f.blockSize}else l=e.offsetWidth,u=e.offsetHeight;n({width:l,height:u})});return r.observe(e,{box:\"border-box\"}),()=>r.unobserve(e)}else n(void 0)},[e]),t}var zx=\"Popper\",[_P,RP]=EP(zx),[AQ,PP]=_P(zx),OP=e=>{const{__scopePopper:t,children:n}=e,[r,s]=y.useState(null);return i.jsx(AQ,{scope:t,anchor:r,onAnchorChange:s,children:n})};OP.displayName=zx;var IP=\"PopperAnchor\",AP=y.forwardRef((e,t)=>{const{__scopePopper:n,virtualRef:r,...s}=e,o=PP(IP,n),l=y.useRef(null),u=Ui(t,l),d=y.useRef(null);return y.useEffect(()=>{const f=d.current;d.current=r?.current||l.current,f!==d.current&&o.onAnchorChange(d.current)}),r?null:i.jsx(Fa.div,{...s,ref:u})});AP.displayName=IP;var Ux=\"PopperContent\",[DQ,FQ]=_P(Ux),DP=y.forwardRef((e,t)=>{const{__scopePopper:n,side:r=\"bottom\",sideOffset:s=0,align:o=\"center\",alignOffset:l=0,arrowPadding:u=0,avoidCollisions:d=!0,collisionBoundary:f=[],collisionPadding:h=0,sticky:m=\"partial\",hideWhenDetached:g=!1,updatePositionStrategy:x=\"optimized\",onPlaced:b,...w}=e,C=PP(Ux,n),[k,j]=y.useState(null),M=Ui(t,Z=>j(Z)),[_,R]=y.useState(null),N=IQ(_),O=N?.width??0,D=N?.height??0,z=r+(o!==\"center\"?\"-\"+o:\"\"),Q=typeof h==\"number\"?h:{top:0,right:0,bottom:0,left:0,...h},pe=Array.isArray(f)?f:[f],V=pe.length>0,G={padding:Q,boundary:pe.filter($Q),altBoundary:V},{refs:W,floatingStyles:ie,placement:re,isPositioned:Y,middlewareData:H}=PT({strategy:\"fixed\",placement:z,whileElementsMounted:(...Z)=>_T(...Z,{animationFrame:x===\"always\"}),elements:{reference:C.anchor},middleware:[OT({mainAxis:s+D,alignmentAxis:l}),d&&IT({mainAxis:!0,crossAxis:!1,limiter:m===\"partial\"?AT():void 0,...G}),d&&DT({...G}),FT({...G,apply:({elements:Z,rects:ye,availableWidth:Re,availableHeight:$e})=>{const{width:Ye,height:Fe}=ye.reference,ft=Z.floating.style;ft.setProperty(\"--radix-popper-available-width\",`${Re}px`),ft.setProperty(\"--radix-popper-available-height\",`${$e}px`),ft.setProperty(\"--radix-popper-anchor-width\",`${Ye}px`),ft.setProperty(\"--radix-popper-anchor-height\",`${Fe}px`)}}),_&&$T({element:_,padding:u}),BQ({arrowWidth:O,arrowHeight:D}),g&&LT({strategy:\"referenceHidden\",...G})]}),[q,he]=$P(re),A=ig(b);Ta(()=>{Y&&A?.()},[Y,A]);const F=H.arrow?.x,fe=H.arrow?.y,te=H.arrow?.centerOffset!==0,[de,ge]=y.useState();return Ta(()=>{k&&ge(window.getComputedStyle(k).zIndex)},[k]),i.jsx(\"div\",{ref:W.setFloating,\"data-radix-popper-content-wrapper\":\"\",style:{...ie,transform:Y?ie.transform:\"translate(0, -200%)\",minWidth:\"max-content\",zIndex:de,\"--radix-popper-transform-origin\":[H.transformOrigin?.x,H.transformOrigin?.y].join(\" \"),...H.hide?.referenceHidden&&{visibility:\"hidden\",pointerEvents:\"none\"}},dir:e.dir,children:i.jsx(DQ,{scope:n,placedSide:q,onArrowChange:R,arrowX:F,arrowY:fe,shouldHideArrow:te,children:i.jsx(Fa.div,{\"data-side\":q,\"data-align\":he,...w,ref:M,style:{...w.style,animation:Y?void 0:\"none\"}})})})});DP.displayName=Ux;var FP=\"PopperArrow\",LQ={top:\"bottom\",right:\"left\",bottom:\"top\",left:\"right\"},LP=y.forwardRef(function(t,n){const{__scopePopper:r,...s}=t,o=FQ(FP,r),l=LQ[o.placedSide];return i.jsx(\"span\",{ref:o.onArrowChange,style:{position:\"absolute\",left:o.arrowX,top:o.arrowY,[l]:0,transformOrigin:{top:\"\",right:\"0 0\",bottom:\"center 0\",left:\"100% 0\"}[o.placedSide],transform:{top:\"translateY(100%)\",right:\"translateY(50%) rotate(90deg) translateX(-50%)\",bottom:\"rotate(180deg)\",left:\"translateY(50%) rotate(-90deg) translateX(50%)\"}[o.placedSide],visibility:o.shouldHideArrow?\"hidden\":void 0},children:i.jsx(OQ,{...s,ref:n,style:{...s.style,display:\"block\"}})})});LP.displayName=FP;function $Q(e){return e!==null}var BQ=e=>({name:\"transformOrigin\",options:e,fn(t){const{placement:n,rects:r,middlewareData:s}=t,l=s.arrow?.centerOffset!==0,u=l?0:e.arrowWidth,d=l?0:e.arrowHeight,[f,h]=$P(n),m={start:\"0%\",center:\"50%\",end:\"100%\"}[h],g=(s.arrow?.x??0)+u/2,x=(s.arrow?.y??0)+d/2;let b=\"\",w=\"\";return f===\"bottom\"?(b=l?m:`${g}px`,w=`${-d}px`):f===\"top\"?(b=l?m:`${g}px`,w=`${r.floating.height+d}px`):f===\"right\"?(b=`${-d}px`,w=l?m:`${x}px`):f===\"left\"&&(b=`${r.floating.width+d}px`,w=l?m:`${x}px`),{data:{x:b,y:w}}}});function $P(e){const[t,n=\"center\"]=e.split(\"-\");return[t,n]}var zQ=OP,UQ=AP,VQ=DP,HQ=LP,qQ=\"Portal\",BP=y.forwardRef((e,t)=>{const{container:n,...r}=e,[s,o]=y.useState(!1);Ta(()=>o(!0),[]);const l=n||s&&globalThis?.document?.body;return l?Ib.createPortal(i.jsx(Fa.div,{...r,ref:t}),l):null});BP.displayName=qQ;function KQ(e,t){return y.useReducer((n,r)=>t[n][r]??n,e)}var Vx=e=>{const{present:t,children:n}=e,r=WQ(t),s=typeof n==\"function\"?n({present:r.isPresent}):y.Children.only(n),o=Ui(r.ref,GQ(s));return typeof n==\"function\"||r.isPresent?y.cloneElement(s,{ref:o}):null};Vx.displayName=\"Presence\";function WQ(e){const[t,n]=y.useState(),r=y.useRef(null),s=y.useRef(e),o=y.useRef(\"none\"),l=e?\"mounted\":\"unmounted\",[u,d]=KQ(l,{mounted:{UNMOUNT:\"unmounted\",ANIMATION_OUT:\"unmountSuspended\"},unmountSuspended:{MOUNT:\"mounted\",ANIMATION_END:\"unmounted\"},unmounted:{MOUNT:\"mounted\"}});return y.useEffect(()=>{const f=Xf(r.current);o.current=u===\"mounted\"?f:\"none\"},[u]),Ta(()=>{const f=r.current,h=s.current;if(h!==e){const g=o.current,x=Xf(f);e?d(\"MOUNT\"):x===\"none\"||f?.display===\"none\"?d(\"UNMOUNT\"):d(h&&g!==x?\"ANIMATION_OUT\":\"UNMOUNT\"),s.current=e}},[e,d]),Ta(()=>{if(t){let f;const h=t.ownerDocument.defaultView??window,m=x=>{const w=Xf(r.current).includes(CSS.escape(x.animationName));if(x.target===t&&w&&(d(\"ANIMATION_END\"),!s.current)){const C=t.style.animationFillMode;t.style.animationFillMode=\"forwards\",f=h.setTimeout(()=>{t.style.animationFillMode===\"forwards\"&&(t.style.animationFillMode=C)})}},g=x=>{x.target===t&&(o.current=Xf(r.current))};return t.addEventListener(\"animationstart\",g),t.addEventListener(\"animationcancel\",m),t.addEventListener(\"animationend\",m),()=>{h.clearTimeout(f),t.removeEventListener(\"animationstart\",g),t.removeEventListener(\"animationcancel\",m),t.removeEventListener(\"animationend\",m)}}else d(\"ANIMATION_END\")},[t,d]),{isPresent:[\"mounted\",\"unmountSuspended\"].includes(u),ref:y.useCallback(f=>{r.current=f?getComputedStyle(f):null,n(f)},[])}}function Xf(e){return e?.animationName||\"none\"}function GQ(e){let t=Object.getOwnPropertyDescriptor(e.props,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,\"ref\")?.get,n=t&&\"isReactWarning\"in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var JQ=Yl[\" useInsertionEffect \".trim().toString()]||Ta;function QQ({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){const[s,o,l]=ZQ({defaultProp:t,onChange:n}),u=e!==void 0,d=u?e:s;{const h=y.useRef(e!==void 0);y.useEffect(()=>{const m=h.current;m!==u&&console.warn(`${r} is changing from ${m?\"controlled\":\"uncontrolled\"} to ${u?\"controlled\":\"uncontrolled\"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),h.current=u},[u,r])}const f=y.useCallback(h=>{if(u){const m=YQ(h)?h(e):h;m!==e&&l.current?.(m)}else o(h)},[u,e,o,l]);return[d,f]}function ZQ({defaultProp:e,onChange:t}){const[n,r]=y.useState(e),s=y.useRef(n),o=y.useRef(t);return JQ(()=>{o.current=t},[t]),y.useEffect(()=>{s.current!==n&&(o.current?.(n),s.current=n)},[n,s]),[n,r,o]}function YQ(e){return typeof e==\"function\"}var XQ=Object.freeze({position:\"absolute\",border:0,width:1,height:1,padding:0,margin:-1,overflow:\"hidden\",clip:\"rect(0, 0, 0, 0)\",whiteSpace:\"nowrap\",wordWrap:\"normal\"}),eZ=\"VisuallyHidden\",zP=y.forwardRef((e,t)=>i.jsx(Fa.span,{...e,ref:t,style:{...XQ,...e.style}}));zP.displayName=eZ;var tZ=zP,[lg]=EP(\"Tooltip\",[RP]),cg=RP(),UP=\"TooltipProvider\",nZ=700,gb=\"tooltip.open\",[rZ,Hx]=lg(UP),VP=e=>{const{__scopeTooltip:t,delayDuration:n=nZ,skipDelayDuration:r=300,disableHoverableContent:s=!1,children:o}=e,l=y.useRef(!0),u=y.useRef(!1),d=y.useRef(0);return y.useEffect(()=>{const f=d.current;return()=>window.clearTimeout(f)},[]),i.jsx(rZ,{scope:t,isOpenDelayedRef:l,delayDuration:n,onOpen:y.useCallback(()=>{window.clearTimeout(d.current),l.current=!1},[]),onClose:y.useCallback(()=>{window.clearTimeout(d.current),d.current=window.setTimeout(()=>l.current=!0,r)},[r]),isPointerInTransitRef:u,onPointerInTransitChange:y.useCallback(f=>{u.current=f},[]),disableHoverableContent:s,children:o})};VP.displayName=UP;var id=\"Tooltip\",[sZ,Nd]=lg(id),HP=e=>{const{__scopeTooltip:t,children:n,open:r,defaultOpen:s,onOpenChange:o,disableHoverableContent:l,delayDuration:u}=e,d=Hx(id,e.__scopeTooltip),f=cg(t),[h,m]=y.useState(null),g=RQ(),x=y.useRef(0),b=l??d.disableHoverableContent,w=u??d.delayDuration,C=y.useRef(!1),[k,j]=QQ({prop:r,defaultProp:s??!1,onChange:O=>{O?(d.onOpen(),document.dispatchEvent(new CustomEvent(gb))):d.onClose(),o?.(O)},caller:id}),M=y.useMemo(()=>k?C.current?\"delayed-open\":\"instant-open\":\"closed\",[k]),_=y.useCallback(()=>{window.clearTimeout(x.current),x.current=0,C.current=!1,j(!0)},[j]),R=y.useCallback(()=>{window.clearTimeout(x.current),x.current=0,j(!1)},[j]),N=y.useCallback(()=>{window.clearTimeout(x.current),x.current=window.setTimeout(()=>{C.current=!0,j(!0),x.current=0},w)},[w,j]);return y.useEffect(()=>()=>{x.current&&(window.clearTimeout(x.current),x.current=0)},[]),i.jsx(zQ,{...f,children:i.jsx(sZ,{scope:t,contentId:g,open:k,stateAttribute:M,trigger:h,onTriggerChange:m,onTriggerEnter:y.useCallback(()=>{d.isOpenDelayedRef.current?N():_()},[d.isOpenDelayedRef,N,_]),onTriggerLeave:y.useCallback(()=>{b?R():(window.clearTimeout(x.current),x.current=0)},[R,b]),onOpen:_,onClose:R,disableHoverableContent:b,children:n})})};HP.displayName=id;var mb=\"TooltipTrigger\",qP=y.forwardRef((e,t)=>{const{__scopeTooltip:n,...r}=e,s=Nd(mb,n),o=Hx(mb,n),l=cg(n),u=y.useRef(null),d=Ui(t,u,s.onTriggerChange),f=y.useRef(!1),h=y.useRef(!1),m=y.useCallback(()=>f.current=!1,[]);return y.useEffect(()=>()=>document.removeEventListener(\"pointerup\",m),[m]),i.jsx(UQ,{asChild:!0,...l,children:i.jsx(Fa.button,{\"aria-describedby\":s.open?s.contentId:void 0,\"data-state\":s.stateAttribute,...r,ref:d,onPointerMove:bo(e.onPointerMove,g=>{g.pointerType!==\"touch\"&&!h.current&&!o.isPointerInTransitRef.current&&(s.onTriggerEnter(),h.current=!0)}),onPointerLeave:bo(e.onPointerLeave,()=>{s.onTriggerLeave(),h.current=!1}),onPointerDown:bo(e.onPointerDown,()=>{s.open&&s.onClose(),f.current=!0,document.addEventListener(\"pointerup\",m,{once:!0})}),onFocus:bo(e.onFocus,()=>{f.current||s.onOpen()}),onBlur:bo(e.onBlur,s.onClose),onClick:bo(e.onClick,s.onClose)})})});qP.displayName=mb;var qx=\"TooltipPortal\",[oZ,aZ]=lg(qx,{forceMount:void 0}),KP=e=>{const{__scopeTooltip:t,forceMount:n,children:r,container:s}=e,o=Nd(qx,t);return i.jsx(oZ,{scope:t,forceMount:n,children:i.jsx(Vx,{present:n||o.open,children:i.jsx(BP,{asChild:!0,container:s,children:r})})})};KP.displayName=qx;var Wl=\"TooltipContent\",WP=y.forwardRef((e,t)=>{const n=aZ(Wl,e.__scopeTooltip),{forceMount:r=n.forceMount,side:s=\"top\",...o}=e,l=Nd(Wl,e.__scopeTooltip);return i.jsx(Vx,{present:r||l.open,children:l.disableHoverableContent?i.jsx(GP,{side:s,...o,ref:t}):i.jsx(iZ,{side:s,...o,ref:t})})}),iZ=y.forwardRef((e,t)=>{const n=Nd(Wl,e.__scopeTooltip),r=Hx(Wl,e.__scopeTooltip),s=y.useRef(null),o=Ui(t,s),[l,u]=y.useState(null),{trigger:d,onClose:f}=n,h=s.current,{onPointerInTransitChange:m}=r,g=y.useCallback(()=>{u(null),m(!1)},[m]),x=y.useCallback((b,w)=>{const C=b.currentTarget,k={x:b.clientX,y:b.clientY},j=dZ(k,C.getBoundingClientRect()),M=fZ(k,j),_=pZ(w.getBoundingClientRect()),R=gZ([...M,..._]);u(R),m(!0)},[m]);return y.useEffect(()=>()=>g(),[g]),y.useEffect(()=>{if(d&&h){const b=C=>x(C,h),w=C=>x(C,d);return d.addEventListener(\"pointerleave\",b),h.addEventListener(\"pointerleave\",w),()=>{d.removeEventListener(\"pointerleave\",b),h.removeEventListener(\"pointerleave\",w)}}},[d,h,x,g]),y.useEffect(()=>{if(l){const b=w=>{const C=w.target,k={x:w.clientX,y:w.clientY},j=d?.contains(C)||h?.contains(C),M=!hZ(k,l);j?g():M&&(g(),f())};return document.addEventListener(\"pointermove\",b),()=>document.removeEventListener(\"pointermove\",b)}},[d,h,l,f,g]),i.jsx(GP,{...e,ref:o})}),[lZ,cZ]=lg(id,{isInside:!1}),uZ=gQ(\"TooltipContent\"),GP=y.forwardRef((e,t)=>{const{__scopeTooltip:n,children:r,\"aria-label\":s,onEscapeKeyDown:o,onPointerDownOutside:l,...u}=e,d=Nd(Wl,n),f=cg(n),{onClose:h}=d;return y.useEffect(()=>(document.addEventListener(gb,h),()=>document.removeEventListener(gb,h)),[h]),y.useEffect(()=>{if(d.trigger){const m=g=>{g.target?.contains(d.trigger)&&h()};return window.addEventListener(\"scroll\",m,{capture:!0}),()=>window.removeEventListener(\"scroll\",m,{capture:!0})}},[d.trigger,h]),i.jsx(TP,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:o,onPointerDownOutside:l,onFocusOutside:m=>m.preventDefault(),onDismiss:h,children:i.jsxs(VQ,{\"data-state\":d.stateAttribute,...f,...u,ref:t,style:{...u.style,\"--radix-tooltip-content-transform-origin\":\"var(--radix-popper-transform-origin)\",\"--radix-tooltip-content-available-width\":\"var(--radix-popper-available-width)\",\"--radix-tooltip-content-available-height\":\"var(--radix-popper-available-height)\",\"--radix-tooltip-trigger-width\":\"var(--radix-popper-anchor-width)\",\"--radix-tooltip-trigger-height\":\"var(--radix-popper-anchor-height)\"},children:[i.jsx(uZ,{children:r}),i.jsx(lZ,{scope:n,isInside:!0,children:i.jsx(tZ,{id:d.contentId,role:\"tooltip\",children:s||r})})]})})});WP.displayName=Wl;var JP=\"TooltipArrow\",QP=y.forwardRef((e,t)=>{const{__scopeTooltip:n,...r}=e,s=cg(n);return cZ(JP,n).isInside?null:i.jsx(HQ,{...s,...r,ref:t})});QP.displayName=JP;function dZ(e,t){const n=Math.abs(t.top-e.y),r=Math.abs(t.bottom-e.y),s=Math.abs(t.right-e.x),o=Math.abs(t.left-e.x);switch(Math.min(n,r,s,o)){case o:return\"left\";case s:return\"right\";case n:return\"top\";case r:return\"bottom\";default:throw new Error(\"unreachable\")}}function fZ(e,t,n=5){const r=[];switch(t){case\"top\":r.push({x:e.x-n,y:e.y+n},{x:e.x+n,y:e.y+n});break;case\"bottom\":r.push({x:e.x-n,y:e.y-n},{x:e.x+n,y:e.y-n});break;case\"left\":r.push({x:e.x+n,y:e.y-n},{x:e.x+n,y:e.y+n});break;case\"right\":r.push({x:e.x-n,y:e.y-n},{x:e.x-n,y:e.y+n});break}return r}function pZ(e){const{top:t,right:n,bottom:r,left:s}=e;return[{x:s,y:t},{x:n,y:t},{x:n,y:r},{x:s,y:r}]}function hZ(e,t){const{x:n,y:r}=e;let s=!1;for(let o=0,l=t.length-1;o<t.length;l=o++){const u=t[o],d=t[l],f=u.x,h=u.y,m=d.x,g=d.y;h>r!=g>r&&n<(m-f)*(r-h)/(g-h)+f&&(s=!s)}return s}function gZ(e){const t=e.slice();return t.sort((n,r)=>n.x<r.x?-1:n.x>r.x?1:n.y<r.y?-1:n.y>r.y?1:0),mZ(t)}function mZ(e){if(e.length<=1)return e.slice();const t=[];for(let r=0;r<e.length;r++){const s=e[r];for(;t.length>=2;){const o=t[t.length-1],l=t[t.length-2];if((o.x-l.x)*(s.y-l.y)>=(o.y-l.y)*(s.x-l.x))t.pop();else break}t.push(s)}t.pop();const n=[];for(let r=e.length-1;r>=0;r--){const s=e[r];for(;n.length>=2;){const o=n[n.length-1],l=n[n.length-2];if((o.x-l.x)*(s.y-l.y)>=(o.y-l.y)*(s.x-l.x))n.pop();else break}n.push(s)}return n.pop(),t.length===1&&n.length===1&&t[0].x===n[0].x&&t[0].y===n[0].y?t:t.concat(n)}var vZ=VP,yZ=HP,bZ=qP,xZ=KP,wZ=WP,SZ=QP;function FE({content:e,children:t,side:n=\"top\"}){return i.jsx(vZ,{delayDuration:200,children:i.jsxs(yZ,{children:[i.jsx(bZ,{asChild:!0,children:t}),i.jsx(xZ,{children:i.jsxs(wZ,{side:n,className:`\n              rounded px-3 py-1.5 text-sm z-50 border shadow-lg\n            bg-gray-100 text-gray-900 border-gray-300\n            dark:bg-gray-800 dark:text-gray-100 dark:border-gray-700\n            `,children:[e,i.jsx(SZ,{className:\"fill-gray-100 dark:fill-gray-800\",width:18,height:9})]})})]})})}function CZ(){const{t:e}=Ve(),[t,n]=y.useState(null),{deleteInstance:r,logout:s}=Hh(),{data:o,refetch:l}=q5(),[u,d]=y.useState([]),[f,h]=y.useState(\"all\"),[m,g]=y.useState(\"\"),x=async()=>{await l()},b=async k=>{n(null),d([...u,k]);try{try{await s(k)}catch(j){console.error(\"Error logout:\",j)}await r(k),await new Promise(j=>setTimeout(j,1e3)),x()}catch(j){console.error(\"Error instance delete:\",j),me.error(`Error : ${j?.response?.data?.response?.message}`)}finally{d(u.filter(j=>j!==k))}},w=y.useMemo(()=>{let k=o?[...o]:[];return f!==\"all\"&&(k=k.filter(j=>j.connectionStatus===f)),m!==\"\"&&(k=k.filter(j=>j.name.toLowerCase().includes(m.toLowerCase()))),k},[o,m,f]),C=[{value:\"all\",label:e(\"status.all\")},{value:\"close\",label:e(\"status.closed\")},{value:\"connecting\",label:e(\"status.connecting\")},{value:\"open\",label:e(\"status.open\")}];return i.jsxs(\"div\",{className:\"my-4 px-4\",children:[i.jsxs(\"div\",{className:\"flex w-full items-center justify-between\",children:[i.jsx(\"h2\",{className:\"text-lg\",children:e(\"dashboard.title\")}),i.jsxs(\"div\",{className:\"flex gap-2\",children:[i.jsx(se,{variant:\"outline\",size:\"icon\",children:i.jsx(Ip,{onClick:x,size:\"20\"})}),i.jsx(dQ,{resetTable:x})]})]}),i.jsxs(\"div\",{className:\"my-4 flex items-center justify-between gap-3 px-4\",children:[i.jsx(\"div\",{className:\"flex-1\",children:i.jsx(ne,{placeholder:e(\"dashboard.search\"),value:m,onChange:k=>g(k.target.value)})}),i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",children:[e(\"dashboard.status\"),\" \",i.jsx(J$,{size:\"15\"})]})}),i.jsx(hr,{children:C.map(k=>i.jsx(aM,{checked:f===k.value,onCheckedChange:j=>{j&&h(k.value)},children:k.label},k.value))})]})]}),i.jsx(\"main\",{className:\"grid gap-6 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\",children:w.length>0&&Array.isArray(w)?w.map(k=>i.jsxs(So,{children:[i.jsx(Co,{children:i.jsxs(Fu,{to:`/manager/instance/${k.id}/dashboard`,className:\"flex w-full flex-row items-center justify-between gap-4\",children:[i.jsx(FE,{content:k.name,side:\"top\",children:i.jsx(\"h3\",{className:\"text-wrap font-semibold truncate\",children:k.name})}),i.jsx(FE,{content:e(\"dashboard.settings\"),side:\"top\",children:i.jsx(se,{variant:\"ghost\",size:\"icon\",children:i.jsx(Oo,{className:\"card-icon\",size:\"20\"})})})]})}),i.jsxs(Eo,{className:\"flex-1 space-y-6\",children:[i.jsx(c_,{token:k.token}),i.jsxs(\"div\",{className:\"flex w-full flex-wrap\",children:[i.jsx(\"div\",{className:\"flex flex-1 gap-2\",children:k.profileName&&i.jsxs(i.Fragment,{children:[i.jsx(Ei,{children:i.jsx(ki,{src:k.profilePicUrl,alt:\"\"})}),i.jsxs(\"div\",{className:\"space-y-1\",children:[i.jsx(\"strong\",{children:k.profileName}),i.jsx(\"p\",{className:\"text-sm text-muted-foreground\",children:k.ownerJid&&k.ownerJid.split(\"@\")[0]})]})]})}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-4 text-sm\",children:[i.jsxs(\"div\",{className:\"flex flex-col items-center justify-center gap-1\",children:[i.jsx(pT,{className:\"text-muted-foreground\",size:\"20\"}),i.jsx(\"span\",{children:new Intl.NumberFormat(\"pt-BR\").format(k?._count?.Contact||0)})]}),i.jsxs(\"div\",{className:\"flex flex-col items-center justify-center gap-1\",children:[i.jsx(Bl,{className:\"text-muted-foreground\",size:\"20\"}),i.jsx(\"span\",{children:new Intl.NumberFormat(\"pt-BR\").format(k?._count?.Message||0)})]})]})]})]}),i.jsxs(Vh,{className:\"justify-between\",children:[i.jsx(l_,{status:k.connectionStatus}),i.jsx(se,{variant:\"destructive\",size:\"sm\",onClick:()=>n(k.name),disabled:u.includes(k.name),children:u.includes(k.name)?i.jsx(\"span\",{children:e(\"button.deleting\")}):i.jsx(\"span\",{children:e(\"button.delete\")})})]})]},k.id)):i.jsx(\"p\",{children:e(\"dashboard.instancesNotFound\")})}),!!t&&i.jsx(Pt,{onOpenChange:()=>n(null),open:!0,children:i.jsxs(Nt,{children:[i.jsx($M,{}),i.jsx(Mt,{children:e(\"modal.delete.title\")}),i.jsx(\"p\",{children:e(\"modal.delete.message\",{instanceName:t})}),i.jsx(Yt,{children:i.jsxs(\"div\",{className:\"flex items-center gap-4\",children:[i.jsx(se,{onClick:()=>n(null),size:\"sm\",variant:\"outline\",children:e(\"button.cancel\")}),i.jsx(se,{onClick:()=>b(t),variant:\"destructive\",children:e(\"button.delete\")})]})})]})})]})}const{createElement:Gl,createContext:EZ,forwardRef:ZP,useCallback:Fr,useContext:YP,useEffect:vi,useImperativeHandle:XP,useLayoutEffect:kZ,useMemo:jZ,useRef:kr,useState:Mu}=Yl,LE=Yl.useId,TZ=kZ,ug=EZ(null);ug.displayName=\"PanelGroupContext\";const yi=TZ,NZ=typeof LE==\"function\"?LE:()=>null;let MZ=0;function Kx(e=null){const t=NZ(),n=kr(e||t||null);return n.current===null&&(n.current=\"\"+MZ++),e??n.current}function eO({children:e,className:t=\"\",collapsedSize:n,collapsible:r,defaultSize:s,forwardedRef:o,id:l,maxSize:u,minSize:d,onCollapse:f,onExpand:h,onResize:m,order:g,style:x,tagName:b=\"div\",...w}){const C=YP(ug);if(C===null)throw Error(\"Panel components must be rendered within a PanelGroup container\");const{collapsePanel:k,expandPanel:j,getPanelSize:M,getPanelStyle:_,groupId:R,isPanelCollapsed:N,reevaluatePanelConstraints:O,registerPanel:D,resizePanel:z,unregisterPanel:Q}=C,pe=Kx(l),V=kr({callbacks:{onCollapse:f,onExpand:h,onResize:m},constraints:{collapsedSize:n,collapsible:r,defaultSize:s,maxSize:u,minSize:d},id:pe,idIsFromProps:l!==void 0,order:g});kr({didLogMissingDefaultSizeWarning:!1}),yi(()=>{const{callbacks:W,constraints:ie}=V.current,re={...ie};V.current.id=pe,V.current.idIsFromProps=l!==void 0,V.current.order=g,W.onCollapse=f,W.onExpand=h,W.onResize=m,ie.collapsedSize=n,ie.collapsible=r,ie.defaultSize=s,ie.maxSize=u,ie.minSize=d,(re.collapsedSize!==ie.collapsedSize||re.collapsible!==ie.collapsible||re.maxSize!==ie.maxSize||re.minSize!==ie.minSize)&&O(V.current,re)}),yi(()=>{const W=V.current;return D(W),()=>{Q(W)}},[g,pe,D,Q]),XP(o,()=>({collapse:()=>{k(V.current)},expand:W=>{j(V.current,W)},getId(){return pe},getSize(){return M(V.current)},isCollapsed(){return N(V.current)},isExpanded(){return!N(V.current)},resize:W=>{z(V.current,W)}}),[k,j,M,N,pe,z]);const G=_(V.current,s);return Gl(b,{...w,children:e,className:t,id:l,style:{...G,...x},\"data-panel\":\"\",\"data-panel-collapsible\":r||void 0,\"data-panel-group-id\":R,\"data-panel-id\":pe,\"data-panel-size\":parseFloat(\"\"+G.flexGrow).toFixed(1)})}const tO=ZP((e,t)=>Gl(eO,{...e,forwardedRef:t}));eO.displayName=\"Panel\";tO.displayName=\"forwardRef(Panel)\";let vb=null,di=null;function _Z(e,t){if(t){const n=(t&aO)!==0,r=(t&iO)!==0,s=(t&lO)!==0,o=(t&cO)!==0;if(n)return s?\"se-resize\":o?\"ne-resize\":\"e-resize\";if(r)return s?\"sw-resize\":o?\"nw-resize\":\"w-resize\";if(s)return\"s-resize\";if(o)return\"n-resize\"}switch(e){case\"horizontal\":return\"ew-resize\";case\"intersection\":return\"move\";case\"vertical\":return\"ns-resize\"}}function RZ(){di!==null&&(document.head.removeChild(di),vb=null,di=null)}function Wv(e,t){const n=_Z(e,t);vb!==n&&(vb=n,di===null&&(di=document.createElement(\"style\"),document.head.appendChild(di)),di.innerHTML=`*{cursor: ${n}!important;}`)}function nO(e){return e.type===\"keydown\"}function rO(e){return e.type.startsWith(\"pointer\")}function sO(e){return e.type.startsWith(\"mouse\")}function dg(e){if(rO(e)){if(e.isPrimary)return{x:e.clientX,y:e.clientY}}else if(sO(e))return{x:e.clientX,y:e.clientY};return{x:1/0,y:1/0}}function PZ(){if(typeof matchMedia==\"function\")return matchMedia(\"(pointer:coarse)\").matches?\"coarse\":\"fine\"}function OZ(e,t,n){return e.x<t.x+t.width&&e.x+e.width>t.x&&e.y<t.y+t.height&&e.y+e.height>t.y}function IZ(e,t){if(e===t)throw new Error(\"Cannot compare node with itself\");const n={a:zE(e),b:zE(t)};let r;for(;n.a.at(-1)===n.b.at(-1);)e=n.a.pop(),t=n.b.pop(),r=e;kt(r,\"Stacking order can only be calculated for elements with a common ancestor\");const s={a:BE($E(n.a)),b:BE($E(n.b))};if(s.a===s.b){const o=r.childNodes,l={a:n.a.at(-1),b:n.b.at(-1)};let u=o.length;for(;u--;){const d=o[u];if(d===l.a)return 1;if(d===l.b)return-1}}return Math.sign(s.a-s.b)}const AZ=/\\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\\b/;function DZ(e){var t;const n=getComputedStyle((t=oO(e))!==null&&t!==void 0?t:e).display;return n===\"flex\"||n===\"inline-flex\"}function FZ(e){const t=getComputedStyle(e);return!!(t.position===\"fixed\"||t.zIndex!==\"auto\"&&(t.position!==\"static\"||DZ(e))||+t.opacity<1||\"transform\"in t&&t.transform!==\"none\"||\"webkitTransform\"in t&&t.webkitTransform!==\"none\"||\"mixBlendMode\"in t&&t.mixBlendMode!==\"normal\"||\"filter\"in t&&t.filter!==\"none\"||\"webkitFilter\"in t&&t.webkitFilter!==\"none\"||\"isolation\"in t&&t.isolation===\"isolate\"||AZ.test(t.willChange)||t.webkitOverflowScrolling===\"touch\")}function $E(e){let t=e.length;for(;t--;){const n=e[t];if(kt(n,\"Missing node\"),FZ(n))return n}return null}function BE(e){return e&&Number(getComputedStyle(e).zIndex)||0}function zE(e){const t=[];for(;e;)t.push(e),e=oO(e);return t}function oO(e){const{parentNode:t}=e;return t&&t instanceof ShadowRoot?t.host:t}const aO=1,iO=2,lO=4,cO=8,LZ=PZ()===\"coarse\";let js=[],ld=!1,ha=new Map,fg=new Map;const cd=new Set;function $Z(e,t,n,r,s){var o;const{ownerDocument:l}=t,u={direction:n,element:t,hitAreaMargins:r,setResizeHandlerState:s},d=(o=ha.get(l))!==null&&o!==void 0?o:0;return ha.set(l,d+1),cd.add(u),lh(),function(){var h;fg.delete(e),cd.delete(u);const m=(h=ha.get(l))!==null&&h!==void 0?h:1;if(ha.set(l,m-1),lh(),m===1&&ha.delete(l),js.includes(u)){const g=js.indexOf(u);g>=0&&js.splice(g,1),Gx()}}}function UE(e){const{target:t}=e,{x:n,y:r}=dg(e);ld=!0,Wx({target:t,x:n,y:r}),lh(),js.length>0&&(ch(\"down\",e),e.preventDefault(),e.stopPropagation())}function du(e){const{x:t,y:n}=dg(e);if(e.buttons===0&&(ld=!1,ch(\"up\",e)),!ld){const{target:r}=e;Wx({target:r,x:t,y:n})}ch(\"move\",e),Gx(),js.length>0&&e.preventDefault()}function bl(e){const{target:t}=e,{x:n,y:r}=dg(e);fg.clear(),ld=!1,js.length>0&&e.preventDefault(),ch(\"up\",e),Wx({target:t,x:n,y:r}),Gx(),lh()}function Wx({target:e,x:t,y:n}){js.splice(0);let r=null;e instanceof HTMLElement&&(r=e),cd.forEach(s=>{const{element:o,hitAreaMargins:l}=s,u=o.getBoundingClientRect(),{bottom:d,left:f,right:h,top:m}=u,g=LZ?l.coarse:l.fine;if(t>=f-g&&t<=h+g&&n>=m-g&&n<=d+g){if(r!==null&&o!==r&&!o.contains(r)&&!r.contains(o)&&IZ(r,o)>0){let b=r,w=!1;for(;b&&!b.contains(o);){if(OZ(b.getBoundingClientRect(),u)){w=!0;break}b=b.parentElement}if(w)return}js.push(s)}})}function Gv(e,t){fg.set(e,t)}function Gx(){let e=!1,t=!1;js.forEach(r=>{const{direction:s}=r;s===\"horizontal\"?e=!0:t=!0});let n=0;fg.forEach(r=>{n|=r}),e&&t?Wv(\"intersection\",n):e?Wv(\"horizontal\",n):t?Wv(\"vertical\",n):RZ()}function lh(){ha.forEach((e,t)=>{const{body:n}=t;n.removeEventListener(\"contextmenu\",bl),n.removeEventListener(\"pointerdown\",UE),n.removeEventListener(\"pointerleave\",du),n.removeEventListener(\"pointermove\",du)}),window.removeEventListener(\"pointerup\",bl),window.removeEventListener(\"pointercancel\",bl),cd.size>0&&(ld?(js.length>0&&ha.forEach((e,t)=>{const{body:n}=t;e>0&&(n.addEventListener(\"contextmenu\",bl),n.addEventListener(\"pointerleave\",du),n.addEventListener(\"pointermove\",du))}),window.addEventListener(\"pointerup\",bl),window.addEventListener(\"pointercancel\",bl)):ha.forEach((e,t)=>{const{body:n}=t;e>0&&(n.addEventListener(\"pointerdown\",UE,{capture:!0}),n.addEventListener(\"pointermove\",du))}))}function ch(e,t){cd.forEach(n=>{const{setResizeHandlerState:r}=n,s=js.includes(n);r(e,s,t)})}function kt(e,t){if(!e)throw console.error(t),Error(t)}const Jx=10;function Ri(e,t,n=Jx){return e.toFixed(n)===t.toFixed(n)?0:e>t?1:-1}function xo(e,t,n=Jx){return Ri(e,t,n)===0}function $r(e,t,n){return Ri(e,t,n)===0}function BZ(e,t,n){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++){const s=e[r],o=t[r];if(!$r(s,o,n))return!1}return!0}function Ml({panelConstraints:e,panelIndex:t,size:n}){const r=e[t];kt(r!=null,`Panel constraints not found for index ${t}`);let{collapsedSize:s=0,collapsible:o,maxSize:l=100,minSize:u=0}=r;if(Ri(n,u)<0)if(o){const d=(s+u)/2;Ri(n,d)<0?n=s:n=u}else n=u;return n=Math.min(l,n),n=parseFloat(n.toFixed(Jx)),n}function wu({delta:e,initialLayout:t,panelConstraints:n,pivotIndices:r,prevLayout:s,trigger:o}){if($r(e,0))return t;const l=[...t],[u,d]=r;kt(u!=null,\"Invalid first pivot index\"),kt(d!=null,\"Invalid second pivot index\");let f=0;if(o===\"keyboard\"){{const m=e<0?d:u,g=n[m];kt(g,`Panel constraints not found for index ${m}`);const{collapsedSize:x=0,collapsible:b,minSize:w=0}=g;if(b){const C=t[m];if(kt(C!=null,`Previous layout not found for panel index ${m}`),$r(C,x)){const k=w-C;Ri(k,Math.abs(e))>0&&(e=e<0?0-k:k)}}}{const m=e<0?u:d,g=n[m];kt(g,`No panel constraints found for index ${m}`);const{collapsedSize:x=0,collapsible:b,minSize:w=0}=g;if(b){const C=t[m];if(kt(C!=null,`Previous layout not found for panel index ${m}`),$r(C,w)){const k=C-x;Ri(k,Math.abs(e))>0&&(e=e<0?0-k:k)}}}}{const m=e<0?1:-1;let g=e<0?d:u,x=0;for(;;){const w=t[g];kt(w!=null,`Previous layout not found for panel index ${g}`);const k=Ml({panelConstraints:n,panelIndex:g,size:100})-w;if(x+=k,g+=m,g<0||g>=n.length)break}const b=Math.min(Math.abs(e),Math.abs(x));e=e<0?0-b:b}{let g=e<0?u:d;for(;g>=0&&g<n.length;){const x=Math.abs(e)-Math.abs(f),b=t[g];kt(b!=null,`Previous layout not found for panel index ${g}`);const w=b-x,C=Ml({panelConstraints:n,panelIndex:g,size:w});if(!$r(b,C)&&(f+=b-C,l[g]=C,f.toPrecision(3).localeCompare(Math.abs(e).toPrecision(3),void 0,{numeric:!0})>=0))break;e<0?g--:g++}}if(BZ(s,l))return s;{const m=e<0?d:u,g=t[m];kt(g!=null,`Previous layout not found for panel index ${m}`);const x=g+f,b=Ml({panelConstraints:n,panelIndex:m,size:x});if(l[m]=b,!$r(b,x)){let w=x-b,k=e<0?d:u;for(;k>=0&&k<n.length;){const j=l[k];kt(j!=null,`Previous layout not found for panel index ${k}`);const M=j+w,_=Ml({panelConstraints:n,panelIndex:k,size:M});if($r(j,_)||(w-=_-j,l[k]=_),$r(w,0))break;e>0?k--:k++}}}const h=l.reduce((m,g)=>g+m,0);return $r(h,100)?l:s}function zZ({layout:e,panelsArray:t,pivotIndices:n}){let r=0,s=100,o=0,l=0;const u=n[0];kt(u!=null,\"No pivot index found\"),t.forEach((m,g)=>{const{constraints:x}=m,{maxSize:b=100,minSize:w=0}=x;g===u?(r=w,s=b):(o+=w,l+=b)});const d=Math.min(s,100-o),f=Math.max(r,100-l),h=e[u];return{valueMax:d,valueMin:f,valueNow:h}}function ud(e,t=document){return Array.from(t.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id=\"${e}\"]`))}function uO(e,t,n=document){const s=ud(e,n).findIndex(o=>o.getAttribute(\"data-panel-resize-handle-id\")===t);return s??null}function dO(e,t,n){const r=uO(e,t,n);return r!=null?[r,r+1]:[-1,-1]}function fO(e,t=document){var n;if(t instanceof HTMLElement&&(t==null||(n=t.dataset)===null||n===void 0?void 0:n.panelGroupId)==e)return t;const r=t.querySelector(`[data-panel-group][data-panel-group-id=\"${e}\"]`);return r||null}function pg(e,t=document){const n=t.querySelector(`[data-panel-resize-handle-id=\"${e}\"]`);return n||null}function UZ(e,t,n,r=document){var s,o,l,u;const d=pg(t,r),f=ud(e,r),h=d?f.indexOf(d):-1,m=(s=(o=n[h])===null||o===void 0?void 0:o.id)!==null&&s!==void 0?s:null,g=(l=(u=n[h+1])===null||u===void 0?void 0:u.id)!==null&&l!==void 0?l:null;return[m,g]}function VZ({committedValuesRef:e,eagerValuesRef:t,groupId:n,layout:r,panelDataArray:s,panelGroupElement:o,setLayout:l}){kr({didWarnAboutMissingResizeHandle:!1}),yi(()=>{if(!o)return;const u=ud(n,o);for(let d=0;d<s.length-1;d++){const{valueMax:f,valueMin:h,valueNow:m}=zZ({layout:r,panelsArray:s,pivotIndices:[d,d+1]}),g=u[d];if(g!=null){const x=s[d];kt(x,`No panel data found for index \"${d}\"`),g.setAttribute(\"aria-controls\",x.id),g.setAttribute(\"aria-valuemax\",\"\"+Math.round(f)),g.setAttribute(\"aria-valuemin\",\"\"+Math.round(h)),g.setAttribute(\"aria-valuenow\",m!=null?\"\"+Math.round(m):\"\")}}return()=>{u.forEach((d,f)=>{d.removeAttribute(\"aria-controls\"),d.removeAttribute(\"aria-valuemax\"),d.removeAttribute(\"aria-valuemin\"),d.removeAttribute(\"aria-valuenow\")})}},[n,r,s,o]),vi(()=>{if(!o)return;const u=t.current;kt(u,\"Eager values not found\");const{panelDataArray:d}=u,f=fO(n,o);kt(f!=null,`No group found for id \"${n}\"`);const h=ud(n,o);kt(h,`No resize handles found for group id \"${n}\"`);const m=h.map(g=>{const x=g.getAttribute(\"data-panel-resize-handle-id\");kt(x,\"Resize handle element has no handle id attribute\");const[b,w]=UZ(n,x,d,o);if(b==null||w==null)return()=>{};const C=k=>{if(!k.defaultPrevented)switch(k.key){case\"Enter\":{k.preventDefault();const j=d.findIndex(M=>M.id===b);if(j>=0){const M=d[j];kt(M,`No panel data found for index ${j}`);const _=r[j],{collapsedSize:R=0,collapsible:N,minSize:O=0}=M.constraints;if(_!=null&&N){const D=wu({delta:$r(_,R)?O-R:R-_,initialLayout:r,panelConstraints:d.map(z=>z.constraints),pivotIndices:dO(n,x,o),prevLayout:r,trigger:\"keyboard\"});r!==D&&l(D)}}break}}};return g.addEventListener(\"keydown\",C),()=>{g.removeEventListener(\"keydown\",C)}});return()=>{m.forEach(g=>g())}},[o,e,t,n,r,s,l])}function VE(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function pO(e,t){const n=e===\"horizontal\",{x:r,y:s}=dg(t);return n?r:s}function HZ(e,t,n,r,s){const o=n===\"horizontal\",l=pg(t,s);kt(l,`No resize handle element found for id \"${t}\"`);const u=l.getAttribute(\"data-panel-group-id\");kt(u,\"Resize handle element has no group id attribute\");let{initialCursorPosition:d}=r;const f=pO(n,e),h=fO(u,s);kt(h,`No group element found for id \"${u}\"`);const m=h.getBoundingClientRect(),g=o?m.width:m.height;return(f-d)/g*100}function qZ(e,t,n,r,s,o){if(nO(e)){const l=n===\"horizontal\";let u=0;e.shiftKey?u=100:s!=null?u=s:u=10;let d=0;switch(e.key){case\"ArrowDown\":d=l?0:u;break;case\"ArrowLeft\":d=l?-u:0;break;case\"ArrowRight\":d=l?u:0;break;case\"ArrowUp\":d=l?0:-u;break;case\"End\":d=100;break;case\"Home\":d=-100;break}return d}else return r==null?0:HZ(e,t,n,r,o)}function KZ({panelDataArray:e}){const t=Array(e.length),n=e.map(o=>o.constraints);let r=0,s=100;for(let o=0;o<e.length;o++){const l=n[o];kt(l,`Panel constraints not found for index ${o}`);const{defaultSize:u}=l;u!=null&&(r++,t[o]=u,s-=u)}for(let o=0;o<e.length;o++){const l=n[o];kt(l,`Panel constraints not found for index ${o}`);const{defaultSize:u}=l;if(u!=null)continue;const d=e.length-r,f=s/d;r++,t[o]=f,s-=f}return t}function xl(e,t,n){t.forEach((r,s)=>{const o=e[s];kt(o,`Panel data not found for index ${s}`);const{callbacks:l,constraints:u,id:d}=o,{collapsedSize:f=0,collapsible:h}=u,m=n[d];if(m==null||r!==m){n[d]=r;const{onCollapse:g,onExpand:x,onResize:b}=l;b&&b(r,m),h&&(g||x)&&(x&&(m==null||xo(m,f))&&!xo(r,f)&&x(),g&&(m==null||!xo(m,f))&&xo(r,f)&&g())}})}function ep(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!=t[n])return!1;return!0}function WZ({defaultSize:e,dragState:t,layout:n,panelData:r,panelIndex:s,precision:o=3}){const l=n[s];let u;return l==null?u=e!=null?e.toPrecision(o):\"1\":r.length===1?u=\"1\":u=l.toPrecision(o),{flexBasis:0,flexGrow:u,flexShrink:1,overflow:\"hidden\",pointerEvents:t!==null?\"none\":void 0}}function GZ(e,t=10){let n=null;return(...s)=>{n!==null&&clearTimeout(n),n=setTimeout(()=>{e(...s)},t)}}function HE(e){try{if(typeof localStorage<\"u\")e.getItem=t=>localStorage.getItem(t),e.setItem=(t,n)=>{localStorage.setItem(t,n)};else throw new Error(\"localStorage not supported in this environment\")}catch(t){console.error(t),e.getItem=()=>null,e.setItem=()=>{}}}function hO(e){return`react-resizable-panels:${e}`}function gO(e){return e.map(t=>{const{constraints:n,id:r,idIsFromProps:s,order:o}=t;return s?r:o?`${o}:${JSON.stringify(n)}`:JSON.stringify(n)}).sort((t,n)=>t.localeCompare(n)).join(\",\")}function mO(e,t){try{const n=hO(e),r=t.getItem(n);if(r){const s=JSON.parse(r);if(typeof s==\"object\"&&s!=null)return s}}catch{}return null}function JZ(e,t,n){var r,s;const o=(r=mO(e,n))!==null&&r!==void 0?r:{},l=gO(t);return(s=o[l])!==null&&s!==void 0?s:null}function QZ(e,t,n,r,s){var o;const l=hO(e),u=gO(t),d=(o=mO(e,s))!==null&&o!==void 0?o:{};d[u]={expandToSizes:Object.fromEntries(n.entries()),layout:r};try{s.setItem(l,JSON.stringify(d))}catch(f){console.error(f)}}function qE({layout:e,panelConstraints:t}){const n=[...e],r=n.reduce((o,l)=>o+l,0);if(n.length!==t.length)throw Error(`Invalid ${t.length} panel layout: ${n.map(o=>`${o}%`).join(\", \")}`);if(!$r(r,100))for(let o=0;o<t.length;o++){const l=n[o];kt(l!=null,`No layout data found for index ${o}`);const u=100/r*l;n[o]=u}let s=0;for(let o=0;o<t.length;o++){const l=n[o];kt(l!=null,`No layout data found for index ${o}`);const u=Ml({panelConstraints:t,panelIndex:o,size:l});l!=u&&(s+=l-u,n[o]=u)}if(!$r(s,0))for(let o=0;o<t.length;o++){const l=n[o];kt(l!=null,`No layout data found for index ${o}`);const u=l+s,d=Ml({panelConstraints:t,panelIndex:o,size:u});if(l!==d&&(s-=d-l,n[o]=d,$r(s,0)))break}return n}const ZZ=100,Su={getItem:e=>(HE(Su),Su.getItem(e)),setItem:(e,t)=>{HE(Su),Su.setItem(e,t)}},KE={};function vO({autoSaveId:e=null,children:t,className:n=\"\",direction:r,forwardedRef:s,id:o=null,onLayout:l=null,keyboardResizeBy:u=null,storage:d=Su,style:f,tagName:h=\"div\",...m}){const g=Kx(o),x=kr(null),[b,w]=Mu(null),[C,k]=Mu([]),j=kr({}),M=kr(new Map),_=kr(0),R=kr({autoSaveId:e,direction:r,dragState:b,id:g,keyboardResizeBy:u,onLayout:l,storage:d}),N=kr({layout:C,panelDataArray:[],panelDataArrayChanged:!1});kr({didLogIdAndOrderWarning:!1,didLogPanelConstraintsWarning:!1,prevPanelIds:[]}),XP(s,()=>({getId:()=>R.current.id,getLayout:()=>{const{layout:F}=N.current;return F},setLayout:F=>{const{onLayout:fe}=R.current,{layout:te,panelDataArray:de}=N.current,ge=qE({layout:F,panelConstraints:de.map(Z=>Z.constraints)});VE(te,ge)||(k(ge),N.current.layout=ge,fe&&fe(ge),xl(de,ge,j.current))}}),[]),yi(()=>{R.current.autoSaveId=e,R.current.direction=r,R.current.dragState=b,R.current.id=g,R.current.onLayout=l,R.current.storage=d}),VZ({committedValuesRef:R,eagerValuesRef:N,groupId:g,layout:C,panelDataArray:N.current.panelDataArray,setLayout:k,panelGroupElement:x.current}),vi(()=>{const{panelDataArray:F}=N.current;if(e){if(C.length===0||C.length!==F.length)return;let fe=KE[e];fe==null&&(fe=GZ(QZ,ZZ),KE[e]=fe);const te=[...F],de=new Map(M.current);fe(e,te,de,C,d)}},[e,C,d]),vi(()=>{});const O=Fr(F=>{const{onLayout:fe}=R.current,{layout:te,panelDataArray:de}=N.current;if(F.constraints.collapsible){const ge=de.map($e=>$e.constraints),{collapsedSize:Z=0,panelSize:ye,pivotIndices:Re}=ri(de,F,te);if(kt(ye!=null,`Panel size not found for panel \"${F.id}\"`),!xo(ye,Z)){M.current.set(F.id,ye);const Ye=kl(de,F)===de.length-1?ye-Z:Z-ye,Fe=wu({delta:Ye,initialLayout:te,panelConstraints:ge,pivotIndices:Re,prevLayout:te,trigger:\"imperative-api\"});ep(te,Fe)||(k(Fe),N.current.layout=Fe,fe&&fe(Fe),xl(de,Fe,j.current))}}},[]),D=Fr((F,fe)=>{const{onLayout:te}=R.current,{layout:de,panelDataArray:ge}=N.current;if(F.constraints.collapsible){const Z=ge.map(ft=>ft.constraints),{collapsedSize:ye=0,panelSize:Re=0,minSize:$e=0,pivotIndices:Ye}=ri(ge,F,de),Fe=fe??$e;if(xo(Re,ye)){const ft=M.current.get(F.id),ln=ft!=null&&ft>=Fe?ft:Fe,vn=kl(ge,F)===ge.length-1?Re-ln:ln-Re,Cn=wu({delta:vn,initialLayout:de,panelConstraints:Z,pivotIndices:Ye,prevLayout:de,trigger:\"imperative-api\"});ep(de,Cn)||(k(Cn),N.current.layout=Cn,te&&te(Cn),xl(ge,Cn,j.current))}}},[]),z=Fr(F=>{const{layout:fe,panelDataArray:te}=N.current,{panelSize:de}=ri(te,F,fe);return kt(de!=null,`Panel size not found for panel \"${F.id}\"`),de},[]),Q=Fr((F,fe)=>{const{panelDataArray:te}=N.current,de=kl(te,F);return WZ({defaultSize:fe,dragState:b,layout:C,panelData:te,panelIndex:de})},[b,C]),pe=Fr(F=>{const{layout:fe,panelDataArray:te}=N.current,{collapsedSize:de=0,collapsible:ge,panelSize:Z}=ri(te,F,fe);return kt(Z!=null,`Panel size not found for panel \"${F.id}\"`),ge===!0&&xo(Z,de)},[]),V=Fr(F=>{const{layout:fe,panelDataArray:te}=N.current,{collapsedSize:de=0,collapsible:ge,panelSize:Z}=ri(te,F,fe);return kt(Z!=null,`Panel size not found for panel \"${F.id}\"`),!ge||Ri(Z,de)>0},[]),G=Fr(F=>{const{panelDataArray:fe}=N.current;fe.push(F),fe.sort((te,de)=>{const ge=te.order,Z=de.order;return ge==null&&Z==null?0:ge==null?-1:Z==null?1:ge-Z}),N.current.panelDataArrayChanged=!0},[]);yi(()=>{if(N.current.panelDataArrayChanged){N.current.panelDataArrayChanged=!1;const{autoSaveId:F,onLayout:fe,storage:te}=R.current,{layout:de,panelDataArray:ge}=N.current;let Z=null;if(F){const Re=JZ(F,ge,te);Re&&(M.current=new Map(Object.entries(Re.expandToSizes)),Z=Re.layout)}Z==null&&(Z=KZ({panelDataArray:ge}));const ye=qE({layout:Z,panelConstraints:ge.map(Re=>Re.constraints)});VE(de,ye)||(k(ye),N.current.layout=ye,fe&&fe(ye),xl(ge,ye,j.current))}}),yi(()=>{const F=N.current;return()=>{F.layout=[]}},[]);const W=Fr(F=>function(te){te.preventDefault();const de=x.current;if(!de)return()=>null;const{direction:ge,dragState:Z,id:ye,keyboardResizeBy:Re,onLayout:$e}=R.current,{layout:Ye,panelDataArray:Fe}=N.current,{initialLayout:ft}=Z??{},ln=dO(ye,F,de);let Sn=qZ(te,F,ge,Z,Re,de);const vn=ge===\"horizontal\";document.dir===\"rtl\"&&vn&&(Sn=-Sn);const Cn=Fe.map(ue=>ue.constraints),L=wu({delta:Sn,initialLayout:ft??Ye,panelConstraints:Cn,pivotIndices:ln,prevLayout:Ye,trigger:nO(te)?\"keyboard\":\"mouse-or-touch\"}),X=!ep(Ye,L);(rO(te)||sO(te))&&_.current!=Sn&&(_.current=Sn,X?Gv(F,0):vn?Gv(F,Sn<0?aO:iO):Gv(F,Sn<0?lO:cO)),X&&(k(L),N.current.layout=L,$e&&$e(L),xl(Fe,L,j.current))},[]),ie=Fr((F,fe)=>{const{onLayout:te}=R.current,{layout:de,panelDataArray:ge}=N.current,Z=ge.map(ft=>ft.constraints),{panelSize:ye,pivotIndices:Re}=ri(ge,F,de);kt(ye!=null,`Panel size not found for panel \"${F.id}\"`);const Ye=kl(ge,F)===ge.length-1?ye-fe:fe-ye,Fe=wu({delta:Ye,initialLayout:de,panelConstraints:Z,pivotIndices:Re,prevLayout:de,trigger:\"imperative-api\"});ep(de,Fe)||(k(Fe),N.current.layout=Fe,te&&te(Fe),xl(ge,Fe,j.current))},[]),re=Fr((F,fe)=>{const{layout:te,panelDataArray:de}=N.current,{collapsedSize:ge=0,collapsible:Z}=fe,{collapsedSize:ye=0,collapsible:Re,maxSize:$e=100,minSize:Ye=0}=F.constraints,{panelSize:Fe}=ri(de,F,te);Fe!=null&&(Z&&Re&&xo(Fe,ge)?xo(ge,ye)||ie(F,ye):Fe<Ye?ie(F,Ye):Fe>$e&&ie(F,$e))},[ie]),Y=Fr((F,fe)=>{const{direction:te}=R.current,{layout:de}=N.current;if(!x.current)return;const ge=pg(F,x.current);kt(ge,`Drag handle element not found for id \"${F}\"`);const Z=pO(te,fe);w({dragHandleId:F,dragHandleRect:ge.getBoundingClientRect(),initialCursorPosition:Z,initialLayout:de})},[]),H=Fr(()=>{w(null)},[]),q=Fr(F=>{const{panelDataArray:fe}=N.current,te=kl(fe,F);te>=0&&(fe.splice(te,1),delete j.current[F.id],N.current.panelDataArrayChanged=!0)},[]),he=jZ(()=>({collapsePanel:O,direction:r,dragState:b,expandPanel:D,getPanelSize:z,getPanelStyle:Q,groupId:g,isPanelCollapsed:pe,isPanelExpanded:V,reevaluatePanelConstraints:re,registerPanel:G,registerResizeHandle:W,resizePanel:ie,startDragging:Y,stopDragging:H,unregisterPanel:q,panelGroupElement:x.current}),[O,b,r,D,z,Q,g,pe,V,re,G,W,ie,Y,H,q]),A={display:\"flex\",flexDirection:r===\"horizontal\"?\"row\":\"column\",height:\"100%\",overflow:\"hidden\",width:\"100%\"};return Gl(ug.Provider,{value:he},Gl(h,{...m,children:t,className:n,id:o,ref:x,style:{...A,...f},\"data-panel-group\":\"\",\"data-panel-group-direction\":r,\"data-panel-group-id\":g}))}const yO=ZP((e,t)=>Gl(vO,{...e,forwardedRef:t}));vO.displayName=\"PanelGroup\";yO.displayName=\"forwardRef(PanelGroup)\";function kl(e,t){return e.findIndex(n=>n===t||n.id===t.id)}function ri(e,t,n){const r=kl(e,t),o=r===e.length-1?[r-1,r]:[r,r+1],l=n[r];return{...t.constraints,panelSize:l,pivotIndices:o}}function YZ({disabled:e,handleId:t,resizeHandler:n,panelGroupElement:r}){vi(()=>{if(e||n==null||r==null)return;const s=pg(t,r);if(s==null)return;const o=l=>{if(!l.defaultPrevented)switch(l.key){case\"ArrowDown\":case\"ArrowLeft\":case\"ArrowRight\":case\"ArrowUp\":case\"End\":case\"Home\":{l.preventDefault(),n(l);break}case\"F6\":{l.preventDefault();const u=s.getAttribute(\"data-panel-group-id\");kt(u,`No group element found for id \"${u}\"`);const d=ud(u,r),f=uO(u,t,r);kt(f!==null,`No resize element found for id \"${t}\"`);const h=l.shiftKey?f>0?f-1:d.length-1:f+1<d.length?f+1:0;d[h].focus();break}}};return s.addEventListener(\"keydown\",o),()=>{s.removeEventListener(\"keydown\",o)}},[r,e,t,n])}function bO({children:e=null,className:t=\"\",disabled:n=!1,hitAreaMargins:r,id:s,onBlur:o,onDragging:l,onFocus:u,style:d={},tabIndex:f=0,tagName:h=\"div\",...m}){var g,x;const b=kr(null),w=kr({onDragging:l});vi(()=>{w.current.onDragging=l});const C=YP(ug);if(C===null)throw Error(\"PanelResizeHandle components must be rendered within a PanelGroup container\");const{direction:k,groupId:j,registerResizeHandle:M,startDragging:_,stopDragging:R,panelGroupElement:N}=C,O=Kx(s),[D,z]=Mu(\"inactive\"),[Q,pe]=Mu(!1),[V,G]=Mu(null),W=kr({state:D});yi(()=>{W.current.state=D}),vi(()=>{if(n)G(null);else{const H=M(O);G(()=>H)}},[n,O,M]);const ie=(g=r?.coarse)!==null&&g!==void 0?g:15,re=(x=r?.fine)!==null&&x!==void 0?x:5;return vi(()=>{if(n||V==null)return;const H=b.current;return kt(H,\"Element ref not attached\"),$Z(O,H,k,{coarse:ie,fine:re},(he,A,F)=>{if(A)switch(he){case\"down\":{z(\"drag\"),_(O,F);const{onDragging:fe}=w.current;fe&&fe(!0);break}case\"move\":{const{state:fe}=W.current;fe!==\"drag\"&&z(\"hover\"),V(F);break}case\"up\":{z(\"hover\"),R();const{onDragging:fe}=w.current;fe&&fe(!1);break}}else z(\"inactive\")})},[ie,k,n,re,M,O,V,_,R]),YZ({disabled:n,handleId:O,resizeHandler:V,panelGroupElement:N}),Gl(h,{...m,children:e,className:t,id:s,onBlur:()=>{pe(!1),o?.()},onFocus:()=>{pe(!0),u?.()},ref:b,role:\"separator\",style:{...{touchAction:\"none\",userSelect:\"none\"},...d},tabIndex:f,\"data-panel-group-direction\":k,\"data-panel-group-id\":j,\"data-resize-handle\":\"\",\"data-resize-handle-active\":D===\"drag\"?\"pointer\":Q?\"keyboard\":void 0,\"data-resize-handle-state\":D,\"data-panel-resize-handle-enabled\":!n,\"data-panel-resize-handle-id\":O})}bO.displayName=\"PanelResizeHandle\";const $o=({className:e,...t})=>i.jsx(yO,{className:Ie(\"flex h-full w-full data-[panel-group-direction=vertical]:flex-col\",e),...t}),Hn=tO,Bo=({withHandle:e,className:t,...n})=>i.jsx(bO,{className:Ie(\"relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 after:bg-border focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90\",t),...n,children:e&&i.jsx(\"div\",{className:\"z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border\",children:i.jsx(lB,{className:\"h-2.5 w-2.5\"})})});var Qx=\"Tabs\",[XZ]=us(Qx,[Dh]),xO=Dh(),[eY,Zx]=XZ(Qx),wO=y.forwardRef((e,t)=>{const{__scopeTabs:n,value:r,onValueChange:s,defaultValue:o,orientation:l=\"horizontal\",dir:u,activationMode:d=\"automatic\",...f}=e,h=xd(u),[m,g]=ya({prop:r,onChange:s,defaultProp:o});return i.jsx(eY,{scope:n,baseId:Es(),value:m,onValueChange:g,orientation:l,dir:h,activationMode:d,children:i.jsx(rt.div,{dir:h,\"data-orientation\":l,...f,ref:t})})});wO.displayName=Qx;var SO=\"TabsList\",CO=y.forwardRef((e,t)=>{const{__scopeTabs:n,loop:r=!0,...s}=e,o=Zx(SO,n),l=xO(n);return i.jsx(aN,{asChild:!0,...l,orientation:o.orientation,dir:o.dir,loop:r,children:i.jsx(rt.div,{role:\"tablist\",\"aria-orientation\":o.orientation,...s,ref:t})})});CO.displayName=SO;var EO=\"TabsTrigger\",kO=y.forwardRef((e,t)=>{const{__scopeTabs:n,value:r,disabled:s=!1,...o}=e,l=Zx(EO,n),u=xO(n),d=NO(l.baseId,r),f=MO(l.baseId,r),h=r===l.value;return i.jsx(iN,{asChild:!0,...u,focusable:!s,active:h,children:i.jsx(rt.button,{type:\"button\",role:\"tab\",\"aria-selected\":h,\"aria-controls\":f,\"data-state\":h?\"active\":\"inactive\",\"data-disabled\":s?\"\":void 0,disabled:s,id:d,...o,ref:t,onMouseDown:Ue(e.onMouseDown,m=>{!s&&m.button===0&&m.ctrlKey===!1?l.onValueChange(r):m.preventDefault()}),onKeyDown:Ue(e.onKeyDown,m=>{[\" \",\"Enter\"].includes(m.key)&&l.onValueChange(r)}),onFocus:Ue(e.onFocus,()=>{const m=l.activationMode!==\"manual\";!h&&!s&&m&&l.onValueChange(r)})})})});kO.displayName=EO;var jO=\"TabsContent\",TO=y.forwardRef((e,t)=>{const{__scopeTabs:n,value:r,forceMount:s,children:o,...l}=e,u=Zx(jO,n),d=NO(u.baseId,r),f=MO(u.baseId,r),h=r===u.value,m=y.useRef(h);return y.useEffect(()=>{const g=requestAnimationFrame(()=>m.current=!1);return()=>cancelAnimationFrame(g)},[]),i.jsx(Mr,{present:s||h,children:({present:g})=>i.jsx(rt.div,{\"data-state\":h?\"active\":\"inactive\",\"data-orientation\":u.orientation,role:\"tabpanel\",\"aria-labelledby\":d,hidden:!g,id:f,tabIndex:0,...l,ref:t,style:{...e.style,animationDuration:m.current?\"0s\":void 0},children:g&&o})})});TO.displayName=jO;function NO(e,t){return`${e}-trigger-${t}`}function MO(e,t){return`${e}-content-${t}`}var tY=wO,_O=CO,RO=kO,PO=TO;const Yx=tY,hg=y.forwardRef(({className:e,...t},n)=>i.jsx(_O,{ref:n,className:Ie(\"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground\",e),...t}));hg.displayName=_O.displayName;const Jl=y.forwardRef(({className:e,...t},n)=>i.jsx(RO,{ref:n,className:Ie(\"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm\",e),...t}));Jl.displayName=RO.displayName;const Ql=y.forwardRef(({className:e,...t},n)=>i.jsx(PO,{ref:n,className:Ie(\"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",e),...t}));Ql.displayName=PO.displayName;const nY=e=>[\"chats\",\"findChats\",JSON.stringify(e)],rY=async({instanceName:e})=>(await Ee.post(`/chat/findChats/${e}`,{where:{}})).data,sY=e=>{const{instanceName:t,...n}=e;return mt({...n,queryKey:nY({instanceName:t}),queryFn:()=>rY({instanceName:t}),enabled:!!t})};function zo(e){const t=o=>typeof window<\"u\"?window.matchMedia(o).matches:!1,[n,r]=y.useState(t(e));function s(){r(t(e))}return y.useEffect(()=>{const o=window.matchMedia(e);return s(),o.addListener?o.addListener(s):o.addEventListener(\"change\",s),()=>{o.removeListener?o.removeListener(s):o.removeEventListener(\"change\",s)}},[e]),n}const Ys=Object.create(null);Ys.open=\"0\";Ys.close=\"1\";Ys.ping=\"2\";Ys.pong=\"3\";Ys.message=\"4\";Ys.upgrade=\"5\";Ys.noop=\"6\";const Cp=Object.create(null);Object.keys(Ys).forEach(e=>{Cp[Ys[e]]=e});const yb={type:\"error\",data:\"parser error\"},OO=typeof Blob==\"function\"||typeof Blob<\"u\"&&Object.prototype.toString.call(Blob)===\"[object BlobConstructor]\",IO=typeof ArrayBuffer==\"function\",AO=e=>typeof ArrayBuffer.isView==\"function\"?ArrayBuffer.isView(e):e&&e.buffer instanceof ArrayBuffer,Xx=({type:e,data:t},n,r)=>OO&&t instanceof Blob?n?r(t):WE(t,r):IO&&(t instanceof ArrayBuffer||AO(t))?n?r(t):WE(new Blob([t]),r):r(Ys[e]+(t||\"\")),WE=(e,t)=>{const n=new FileReader;return n.onload=function(){const r=n.result.split(\",\")[1];t(\"b\"+(r||\"\"))},n.readAsDataURL(e)};function GE(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}let Jv;function oY(e,t){if(OO&&e.data instanceof Blob)return e.data.arrayBuffer().then(GE).then(t);if(IO&&(e.data instanceof ArrayBuffer||AO(e.data)))return t(GE(e.data));Xx(e,!1,n=>{Jv||(Jv=new TextEncoder),t(Jv.encode(n))})}const JE=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",Cu=typeof Uint8Array>\"u\"?[]:new Uint8Array(256);for(let e=0;e<JE.length;e++)Cu[JE.charCodeAt(e)]=e;const aY=e=>{let t=e.length*.75,n=e.length,r,s=0,o,l,u,d;e[e.length-1]===\"=\"&&(t--,e[e.length-2]===\"=\"&&t--);const f=new ArrayBuffer(t),h=new Uint8Array(f);for(r=0;r<n;r+=4)o=Cu[e.charCodeAt(r)],l=Cu[e.charCodeAt(r+1)],u=Cu[e.charCodeAt(r+2)],d=Cu[e.charCodeAt(r+3)],h[s++]=o<<2|l>>4,h[s++]=(l&15)<<4|u>>2,h[s++]=(u&3)<<6|d&63;return f},iY=typeof ArrayBuffer==\"function\",ew=(e,t)=>{if(typeof e!=\"string\")return{type:\"message\",data:DO(e,t)};const n=e.charAt(0);return n===\"b\"?{type:\"message\",data:lY(e.substring(1),t)}:Cp[n]?e.length>1?{type:Cp[n],data:e.substring(1)}:{type:Cp[n]}:yb},lY=(e,t)=>{if(iY){const n=aY(e);return DO(n,t)}else return{base64:!0,data:e}},DO=(e,t)=>{switch(t){case\"blob\":return e instanceof Blob?e:new Blob([e]);case\"arraybuffer\":default:return e instanceof ArrayBuffer?e:e.buffer}},FO=\"\u001e\",cY=(e,t)=>{const n=e.length,r=new Array(n);let s=0;e.forEach((o,l)=>{Xx(o,!1,u=>{r[l]=u,++s===n&&t(r.join(FO))})})},uY=(e,t)=>{const n=e.split(FO),r=[];for(let s=0;s<n.length;s++){const o=ew(n[s],t);if(r.push(o),o.type===\"error\")break}return r};function dY(){return new TransformStream({transform(e,t){oY(e,n=>{const r=n.length;let s;if(r<126)s=new Uint8Array(1),new DataView(s.buffer).setUint8(0,r);else if(r<65536){s=new Uint8Array(3);const o=new DataView(s.buffer);o.setUint8(0,126),o.setUint16(1,r)}else{s=new Uint8Array(9);const o=new DataView(s.buffer);o.setUint8(0,127),o.setBigUint64(1,BigInt(r))}e.data&&typeof e.data!=\"string\"&&(s[0]|=128),t.enqueue(s),t.enqueue(n)})}})}let Qv;function tp(e){return e.reduce((t,n)=>t+n.length,0)}function np(e,t){if(e[0].length===t)return e.shift();const n=new Uint8Array(t);let r=0;for(let s=0;s<t;s++)n[s]=e[0][r++],r===e[0].length&&(e.shift(),r=0);return e.length&&r<e[0].length&&(e[0]=e[0].slice(r)),n}function fY(e,t){Qv||(Qv=new TextDecoder);const n=[];let r=0,s=-1,o=!1;return new TransformStream({transform(l,u){for(n.push(l);;){if(r===0){if(tp(n)<1)break;const d=np(n,1);o=(d[0]&128)===128,s=d[0]&127,s<126?r=3:s===126?r=1:r=2}else if(r===1){if(tp(n)<2)break;const d=np(n,2);s=new DataView(d.buffer,d.byteOffset,d.length).getUint16(0),r=3}else if(r===2){if(tp(n)<8)break;const d=np(n,8),f=new DataView(d.buffer,d.byteOffset,d.length),h=f.getUint32(0);if(h>Math.pow(2,21)-1){u.enqueue(yb);break}s=h*Math.pow(2,32)+f.getUint32(4),r=3}else{if(tp(n)<s)break;const d=np(n,s);u.enqueue(ew(o?d:Qv.decode(d),t)),r=0}if(s===0||s>e){u.enqueue(yb);break}}}})}const LO=4;function Pn(e){if(e)return pY(e)}function pY(e){for(var t in Pn.prototype)e[t]=Pn.prototype[t];return e}Pn.prototype.on=Pn.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks[\"$\"+e]=this._callbacks[\"$\"+e]||[]).push(t),this};Pn.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this};Pn.prototype.off=Pn.prototype.removeListener=Pn.prototype.removeAllListeners=Pn.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var n=this._callbacks[\"$\"+e];if(!n)return this;if(arguments.length==1)return delete this._callbacks[\"$\"+e],this;for(var r,s=0;s<n.length;s++)if(r=n[s],r===t||r.fn===t){n.splice(s,1);break}return n.length===0&&delete this._callbacks[\"$\"+e],this};Pn.prototype.emit=function(e){this._callbacks=this._callbacks||{};for(var t=new Array(arguments.length-1),n=this._callbacks[\"$\"+e],r=1;r<arguments.length;r++)t[r-1]=arguments[r];if(n){n=n.slice(0);for(var r=0,s=n.length;r<s;++r)n[r].apply(this,t)}return this};Pn.prototype.emitReserved=Pn.prototype.emit;Pn.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks[\"$\"+e]||[]};Pn.prototype.hasListeners=function(e){return!!this.listeners(e).length};const gg=typeof Promise==\"function\"&&typeof Promise.resolve==\"function\"?t=>Promise.resolve().then(t):(t,n)=>n(t,0),as=typeof self<\"u\"?self:typeof window<\"u\"?window:Function(\"return this\")(),hY=\"arraybuffer\";function $O(e,...t){return t.reduce((n,r)=>(e.hasOwnProperty(r)&&(n[r]=e[r]),n),{})}const gY=as.setTimeout,mY=as.clearTimeout;function mg(e,t){t.useNativeTimers?(e.setTimeoutFn=gY.bind(as),e.clearTimeoutFn=mY.bind(as)):(e.setTimeoutFn=as.setTimeout.bind(as),e.clearTimeoutFn=as.clearTimeout.bind(as))}const vY=1.33;function yY(e){return typeof e==\"string\"?bY(e):Math.ceil((e.byteLength||e.size)*vY)}function bY(e){let t=0,n=0;for(let r=0,s=e.length;r<s;r++)t=e.charCodeAt(r),t<128?n+=1:t<2048?n+=2:t<55296||t>=57344?n+=3:(r++,n+=4);return n}function BO(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function xY(e){let t=\"\";for(let n in e)e.hasOwnProperty(n)&&(t.length&&(t+=\"&\"),t+=encodeURIComponent(n)+\"=\"+encodeURIComponent(e[n]));return t}function wY(e){let t={},n=e.split(\"&\");for(let r=0,s=n.length;r<s;r++){let o=n[r].split(\"=\");t[decodeURIComponent(o[0])]=decodeURIComponent(o[1])}return t}class SY extends Error{constructor(t,n,r){super(t),this.description=n,this.context=r,this.type=\"TransportError\"}}class tw extends Pn{constructor(t){super(),this.writable=!1,mg(this,t),this.opts=t,this.query=t.query,this.socket=t.socket,this.supportsBinary=!t.forceBase64}onError(t,n,r){return super.emitReserved(\"error\",new SY(t,n,r)),this}open(){return this.readyState=\"opening\",this.doOpen(),this}close(){return(this.readyState===\"opening\"||this.readyState===\"open\")&&(this.doClose(),this.onClose()),this}send(t){this.readyState===\"open\"&&this.write(t)}onOpen(){this.readyState=\"open\",this.writable=!0,super.emitReserved(\"open\")}onData(t){const n=ew(t,this.socket.binaryType);this.onPacket(n)}onPacket(t){super.emitReserved(\"packet\",t)}onClose(t){this.readyState=\"closed\",super.emitReserved(\"close\",t)}pause(t){}createUri(t,n={}){return t+\"://\"+this._hostname()+this._port()+this.opts.path+this._query(n)}_hostname(){const t=this.opts.hostname;return t.indexOf(\":\")===-1?t:\"[\"+t+\"]\"}_port(){return this.opts.port&&(this.opts.secure&&+(this.opts.port!==443)||!this.opts.secure&&Number(this.opts.port)!==80)?\":\"+this.opts.port:\"\"}_query(t){const n=xY(t);return n.length?\"?\"+n:\"\"}}class CY extends tw{constructor(){super(...arguments),this._polling=!1}get name(){return\"polling\"}doOpen(){this._poll()}pause(t){this.readyState=\"pausing\";const n=()=>{this.readyState=\"paused\",t()};if(this._polling||!this.writable){let r=0;this._polling&&(r++,this.once(\"pollComplete\",function(){--r||n()})),this.writable||(r++,this.once(\"drain\",function(){--r||n()}))}else n()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved(\"poll\")}onData(t){const n=r=>{if(this.readyState===\"opening\"&&r.type===\"open\"&&this.onOpen(),r.type===\"close\")return this.onClose({description:\"transport closed by the server\"}),!1;this.onPacket(r)};uY(t,this.socket.binaryType).forEach(n),this.readyState!==\"closed\"&&(this._polling=!1,this.emitReserved(\"pollComplete\"),this.readyState===\"open\"&&this._poll())}doClose(){const t=()=>{this.write([{type:\"close\"}])};this.readyState===\"open\"?t():this.once(\"open\",t)}write(t){this.writable=!1,cY(t,n=>{this.doWrite(n,()=>{this.writable=!0,this.emitReserved(\"drain\")})})}uri(){const t=this.opts.secure?\"https\":\"http\",n=this.query||{};return this.opts.timestampRequests!==!1&&(n[this.opts.timestampParam]=BO()),!this.supportsBinary&&!n.sid&&(n.b64=1),this.createUri(t,n)}}let zO=!1;try{zO=typeof XMLHttpRequest<\"u\"&&\"withCredentials\"in new XMLHttpRequest}catch{}const EY=zO;function kY(){}class jY extends CY{constructor(t){if(super(t),typeof location<\"u\"){const n=location.protocol===\"https:\";let r=location.port;r||(r=n?\"443\":\"80\"),this.xd=typeof location<\"u\"&&t.hostname!==location.hostname||r!==t.port}}doWrite(t,n){const r=this.request({method:\"POST\",data:t});r.on(\"success\",n),r.on(\"error\",(s,o)=>{this.onError(\"xhr post error\",s,o)})}doPoll(){const t=this.request();t.on(\"data\",this.onData.bind(this)),t.on(\"error\",(n,r)=>{this.onError(\"xhr poll error\",n,r)}),this.pollXhr=t}}let Dl=class Ep extends Pn{constructor(t,n,r){super(),this.createRequest=t,mg(this,r),this._opts=r,this._method=r.method||\"GET\",this._uri=n,this._data=r.data!==void 0?r.data:null,this._create()}_create(){var t;const n=$O(this._opts,\"agent\",\"pfx\",\"key\",\"passphrase\",\"cert\",\"ca\",\"ciphers\",\"rejectUnauthorized\",\"autoUnref\");n.xdomain=!!this._opts.xd;const r=this._xhr=this.createRequest(n);try{r.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){r.setDisableHeaderCheck&&r.setDisableHeaderCheck(!0);for(let s in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(s)&&r.setRequestHeader(s,this._opts.extraHeaders[s])}}catch{}if(this._method===\"POST\")try{r.setRequestHeader(\"Content-type\",\"text/plain;charset=UTF-8\")}catch{}try{r.setRequestHeader(\"Accept\",\"*/*\")}catch{}(t=this._opts.cookieJar)===null||t===void 0||t.addCookies(r),\"withCredentials\"in r&&(r.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(r.timeout=this._opts.requestTimeout),r.onreadystatechange=()=>{var s;r.readyState===3&&((s=this._opts.cookieJar)===null||s===void 0||s.parseCookies(r.getResponseHeader(\"set-cookie\"))),r.readyState===4&&(r.status===200||r.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof r.status==\"number\"?r.status:0)},0))},r.send(this._data)}catch(s){this.setTimeoutFn(()=>{this._onError(s)},0);return}typeof document<\"u\"&&(this._index=Ep.requestsCount++,Ep.requests[this._index]=this)}_onError(t){this.emitReserved(\"error\",t,this._xhr),this._cleanup(!0)}_cleanup(t){if(!(typeof this._xhr>\"u\"||this._xhr===null)){if(this._xhr.onreadystatechange=kY,t)try{this._xhr.abort()}catch{}typeof document<\"u\"&&delete Ep.requests[this._index],this._xhr=null}}_onLoad(){const t=this._xhr.responseText;t!==null&&(this.emitReserved(\"data\",t),this.emitReserved(\"success\"),this._cleanup())}abort(){this._cleanup()}};Dl.requestsCount=0;Dl.requests={};if(typeof document<\"u\"){if(typeof attachEvent==\"function\")attachEvent(\"onunload\",QE);else if(typeof addEventListener==\"function\"){const e=\"onpagehide\"in as?\"pagehide\":\"unload\";addEventListener(e,QE,!1)}}function QE(){for(let e in Dl.requests)Dl.requests.hasOwnProperty(e)&&Dl.requests[e].abort()}const TY=(function(){const e=UO({xdomain:!1});return e&&e.responseType!==null})();class NY extends jY{constructor(t){super(t);const n=t&&t.forceBase64;this.supportsBinary=TY&&!n}request(t={}){return Object.assign(t,{xd:this.xd},this.opts),new Dl(UO,this.uri(),t)}}function UO(e){const t=e.xdomain;try{if(typeof XMLHttpRequest<\"u\"&&(!t||EY))return new XMLHttpRequest}catch{}if(!t)try{return new as[[\"Active\"].concat(\"Object\").join(\"X\")](\"Microsoft.XMLHTTP\")}catch{}}const VO=typeof navigator<\"u\"&&typeof navigator.product==\"string\"&&navigator.product.toLowerCase()===\"reactnative\";class MY extends tw{get name(){return\"websocket\"}doOpen(){const t=this.uri(),n=this.opts.protocols,r=VO?{}:$O(this.opts,\"agent\",\"perMessageDeflate\",\"pfx\",\"key\",\"passphrase\",\"cert\",\"ca\",\"ciphers\",\"rejectUnauthorized\",\"localAddress\",\"protocolVersion\",\"origin\",\"maxPayload\",\"family\",\"checkServerIdentity\");this.opts.extraHeaders&&(r.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,n,r)}catch(s){return this.emitReserved(\"error\",s)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=t=>this.onClose({description:\"websocket connection closed\",context:t}),this.ws.onmessage=t=>this.onData(t.data),this.ws.onerror=t=>this.onError(\"websocket error\",t)}write(t){this.writable=!1;for(let n=0;n<t.length;n++){const r=t[n],s=n===t.length-1;Xx(r,this.supportsBinary,o=>{try{this.doWrite(r,o)}catch{}s&&gg(()=>{this.writable=!0,this.emitReserved(\"drain\")},this.setTimeoutFn)})}}doClose(){typeof this.ws<\"u\"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const t=this.opts.secure?\"wss\":\"ws\",n=this.query||{};return this.opts.timestampRequests&&(n[this.opts.timestampParam]=BO()),this.supportsBinary||(n.b64=1),this.createUri(t,n)}}const Zv=as.WebSocket||as.MozWebSocket;class _Y extends MY{createSocket(t,n,r){return VO?new Zv(t,n,r):n?new Zv(t,n):new Zv(t)}doWrite(t,n){this.ws.send(n)}}class RY extends tw{get name(){return\"webtransport\"}doOpen(){try{this._transport=new WebTransport(this.createUri(\"https\"),this.opts.transportOptions[this.name])}catch(t){return this.emitReserved(\"error\",t)}this._transport.closed.then(()=>{this.onClose()}).catch(t=>{this.onError(\"webtransport error\",t)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(t=>{const n=fY(Number.MAX_SAFE_INTEGER,this.socket.binaryType),r=t.readable.pipeThrough(n).getReader(),s=dY();s.readable.pipeTo(t.writable),this._writer=s.writable.getWriter();const o=()=>{r.read().then(({done:u,value:d})=>{u||(this.onPacket(d),o())}).catch(u=>{})};o();const l={type:\"open\"};this.query.sid&&(l.data=`{\"sid\":\"${this.query.sid}\"}`),this._writer.write(l).then(()=>this.onOpen())})})}write(t){this.writable=!1;for(let n=0;n<t.length;n++){const r=t[n],s=n===t.length-1;this._writer.write(r).then(()=>{s&&gg(()=>{this.writable=!0,this.emitReserved(\"drain\")},this.setTimeoutFn)})}}doClose(){var t;(t=this._transport)===null||t===void 0||t.close()}}const PY={websocket:_Y,webtransport:RY,polling:NY},OY=/^(?:(?![^:@\\/?#]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@\\/?#]*)(?::([^:@\\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/,IY=[\"source\",\"protocol\",\"authority\",\"userInfo\",\"user\",\"password\",\"host\",\"port\",\"relative\",\"path\",\"directory\",\"file\",\"query\",\"anchor\"];function bb(e){if(e.length>8e3)throw\"URI too long\";const t=e,n=e.indexOf(\"[\"),r=e.indexOf(\"]\");n!=-1&&r!=-1&&(e=e.substring(0,n)+e.substring(n,r).replace(/:/g,\";\")+e.substring(r,e.length));let s=OY.exec(e||\"\"),o={},l=14;for(;l--;)o[IY[l]]=s[l]||\"\";return n!=-1&&r!=-1&&(o.source=t,o.host=o.host.substring(1,o.host.length-1).replace(/;/g,\":\"),o.authority=o.authority.replace(\"[\",\"\").replace(\"]\",\"\").replace(/;/g,\":\"),o.ipv6uri=!0),o.pathNames=AY(o,o.path),o.queryKey=DY(o,o.query),o}function AY(e,t){const n=/\\/{2,9}/g,r=t.replace(n,\"/\").split(\"/\");return(t.slice(0,1)==\"/\"||t.length===0)&&r.splice(0,1),t.slice(-1)==\"/\"&&r.splice(r.length-1,1),r}function DY(e,t){const n={};return t.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(r,s,o){s&&(n[s]=o)}),n}const xb=typeof addEventListener==\"function\"&&typeof removeEventListener==\"function\",kp=[];xb&&addEventListener(\"offline\",()=>{kp.forEach(e=>e())},!1);class va extends Pn{constructor(t,n){if(super(),this.binaryType=hY,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,t&&typeof t==\"object\"&&(n=t,t=null),t){const r=bb(t);n.hostname=r.host,n.secure=r.protocol===\"https\"||r.protocol===\"wss\",n.port=r.port,r.query&&(n.query=r.query)}else n.host&&(n.hostname=bb(n.host).host);mg(this,n),this.secure=n.secure!=null?n.secure:typeof location<\"u\"&&location.protocol===\"https:\",n.hostname&&!n.port&&(n.port=this.secure?\"443\":\"80\"),this.hostname=n.hostname||(typeof location<\"u\"?location.hostname:\"localhost\"),this.port=n.port||(typeof location<\"u\"&&location.port?location.port:this.secure?\"443\":\"80\"),this.transports=[],this._transportsByName={},n.transports.forEach(r=>{const s=r.prototype.name;this.transports.push(s),this._transportsByName[s]=r}),this.opts=Object.assign({path:\"/engine.io\",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:\"t\",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},n),this.opts.path=this.opts.path.replace(/\\/$/,\"\")+(this.opts.addTrailingSlash?\"/\":\"\"),typeof this.opts.query==\"string\"&&(this.opts.query=wY(this.opts.query)),xb&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener(\"beforeunload\",this._beforeunloadEventListener,!1)),this.hostname!==\"localhost\"&&(this._offlineEventListener=()=>{this._onClose(\"transport close\",{description:\"network connection lost\"})},kp.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(t){const n=Object.assign({},this.opts.query);n.EIO=LO,n.transport=t,this.id&&(n.sid=this.id);const r=Object.assign({},this.opts,{query:n,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[t]);return new this._transportsByName[t](r)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved(\"error\",\"No transports available\")},0);return}const t=this.opts.rememberUpgrade&&va.priorWebsocketSuccess&&this.transports.indexOf(\"websocket\")!==-1?\"websocket\":this.transports[0];this.readyState=\"opening\";const n=this.createTransport(t);n.open(),this.setTransport(n)}setTransport(t){this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on(\"drain\",this._onDrain.bind(this)).on(\"packet\",this._onPacket.bind(this)).on(\"error\",this._onError.bind(this)).on(\"close\",n=>this._onClose(\"transport close\",n))}onOpen(){this.readyState=\"open\",va.priorWebsocketSuccess=this.transport.name===\"websocket\",this.emitReserved(\"open\"),this.flush()}_onPacket(t){if(this.readyState===\"opening\"||this.readyState===\"open\"||this.readyState===\"closing\")switch(this.emitReserved(\"packet\",t),this.emitReserved(\"heartbeat\"),t.type){case\"open\":this.onHandshake(JSON.parse(t.data));break;case\"ping\":this._sendPacket(\"pong\"),this.emitReserved(\"ping\"),this.emitReserved(\"pong\"),this._resetPingTimeout();break;case\"error\":const n=new Error(\"server error\");n.code=t.data,this._onError(n);break;case\"message\":this.emitReserved(\"data\",t.data),this.emitReserved(\"message\",t.data);break}}onHandshake(t){this.emitReserved(\"handshake\",t),this.id=t.sid,this.transport.query.sid=t.sid,this._pingInterval=t.pingInterval,this._pingTimeout=t.pingTimeout,this._maxPayload=t.maxPayload,this.onOpen(),this.readyState!==\"closed\"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const t=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+t,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose(\"ping timeout\")},t),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved(\"drain\"):this.flush()}flush(){if(this.readyState!==\"closed\"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const t=this._getWritablePackets();this.transport.send(t),this._prevBufferLen=t.length,this.emitReserved(\"flush\")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name===\"polling\"&&this.writeBuffer.length>1))return this.writeBuffer;let n=1;for(let r=0;r<this.writeBuffer.length;r++){const s=this.writeBuffer[r].data;if(s&&(n+=yY(s)),r>0&&n>this._maxPayload)return this.writeBuffer.slice(0,r);n+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const t=Date.now()>this._pingTimeoutTime;return t&&(this._pingTimeoutTime=0,gg(()=>{this._onClose(\"ping timeout\")},this.setTimeoutFn)),t}write(t,n,r){return this._sendPacket(\"message\",t,n,r),this}send(t,n,r){return this._sendPacket(\"message\",t,n,r),this}_sendPacket(t,n,r,s){if(typeof n==\"function\"&&(s=n,n=void 0),typeof r==\"function\"&&(s=r,r=null),this.readyState===\"closing\"||this.readyState===\"closed\")return;r=r||{},r.compress=r.compress!==!1;const o={type:t,data:n,options:r};this.emitReserved(\"packetCreate\",o),this.writeBuffer.push(o),s&&this.once(\"flush\",s),this.flush()}close(){const t=()=>{this._onClose(\"forced close\"),this.transport.close()},n=()=>{this.off(\"upgrade\",n),this.off(\"upgradeError\",n),t()},r=()=>{this.once(\"upgrade\",n),this.once(\"upgradeError\",n)};return(this.readyState===\"opening\"||this.readyState===\"open\")&&(this.readyState=\"closing\",this.writeBuffer.length?this.once(\"drain\",()=>{this.upgrading?r():t()}):this.upgrading?r():t()),this}_onError(t){if(va.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState===\"opening\")return this.transports.shift(),this._open();this.emitReserved(\"error\",t),this._onClose(\"transport error\",t)}_onClose(t,n){if(this.readyState===\"opening\"||this.readyState===\"open\"||this.readyState===\"closing\"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners(\"close\"),this.transport.close(),this.transport.removeAllListeners(),xb&&(this._beforeunloadEventListener&&removeEventListener(\"beforeunload\",this._beforeunloadEventListener,!1),this._offlineEventListener)){const r=kp.indexOf(this._offlineEventListener);r!==-1&&kp.splice(r,1)}this.readyState=\"closed\",this.id=null,this.emitReserved(\"close\",t,n),this.writeBuffer=[],this._prevBufferLen=0}}}va.protocol=LO;class FY extends va{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState===\"open\"&&this.opts.upgrade)for(let t=0;t<this._upgrades.length;t++)this._probe(this._upgrades[t])}_probe(t){let n=this.createTransport(t),r=!1;va.priorWebsocketSuccess=!1;const s=()=>{r||(n.send([{type:\"ping\",data:\"probe\"}]),n.once(\"packet\",m=>{if(!r)if(m.type===\"pong\"&&m.data===\"probe\"){if(this.upgrading=!0,this.emitReserved(\"upgrading\",n),!n)return;va.priorWebsocketSuccess=n.name===\"websocket\",this.transport.pause(()=>{r||this.readyState!==\"closed\"&&(h(),this.setTransport(n),n.send([{type:\"upgrade\"}]),this.emitReserved(\"upgrade\",n),n=null,this.upgrading=!1,this.flush())})}else{const g=new Error(\"probe error\");g.transport=n.name,this.emitReserved(\"upgradeError\",g)}}))};function o(){r||(r=!0,h(),n.close(),n=null)}const l=m=>{const g=new Error(\"probe error: \"+m);g.transport=n.name,o(),this.emitReserved(\"upgradeError\",g)};function u(){l(\"transport closed\")}function d(){l(\"socket closed\")}function f(m){n&&m.name!==n.name&&o()}const h=()=>{n.removeListener(\"open\",s),n.removeListener(\"error\",l),n.removeListener(\"close\",u),this.off(\"close\",d),this.off(\"upgrading\",f)};n.once(\"open\",s),n.once(\"error\",l),n.once(\"close\",u),this.once(\"close\",d),this.once(\"upgrading\",f),this._upgrades.indexOf(\"webtransport\")!==-1&&t!==\"webtransport\"?this.setTimeoutFn(()=>{r||n.open()},200):n.open()}onHandshake(t){this._upgrades=this._filterUpgrades(t.upgrades),super.onHandshake(t)}_filterUpgrades(t){const n=[];for(let r=0;r<t.length;r++)~this.transports.indexOf(t[r])&&n.push(t[r]);return n}}let LY=class extends FY{constructor(t,n={}){const r=typeof t==\"object\"?t:n;(!r.transports||r.transports&&typeof r.transports[0]==\"string\")&&(r.transports=(r.transports||[\"polling\",\"websocket\",\"webtransport\"]).map(s=>PY[s]).filter(s=>!!s)),super(t,r)}};function $Y(e,t=\"\",n){let r=e;n=n||typeof location<\"u\"&&location,e==null&&(e=n.protocol+\"//\"+n.host),typeof e==\"string\"&&(e.charAt(0)===\"/\"&&(e.charAt(1)===\"/\"?e=n.protocol+e:e=n.host+e),/^(https?|wss?):\\/\\//.test(e)||(typeof n<\"u\"?e=n.protocol+\"//\"+e:e=\"https://\"+e),r=bb(e)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port=\"80\":/^(http|ws)s$/.test(r.protocol)&&(r.port=\"443\")),r.path=r.path||\"/\";const o=r.host.indexOf(\":\")!==-1?\"[\"+r.host+\"]\":r.host;return r.id=r.protocol+\"://\"+o+\":\"+r.port+t,r.href=r.protocol+\"://\"+o+(n&&n.port===r.port?\"\":\":\"+r.port),r}const BY=typeof ArrayBuffer==\"function\",zY=e=>typeof ArrayBuffer.isView==\"function\"?ArrayBuffer.isView(e):e.buffer instanceof ArrayBuffer,HO=Object.prototype.toString,UY=typeof Blob==\"function\"||typeof Blob<\"u\"&&HO.call(Blob)===\"[object BlobConstructor]\",VY=typeof File==\"function\"||typeof File<\"u\"&&HO.call(File)===\"[object FileConstructor]\";function nw(e){return BY&&(e instanceof ArrayBuffer||zY(e))||UY&&e instanceof Blob||VY&&e instanceof File}function jp(e,t){if(!e||typeof e!=\"object\")return!1;if(Array.isArray(e)){for(let n=0,r=e.length;n<r;n++)if(jp(e[n]))return!0;return!1}if(nw(e))return!0;if(e.toJSON&&typeof e.toJSON==\"function\"&&arguments.length===1)return jp(e.toJSON(),!0);for(const n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&jp(e[n]))return!0;return!1}function HY(e){const t=[],n=e.data,r=e;return r.data=wb(n,t),r.attachments=t.length,{packet:r,buffers:t}}function wb(e,t){if(!e)return e;if(nw(e)){const n={_placeholder:!0,num:t.length};return t.push(e),n}else if(Array.isArray(e)){const n=new Array(e.length);for(let r=0;r<e.length;r++)n[r]=wb(e[r],t);return n}else if(typeof e==\"object\"&&!(e instanceof Date)){const n={};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=wb(e[r],t));return n}return e}function qY(e,t){return e.data=Sb(e.data,t),delete e.attachments,e}function Sb(e,t){if(!e)return e;if(e&&e._placeholder===!0){if(typeof e.num==\"number\"&&e.num>=0&&e.num<t.length)return t[e.num];throw new Error(\"illegal attachments\")}else if(Array.isArray(e))for(let n=0;n<e.length;n++)e[n]=Sb(e[n],t);else if(typeof e==\"object\")for(const n in e)Object.prototype.hasOwnProperty.call(e,n)&&(e[n]=Sb(e[n],t));return e}const KY=[\"connect\",\"connect_error\",\"disconnect\",\"disconnecting\",\"newListener\",\"removeListener\"],WY=5;var _t;(function(e){e[e.CONNECT=0]=\"CONNECT\",e[e.DISCONNECT=1]=\"DISCONNECT\",e[e.EVENT=2]=\"EVENT\",e[e.ACK=3]=\"ACK\",e[e.CONNECT_ERROR=4]=\"CONNECT_ERROR\",e[e.BINARY_EVENT=5]=\"BINARY_EVENT\",e[e.BINARY_ACK=6]=\"BINARY_ACK\"})(_t||(_t={}));class GY{constructor(t){this.replacer=t}encode(t){return(t.type===_t.EVENT||t.type===_t.ACK)&&jp(t)?this.encodeAsBinary({type:t.type===_t.EVENT?_t.BINARY_EVENT:_t.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id}):[this.encodeAsString(t)]}encodeAsString(t){let n=\"\"+t.type;return(t.type===_t.BINARY_EVENT||t.type===_t.BINARY_ACK)&&(n+=t.attachments+\"-\"),t.nsp&&t.nsp!==\"/\"&&(n+=t.nsp+\",\"),t.id!=null&&(n+=t.id),t.data!=null&&(n+=JSON.stringify(t.data,this.replacer)),n}encodeAsBinary(t){const n=HY(t),r=this.encodeAsString(n.packet),s=n.buffers;return s.unshift(r),s}}function ZE(e){return Object.prototype.toString.call(e)===\"[object Object]\"}class rw extends Pn{constructor(t){super(),this.reviver=t}add(t){let n;if(typeof t==\"string\"){if(this.reconstructor)throw new Error(\"got plaintext data when reconstructing a packet\");n=this.decodeString(t);const r=n.type===_t.BINARY_EVENT;r||n.type===_t.BINARY_ACK?(n.type=r?_t.EVENT:_t.ACK,this.reconstructor=new JY(n),n.attachments===0&&super.emitReserved(\"decoded\",n)):super.emitReserved(\"decoded\",n)}else if(nw(t)||t.base64)if(this.reconstructor)n=this.reconstructor.takeBinaryData(t),n&&(this.reconstructor=null,super.emitReserved(\"decoded\",n));else throw new Error(\"got binary data when not reconstructing a packet\");else throw new Error(\"Unknown type: \"+t)}decodeString(t){let n=0;const r={type:Number(t.charAt(0))};if(_t[r.type]===void 0)throw new Error(\"unknown packet type \"+r.type);if(r.type===_t.BINARY_EVENT||r.type===_t.BINARY_ACK){const o=n+1;for(;t.charAt(++n)!==\"-\"&&n!=t.length;);const l=t.substring(o,n);if(l!=Number(l)||t.charAt(n)!==\"-\")throw new Error(\"Illegal attachments\");r.attachments=Number(l)}if(t.charAt(n+1)===\"/\"){const o=n+1;for(;++n&&!(t.charAt(n)===\",\"||n===t.length););r.nsp=t.substring(o,n)}else r.nsp=\"/\";const s=t.charAt(n+1);if(s!==\"\"&&Number(s)==s){const o=n+1;for(;++n;){const l=t.charAt(n);if(l==null||Number(l)!=l){--n;break}if(n===t.length)break}r.id=Number(t.substring(o,n+1))}if(t.charAt(++n)){const o=this.tryParse(t.substr(n));if(rw.isPayloadValid(r.type,o))r.data=o;else throw new Error(\"invalid payload\")}return r}tryParse(t){try{return JSON.parse(t,this.reviver)}catch{return!1}}static isPayloadValid(t,n){switch(t){case _t.CONNECT:return ZE(n);case _t.DISCONNECT:return n===void 0;case _t.CONNECT_ERROR:return typeof n==\"string\"||ZE(n);case _t.EVENT:case _t.BINARY_EVENT:return Array.isArray(n)&&(typeof n[0]==\"number\"||typeof n[0]==\"string\"&&KY.indexOf(n[0])===-1);case _t.ACK:case _t.BINARY_ACK:return Array.isArray(n)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class JY{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const n=qY(this.reconPack,this.buffers);return this.finishedReconstruction(),n}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const QY=Object.freeze(Object.defineProperty({__proto__:null,Decoder:rw,Encoder:GY,get PacketType(){return _t},protocol:WY},Symbol.toStringTag,{value:\"Module\"}));function xs(e,t,n){return e.on(t,n),function(){e.off(t,n)}}const ZY=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class qO extends Pn{constructor(t,n,r){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=t,this.nsp=n,r&&r.auth&&(this.auth=r.auth),this._opts=Object.assign({},r),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const t=this.io;this.subs=[xs(t,\"open\",this.onopen.bind(this)),xs(t,\"packet\",this.onpacket.bind(this)),xs(t,\"error\",this.onerror.bind(this)),xs(t,\"close\",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState===\"open\"&&this.onopen(),this)}open(){return this.connect()}send(...t){return t.unshift(\"message\"),this.emit.apply(this,t),this}emit(t,...n){var r,s,o;if(ZY.hasOwnProperty(t))throw new Error('\"'+t.toString()+'\" is a reserved event name');if(n.unshift(t),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(n),this;const l={type:_t.EVENT,data:n};if(l.options={},l.options.compress=this.flags.compress!==!1,typeof n[n.length-1]==\"function\"){const h=this.ids++,m=n.pop();this._registerAckCallback(h,m),l.id=h}const u=(s=(r=this.io.engine)===null||r===void 0?void 0:r.transport)===null||s===void 0?void 0:s.writable,d=this.connected&&!(!((o=this.io.engine)===null||o===void 0)&&o._hasPingExpired());return this.flags.volatile&&!u||(d?(this.notifyOutgoingListeners(l),this.packet(l)):this.sendBuffer.push(l)),this.flags={},this}_registerAckCallback(t,n){var r;const s=(r=this.flags.timeout)!==null&&r!==void 0?r:this._opts.ackTimeout;if(s===void 0){this.acks[t]=n;return}const o=this.io.setTimeoutFn(()=>{delete this.acks[t];for(let u=0;u<this.sendBuffer.length;u++)this.sendBuffer[u].id===t&&this.sendBuffer.splice(u,1);n.call(this,new Error(\"operation has timed out\"))},s),l=(...u)=>{this.io.clearTimeoutFn(o),n.apply(this,u)};l.withError=!0,this.acks[t]=l}emitWithAck(t,...n){return new Promise((r,s)=>{const o=(l,u)=>l?s(l):r(u);o.withError=!0,n.push(o),this.emit(t,...n)})}_addToQueue(t){let n;typeof t[t.length-1]==\"function\"&&(n=t.pop());const r={id:this._queueSeq++,tryCount:0,pending:!1,args:t,flags:Object.assign({fromQueue:!0},this.flags)};t.push((s,...o)=>r!==this._queue[0]?void 0:(s!==null?r.tryCount>this._opts.retries&&(this._queue.shift(),n&&n(s)):(this._queue.shift(),n&&n(null,...o)),r.pending=!1,this._drainQueue())),this._queue.push(r),this._drainQueue()}_drainQueue(t=!1){if(!this.connected||this._queue.length===0)return;const n=this._queue[0];n.pending&&!t||(n.pending=!0,n.tryCount++,this.flags=n.flags,this.emit.apply(this,n.args))}packet(t){t.nsp=this.nsp,this.io._packet(t)}onopen(){typeof this.auth==\"function\"?this.auth(t=>{this._sendConnectPacket(t)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(t){this.packet({type:_t.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},t):t})}onerror(t){this.connected||this.emitReserved(\"connect_error\",t)}onclose(t,n){this.connected=!1,delete this.id,this.emitReserved(\"disconnect\",t,n),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(t=>{if(!this.sendBuffer.some(r=>String(r.id)===t)){const r=this.acks[t];delete this.acks[t],r.withError&&r.call(this,new Error(\"socket has been disconnected\"))}})}onpacket(t){if(t.nsp===this.nsp)switch(t.type){case _t.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved(\"connect_error\",new Error(\"It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)\"));break;case _t.EVENT:case _t.BINARY_EVENT:this.onevent(t);break;case _t.ACK:case _t.BINARY_ACK:this.onack(t);break;case _t.DISCONNECT:this.ondisconnect();break;case _t.CONNECT_ERROR:this.destroy();const r=new Error(t.data.message);r.data=t.data.data,this.emitReserved(\"connect_error\",r);break}}onevent(t){const n=t.data||[];t.id!=null&&n.push(this.ack(t.id)),this.connected?this.emitEvent(n):this.receiveBuffer.push(Object.freeze(n))}emitEvent(t){if(this._anyListeners&&this._anyListeners.length){const n=this._anyListeners.slice();for(const r of n)r.apply(this,t)}super.emit.apply(this,t),this._pid&&t.length&&typeof t[t.length-1]==\"string\"&&(this._lastOffset=t[t.length-1])}ack(t){const n=this;let r=!1;return function(...s){r||(r=!0,n.packet({type:_t.ACK,id:t,data:s}))}}onack(t){const n=this.acks[t.id];typeof n==\"function\"&&(delete this.acks[t.id],n.withError&&t.data.unshift(null),n.apply(this,t.data))}onconnect(t,n){this.id=t,this.recovered=n&&this._pid===n,this._pid=n,this.connected=!0,this.emitBuffered(),this.emitReserved(\"connect\"),this._drainQueue(!0)}emitBuffered(){this.receiveBuffer.forEach(t=>this.emitEvent(t)),this.receiveBuffer=[],this.sendBuffer.forEach(t=>{this.notifyOutgoingListeners(t),this.packet(t)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose(\"io server disconnect\")}destroy(){this.subs&&(this.subs.forEach(t=>t()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:_t.DISCONNECT}),this.destroy(),this.connected&&this.onclose(\"io client disconnect\"),this}close(){return this.disconnect()}compress(t){return this.flags.compress=t,this}get volatile(){return this.flags.volatile=!0,this}timeout(t){return this.flags.timeout=t,this}onAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(t),this}prependAny(t){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(t),this}offAny(t){if(!this._anyListeners)return this;if(t){const n=this._anyListeners;for(let r=0;r<n.length;r++)if(t===n[r])return n.splice(r,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(t),this}prependAnyOutgoing(t){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(t),this}offAnyOutgoing(t){if(!this._anyOutgoingListeners)return this;if(t){const n=this._anyOutgoingListeners;for(let r=0;r<n.length;r++)if(t===n[r])return n.splice(r,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(t){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const n=this._anyOutgoingListeners.slice();for(const r of n)r.apply(this,t.data)}}}function mc(e){e=e||{},this.ms=e.min||100,this.max=e.max||1e4,this.factor=e.factor||2,this.jitter=e.jitter>0&&e.jitter<=1?e.jitter:0,this.attempts=0}mc.prototype.duration=function(){var e=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var t=Math.random(),n=Math.floor(t*this.jitter*e);e=(Math.floor(t*10)&1)==0?e-n:e+n}return Math.min(e,this.max)|0};mc.prototype.reset=function(){this.attempts=0};mc.prototype.setMin=function(e){this.ms=e};mc.prototype.setMax=function(e){this.max=e};mc.prototype.setJitter=function(e){this.jitter=e};class Cb extends Pn{constructor(t,n){var r;super(),this.nsps={},this.subs=[],t&&typeof t==\"object\"&&(n=t,t=void 0),n=n||{},n.path=n.path||\"/socket.io\",this.opts=n,mg(this,n),this.reconnection(n.reconnection!==!1),this.reconnectionAttempts(n.reconnectionAttempts||1/0),this.reconnectionDelay(n.reconnectionDelay||1e3),this.reconnectionDelayMax(n.reconnectionDelayMax||5e3),this.randomizationFactor((r=n.randomizationFactor)!==null&&r!==void 0?r:.5),this.backoff=new mc({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(n.timeout==null?2e4:n.timeout),this._readyState=\"closed\",this.uri=t;const s=n.parser||QY;this.encoder=new s.Encoder,this.decoder=new s.Decoder,this._autoConnect=n.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(t){return arguments.length?(this._reconnection=!!t,t||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(t){return t===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}reconnectionDelay(t){var n;return t===void 0?this._reconnectionDelay:(this._reconnectionDelay=t,(n=this.backoff)===null||n===void 0||n.setMin(t),this)}randomizationFactor(t){var n;return t===void 0?this._randomizationFactor:(this._randomizationFactor=t,(n=this.backoff)===null||n===void 0||n.setJitter(t),this)}reconnectionDelayMax(t){var n;return t===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,(n=this.backoff)===null||n===void 0||n.setMax(t),this)}timeout(t){return arguments.length?(this._timeout=t,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(t){if(~this._readyState.indexOf(\"open\"))return this;this.engine=new LY(this.uri,this.opts);const n=this.engine,r=this;this._readyState=\"opening\",this.skipReconnect=!1;const s=xs(n,\"open\",function(){r.onopen(),t&&t()}),o=u=>{this.cleanup(),this._readyState=\"closed\",this.emitReserved(\"error\",u),t?t(u):this.maybeReconnectOnOpen()},l=xs(n,\"error\",o);if(this._timeout!==!1){const u=this._timeout,d=this.setTimeoutFn(()=>{s(),o(new Error(\"timeout\")),n.close()},u);this.opts.autoUnref&&d.unref(),this.subs.push(()=>{this.clearTimeoutFn(d)})}return this.subs.push(s),this.subs.push(l),this}connect(t){return this.open(t)}onopen(){this.cleanup(),this._readyState=\"open\",this.emitReserved(\"open\");const t=this.engine;this.subs.push(xs(t,\"ping\",this.onping.bind(this)),xs(t,\"data\",this.ondata.bind(this)),xs(t,\"error\",this.onerror.bind(this)),xs(t,\"close\",this.onclose.bind(this)),xs(this.decoder,\"decoded\",this.ondecoded.bind(this)))}onping(){this.emitReserved(\"ping\")}ondata(t){try{this.decoder.add(t)}catch(n){this.onclose(\"parse error\",n)}}ondecoded(t){gg(()=>{this.emitReserved(\"packet\",t)},this.setTimeoutFn)}onerror(t){this.emitReserved(\"error\",t)}socket(t,n){let r=this.nsps[t];return r?this._autoConnect&&!r.active&&r.connect():(r=new qO(this,t,n),this.nsps[t]=r),r}_destroy(t){const n=Object.keys(this.nsps);for(const r of n)if(this.nsps[r].active)return;this._close()}_packet(t){const n=this.encoder.encode(t);for(let r=0;r<n.length;r++)this.engine.write(n[r],t.options)}cleanup(){this.subs.forEach(t=>t()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose(\"forced close\")}disconnect(){return this._close()}onclose(t,n){var r;this.cleanup(),(r=this.engine)===null||r===void 0||r.close(),this.backoff.reset(),this._readyState=\"closed\",this.emitReserved(\"close\",t,n),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const t=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved(\"reconnect_failed\"),this._reconnecting=!1;else{const n=this.backoff.duration();this._reconnecting=!0;const r=this.setTimeoutFn(()=>{t.skipReconnect||(this.emitReserved(\"reconnect_attempt\",t.backoff.attempts),!t.skipReconnect&&t.open(s=>{s?(t._reconnecting=!1,t.reconnect(),this.emitReserved(\"reconnect_error\",s)):t.onreconnect()}))},n);this.opts.autoUnref&&r.unref(),this.subs.push(()=>{this.clearTimeoutFn(r)})}}onreconnect(){const t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved(\"reconnect\",t)}}const fu={};function Tp(e,t){typeof e==\"object\"&&(t=e,e=void 0),t=t||{};const n=$Y(e,t.path||\"/socket.io\"),r=n.source,s=n.id,o=n.path,l=fu[s]&&o in fu[s].nsps,u=t.forceNew||t[\"force new connection\"]||t.multiplex===!1||l;let d;return u?d=new Cb(r,t):(fu[s]||(fu[s]=new Cb(r,t)),d=fu[s]),n.query&&!t.query&&(t.query=n.queryKey),d.socket(n.path,t)}Object.assign(Tp,{Manager:Cb,Socket:qO,io:Tp,connect:Tp});const _u=new Map,sw=e=>{if(_u.has(e)){const n=_u.get(e);return YE(n)}const t=Tp(e,{transports:[\"websocket\",\"polling\"],autoConnect:!1,reconnection:!0,reconnectionAttempts:5,reconnectionDelay:1e3,timeout:2e4});return _u.set(e,t),t.on(\"connect\",()=>{console.log(`✅ WebSocket connected to ${e}`)}),t.on(\"disconnect\",n=>{console.log(`❌ WebSocket disconnected from ${e}:`,n)}),t.on(\"connect_error\",n=>{console.error(`🚫 WebSocket connection error to ${e}:`,n)}),t.on(\"reconnect\",n=>{console.log(`🔄 WebSocket reconnected to ${e} after ${n} attempts`)}),t.on(\"reconnect_error\",n=>{console.error(`🔄❌ WebSocket reconnection error to ${e}:`,n)}),YE(t)},ow=e=>{for(const[t,n]of _u.entries())if(n===e||e._socket===n){console.log(`🔌 Disconnecting socket for ${t}`),n.disconnect(),_u.delete(t);break}},YE=e=>({on:(t,n)=>{e.on(t,n)},off:t=>{e.off(t)},connect:()=>{e.connected||e.connect()},disconnect:()=>{e.disconnect()}}),bi=y.forwardRef(({className:e,...t},n)=>i.jsx(\"textarea\",{className:Ie(\"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",e),ref:n,...t}));bi.displayName=\"Textarea\";const YY=e=>[\"chats\",\"findChats\",JSON.stringify(e)],XY=async({instanceName:e,remoteJid:t})=>{const n=await Ee.post(`/chat/findChats/${e}`,{where:{remoteJid:t}});return Array.isArray(n.data)?n.data[0]:n.data},eX=e=>{const{instanceName:t,remoteJid:n,...r}=e;return mt({...r,queryKey:YY({instanceName:t,remoteJid:n}),queryFn:()=>XY({instanceName:t,remoteJid:n}),enabled:!!t&&!!n})},tX=e=>[\"chats\",\"findMessages\",JSON.stringify(e)],nX=async({instanceName:e,remoteJid:t})=>{const n=await Ee.post(`/chat/findMessages/${e}`,{where:{key:{remoteJid:t}}});return n.data?.messages?.records?n.data.messages.records:n.data},rX=e=>{const{instanceName:t,remoteJid:n,...r}=e;return mt({...r,queryKey:tX({instanceName:t,remoteJid:n}),queryFn:()=>nX({instanceName:t,remoteJid:n}),enabled:!!t&&!!n})},sX=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/message/sendText/${e}`,n,{headers:{apikey:t,\"content-type\":\"application/json\"}})).data,oX=async({instanceName:e,token:t,data:n})=>{try{const r={number:n.number,mediatype:n.mediaMessage.mediatype,mimetype:n.mediaMessage.mimetype,caption:n.mediaMessage.caption,media:n.mediaMessage.media,fileName:n.mediaMessage.fileName};return(await Ee.post(`/message/sendMedia/${e}`,r,{headers:{apikey:t,\"content-type\":\"application/json\"}})).data}catch(r){throw console.error(\"Erro ao enviar mídia:\",r),r}},aX=async({instanceName:e,token:t,data:n})=>{try{const r={number:n.number,audioMessage:{audio:n.audioMessage.audio},options:n.options};return(await Ee.post(`/message/sendWhatsAppAudio/${e}`,r,{headers:{apikey:t,\"content-type\":\"application/json\"}})).data}catch(r){throw console.error(\"Erro ao enviar áudio:\",r),r}};function KO(){return{sendText:nt(sX,{invalidateKeys:[[\"chats\",\"findMessages\"],[\"chats\",\"findChats\"]]})}}function WO(){return{sendMedia:nt(oX)}}function iX(){return{sendAudio:nt(aX)}}const GO=y.createContext({backgroundColor:\"\",textForegroundColor:\"\",primaryColor:\"\",fromMeBubbleColor:\"\",fromMeForegroundColor:\"\",fromOtherBubbleColor:\"\",fromOtherForegroundColor:\"\",fromMeQuotedBubbleColor:\"\",fromOtherQuotedBubbleColor:\"\",inputBackgroundColor:\"\",inputTextForegroundColor:\"\",inputIconsMainColor:\"\"});function lX({children:e}){const[t]=hd(),{theme:n}=tc(),r=t.get(\"backgroundColor\"),s=t.get(\"textForegroundColor\"),o=t.get(\"primaryColor\"),l=t.get(\"fromMeBubbleColor\"),u=t.get(\"fromMeForegroundColor\"),d=t.get(\"fromOtherBubbleColor\"),f=t.get(\"fromOtherForegroundColor\"),h=t.get(\"fromMeQuotedBubbleColor\"),m=t.get(\"fromOtherQuotedBubbleColor\"),g=t.get(\"inputBackgroundColor\"),x=t.get(\"inputTextForegroundColor\"),b=t.get(\"inputIconsMainColor\"),w=()=>n===\"dark\"?\"#0f0f0f\":\"#faf9fa\",C=()=>n===\"dark\"?\"#faf9fa\":\"#020202\",k=()=>n===\"dark\"?\"#0b332a\":\"#e0f0f0\",j=()=>n===\"dark\"?\"#0b332a\":\"#c8fff2\",M=()=>n===\"dark\"?\"#ffffff\":\"#020202\",_=()=>n===\"dark\"?\"#1d2724\":\"#e0f0f0\",R=()=>n===\"dark\"?\"#ffffff\":\"#020202\",N=()=>n===\"dark\"?\"#161616\":\"#e0f0f0\",O=()=>n===\"dark\"?\"#faf9fa\":\"#020202\",D=()=>n===\"dark\"?\"#1f463d\":\"#aff7e6\",z=()=>n===\"dark\"?\"#0f1413\":\"#d2e2e2\",Q=()=>n===\"dark\"?\"#0e6451\":\"#0b332a\";return i.jsx(GO.Provider,{value:{backgroundColor:r||w(),textForegroundColor:s||C(),primaryColor:o||k(),fromMeBubbleColor:l||j(),fromMeForegroundColor:u||M(),fromOtherBubbleColor:d||_(),fromOtherForegroundColor:f||R(),fromMeQuotedBubbleColor:h||D(),fromOtherQuotedBubbleColor:m||z(),inputBackgroundColor:g||N(),inputTextForegroundColor:x||O(),inputIconsMainColor:b||Q()},children:e})}const La=()=>y.useContext(GO),JO=({setSelectedMedia:e})=>{const{t}=Ve(),{inputIconsMainColor:n}=La(),r=y.useRef(null),s=y.useRef(null),[o,l]=y.useState(!1),u=m=>{const g=m.target.files?.[0];if(!g){e(null);return}const x=g.type.split(\"/\")[0],b=g.size/(1024*1024);switch(x){case\"audio\":if(b>16){me.error(t(\"chat.media.errors.audioSize\"));return}break;case\"image\":if(b>5){me.error(t(\"chat.media.errors.imageSize\"));return}break;case\"video\":if(b>16){me.error(t(\"chat.media.errors.videoSize\"));return}break;case\"application\":case\"text\":if(b>100){me.error(t(\"chat.media.errors.documentSize\"));return}break;default:me.error(t(\"chat.media.errors.unsupportedType\"));return}e(g)},d=m=>{m.preventDefault(),r.current&&r.current.click()},f=m=>{m.preventDefault(),s.current&&s.current.click()},h=[\"text/plain\",\"application/pdf\",\"application/msword\",\"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\"application/vnd.ms-excel\",\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\"application/vnd.ms-powerpoint\",\"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\"application/zip\",\"application/x-rar-compressed\",\"application/x-7z-compressed\"];return i.jsx(i.Fragment,{children:i.jsxs(Kr,{open:o,onOpenChange:l,children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{type:\"button\",variant:\"ghost\",size:\"icon\",className:\"rounded-full p-2\",children:[i.jsx(cs,{className:\"h-6 w-6\",style:{color:n}}),i.jsx(\"span\",{className:\"sr-only\",children:t(\"chat.media.attach\")})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(\"input\",{ref:s,type:\"file\",accept:h.join(\", \"),onChange:u,className:\"hidden\"}),i.jsxs(wt,{onClick:f,children:[i.jsx(rB,{className:\"mr-2 h-4 w-4\"}),t(\"chat.media.document\")]}),i.jsx(\"input\",{ref:r,type:\"file\",accept:\"image/*, video/*\",onChange:u,className:\"hidden\"}),i.jsxs(wt,{onClick:d,children:[i.jsx(uB,{className:\"mr-2 h-4 w-4\"}),t(\"chat.media.photosAndVideos\")]})]})]})})},QO=({selectedMedia:e,setSelectedMedia:t})=>{const{t:n}=Ve(),r=()=>{t(null)},s=l=>l.type.includes(\"image\")?i.jsx(\"img\",{className:\"w-80 rounded-lg\",src:URL.createObjectURL(l),alt:n(\"chat.media.selectedMedia.imageAlt\"),style:{maxHeight:\"400px\",objectFit:\"contain\"}}):l.type.includes(\"video\")?i.jsx(\"div\",{className:\"flex items-center justify-center\",children:i.jsx(\"video\",{className:\"w-80 rounded-lg object-cover\",src:URL.createObjectURL(l),controls:!0})}):i.jsx(\"div\",{className:\"flex items-center justify-center\",children:i.jsxs(\"span\",{className:\"flex items-center gap-2\",children:[i.jsx(Hb,{className:\"h-6 w-6\"}),n(\"chat.media.selectedMedia.file\")]})}),o=l=>{const u=[\"B\",\"KB\",\"MB\",\"GB\",\"TB\"];let d=0;for(;l>1024;)l/=1024,d++;return`${l.toFixed(2)} ${u[d]}`};return i.jsxs(\"div\",{className:\"relative flex items-center rounded-lg bg-[#e0f0f0] dark:bg-[#1d2724] dark:text-white\",children:[i.jsx(\"div\",{className:\"absolute h-full w-1 rounded-l-lg bg-blue-700 dark:bg-blue-300\"}),i.jsxs(\"div\",{className:\"flex w-full flex-col items-center justify-center gap-6 p-4 pl-4\",children:[e&&s(e),i.jsxs(\"div\",{className:\"flex flex-col items-center justify-center gap-2\",children:[i.jsx(\"span\",{className:\"text-sm font-medium\",children:e?.name||n(\"chat.media.selectedMedia.selectedFile\")}),i.jsx(\"span\",{className:\"text-xs text-gray-500\",children:o(e?.size||0)})]})]}),i.jsx(se,{size:\"icon\",variant:\"ghost\",className:\"ml-auto h-10 w-10 rounded-full\",onClick:r,children:i.jsx(qb,{className:\"h-6 w-6\"})})]})},XE=e=>{const t=new Date,n=new Date(t);n.setDate(n.getDate()-1);const r=new Date(e);return r.toDateString()===t.toDateString()?\"Hoje\":r.toDateString()===n.toDateString()?\"Ontem\":Math.floor((t.getTime()-r.getTime())/(1e3*60*60*24))<7?r.toLocaleDateString(\"pt-BR\",{weekday:\"long\"}):r.toLocaleDateString(\"pt-BR\",{day:\"2-digit\",month:\"2-digit\",year:\"numeric\"})},Yv=e=>{try{if(!e.messageTimestamp)return new Date;if(typeof e.messageTimestamp==\"object\"){const n=[e.messageTimestamp.low,e.messageTimestamp.seconds,e.messageTimestamp.timestamp,e.messageTimestamp.time,e.messageTimestamp.value].find(r=>typeof r==\"number\"&&!isNaN(r))||Date.now()/1e3;return new Date(n*1e3)}else if(isNaN(Number(e.messageTimestamp))){if(typeof e.messageTimestamp==\"string\"&&e.messageTimestamp.includes(\"T\"))return new Date(e.messageTimestamp)}else{const t=Number(e.messageTimestamp);return t>1e12?new Date(t):new Date(t*1e3)}return new Date}catch{return new Date}},cX=({date:e})=>i.jsx(\"div\",{className:\"flex items-center justify-center py-4\",children:i.jsx(\"div\",{className:\"rounded-full bg-muted px-3 py-1\",children:i.jsx(\"span\",{className:\"text-sm font-medium text-muted-foreground\",children:e})})}),uX=e=>{if(!e)return\"\";if(typeof e==\"string\")try{const t=JSON.parse(e);return t.conversation||t.text||e}catch{return e}return typeof e==\"object\"?e.conversation||e.text||\"\":String(e)},ek=({message:e})=>{const t=e.messageType;switch(t){case\"conversation\":if(e.message.contactMessage){const d=e.message.contactMessage;return i.jsxs(\"div\",{className:\"p-3 bg-muted rounded-lg max-w-xs\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2 mb-2\",children:[i.jsx(\"div\",{className:\"text-xl\",children:\"👤\"}),i.jsx(\"span\",{className:\"font-medium\",children:\"Contact\"})]}),d.displayName&&i.jsx(\"p\",{className:\"text-sm font-medium\",children:d.displayName}),d.vcard&&i.jsx(\"p\",{className:\"text-xs text-muted-foreground\",children:\"Contact card\"})]})}if(e.message.locationMessage){const d=e.message.locationMessage;return i.jsxs(\"div\",{className:\"p-3 bg-muted rounded-lg max-w-xs\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2 mb-2\",children:[i.jsx(\"div\",{className:\"text-xl\",children:\"📍\"}),i.jsx(\"span\",{className:\"font-medium\",children:\"Location\"})]}),d.name&&i.jsx(\"p\",{className:\"text-sm font-medium\",children:d.name}),d.address&&i.jsx(\"p\",{className:\"text-xs text-muted-foreground\",children:d.address}),d.degreesLatitude&&d.degreesLongitude&&i.jsx(\"a\",{href:`https://maps.google.com/?q=${d.degreesLatitude},${d.degreesLongitude}`,target:\"_blank\",rel:\"noopener noreferrer\",className:\"text-primary hover:underline text-sm mt-1 inline-block\",children:\"View on Maps\"})]})}return i.jsx(\"span\",{children:uX(e.message)});case\"extendedTextMessage\":return i.jsx(\"span\",{children:e.message.conversation??e.message.extendedTextMessage?.text});case\"imageMessage\":const r=(e.message.base64?e.message.base64.startsWith(\"data:\")?e.message.base64:`data:image/jpeg;base64,${e.message.base64}`:null)||e.message.mediaUrl;return i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[r?i.jsx(\"img\",{src:r,alt:\"Image\",className:\"rounded-lg max-w-full h-auto\",style:{maxWidth:\"400px\",maxHeight:\"400px\",objectFit:\"contain\"},loading:\"lazy\"}):i.jsxs(\"div\",{className:\"rounded bg-muted p-4 max-w-xs\",children:[i.jsx(\"p\",{className:\"text-center text-muted-foreground\",children:\"Image couldn't be loaded\"}),i.jsx(\"p\",{className:\"text-center text-xs text-muted-foreground mt-1\",children:\"Missing base64 data and mediaUrl\"})]}),e.message.imageMessage?.caption&&i.jsx(\"p\",{className:\"text-sm\",children:e.message.imageMessage.caption})]});case\"videoMessage\":const o=(e.message.base64?e.message.base64.startsWith(\"data:\")?e.message.base64:`data:video/mp4;base64,${e.message.base64}`:null)||e.message.mediaUrl;return i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[o?i.jsx(\"video\",{src:o,controls:!0,className:\"rounded-lg max-w-full h-auto\",style:{maxWidth:\"400px\",maxHeight:\"400px\"}}):i.jsxs(\"div\",{className:\"rounded bg-muted p-4 max-w-xs\",children:[i.jsx(\"p\",{className:\"text-center text-muted-foreground\",children:\"Video couldn't be loaded\"}),i.jsx(\"p\",{className:\"text-center text-xs text-muted-foreground mt-1\",children:\"Missing base64 data and mediaUrl\"})]}),e.message.videoMessage?.caption&&i.jsx(\"p\",{className:\"text-sm\",children:e.message.videoMessage.caption})]});case\"audioMessage\":const u=(e.message.base64?e.message.base64.startsWith(\"data:\")?e.message.base64:`data:audio/mpeg;base64,${e.message.base64}`:null)||e.message.mediaUrl;return u?i.jsxs(\"audio\",{controls:!0,className:\"w-full max-w-xs\",children:[i.jsx(\"source\",{src:u,type:\"audio/mpeg\"}),\"Your browser does not support the audio element.\"]}):i.jsxs(\"div\",{className:\"rounded bg-muted p-4 max-w-xs\",children:[i.jsx(\"p\",{className:\"text-center text-muted-foreground\",children:\"Audio couldn't be loaded\"}),i.jsx(\"p\",{className:\"text-center text-xs text-muted-foreground mt-1\",children:\"Missing base64 data and mediaUrl\"})]});case\"documentMessage\":return i.jsxs(\"div\",{className:\"flex items-center gap-2 p-3 bg-muted rounded-lg max-w-xs\",children:[i.jsx(\"div\",{className:\"text-2xl\",children:\"📄\"}),i.jsxs(\"div\",{className:\"flex-1 min-w-0\",children:[i.jsx(\"p\",{className:\"font-medium truncate\",children:e.message.documentMessage?.fileName||\"Document\"}),e.message.documentMessage?.fileLength&&i.jsxs(\"p\",{className:\"text-xs text-muted-foreground\",children:[(e.message.documentMessage.fileLength/1024/1024).toFixed(2),\" MB\"]})]})]});case\"stickerMessage\":return i.jsx(\"img\",{src:e.message.mediaUrl,alt:\"Sticker\",className:\"max-w-32 max-h-32 object-contain\"});default:return i.jsx(\"div\",{className:\"text-xs text-muted-foreground bg-muted p-2 rounded max-w-xs\",children:i.jsxs(\"details\",{children:[i.jsxs(\"summary\",{children:[\"Unknown message type: \",t]}),i.jsx(\"pre\",{className:\"mt-2 whitespace-pre-wrap break-all text-xs\",children:JSON.stringify(e.message,null,2)})]})})}};function ZO({textareaRef:e,handleTextareaChange:t,textareaHeight:n,lastMessageRef:r,scrollToBottom:s}){const{instance:o}=ct(),[l,u]=y.useState(\"\"),[d,f]=y.useState(!1),[h,m]=y.useState(null),[g,x]=y.useState([]),{sendText:b}=KO(),{sendMedia:w}=WO(),{remoteJid:C}=ls(),k=async()=>{if(!(!l.trim()||!C||!o?.name||!o?.token||d))try{f(!0),await b({instanceName:o.name,token:o.token,data:{number:C,text:l.trim()}}),u(\"\"),e.current&&(e.current.value=\"\",t())}catch(G){console.error(\"Error sending message:\",G)}finally{f(!1)}},j=async()=>{if(!(!h||!C||!o?.name||!o?.token||d))try{f(!0);const G=await new Promise((W,ie)=>{const re=new FileReader;re.readAsDataURL(h),re.onload=()=>{const H=re.result.split(\",\")[1];W(H)},re.onerror=ie});await w({instanceName:o.name,token:o.token,data:{number:C,mediaMessage:{mediatype:h.type.split(\"/\")[0]===\"application\"?\"document\":h.type.split(\"/\")[0],mimetype:h.type,caption:l.trim(),media:G,fileName:h.name}}}),m(null),u(\"\"),e.current&&(e.current.value=\"\",t())}catch(G){console.error(\"Error sending media:\",G)}finally{f(!1)}},M=async()=>{h?await j():await k()},_=G=>{G.key===\"Enter\"&&!G.shiftKey&&(G.preventDefault(),M())},R=G=>{u(G.target.value),t()},{data:N}=eX({remoteJid:C,instanceName:o?.name}),{data:O,isSuccess:D}=rX({remoteJid:C,instanceName:o?.name}),z=y.useMemo(()=>{if(!O)return g;const G=new Map;return O.forEach(W=>G.set(W.key.id,W)),g.forEach(W=>{G.set(W.key.id,W)}),Array.from(G.values())},[O,g]);y.useEffect(()=>{if(!o?.name||!C)return;const G=dr(jn.API_URL);if(!G){console.error(\"API URL not found in localStorage\");return}const W=sw(G),ie=(Y,H)=>{if(!o||H.instance!==o.name||H?.data?.key?.remoteJid!==C)return;const q=H.data;x(he=>{const A=he.findIndex(F=>F.key.id===q.key.id);if(A!==-1){const F=[...he];return F[A]=q,F}else return[...he,q]})},re=Y=>{o&&Y.instance===o.name&&console.log(\"Received message status update:\",Y)};return W.on(\"messages.upsert\",Y=>{ie(\"messages.upsert\",Y)}),W.on(\"send.message\",Y=>{ie(\"send.message\",Y)}),W.on(\"messages.update\",Y=>{re(Y)}),W.connect(),()=>{W.off(\"messages.upsert\"),W.off(\"send.message\"),W.off(\"messages.update\"),ow(W)}},[o?.name,C]);const Q=y.useMemo(()=>{if(!z)return[];const G=[...z].sort((Y,H)=>{const q=Yv(Y).getTime(),he=Yv(H).getTime();return q-he}),W=[];let ie=\"\",re=[];return G.forEach(Y=>{const q=Yv(Y).toDateString();q!==ie?(re.length>0&&W.push({date:XE(new Date(ie)),messages:re}),ie=q,re=[Y]):re.push(Y)}),re.length>0&&W.push({date:XE(new Date(ie)),messages:re}),W},[z]);y.useEffect(()=>{D&&z&&s()},[D,z,s]),y.useEffect(()=>{m(null),u(\"\"),x([]),e.current&&(e.current.value=\"\",t())},[C]);const pe=G=>i.jsx(\"div\",{className:\"bubble-right\",children:i.jsx(\"div\",{className:\"flex items-start gap-4 self-end\",children:i.jsx(\"div\",{className:\"grid gap-1\",children:i.jsx(\"div\",{className:\"bubble\",children:i.jsx(ek,{message:G})})})})},G.id),V=G=>i.jsx(\"div\",{className:\"bubble-left\",children:i.jsx(\"div\",{className:\"flex items-start gap-4\",children:i.jsx(\"div\",{className:\"grid gap-1\",children:i.jsx(\"div\",{className:\"bubble\",children:i.jsx(ek,{message:G})})})})},G.id);return i.jsxs(\"div\",{className:\"flex h-full flex-col\",children:[i.jsx(\"div\",{className:\"sticky top-0 bg-background border-b border-border p-3\",children:i.jsxs(\"div\",{className:\"flex items-center gap-3\",children:[i.jsxs(Ei,{className:\"h-10 w-10\",children:[i.jsx(ki,{src:N?.profilePicUrl,alt:N?.pushName||N?.remoteJid?.split(\"@\")[0]}),i.jsx(Up,{className:\"bg-slate-700 text-slate-300 border border-slate-600\",children:i.jsx(Ap,{className:\"h-5 w-5\"})})]}),i.jsxs(\"div\",{className:\"flex-1 min-w-0\",children:[i.jsx(\"div\",{className:\"font-medium text-sm truncate\",children:N?.pushName||N?.remoteJid?.split(\"@\")[0]}),i.jsx(\"div\",{className:\"text-xs text-muted-foreground truncate\",children:N?.remoteJid?.split(\"@\")[0]})]}),i.jsxs(dx,{children:[i.jsx(fx,{asChild:!0,children:i.jsx(se,{variant:\"ghost\",size:\"sm\",className:\"h-8 w-8 p-0\",children:i.jsx(Nh,{className:\"h-4 w-4\"})})}),i.jsxs(hr,{align:\"start\",className:\"max-w-[300px]\",children:[i.jsxs(wt,{className:\"items-start gap-2\",children:[i.jsx(wB,{className:\"mr-2 h-4 w-4 shrink-0 translate-y-1\"}),i.jsxs(\"div\",{children:[i.jsx(\"div\",{className:\"font-medium\",children:\"GPT-4\"}),i.jsx(\"div\",{className:\"text-muted-foreground/80\",children:\"With DALL-E, browsing and analysis. Limit 40 messages / 3 hours\"})]})]}),i.jsx(Xs,{}),i.jsxs(wt,{className:\"items-start gap-2\",children:[i.jsx(mT,{className:\"mr-2 h-4 w-4 shrink-0 translate-y-1\"}),i.jsxs(\"div\",{children:[i.jsx(\"div\",{className:\"font-medium\",children:\"GPT-3\"}),i.jsx(\"div\",{className:\"text-muted-foreground/80\",children:\"Great for everyday tasks\"})]})]})]})]})]})}),i.jsxs(\"div\",{className:\"message-container mx-auto flex max-w-4xl flex-1 flex-col gap-2 overflow-y-auto px-2\",children:[Q.map((G,W)=>i.jsxs(\"div\",{children:[i.jsx(cX,{date:G.date}),i.jsx(\"div\",{className:\"flex flex-col gap-2\",children:G.messages.map(ie=>ie.key.fromMe?pe(ie):V(ie))})]},W)),i.jsx(\"div\",{ref:r})]}),i.jsxs(\"div\",{className:\"sticky bottom-0 mx-auto flex w-full max-w-2xl flex-col gap-1.5 bg-background px-2 py-2\",children:[h&&i.jsx(QO,{selectedMedia:h,setSelectedMedia:m}),i.jsxs(\"div\",{className:\"flex items-center rounded-3xl border border-border bg-background px-2 py-1\",children:[o&&i.jsx(JO,{instance:o,setSelectedMedia:m}),i.jsx(bi,{placeholder:\"Enviar mensagem...\",name:\"message\",id:\"message\",rows:1,ref:e,value:l,onChange:R,onKeyDown:_,disabled:d,style:{height:n},className:\"min-h-0 w-full resize-none border-none p-3 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 focus-visible:ring-offset-transparent\"}),i.jsxs(se,{type:\"button\",size:\"icon\",onClick:M,disabled:!l.trim()&&!h||d,className:\"rounded-full p-2 disabled:opacity-50\",children:[i.jsx(Th,{className:\"h-6 w-6\"}),i.jsx(\"span\",{className:\"sr-only\",children:\"Enviar\"})]})]})]})]})}const dX=e=>e.split(\"@\")[0];function tk(){const e=zo(\"(min-width: 768px)\"),t=y.useRef(null),[n]=y.useState(\"auto\"),r=y.useRef(null),{instance:s}=ct(),[o,l]=y.useState([]),{data:u,isSuccess:d}=sY({instanceName:s?.name}),f=qe.useMemo(()=>{if(!u)return o;const C=new Map;return u.forEach(k=>C.set(k.remoteJid,k)),o.forEach(k=>{const j=C.get(k.remoteJid);j?C.set(k.remoteJid,{...j,...k}):C.set(k.remoteJid,k)}),Array.from(C.values())},[u,o]),{instanceId:h,remoteJid:m}=ls(),g=dn();y.useEffect(()=>{if(!s?.name)return;const C=dr(jn.API_URL);if(!C){console.error(\"API URL not found in localStorage\");return}const k=sw(C),j=(M,_)=>{if(!s||_.instance!==s.name)return;const R=_?.data?.key?.remoteJid;R&&l(N=>{const O=N.findIndex(z=>z.remoteJid===R),D={id:R,remoteJid:R,pushName:_?.data?.pushName||dX(R),profilePicUrl:_?.data?.key?.profilePictureUrl||\"\",..._?.data};if(O!==-1){const z=[...N];return z[O]={...z[O],...D},z}else return[...N,D]})};return k.on(\"messages.upsert\",M=>{j(\"messages.upsert\",M)}),k.on(\"send.message\",M=>{j(\"send.message\",M)}),k.connect(),()=>{k.off(\"messages.upsert\"),k.off(\"send.message\"),ow(k)}},[s?.name]);const x=y.useCallback(()=>{t.current&&t.current.scrollIntoView({})},[]),b=()=>{if(r.current){r.current.style.height=\"auto\";const C=r.current.scrollHeight,j=parseInt(getComputedStyle(r.current).lineHeight)*10;r.current.style.height=`${Math.min(C,j)}px`}};y.useEffect(()=>{d&&x()},[d,x]);const w=C=>{g(`/manager/instance/${h}/chat/${C}`)};return i.jsx(\"div\",{className:\"h-[calc(100vh-160px)] overflow-hidden\",children:i.jsxs($o,{direction:e?\"horizontal\":\"vertical\",className:\"h-full\",children:[i.jsx(Hn,{defaultSize:20,children:i.jsxs(\"div\",{className:\"hidden h-full flex-col bg-background text-foreground md:flex\",children:[i.jsx(\"div\",{className:\"flex-shrink-0 p-2\",children:i.jsxs(se,{variant:\"ghost\",className:\"w-full justify-start gap-2 px-2 text-left\",children:[i.jsx(\"div\",{className:\"flex h-7 w-7 items-center justify-center rounded-full\",children:i.jsx(Bl,{className:\"h-4 w-4\"})}),i.jsx(\"div\",{className:\"grow overflow-hidden text-ellipsis whitespace-nowrap text-sm\",children:\"Chat\"}),i.jsx(cs,{className:\"h-4 w-4\"})]})}),i.jsxs(Yx,{defaultValue:\"contacts\",className:\"flex flex-col flex-1 min-h-0\",children:[i.jsxs(hg,{className:\"tabs-chat flex-shrink-0\",children:[i.jsx(Jl,{value:\"contacts\",children:\"Contatos\"}),i.jsx(Jl,{value:\"groups\",children:\"Grupos\"})]}),i.jsx(Ql,{value:\"contacts\",className:\"flex-1 overflow-hidden\",children:i.jsx(\"div\",{className:\"h-full overflow-auto\",children:i.jsxs(\"div\",{className:\"grid gap-1 p-2 text-foreground\",children:[i.jsx(\"div\",{className:\"px-2 text-xs font-medium text-muted-foreground\",children:\"Contatos\"}),u?.map(C=>C.remoteJid.includes(\"@s.whatsapp.net\")&&i.jsxs(Fu,{to:\"#\",onClick:()=>w(C.remoteJid),className:`chat-item flex items-center overflow-hidden truncate whitespace-nowrap rounded-md border-b border-gray-600/50 p-2 text-sm transition-colors hover:bg-muted/50 ${m===C.remoteJid?\"active\":\"\"}`,children:[i.jsx(\"span\",{className:\"chat-avatar mr-2\",children:i.jsxs(Ei,{className:\"h-8 w-8\",children:[i.jsx(ki,{src:C.profilePicUrl,alt:C.pushName||C.remoteJid.split(\"@\")[0]}),i.jsx(Up,{className:\"bg-slate-700 text-slate-300 border border-slate-600\",children:i.jsx(Ap,{className:\"h-5 w-5\"})})]})}),i.jsxs(\"div\",{className:\"min-w-0 flex-1\",children:[i.jsx(\"span\",{className:\"chat-title block font-medium\",children:C.pushName||C.remoteJid.split(\"@\")[0]}),i.jsx(\"span\",{className:\"chat-description block text-xs text-gray-500\",children:C.remoteJid.split(\"@\")[0]})]})]},C.id))]})})}),i.jsx(Ql,{value:\"groups\",className:\"flex-1 overflow-hidden\",children:i.jsx(\"div\",{className:\"h-full overflow-auto\",children:i.jsx(\"div\",{className:\"grid gap-1 p-2 text-foreground\",children:f?.map(C=>C.remoteJid.includes(\"@g.us\")&&i.jsxs(Fu,{to:\"#\",onClick:()=>w(C.remoteJid),className:`chat-item flex items-center overflow-hidden truncate whitespace-nowrap rounded-md border-b border-gray-600/50 p-2 text-sm transition-colors hover:bg-muted/50 ${m===C.remoteJid?\"active\":\"\"}`,children:[i.jsx(\"span\",{className:\"chat-avatar mr-2\",children:i.jsxs(Ei,{className:\"h-8 w-8\",children:[i.jsx(ki,{src:C.profilePicUrl,alt:C.pushName||C.remoteJid.split(\"@\")[0]}),i.jsx(Up,{className:\"bg-slate-700 text-slate-300 border border-slate-600\",children:i.jsx(Ap,{className:\"h-5 w-5\"})})]})}),i.jsxs(\"div\",{className:\"min-w-0 flex-1\",children:[i.jsx(\"span\",{className:\"chat-title block font-medium\",children:C.pushName||C.remoteJid.split(\"@\")[0]}),i.jsx(\"span\",{className:\"chat-description block text-xs text-gray-500\",children:C.remoteJid})]})]},C.id))})})})]})]})}),i.jsx(Bo,{withHandle:!0,className:\"border border-black\"}),i.jsx(Hn,{children:m&&i.jsx(ZO,{textareaRef:r,handleTextareaChange:b,textareaHeight:n,lastMessageRef:t,scrollToBottom:x})})]})})}const fX=e=>[\"chatwoot\",\"fetchChatwoot\",JSON.stringify(e)],pX=async({instanceName:e,token:t})=>(await Ee.get(`/chatwoot/find/${e}`,{headers:{apiKey:t}})).data,hX=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:fX({instanceName:t,token:n}),queryFn:()=>pX({instanceName:t,token:n}),enabled:!!t})},gX=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/chatwoot/set/${e}`,n,{headers:{apikey:t}})).data;function mX(){return{createChatwoot:nt(gX,{invalidateKeys:[[\"chatwoot\",\"fetchChatwoot\"]]})}}const rp=P.string().optional().transform(e=>e===\"\"?void 0:e),vX=P.object({enabled:P.boolean(),accountId:P.string(),token:P.string(),url:P.string(),signMsg:P.boolean().optional(),signDelimiter:rp,nameInbox:rp,organization:rp,logo:rp,reopenConversation:P.boolean().optional(),conversationPending:P.boolean().optional(),mergeBrazilContacts:P.boolean().optional(),importContacts:P.boolean().optional(),importMessages:P.boolean().optional(),daysLimitImportMessages:P.coerce.number().optional(),autoCreate:P.boolean(),ignoreJids:P.array(P.string()).default([])});function yX(){const{t:e}=Ve(),{instance:t}=ct(),[,n]=y.useState(!1),{createChatwoot:r}=mX(),{data:s}=hX({instanceName:t?.name,token:t?.token}),o=on({resolver:an(vX),defaultValues:{enabled:!0,accountId:\"\",token:\"\",url:\"\",signMsg:!0,signDelimiter:\"\\\\n\",nameInbox:\"\",organization:\"\",logo:\"\",reopenConversation:!0,conversationPending:!1,mergeBrazilContacts:!0,importContacts:!1,importMessages:!1,daysLimitImportMessages:7,autoCreate:!0,ignoreJids:[]}});y.useEffect(()=>{if(s){o.setValue(\"ignoreJids\",s.ignoreJids||[]);const u={enabled:s.enabled,accountId:s.accountId,token:s.token,url:s.url,signMsg:s.signMsg||!1,signDelimiter:s.signDelimiter||\"\\\\n\",nameInbox:s.nameInbox||\"\",organization:s.organization||\"\",logo:s.logo||\"\",reopenConversation:s.reopenConversation||!1,conversationPending:s.conversationPending||!1,mergeBrazilContacts:s.mergeBrazilContacts||!1,importContacts:s.importContacts||!1,importMessages:s.importMessages||!1,daysLimitImportMessages:s.daysLimitImportMessages||7,autoCreate:s.autoCreate||!1,ignoreJids:s.ignoreJids};o.reset(u)}},[s,o]);const l=async u=>{if(!t)return;n(!0);const d={enabled:u.enabled,accountId:u.accountId,token:u.token,url:u.url,signMsg:u.signMsg||!1,signDelimiter:u.signDelimiter||\"\\\\n\",nameInbox:u.nameInbox||\"\",organization:u.organization||\"\",logo:u.logo||\"\",reopenConversation:u.reopenConversation||!1,conversationPending:u.conversationPending||!1,mergeBrazilContacts:u.mergeBrazilContacts||!1,importContacts:u.importContacts||!1,importMessages:u.importMessages||!1,daysLimitImportMessages:u.daysLimitImportMessages||7,autoCreate:u.autoCreate,ignoreJids:u.ignoreJids};await r({instanceName:t.name,token:t.token,data:d},{onSuccess:()=>{me.success(e(\"chatwoot.toast.success\"))},onError:f=>{console.error(e(\"chatwoot.toast.error\"),f),rT(f)?me.error(`Error: ${f?.response?.data?.response?.message}`):me.error(e(\"chatwoot.toast.error\"))},onSettled:()=>{n(!1)}})};return i.jsx(i.Fragment,{children:i.jsx(Fo,{...o,children:i.jsxs(\"form\",{onSubmit:o.handleSubmit(l),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"chatwoot.title\")}),i.jsx(Oa,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y [&>*]:px-4 [&>*]:py-2\",children:[i.jsx(Pe,{name:\"enabled\",label:e(\"chatwoot.form.enabled.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.enabled.description\")}),i.jsx(le,{name:\"url\",label:e(\"chatwoot.form.url.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"accountId\",label:e(\"chatwoot.form.accountId.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"token\",label:e(\"chatwoot.form.token.label\"),children:i.jsx(ne,{type:\"password\"})}),i.jsx(Pe,{name:\"signMsg\",label:e(\"chatwoot.form.signMsg.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.signMsg.description\")}),i.jsx(le,{name:\"signDelimiter\",label:e(\"chatwoot.form.signDelimiter.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"nameInbox\",label:e(\"chatwoot.form.nameInbox.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"organization\",label:e(\"chatwoot.form.organization.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"logo\",label:e(\"chatwoot.form.logo.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"conversationPending\",label:e(\"chatwoot.form.conversationPending.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.conversationPending.description\")}),i.jsx(Pe,{name:\"reopenConversation\",label:e(\"chatwoot.form.reopenConversation.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.reopenConversation.description\")}),i.jsx(Pe,{name:\"importContacts\",label:e(\"chatwoot.form.importContacts.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.importContacts.description\")}),i.jsx(Pe,{name:\"importMessages\",label:e(\"chatwoot.form.importMessages.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.importMessages.description\")}),i.jsx(le,{name:\"daysLimitImportMessages\",label:e(\"chatwoot.form.daysLimitImportMessages.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"chatwoot.form.ignoreJids.label\"),placeholder:e(\"chatwoot.form.ignoreJids.placeholder\")}),i.jsx(Pe,{name:\"autoCreate\",label:e(\"chatwoot.form.autoCreate.label\"),className:\"w-full justify-between\",helper:e(\"chatwoot.form.autoCreate.description\")})]})]}),i.jsx(\"div\",{className:\"mx-4 flex justify-end\",children:i.jsx(se,{type:\"submit\",children:e(\"chatwoot.button.save\")})})]})})})}var wl={},Xv={exports:{}},ey,nk;function bX(){if(nk)return ey;nk=1;var e=\"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED\";return ey=e,ey}var ty,rk;function xX(){if(rk)return ty;rk=1;var e=bX();function t(){}function n(){}return n.resetWarningCache=t,ty=function(){function r(l,u,d,f,h,m){if(m!==e){var g=new Error(\"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types\");throw g.name=\"Invariant Violation\",g}}r.isRequired=r;function s(){return r}var o={array:r,bigint:r,bool:r,func:r,number:r,object:r,string:r,symbol:r,any:r,arrayOf:s,element:r,elementType:r,instanceOf:s,node:r,objectOf:s,oneOf:s,oneOfType:s,shape:s,exact:s,checkPropTypes:n,resetWarningCache:t};return o.PropTypes=o,o},ty}var sk;function YO(){return sk||(sk=1,Xv.exports=xX()()),Xv.exports}var ny,ok;function XO(){return ok||(ok=1,ny={L:1,M:0,Q:3,H:2}),ny}var ry,ak;function eI(){return ak||(ak=1,ry={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8}),ry}var sy,ik;function wX(){if(ik)return sy;ik=1;var e=eI();function t(n){this.mode=e.MODE_8BIT_BYTE,this.data=n}return t.prototype={getLength:function(n){return this.data.length},write:function(n){for(var r=0;r<this.data.length;r++)n.put(this.data.charCodeAt(r),8)}},sy=t,sy}var oy,lk;function SX(){if(lk)return oy;lk=1;var e=XO();function t(n,r){this.totalCount=n,this.dataCount=r}return t.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],t.getRSBlocks=function(n,r){var s=t.getRsBlockTable(n,r);if(s==null)throw new Error(\"bad rs block @ typeNumber:\"+n+\"/errorCorrectLevel:\"+r);for(var o=s.length/3,l=new Array,u=0;u<o;u++)for(var d=s[u*3+0],f=s[u*3+1],h=s[u*3+2],m=0;m<d;m++)l.push(new t(f,h));return l},t.getRsBlockTable=function(n,r){switch(r){case e.L:return t.RS_BLOCK_TABLE[(n-1)*4+0];case e.M:return t.RS_BLOCK_TABLE[(n-1)*4+1];case e.Q:return t.RS_BLOCK_TABLE[(n-1)*4+2];case e.H:return t.RS_BLOCK_TABLE[(n-1)*4+3];default:return}},oy=t,oy}var ay,ck;function CX(){if(ck)return ay;ck=1;function e(){this.buffer=new Array,this.length=0}return e.prototype={get:function(t){var n=Math.floor(t/8);return(this.buffer[n]>>>7-t%8&1)==1},put:function(t,n){for(var r=0;r<n;r++)this.putBit((t>>>n-r-1&1)==1)},getLengthInBits:function(){return this.length},putBit:function(t){var n=Math.floor(this.length/8);this.buffer.length<=n&&this.buffer.push(0),t&&(this.buffer[n]|=128>>>this.length%8),this.length++}},ay=e,ay}var iy,uk;function tI(){if(uk)return iy;uk=1;for(var e={glog:function(n){if(n<1)throw new Error(\"glog(\"+n+\")\");return e.LOG_TABLE[n]},gexp:function(n){for(;n<0;)n+=255;for(;n>=256;)n-=255;return e.EXP_TABLE[n]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},t=0;t<8;t++)e.EXP_TABLE[t]=1<<t;for(var t=8;t<256;t++)e.EXP_TABLE[t]=e.EXP_TABLE[t-4]^e.EXP_TABLE[t-5]^e.EXP_TABLE[t-6]^e.EXP_TABLE[t-8];for(var t=0;t<255;t++)e.LOG_TABLE[e.EXP_TABLE[t]]=t;return iy=e,iy}var ly,dk;function nI(){if(dk)return ly;dk=1;var e=tI();function t(n,r){if(n.length==null)throw new Error(n.length+\"/\"+r);for(var s=0;s<n.length&&n[s]==0;)s++;this.num=new Array(n.length-s+r);for(var o=0;o<n.length-s;o++)this.num[o]=n[o+s]}return t.prototype={get:function(n){return this.num[n]},getLength:function(){return this.num.length},multiply:function(n){for(var r=new Array(this.getLength()+n.getLength()-1),s=0;s<this.getLength();s++)for(var o=0;o<n.getLength();o++)r[s+o]^=e.gexp(e.glog(this.get(s))+e.glog(n.get(o)));return new t(r,0)},mod:function(n){if(this.getLength()-n.getLength()<0)return this;for(var r=e.glog(this.get(0))-e.glog(n.get(0)),s=new Array(this.getLength()),o=0;o<this.getLength();o++)s[o]=this.get(o);for(var o=0;o<n.getLength();o++)s[o]^=e.gexp(e.glog(n.get(o))+r);return new t(s,0).mod(n)}},ly=t,ly}var cy,fk;function EX(){if(fk)return cy;fk=1;var e=eI(),t=nI(),n=tI(),r={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},s={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(o){for(var l=o<<10;s.getBCHDigit(l)-s.getBCHDigit(s.G15)>=0;)l^=s.G15<<s.getBCHDigit(l)-s.getBCHDigit(s.G15);return(o<<10|l)^s.G15_MASK},getBCHTypeNumber:function(o){for(var l=o<<12;s.getBCHDigit(l)-s.getBCHDigit(s.G18)>=0;)l^=s.G18<<s.getBCHDigit(l)-s.getBCHDigit(s.G18);return o<<12|l},getBCHDigit:function(o){for(var l=0;o!=0;)l++,o>>>=1;return l},getPatternPosition:function(o){return s.PATTERN_POSITION_TABLE[o-1]},getMask:function(o,l,u){switch(o){case r.PATTERN000:return(l+u)%2==0;case r.PATTERN001:return l%2==0;case r.PATTERN010:return u%3==0;case r.PATTERN011:return(l+u)%3==0;case r.PATTERN100:return(Math.floor(l/2)+Math.floor(u/3))%2==0;case r.PATTERN101:return l*u%2+l*u%3==0;case r.PATTERN110:return(l*u%2+l*u%3)%2==0;case r.PATTERN111:return(l*u%3+(l+u)%2)%2==0;default:throw new Error(\"bad maskPattern:\"+o)}},getErrorCorrectPolynomial:function(o){for(var l=new t([1],0),u=0;u<o;u++)l=l.multiply(new t([1,n.gexp(u)],0));return l},getLengthInBits:function(o,l){if(1<=l&&l<10)switch(o){case e.MODE_NUMBER:return 10;case e.MODE_ALPHA_NUM:return 9;case e.MODE_8BIT_BYTE:return 8;case e.MODE_KANJI:return 8;default:throw new Error(\"mode:\"+o)}else if(l<27)switch(o){case e.MODE_NUMBER:return 12;case e.MODE_ALPHA_NUM:return 11;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 10;default:throw new Error(\"mode:\"+o)}else if(l<41)switch(o){case e.MODE_NUMBER:return 14;case e.MODE_ALPHA_NUM:return 13;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 12;default:throw new Error(\"mode:\"+o)}else throw new Error(\"type:\"+l)},getLostPoint:function(o){for(var l=o.getModuleCount(),u=0,d=0;d<l;d++)for(var f=0;f<l;f++){for(var h=0,m=o.isDark(d,f),g=-1;g<=1;g++)if(!(d+g<0||l<=d+g))for(var x=-1;x<=1;x++)f+x<0||l<=f+x||g==0&&x==0||m==o.isDark(d+g,f+x)&&h++;h>5&&(u+=3+h-5)}for(var d=0;d<l-1;d++)for(var f=0;f<l-1;f++){var b=0;o.isDark(d,f)&&b++,o.isDark(d+1,f)&&b++,o.isDark(d,f+1)&&b++,o.isDark(d+1,f+1)&&b++,(b==0||b==4)&&(u+=3)}for(var d=0;d<l;d++)for(var f=0;f<l-6;f++)o.isDark(d,f)&&!o.isDark(d,f+1)&&o.isDark(d,f+2)&&o.isDark(d,f+3)&&o.isDark(d,f+4)&&!o.isDark(d,f+5)&&o.isDark(d,f+6)&&(u+=40);for(var f=0;f<l;f++)for(var d=0;d<l-6;d++)o.isDark(d,f)&&!o.isDark(d+1,f)&&o.isDark(d+2,f)&&o.isDark(d+3,f)&&o.isDark(d+4,f)&&!o.isDark(d+5,f)&&o.isDark(d+6,f)&&(u+=40);for(var w=0,f=0;f<l;f++)for(var d=0;d<l;d++)o.isDark(d,f)&&w++;var C=Math.abs(100*w/l/l-50)/5;return u+=C*10,u}};return cy=s,cy}var uy,pk;function kX(){if(pk)return uy;pk=1;var e=wX(),t=SX(),n=CX(),r=EX(),s=nI();function o(u,d){this.typeNumber=u,this.errorCorrectLevel=d,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}var l=o.prototype;return l.addData=function(u){var d=new e(u);this.dataList.push(d),this.dataCache=null},l.isDark=function(u,d){if(u<0||this.moduleCount<=u||d<0||this.moduleCount<=d)throw new Error(u+\",\"+d);return this.modules[u][d]},l.getModuleCount=function(){return this.moduleCount},l.make=function(){if(this.typeNumber<1){var u=1;for(u=1;u<40;u++){for(var d=t.getRSBlocks(u,this.errorCorrectLevel),f=new n,h=0,m=0;m<d.length;m++)h+=d[m].dataCount;for(var m=0;m<this.dataList.length;m++){var g=this.dataList[m];f.put(g.mode,4),f.put(g.getLength(),r.getLengthInBits(g.mode,u)),g.write(f)}if(f.getLengthInBits()<=h*8)break}this.typeNumber=u}this.makeImpl(!1,this.getBestMaskPattern())},l.makeImpl=function(u,d){this.moduleCount=this.typeNumber*4+17,this.modules=new Array(this.moduleCount);for(var f=0;f<this.moduleCount;f++){this.modules[f]=new Array(this.moduleCount);for(var h=0;h<this.moduleCount;h++)this.modules[f][h]=null}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(u,d),this.typeNumber>=7&&this.setupTypeNumber(u),this.dataCache==null&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,d)},l.setupPositionProbePattern=function(u,d){for(var f=-1;f<=7;f++)if(!(u+f<=-1||this.moduleCount<=u+f))for(var h=-1;h<=7;h++)d+h<=-1||this.moduleCount<=d+h||(0<=f&&f<=6&&(h==0||h==6)||0<=h&&h<=6&&(f==0||f==6)||2<=f&&f<=4&&2<=h&&h<=4?this.modules[u+f][d+h]=!0:this.modules[u+f][d+h]=!1)},l.getBestMaskPattern=function(){for(var u=0,d=0,f=0;f<8;f++){this.makeImpl(!0,f);var h=r.getLostPoint(this);(f==0||u>h)&&(u=h,d=f)}return d},l.createMovieClip=function(u,d,f){var h=u.createEmptyMovieClip(d,f),m=1;this.make();for(var g=0;g<this.modules.length;g++)for(var x=g*m,b=0;b<this.modules[g].length;b++){var w=b*m,C=this.modules[g][b];C&&(h.beginFill(0,100),h.moveTo(w,x),h.lineTo(w+m,x),h.lineTo(w+m,x+m),h.lineTo(w,x+m),h.endFill())}return h},l.setupTimingPattern=function(){for(var u=8;u<this.moduleCount-8;u++)this.modules[u][6]==null&&(this.modules[u][6]=u%2==0);for(var d=8;d<this.moduleCount-8;d++)this.modules[6][d]==null&&(this.modules[6][d]=d%2==0)},l.setupPositionAdjustPattern=function(){for(var u=r.getPatternPosition(this.typeNumber),d=0;d<u.length;d++)for(var f=0;f<u.length;f++){var h=u[d],m=u[f];if(this.modules[h][m]==null)for(var g=-2;g<=2;g++)for(var x=-2;x<=2;x++)g==-2||g==2||x==-2||x==2||g==0&&x==0?this.modules[h+g][m+x]=!0:this.modules[h+g][m+x]=!1}},l.setupTypeNumber=function(u){for(var d=r.getBCHTypeNumber(this.typeNumber),f=0;f<18;f++){var h=!u&&(d>>f&1)==1;this.modules[Math.floor(f/3)][f%3+this.moduleCount-8-3]=h}for(var f=0;f<18;f++){var h=!u&&(d>>f&1)==1;this.modules[f%3+this.moduleCount-8-3][Math.floor(f/3)]=h}},l.setupTypeInfo=function(u,d){for(var f=this.errorCorrectLevel<<3|d,h=r.getBCHTypeInfo(f),m=0;m<15;m++){var g=!u&&(h>>m&1)==1;m<6?this.modules[m][8]=g:m<8?this.modules[m+1][8]=g:this.modules[this.moduleCount-15+m][8]=g}for(var m=0;m<15;m++){var g=!u&&(h>>m&1)==1;m<8?this.modules[8][this.moduleCount-m-1]=g:m<9?this.modules[8][15-m-1+1]=g:this.modules[8][15-m-1]=g}this.modules[this.moduleCount-8][8]=!u},l.mapData=function(u,d){for(var f=-1,h=this.moduleCount-1,m=7,g=0,x=this.moduleCount-1;x>0;x-=2)for(x==6&&x--;;){for(var b=0;b<2;b++)if(this.modules[h][x-b]==null){var w=!1;g<u.length&&(w=(u[g]>>>m&1)==1);var C=r.getMask(d,h,x-b);C&&(w=!w),this.modules[h][x-b]=w,m--,m==-1&&(g++,m=7)}if(h+=f,h<0||this.moduleCount<=h){h-=f,f=-f;break}}},o.PAD0=236,o.PAD1=17,o.createData=function(u,d,f){for(var h=t.getRSBlocks(u,d),m=new n,g=0;g<f.length;g++){var x=f[g];m.put(x.mode,4),m.put(x.getLength(),r.getLengthInBits(x.mode,u)),x.write(m)}for(var b=0,g=0;g<h.length;g++)b+=h[g].dataCount;if(m.getLengthInBits()>b*8)throw new Error(\"code length overflow. (\"+m.getLengthInBits()+\">\"+b*8+\")\");for(m.getLengthInBits()+4<=b*8&&m.put(0,4);m.getLengthInBits()%8!=0;)m.putBit(!1);for(;!(m.getLengthInBits()>=b*8||(m.put(o.PAD0,8),m.getLengthInBits()>=b*8));)m.put(o.PAD1,8);return o.createBytes(m,h)},o.createBytes=function(u,d){for(var f=0,h=0,m=0,g=new Array(d.length),x=new Array(d.length),b=0;b<d.length;b++){var w=d[b].dataCount,C=d[b].totalCount-w;h=Math.max(h,w),m=Math.max(m,C),g[b]=new Array(w);for(var k=0;k<g[b].length;k++)g[b][k]=255&u.buffer[k+f];f+=w;var j=r.getErrorCorrectPolynomial(C),M=new s(g[b],j.getLength()-1),_=M.mod(j);x[b]=new Array(j.getLength()-1);for(var k=0;k<x[b].length;k++){var R=k+_.getLength()-x[b].length;x[b][k]=R>=0?_.get(R):0}}for(var N=0,k=0;k<d.length;k++)N+=d[k].totalCount;for(var O=new Array(N),D=0,k=0;k<h;k++)for(var b=0;b<d.length;b++)k<g[b].length&&(O[D++]=g[b][k]);for(var k=0;k<m;k++)for(var b=0;b<d.length;b++)k<x[b].length&&(O[D++]=x[b][k]);return O},uy=o,uy}var sp={},hk;function jX(){if(hk)return sp;hk=1,Object.defineProperty(sp,\"__esModule\",{value:!0});var e=Object.assign||function(f){for(var h=1;h<arguments.length;h++){var m=arguments[h];for(var g in m)Object.prototype.hasOwnProperty.call(m,g)&&(f[g]=m[g])}return f},t=YO(),n=o(t),r=pd(),s=o(r);function o(f){return f&&f.__esModule?f:{default:f}}function l(f,h){var m={};for(var g in f)h.indexOf(g)>=0||Object.prototype.hasOwnProperty.call(f,g)&&(m[g]=f[g]);return m}var u={bgColor:n.default.oneOfType([n.default.object,n.default.string]).isRequired,bgD:n.default.string.isRequired,fgColor:n.default.oneOfType([n.default.object,n.default.string]).isRequired,fgD:n.default.string.isRequired,size:n.default.number.isRequired,title:n.default.string,viewBoxSize:n.default.number.isRequired,xmlns:n.default.string},d=(0,r.forwardRef)(function(f,h){var m=f.bgColor,g=f.bgD,x=f.fgD,b=f.fgColor,w=f.size,C=f.title,k=f.viewBoxSize,j=f.xmlns,M=j===void 0?\"http://www.w3.org/2000/svg\":j,_=l(f,[\"bgColor\",\"bgD\",\"fgD\",\"fgColor\",\"size\",\"title\",\"viewBoxSize\",\"xmlns\"]);return s.default.createElement(\"svg\",e({},_,{height:w,ref:h,viewBox:\"0 0 \"+k+\" \"+k,width:w,xmlns:M}),C?s.default.createElement(\"title\",null,C):null,s.default.createElement(\"path\",{d:g,fill:m}),s.default.createElement(\"path\",{d:x,fill:b}))});return d.displayName=\"QRCodeSvg\",d.propTypes=u,sp.default=d,sp}var gk;function TX(){if(gk)return wl;gk=1,Object.defineProperty(wl,\"__esModule\",{value:!0}),wl.QRCode=void 0;var e=Object.assign||function(w){for(var C=1;C<arguments.length;C++){var k=arguments[C];for(var j in k)Object.prototype.hasOwnProperty.call(k,j)&&(w[j]=k[j])}return w},t=YO(),n=m(t),r=XO(),s=m(r),o=kX(),l=m(o),u=pd(),d=m(u),f=jX(),h=m(f);function m(w){return w&&w.__esModule?w:{default:w}}function g(w,C){var k={};for(var j in w)C.indexOf(j)>=0||Object.prototype.hasOwnProperty.call(w,j)&&(k[j]=w[j]);return k}var x={bgColor:n.default.oneOfType([n.default.object,n.default.string]),fgColor:n.default.oneOfType([n.default.object,n.default.string]),level:n.default.string,size:n.default.number,value:n.default.string.isRequired},b=(0,u.forwardRef)(function(w,C){var k=w.bgColor,j=k===void 0?\"#FFFFFF\":k,M=w.fgColor,_=M===void 0?\"#000000\":M,R=w.level,N=R===void 0?\"L\":R,O=w.size,D=O===void 0?256:O,z=w.value,Q=g(w,[\"bgColor\",\"fgColor\",\"level\",\"size\",\"value\"]),pe=new l.default(-1,s.default[N]);pe.addData(z),pe.make();var V=pe.modules;return d.default.createElement(h.default,e({},Q,{bgColor:j,bgD:V.map(function(G,W){return G.map(function(ie,re){return ie?\"\":\"M \"+re+\" \"+W+\" l 1 0 0 1 -1 0 Z\"}).join(\" \")}).join(\" \"),fgColor:_,fgD:V.map(function(G,W){return G.map(function(ie,re){return ie?\"M \"+re+\" \"+W+\" l 1 0 0 1 -1 0 Z\":\"\"}).join(\" \")}).join(\" \"),ref:C,size:D,viewBoxSize:V.length}))});return wl.QRCode=b,b.displayName=\"QRCode\",b.propTypes=x,wl.default=b,wl}var NX=TX();const MX=fd(NX),_X=jh(\"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7 space-y-1 [&_strong]:text-foreground\",{variants:{variant:{default:\"border-zinc-500/20 bg-zinc-50/50 dark:border-zinc-500/30 dark:bg-zinc-500/10 text-zinc-900 dark:text-zinc-300 [&>svg]:text-zinc-400 dark:[&>svg]:text-zinc-300\",destructive:\"border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10 text-red-900 dark:text-red-200 [&>svg]:text-red-600 dark:[&>svg]:text-red-400/80\",warning:\"border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10 text-amber-900 dark:text-amber-200 [&>svg]:text-amber-500\",info:\"border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10 text-sky-900 dark:text-sky-200 [&>svg]:text-sky-500\",success:\"border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10 text-emerald-900 dark:text-emerald-200 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400/80\"}},defaultVariants:{variant:\"default\"}}),rI=y.forwardRef(({className:e,variant:t,...n},r)=>i.jsx(\"div\",{ref:r,role:\"alert\",className:Ie(_X({variant:t}),e),...n}));rI.displayName=\"Alert\";const sI=y.forwardRef(({className:e,...t},n)=>i.jsx(\"h5\",{ref:n,className:Ie(\"font-medium leading-none tracking-tight\",e),...t}));sI.displayName=\"AlertTitle\";const RX=y.forwardRef(({className:e,...t},n)=>i.jsx(\"div\",{ref:n,className:Ie(\"text-sm [&_p]:leading-relaxed\",e),...t}));RX.displayName=\"AlertDescription\";const On=({size:e=45,className:t,...n})=>i.jsx(\"div\",{style:{display:\"flex\",justifyContent:\"center\",alignItems:\"center\",height:\"100vh\"},children:i.jsx(\"svg\",{xmlns:\"http://www.w3.org/2000/svg\",width:e,height:e,...n,viewBox:\"0 0 24 24\",fill:\"none\",stroke:\"currentColor\",strokeWidth:\"2\",strokeLinecap:\"round\",strokeLinejoin:\"round\",className:Ie(\"animate-spin\",t),children:i.jsx(\"path\",{d:\"M21 12a9 9 0 1 1-6.219-8.56\"})})});function PX(){const{t:e,i18n:t}=Ve(),n=new Intl.NumberFormat(t.language),[r,s]=y.useState(null),[o,l]=y.useState(\"\"),u=dr(jn.TOKEN),{theme:d}=tc(),{connect:f,logout:h,restart:m}=Hh(),{instance:g,reloadInstance:x}=ct();y.useEffect(()=>{g&&(localStorage.setItem(jn.INSTANCE_ID,g.id),localStorage.setItem(jn.INSTANCE_NAME,g.name),localStorage.setItem(jn.INSTANCE_TOKEN,g.token))},[g]);const b=async()=>{await x()},w=async R=>{try{await m(R),await x()}catch(N){console.error(\"Error:\",N)}},C=async R=>{try{await h(R),await x()}catch(N){console.error(\"Error:\",N)}},k=async(R,N)=>{try{if(s(null),!u){console.error(\"Token not found.\");return}if(N){const O=await f({instanceName:R,token:u,number:g?.number});l(O.pairingCode)}else{const O=await f({instanceName:R,token:u});s(O.code)}}catch(O){console.error(\"Error:\",O)}},j=async()=>{s(null),l(\"\"),await x()},M=y.useMemo(()=>g?{contacts:g._count?.Contact||0,chats:g._count?.Chat||0,messages:g._count?.Message||0}:{contacts:0,chats:0,messages:0},[g]),_=y.useMemo(()=>d===\"dark\"?\"#fff\":d===\"light\"?\"#000\":\"#189d68\",[d]);return g?i.jsxs(\"main\",{className:\"flex flex-col gap-8\",children:[i.jsx(\"section\",{children:i.jsxs(So,{children:[i.jsx(Co,{children:i.jsxs(\"div\",{className:\"flex flex-wrap items-center justify-between gap-4\",children:[i.jsx(\"h2\",{className:\"break-all text-lg font-semibold\",children:g.name}),i.jsx(l_,{status:g.connectionStatus})]})}),i.jsxs(Eo,{className:\"flex flex-col items-start space-y-6\",children:[i.jsx(\"div\",{className:\"flex w-full flex-1\",children:i.jsx(c_,{token:g.token})}),g.profileName&&i.jsxs(\"div\",{className:\"flex flex-1 gap-2\",children:[i.jsx(Ei,{children:i.jsx(ki,{src:g.profilePicUrl,alt:\"\"})}),i.jsxs(\"div\",{className:\"space-y-1\",children:[i.jsx(\"strong\",{children:g.profileName}),i.jsx(\"p\",{className:\"break-all text-sm text-muted-foreground\",children:g.ownerJid})]})]}),g.connectionStatus!==\"open\"&&i.jsxs(rI,{variant:\"warning\",className:\"flex flex-wrap items-center justify-between gap-3\",children:[i.jsx(sI,{className:\"text-lg font-bold tracking-wide\",children:e(\"instance.dashboard.alert\")}),i.jsxs(Pt,{children:[i.jsx(Bt,{onClick:()=>k(g.name,!1),asChild:!0,children:i.jsx(se,{variant:\"warning\",children:e(\"instance.dashboard.button.qrcode.label\")})}),i.jsxs(Nt,{onCloseAutoFocus:j,children:[i.jsx(Mt,{children:e(\"instance.dashboard.button.qrcode.title\")}),i.jsx(\"div\",{className:\"flex items-center justify-center\",children:r&&i.jsx(MX,{value:r,size:256,bgColor:\"transparent\",fgColor:_,className:\"rounded-sm\"})})]})]}),g.number&&i.jsxs(Pt,{children:[i.jsx(Bt,{className:\"connect-code-button\",onClick:()=>k(g.name,!0),children:e(\"instance.dashboard.button.pairingCode.label\")}),i.jsx(Nt,{onCloseAutoFocus:j,children:i.jsx(Mt,{children:i.jsx(eo,{children:o?i.jsxs(\"div\",{className:\"py-3\",children:[i.jsx(\"p\",{className:\"text-center\",children:i.jsx(\"strong\",{children:e(\"instance.dashboard.button.pairingCode.title\")})}),i.jsxs(\"p\",{className:\"pairing-code text-center\",children:[o.substring(0,4),\"-\",o.substring(4,8)]})]}):i.jsx(On,{})})})})]})]})]}),i.jsxs(Vh,{className:\"flex flex-wrap items-center justify-end gap-3\",children:[i.jsx(se,{variant:\"outline\",className:\"refresh-button\",size:\"icon\",onClick:b,children:i.jsx(Ip,{size:\"20\"})}),i.jsx(se,{className:\"action-button\",variant:\"secondary\",onClick:()=>w(g.name),children:e(\"instance.dashboard.button.restart\").toUpperCase()}),i.jsx(se,{variant:\"destructive\",onClick:()=>C(g.name),disabled:g.connectionStatus===\"close\",children:e(\"instance.dashboard.button.disconnect\").toUpperCase()})]})]})}),i.jsxs(\"section\",{className:\"grid grid-cols-[repeat(auto-fit,_minmax(15rem,_1fr))] gap-6\",children:[i.jsxs(So,{className:\"instance-card\",children:[i.jsx(Co,{children:i.jsxs(gi,{className:\"flex items-center gap-2\",children:[i.jsx(pT,{size:\"20\"}),e(\"instance.dashboard.contacts\")]})}),i.jsx(Eo,{children:n.format(M.contacts)})]}),i.jsxs(So,{className:\"instance-card\",children:[i.jsx(Co,{children:i.jsxs(gi,{className:\"flex items-center gap-2\",children:[i.jsx(jB,{size:\"20\"}),e(\"instance.dashboard.chats\")]})}),i.jsx(Eo,{children:n.format(M.chats)})]}),i.jsxs(So,{className:\"instance-card\",children:[i.jsx(Co,{children:i.jsxs(gi,{className:\"flex items-center gap-2\",children:[i.jsx(Bl,{size:\"20\"}),e(\"instance.dashboard.messages\")]})}),i.jsx(Eo,{children:n.format(M.messages)})]})]})]}):i.jsx(On,{})}var OX=\"Separator\",mk=\"horizontal\",IX=[\"horizontal\",\"vertical\"],oI=y.forwardRef((e,t)=>{const{decorative:n,orientation:r=mk,...s}=e,o=AX(r)?r:mk,u=n?{role:\"none\"}:{\"aria-orientation\":o===\"vertical\"?o:void 0,role:\"separator\"};return i.jsx(rt.div,{\"data-orientation\":o,...u,...s,ref:t})});oI.displayName=OX;function AX(e){return IX.includes(e)}var aI=oI;const $t=y.forwardRef(({className:e,orientation:t=\"horizontal\",decorative:n=!0,...r},s)=>i.jsx(aI,{ref:s,decorative:n,orientation:t,className:Ie(\"shrink-0 bg-border\",t===\"horizontal\"?\"h-[1px] w-full\":\"h-full w-[1px]\",e),...r}));$t.displayName=aI.displayName;const DX=e=>[\"dify\",\"fetchDify\",JSON.stringify(e)],FX=async({instanceName:e,token:t})=>(await Ee.get(`/dify/find/${e}`,{headers:{apikey:t}})).data,iI=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:DX({instanceName:t,token:n}),queryFn:()=>FX({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},LX=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/dify/create/${e}`,n,{headers:{apikey:t}})).data,$X=async({instanceName:e,difyId:t,data:n})=>(await Ee.put(`/dify/update/${t}/${e}`,n)).data,BX=async({instanceName:e,difyId:t})=>(await Ee.delete(`/dify/delete/${t}/${e}`)).data,zX=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/dify/settings/${e}`,n,{headers:{apikey:t}})).data,UX=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/dify/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data;function vg(){const e=nt(zX,{invalidateKeys:[[\"dify\",\"fetchDefaultSettings\"]]}),t=nt(UX,{invalidateKeys:[[\"dify\",\"getDify\"],[\"dify\",\"fetchSessions\"]]}),n=nt(BX,{invalidateKeys:[[\"dify\",\"getDify\"],[\"dify\",\"fetchDify\"],[\"dify\",\"fetchSessions\"]]}),r=nt($X,{invalidateKeys:[[\"dify\",\"getDify\"],[\"dify\",\"fetchDify\"],[\"dify\",\"fetchSessions\"]]}),s=nt(LX,{invalidateKeys:[[\"dify\",\"fetchDify\"]]});return{setDefaultSettingsDify:e,changeStatusDify:t,deleteDify:n,updateDify:r,createDify:s}}const VX=e=>[\"dify\",\"fetchDefaultSettings\",JSON.stringify(e)],HX=async({instanceName:e,token:t})=>(await Ee.get(`/dify/fetchSettings/${e}`,{headers:{apikey:t}})).data,qX=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:VX({instanceName:t,token:n}),queryFn:()=>HX({instanceName:t,token:n}),enabled:!!t})},KX=P.object({expire:P.string(),keywordFinish:P.string(),delayMessage:P.string(),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.string(),ignoreJids:P.array(P.string()).default([]),difyIdFallback:P.union([P.null(),P.string()]).optional(),splitMessages:P.boolean(),timePerChar:P.string()});function WX(){const{t:e}=Ve(),{instance:t}=ct(),{setDefaultSettingsDify:n}=vg(),[r,s]=y.useState(!1),{data:o,refetch:l}=iI({instanceName:t?.name,token:t?.token,enabled:r}),{data:u,refetch:d}=qX({instanceName:t?.name,token:t?.token}),f=on({resolver:an(KX),defaultValues:{expire:\"0\",keywordFinish:e(\"dify.form.examples.keywordFinish\"),delayMessage:\"1000\",unknownMessage:e(\"dify.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:\"0\",ignoreJids:[],difyIdFallback:void 0,splitMessages:!1,timePerChar:\"0\"}});y.useEffect(()=>{u&&f.reset({expire:u?.expire?u.expire.toString():\"0\",keywordFinish:u.keywordFinish,delayMessage:u.delayMessage?u.delayMessage.toString():\"0\",unknownMessage:u.unknownMessage,listeningFromMe:u.listeningFromMe,stopBotFromMe:u.stopBotFromMe,keepOpen:u.keepOpen,debounceTime:u.debounceTime?u.debounceTime.toString():\"0\",ignoreJids:u.ignoreJids,difyIdFallback:u.difyIdFallback,splitMessages:u.splitMessages,timePerChar:u.timePerChar?u.timePerChar.toString():\"0\"})},[u]);const h=async g=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const x={expire:parseInt(g.expire),keywordFinish:g.keywordFinish,delayMessage:parseInt(g.delayMessage),unknownMessage:g.unknownMessage,listeningFromMe:g.listeningFromMe,stopBotFromMe:g.stopBotFromMe,keepOpen:g.keepOpen,debounceTime:parseInt(g.debounceTime),difyIdFallback:g.difyIdFallback||void 0,ignoreJids:g.ignoreJids,splitMessages:g.splitMessages,timePerChar:parseInt(g.timePerChar)};await n({instanceName:t.name,token:t.token,data:x}),me.success(e(\"dify.toast.defaultSettings.success\"))}catch(x){console.error(\"Error:\",x),me.error(`Error: ${x?.response?.data?.response?.message}`)}};function m(){d(),l()}return i.jsxs(Pt,{open:r,onOpenChange:s,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:e(\"dify.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:m,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"dify.defaultSettings\")})}),i.jsx(Gn,{...f,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:f.handleSubmit(h),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"difyIdFallback\",label:e(\"dify.form.difyIdFallback.label\"),options:o?.filter(g=>!!g.id).map(g=>({label:g.description,value:g.id}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"dify.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"dify.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"dify.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"dify.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"dify.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"dify.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"dify.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"dify.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:e(\"dify.form.splitMessages.label\"),reverse:!0}),i.jsx(le,{name:\"timePerChar\",label:e(\"dify.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"dify.form.ignoreJids.label\"),placeholder:e(\"dify.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"dify.button.save\")})})]})})]})]})}/**\n   * table-core\n   *\n   * Copyright (c) TanStack\n   *\n   * This source code is licensed under the MIT license found in the\n   * LICENSE.md file in the root directory of this source tree.\n   *\n   * @license MIT\n   */function ma(e,t){return typeof e==\"function\"?e(t):e}function qr(e,t){return n=>{t.setState(r=>({...r,[e]:ma(n,r[e])}))}}function yg(e){return e instanceof Function}function GX(e){return Array.isArray(e)&&e.every(t=>typeof t==\"number\")}function lI(e,t){const n=[],r=s=>{s.forEach(o=>{n.push(o);const l=t(o);l!=null&&l.length&&r(l)})};return r(e),n}function ot(e,t,n){let r=[],s;return o=>{let l;n.key&&n.debug&&(l=Date.now());const u=e(o);if(!(u.length!==r.length||u.some((h,m)=>r[m]!==h)))return s;r=u;let f;if(n.key&&n.debug&&(f=Date.now()),s=t(...u),n==null||n.onChange==null||n.onChange(s),n.key&&n.debug&&n!=null&&n.debug()){const h=Math.round((Date.now()-l)*100)/100,m=Math.round((Date.now()-f)*100)/100,g=m/16,x=(b,w)=>{for(b=String(b);b.length<w;)b=\" \"+b;return b};console.info(`%c⏱ ${x(m,5)} /${x(h,5)} ms`,`\n            font-size: .6rem;\n            font-weight: bold;\n            color: hsl(${Math.max(0,Math.min(120-120*g,120))}deg 100% 31%);`,n?.key)}return s}}function at(e,t,n,r){return{debug:()=>{var s;return(s=e?.debugAll)!=null?s:e[t]},key:!1,onChange:r}}function JX(e,t,n,r){const s=()=>{var l;return(l=o.getValue())!=null?l:e.options.renderFallbackValue},o={id:`${t.id}_${n.id}`,row:t,column:n,getValue:()=>t.getValue(r),renderValue:s,getContext:ot(()=>[e,n,t,o],(l,u,d,f)=>({table:l,column:u,row:d,cell:f,getValue:f.getValue,renderValue:f.renderValue}),at(e.options,\"debugCells\"))};return e._features.forEach(l=>{l.createCell==null||l.createCell(o,n,t,e)},{}),o}function QX(e,t,n,r){var s,o;const u={...e._getDefaultColumnDef(),...t},d=u.accessorKey;let f=(s=(o=u.id)!=null?o:d?typeof String.prototype.replaceAll==\"function\"?d.replaceAll(\".\",\"_\"):d.replace(/\\./g,\"_\"):void 0)!=null?s:typeof u.header==\"string\"?u.header:void 0,h;if(u.accessorFn?h=u.accessorFn:d&&(d.includes(\".\")?h=g=>{let x=g;for(const w of d.split(\".\")){var b;x=(b=x)==null?void 0:b[w]}return x}:h=g=>g[u.accessorKey]),!f)throw new Error;let m={id:`${String(f)}`,accessorFn:h,parent:r,depth:n,columnDef:u,columns:[],getFlatColumns:ot(()=>[!0],()=>{var g;return[m,...(g=m.columns)==null?void 0:g.flatMap(x=>x.getFlatColumns())]},at(e.options,\"debugColumns\")),getLeafColumns:ot(()=>[e._getOrderColumnsFn()],g=>{var x;if((x=m.columns)!=null&&x.length){let b=m.columns.flatMap(w=>w.getLeafColumns());return g(b)}return[m]},at(e.options,\"debugColumns\"))};for(const g of e._features)g.createColumn==null||g.createColumn(m,e);return m}const nr=\"debugHeaders\";function vk(e,t,n){var r;let o={id:(r=n.id)!=null?r:t.id,column:t,index:n.index,isPlaceholder:!!n.isPlaceholder,placeholderId:n.placeholderId,depth:n.depth,subHeaders:[],colSpan:0,rowSpan:0,headerGroup:null,getLeafHeaders:()=>{const l=[],u=d=>{d.subHeaders&&d.subHeaders.length&&d.subHeaders.map(u),l.push(d)};return u(o),l},getContext:()=>({table:e,header:o,column:t})};return e._features.forEach(l=>{l.createHeader==null||l.createHeader(o,e)}),o}const ZX={createTable:e=>{e.getHeaderGroups=ot(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,n,r,s)=>{var o,l;const u=(o=r?.map(m=>n.find(g=>g.id===m)).filter(Boolean))!=null?o:[],d=(l=s?.map(m=>n.find(g=>g.id===m)).filter(Boolean))!=null?l:[],f=n.filter(m=>!(r!=null&&r.includes(m.id))&&!(s!=null&&s.includes(m.id)));return op(t,[...u,...f,...d],e)},at(e.options,nr)),e.getCenterHeaderGroups=ot(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,n,r,s)=>(n=n.filter(o=>!(r!=null&&r.includes(o.id))&&!(s!=null&&s.includes(o.id))),op(t,n,e,\"center\")),at(e.options,nr)),e.getLeftHeaderGroups=ot(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left],(t,n,r)=>{var s;const o=(s=r?.map(l=>n.find(u=>u.id===l)).filter(Boolean))!=null?s:[];return op(t,o,e,\"left\")},at(e.options,nr)),e.getRightHeaderGroups=ot(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.right],(t,n,r)=>{var s;const o=(s=r?.map(l=>n.find(u=>u.id===l)).filter(Boolean))!=null?s:[];return op(t,o,e,\"right\")},at(e.options,nr)),e.getFooterGroups=ot(()=>[e.getHeaderGroups()],t=>[...t].reverse(),at(e.options,nr)),e.getLeftFooterGroups=ot(()=>[e.getLeftHeaderGroups()],t=>[...t].reverse(),at(e.options,nr)),e.getCenterFooterGroups=ot(()=>[e.getCenterHeaderGroups()],t=>[...t].reverse(),at(e.options,nr)),e.getRightFooterGroups=ot(()=>[e.getRightHeaderGroups()],t=>[...t].reverse(),at(e.options,nr)),e.getFlatHeaders=ot(()=>[e.getHeaderGroups()],t=>t.map(n=>n.headers).flat(),at(e.options,nr)),e.getLeftFlatHeaders=ot(()=>[e.getLeftHeaderGroups()],t=>t.map(n=>n.headers).flat(),at(e.options,nr)),e.getCenterFlatHeaders=ot(()=>[e.getCenterHeaderGroups()],t=>t.map(n=>n.headers).flat(),at(e.options,nr)),e.getRightFlatHeaders=ot(()=>[e.getRightHeaderGroups()],t=>t.map(n=>n.headers).flat(),at(e.options,nr)),e.getCenterLeafHeaders=ot(()=>[e.getCenterFlatHeaders()],t=>t.filter(n=>{var r;return!((r=n.subHeaders)!=null&&r.length)}),at(e.options,nr)),e.getLeftLeafHeaders=ot(()=>[e.getLeftFlatHeaders()],t=>t.filter(n=>{var r;return!((r=n.subHeaders)!=null&&r.length)}),at(e.options,nr)),e.getRightLeafHeaders=ot(()=>[e.getRightFlatHeaders()],t=>t.filter(n=>{var r;return!((r=n.subHeaders)!=null&&r.length)}),at(e.options,nr)),e.getLeafHeaders=ot(()=>[e.getLeftHeaderGroups(),e.getCenterHeaderGroups(),e.getRightHeaderGroups()],(t,n,r)=>{var s,o,l,u,d,f;return[...(s=(o=t[0])==null?void 0:o.headers)!=null?s:[],...(l=(u=n[0])==null?void 0:u.headers)!=null?l:[],...(d=(f=r[0])==null?void 0:f.headers)!=null?d:[]].map(h=>h.getLeafHeaders()).flat()},at(e.options,nr))}};function op(e,t,n,r){var s,o;let l=0;const u=function(g,x){x===void 0&&(x=1),l=Math.max(l,x),g.filter(b=>b.getIsVisible()).forEach(b=>{var w;(w=b.columns)!=null&&w.length&&u(b.columns,x+1)},0)};u(e);let d=[];const f=(g,x)=>{const b={depth:x,id:[r,`${x}`].filter(Boolean).join(\"_\"),headers:[]},w=[];g.forEach(C=>{const k=[...w].reverse()[0],j=C.column.depth===b.depth;let M,_=!1;if(j&&C.column.parent?M=C.column.parent:(M=C.column,_=!0),k&&k?.column===M)k.subHeaders.push(C);else{const R=vk(n,M,{id:[r,x,M.id,C?.id].filter(Boolean).join(\"_\"),isPlaceholder:_,placeholderId:_?`${w.filter(N=>N.column===M).length}`:void 0,depth:x,index:w.length});R.subHeaders.push(C),w.push(R)}b.headers.push(C),C.headerGroup=b}),d.push(b),x>0&&f(w,x-1)},h=t.map((g,x)=>vk(n,g,{depth:l,index:x}));f(h,l-1),d.reverse();const m=g=>g.filter(b=>b.column.getIsVisible()).map(b=>{let w=0,C=0,k=[0];b.subHeaders&&b.subHeaders.length?(k=[],m(b.subHeaders).forEach(M=>{let{colSpan:_,rowSpan:R}=M;w+=_,k.push(R)})):w=1;const j=Math.min(...k);return C=C+j,b.colSpan=w,b.rowSpan=C,{colSpan:w,rowSpan:C}});return m((s=(o=d[0])==null?void 0:o.headers)!=null?s:[]),d}const bg=(e,t,n,r,s,o,l)=>{let u={id:t,index:r,original:n,depth:s,parentId:l,_valuesCache:{},_uniqueValuesCache:{},getValue:d=>{if(u._valuesCache.hasOwnProperty(d))return u._valuesCache[d];const f=e.getColumn(d);if(f!=null&&f.accessorFn)return u._valuesCache[d]=f.accessorFn(u.original,r),u._valuesCache[d]},getUniqueValues:d=>{if(u._uniqueValuesCache.hasOwnProperty(d))return u._uniqueValuesCache[d];const f=e.getColumn(d);if(f!=null&&f.accessorFn)return f.columnDef.getUniqueValues?(u._uniqueValuesCache[d]=f.columnDef.getUniqueValues(u.original,r),u._uniqueValuesCache[d]):(u._uniqueValuesCache[d]=[u.getValue(d)],u._uniqueValuesCache[d])},renderValue:d=>{var f;return(f=u.getValue(d))!=null?f:e.options.renderFallbackValue},subRows:o??[],getLeafRows:()=>lI(u.subRows,d=>d.subRows),getParentRow:()=>u.parentId?e.getRow(u.parentId,!0):void 0,getParentRows:()=>{let d=[],f=u;for(;;){const h=f.getParentRow();if(!h)break;d.push(h),f=h}return d.reverse()},getAllCells:ot(()=>[e.getAllLeafColumns()],d=>d.map(f=>JX(e,u,f,f.id)),at(e.options,\"debugRows\")),_getAllCellsByColumnId:ot(()=>[u.getAllCells()],d=>d.reduce((f,h)=>(f[h.column.id]=h,f),{}),at(e.options,\"debugRows\"))};for(let d=0;d<e._features.length;d++){const f=e._features[d];f==null||f.createRow==null||f.createRow(u,e)}return u},YX={createColumn:(e,t)=>{e._getFacetedRowModel=t.options.getFacetedRowModel&&t.options.getFacetedRowModel(t,e.id),e.getFacetedRowModel=()=>e._getFacetedRowModel?e._getFacetedRowModel():t.getPreFilteredRowModel(),e._getFacetedUniqueValues=t.options.getFacetedUniqueValues&&t.options.getFacetedUniqueValues(t,e.id),e.getFacetedUniqueValues=()=>e._getFacetedUniqueValues?e._getFacetedUniqueValues():new Map,e._getFacetedMinMaxValues=t.options.getFacetedMinMaxValues&&t.options.getFacetedMinMaxValues(t,e.id),e.getFacetedMinMaxValues=()=>{if(e._getFacetedMinMaxValues)return e._getFacetedMinMaxValues()}}},cI=(e,t,n)=>{var r;const s=n.toLowerCase();return!!(!((r=e.getValue(t))==null||(r=r.toString())==null||(r=r.toLowerCase())==null)&&r.includes(s))};cI.autoRemove=e=>Ts(e);const uI=(e,t,n)=>{var r;return!!(!((r=e.getValue(t))==null||(r=r.toString())==null)&&r.includes(n))};uI.autoRemove=e=>Ts(e);const dI=(e,t,n)=>{var r;return((r=e.getValue(t))==null||(r=r.toString())==null?void 0:r.toLowerCase())===n?.toLowerCase()};dI.autoRemove=e=>Ts(e);const fI=(e,t,n)=>{var r;return(r=e.getValue(t))==null?void 0:r.includes(n)};fI.autoRemove=e=>Ts(e)||!(e!=null&&e.length);const pI=(e,t,n)=>!n.some(r=>{var s;return!((s=e.getValue(t))!=null&&s.includes(r))});pI.autoRemove=e=>Ts(e)||!(e!=null&&e.length);const hI=(e,t,n)=>n.some(r=>{var s;return(s=e.getValue(t))==null?void 0:s.includes(r)});hI.autoRemove=e=>Ts(e)||!(e!=null&&e.length);const gI=(e,t,n)=>e.getValue(t)===n;gI.autoRemove=e=>Ts(e);const mI=(e,t,n)=>e.getValue(t)==n;mI.autoRemove=e=>Ts(e);const aw=(e,t,n)=>{let[r,s]=n;const o=e.getValue(t);return o>=r&&o<=s};aw.resolveFilterValue=e=>{let[t,n]=e,r=typeof t!=\"number\"?parseFloat(t):t,s=typeof n!=\"number\"?parseFloat(n):n,o=t===null||Number.isNaN(r)?-1/0:r,l=n===null||Number.isNaN(s)?1/0:s;if(o>l){const u=o;o=l,l=u}return[o,l]};aw.autoRemove=e=>Ts(e)||Ts(e[0])&&Ts(e[1]);const yo={includesString:cI,includesStringSensitive:uI,equalsString:dI,arrIncludes:fI,arrIncludesAll:pI,arrIncludesSome:hI,equals:gI,weakEquals:mI,inNumberRange:aw};function Ts(e){return e==null||e===\"\"}const XX={getDefaultColumnDef:()=>({filterFn:\"auto\"}),getInitialState:e=>({columnFilters:[],...e}),getDefaultOptions:e=>({onColumnFiltersChange:qr(\"columnFilters\",e),filterFromLeafRows:!1,maxLeafRowFilterDepth:100}),createColumn:(e,t)=>{e.getAutoFilterFn=()=>{const n=t.getCoreRowModel().flatRows[0],r=n?.getValue(e.id);return typeof r==\"string\"?yo.includesString:typeof r==\"number\"?yo.inNumberRange:typeof r==\"boolean\"||r!==null&&typeof r==\"object\"?yo.equals:Array.isArray(r)?yo.arrIncludes:yo.weakEquals},e.getFilterFn=()=>{var n,r;return yg(e.columnDef.filterFn)?e.columnDef.filterFn:e.columnDef.filterFn===\"auto\"?e.getAutoFilterFn():(n=(r=t.options.filterFns)==null?void 0:r[e.columnDef.filterFn])!=null?n:yo[e.columnDef.filterFn]},e.getCanFilter=()=>{var n,r,s;return((n=e.columnDef.enableColumnFilter)!=null?n:!0)&&((r=t.options.enableColumnFilters)!=null?r:!0)&&((s=t.options.enableFilters)!=null?s:!0)&&!!e.accessorFn},e.getIsFiltered=()=>e.getFilterIndex()>-1,e.getFilterValue=()=>{var n;return(n=t.getState().columnFilters)==null||(n=n.find(r=>r.id===e.id))==null?void 0:n.value},e.getFilterIndex=()=>{var n,r;return(n=(r=t.getState().columnFilters)==null?void 0:r.findIndex(s=>s.id===e.id))!=null?n:-1},e.setFilterValue=n=>{t.setColumnFilters(r=>{const s=e.getFilterFn(),o=r?.find(h=>h.id===e.id),l=ma(n,o?o.value:void 0);if(yk(s,l,e)){var u;return(u=r?.filter(h=>h.id!==e.id))!=null?u:[]}const d={id:e.id,value:l};if(o){var f;return(f=r?.map(h=>h.id===e.id?d:h))!=null?f:[]}return r!=null&&r.length?[...r,d]:[d]})}},createRow:(e,t)=>{e.columnFilters={},e.columnFiltersMeta={}},createTable:e=>{e.setColumnFilters=t=>{const n=e.getAllLeafColumns(),r=s=>{var o;return(o=ma(t,s))==null?void 0:o.filter(l=>{const u=n.find(d=>d.id===l.id);if(u){const d=u.getFilterFn();if(yk(d,l.value,u))return!1}return!0})};e.options.onColumnFiltersChange==null||e.options.onColumnFiltersChange(r)},e.resetColumnFilters=t=>{var n,r;e.setColumnFilters(t?[]:(n=(r=e.initialState)==null?void 0:r.columnFilters)!=null?n:[])},e.getPreFilteredRowModel=()=>e.getCoreRowModel(),e.getFilteredRowModel=()=>(!e._getFilteredRowModel&&e.options.getFilteredRowModel&&(e._getFilteredRowModel=e.options.getFilteredRowModel(e)),e.options.manualFiltering||!e._getFilteredRowModel?e.getPreFilteredRowModel():e._getFilteredRowModel())}};function yk(e,t,n){return(e&&e.autoRemove?e.autoRemove(t,n):!1)||typeof t>\"u\"||typeof t==\"string\"&&!t}const eee=(e,t,n)=>n.reduce((r,s)=>{const o=s.getValue(e);return r+(typeof o==\"number\"?o:0)},0),tee=(e,t,n)=>{let r;return n.forEach(s=>{const o=s.getValue(e);o!=null&&(r>o||r===void 0&&o>=o)&&(r=o)}),r},nee=(e,t,n)=>{let r;return n.forEach(s=>{const o=s.getValue(e);o!=null&&(r<o||r===void 0&&o>=o)&&(r=o)}),r},ree=(e,t,n)=>{let r,s;return n.forEach(o=>{const l=o.getValue(e);l!=null&&(r===void 0?l>=l&&(r=s=l):(r>l&&(r=l),s<l&&(s=l)))}),[r,s]},see=(e,t)=>{let n=0,r=0;if(t.forEach(s=>{let o=s.getValue(e);o!=null&&(o=+o)>=o&&(++n,r+=o)}),n)return r/n},oee=(e,t)=>{if(!t.length)return;const n=t.map(o=>o.getValue(e));if(!GX(n))return;if(n.length===1)return n[0];const r=Math.floor(n.length/2),s=n.sort((o,l)=>o-l);return n.length%2!==0?s[r]:(s[r-1]+s[r])/2},aee=(e,t)=>Array.from(new Set(t.map(n=>n.getValue(e))).values()),iee=(e,t)=>new Set(t.map(n=>n.getValue(e))).size,lee=(e,t)=>t.length,dy={sum:eee,min:tee,max:nee,extent:ree,mean:see,median:oee,unique:aee,uniqueCount:iee,count:lee},cee={getDefaultColumnDef:()=>({aggregatedCell:e=>{var t,n;return(t=(n=e.getValue())==null||n.toString==null?void 0:n.toString())!=null?t:null},aggregationFn:\"auto\"}),getInitialState:e=>({grouping:[],...e}),getDefaultOptions:e=>({onGroupingChange:qr(\"grouping\",e),groupedColumnMode:\"reorder\"}),createColumn:(e,t)=>{e.toggleGrouping=()=>{t.setGrouping(n=>n!=null&&n.includes(e.id)?n.filter(r=>r!==e.id):[...n??[],e.id])},e.getCanGroup=()=>{var n,r;return((n=e.columnDef.enableGrouping)!=null?n:!0)&&((r=t.options.enableGrouping)!=null?r:!0)&&(!!e.accessorFn||!!e.columnDef.getGroupingValue)},e.getIsGrouped=()=>{var n;return(n=t.getState().grouping)==null?void 0:n.includes(e.id)},e.getGroupedIndex=()=>{var n;return(n=t.getState().grouping)==null?void 0:n.indexOf(e.id)},e.getToggleGroupingHandler=()=>{const n=e.getCanGroup();return()=>{n&&e.toggleGrouping()}},e.getAutoAggregationFn=()=>{const n=t.getCoreRowModel().flatRows[0],r=n?.getValue(e.id);if(typeof r==\"number\")return dy.sum;if(Object.prototype.toString.call(r)===\"[object Date]\")return dy.extent},e.getAggregationFn=()=>{var n,r;if(!e)throw new Error;return yg(e.columnDef.aggregationFn)?e.columnDef.aggregationFn:e.columnDef.aggregationFn===\"auto\"?e.getAutoAggregationFn():(n=(r=t.options.aggregationFns)==null?void 0:r[e.columnDef.aggregationFn])!=null?n:dy[e.columnDef.aggregationFn]}},createTable:e=>{e.setGrouping=t=>e.options.onGroupingChange==null?void 0:e.options.onGroupingChange(t),e.resetGrouping=t=>{var n,r;e.setGrouping(t?[]:(n=(r=e.initialState)==null?void 0:r.grouping)!=null?n:[])},e.getPreGroupedRowModel=()=>e.getFilteredRowModel(),e.getGroupedRowModel=()=>(!e._getGroupedRowModel&&e.options.getGroupedRowModel&&(e._getGroupedRowModel=e.options.getGroupedRowModel(e)),e.options.manualGrouping||!e._getGroupedRowModel?e.getPreGroupedRowModel():e._getGroupedRowModel())},createRow:(e,t)=>{e.getIsGrouped=()=>!!e.groupingColumnId,e.getGroupingValue=n=>{if(e._groupingValuesCache.hasOwnProperty(n))return e._groupingValuesCache[n];const r=t.getColumn(n);return r!=null&&r.columnDef.getGroupingValue?(e._groupingValuesCache[n]=r.columnDef.getGroupingValue(e.original),e._groupingValuesCache[n]):e.getValue(n)},e._groupingValuesCache={}},createCell:(e,t,n,r)=>{e.getIsGrouped=()=>t.getIsGrouped()&&t.id===n.groupingColumnId,e.getIsPlaceholder=()=>!e.getIsGrouped()&&t.getIsGrouped(),e.getIsAggregated=()=>{var s;return!e.getIsGrouped()&&!e.getIsPlaceholder()&&!!((s=n.subRows)!=null&&s.length)}}};function uee(e,t,n){if(!(t!=null&&t.length)||!n)return e;const r=e.filter(o=>!t.includes(o.id));return n===\"remove\"?r:[...t.map(o=>e.find(l=>l.id===o)).filter(Boolean),...r]}const dee={getInitialState:e=>({columnOrder:[],...e}),getDefaultOptions:e=>({onColumnOrderChange:qr(\"columnOrder\",e)}),createColumn:(e,t)=>{e.getIndex=ot(n=>[Ru(t,n)],n=>n.findIndex(r=>r.id===e.id),at(t.options,\"debugColumns\")),e.getIsFirstColumn=n=>{var r;return((r=Ru(t,n)[0])==null?void 0:r.id)===e.id},e.getIsLastColumn=n=>{var r;const s=Ru(t,n);return((r=s[s.length-1])==null?void 0:r.id)===e.id}},createTable:e=>{e.setColumnOrder=t=>e.options.onColumnOrderChange==null?void 0:e.options.onColumnOrderChange(t),e.resetColumnOrder=t=>{var n;e.setColumnOrder(t?[]:(n=e.initialState.columnOrder)!=null?n:[])},e._getOrderColumnsFn=ot(()=>[e.getState().columnOrder,e.getState().grouping,e.options.groupedColumnMode],(t,n,r)=>s=>{let o=[];if(!(t!=null&&t.length))o=s;else{const l=[...t],u=[...s];for(;u.length&&l.length;){const d=l.shift(),f=u.findIndex(h=>h.id===d);f>-1&&o.push(u.splice(f,1)[0])}o=[...o,...u]}return uee(o,n,r)},at(e.options,\"debugTable\"))}},fy=()=>({left:[],right:[]}),fee={getInitialState:e=>({columnPinning:fy(),...e}),getDefaultOptions:e=>({onColumnPinningChange:qr(\"columnPinning\",e)}),createColumn:(e,t)=>{e.pin=n=>{const r=e.getLeafColumns().map(s=>s.id).filter(Boolean);t.setColumnPinning(s=>{var o,l;if(n===\"right\"){var u,d;return{left:((u=s?.left)!=null?u:[]).filter(m=>!(r!=null&&r.includes(m))),right:[...((d=s?.right)!=null?d:[]).filter(m=>!(r!=null&&r.includes(m))),...r]}}if(n===\"left\"){var f,h;return{left:[...((f=s?.left)!=null?f:[]).filter(m=>!(r!=null&&r.includes(m))),...r],right:((h=s?.right)!=null?h:[]).filter(m=>!(r!=null&&r.includes(m)))}}return{left:((o=s?.left)!=null?o:[]).filter(m=>!(r!=null&&r.includes(m))),right:((l=s?.right)!=null?l:[]).filter(m=>!(r!=null&&r.includes(m)))}})},e.getCanPin=()=>e.getLeafColumns().some(r=>{var s,o,l;return((s=r.columnDef.enablePinning)!=null?s:!0)&&((o=(l=t.options.enableColumnPinning)!=null?l:t.options.enablePinning)!=null?o:!0)}),e.getIsPinned=()=>{const n=e.getLeafColumns().map(u=>u.id),{left:r,right:s}=t.getState().columnPinning,o=n.some(u=>r?.includes(u)),l=n.some(u=>s?.includes(u));return o?\"left\":l?\"right\":!1},e.getPinnedIndex=()=>{var n,r;const s=e.getIsPinned();return s?(n=(r=t.getState().columnPinning)==null||(r=r[s])==null?void 0:r.indexOf(e.id))!=null?n:-1:0}},createRow:(e,t)=>{e.getCenterVisibleCells=ot(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left,t.getState().columnPinning.right],(n,r,s)=>{const o=[...r??[],...s??[]];return n.filter(l=>!o.includes(l.column.id))},at(t.options,\"debugRows\")),e.getLeftVisibleCells=ot(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left],(n,r)=>(r??[]).map(o=>n.find(l=>l.column.id===o)).filter(Boolean).map(o=>({...o,position:\"left\"})),at(t.options,\"debugRows\")),e.getRightVisibleCells=ot(()=>[e._getAllVisibleCells(),t.getState().columnPinning.right],(n,r)=>(r??[]).map(o=>n.find(l=>l.column.id===o)).filter(Boolean).map(o=>({...o,position:\"right\"})),at(t.options,\"debugRows\"))},createTable:e=>{e.setColumnPinning=t=>e.options.onColumnPinningChange==null?void 0:e.options.onColumnPinningChange(t),e.resetColumnPinning=t=>{var n,r;return e.setColumnPinning(t?fy():(n=(r=e.initialState)==null?void 0:r.columnPinning)!=null?n:fy())},e.getIsSomeColumnsPinned=t=>{var n;const r=e.getState().columnPinning;if(!t){var s,o;return!!((s=r.left)!=null&&s.length||(o=r.right)!=null&&o.length)}return!!((n=r[t])!=null&&n.length)},e.getLeftLeafColumns=ot(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left],(t,n)=>(n??[]).map(r=>t.find(s=>s.id===r)).filter(Boolean),at(e.options,\"debugColumns\")),e.getRightLeafColumns=ot(()=>[e.getAllLeafColumns(),e.getState().columnPinning.right],(t,n)=>(n??[]).map(r=>t.find(s=>s.id===r)).filter(Boolean),at(e.options,\"debugColumns\")),e.getCenterLeafColumns=ot(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,n,r)=>{const s=[...n??[],...r??[]];return t.filter(o=>!s.includes(o.id))},at(e.options,\"debugColumns\"))}},ap={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},py=()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),pee={getDefaultColumnDef:()=>ap,getInitialState:e=>({columnSizing:{},columnSizingInfo:py(),...e}),getDefaultOptions:e=>({columnResizeMode:\"onEnd\",columnResizeDirection:\"ltr\",onColumnSizingChange:qr(\"columnSizing\",e),onColumnSizingInfoChange:qr(\"columnSizingInfo\",e)}),createColumn:(e,t)=>{e.getSize=()=>{var n,r,s;const o=t.getState().columnSizing[e.id];return Math.min(Math.max((n=e.columnDef.minSize)!=null?n:ap.minSize,(r=o??e.columnDef.size)!=null?r:ap.size),(s=e.columnDef.maxSize)!=null?s:ap.maxSize)},e.getStart=ot(n=>[n,Ru(t,n),t.getState().columnSizing],(n,r)=>r.slice(0,e.getIndex(n)).reduce((s,o)=>s+o.getSize(),0),at(t.options,\"debugColumns\")),e.getAfter=ot(n=>[n,Ru(t,n),t.getState().columnSizing],(n,r)=>r.slice(e.getIndex(n)+1).reduce((s,o)=>s+o.getSize(),0),at(t.options,\"debugColumns\")),e.resetSize=()=>{t.setColumnSizing(n=>{let{[e.id]:r,...s}=n;return s})},e.getCanResize=()=>{var n,r;return((n=e.columnDef.enableResizing)!=null?n:!0)&&((r=t.options.enableColumnResizing)!=null?r:!0)},e.getIsResizing=()=>t.getState().columnSizingInfo.isResizingColumn===e.id},createHeader:(e,t)=>{e.getSize=()=>{let n=0;const r=s=>{if(s.subHeaders.length)s.subHeaders.forEach(r);else{var o;n+=(o=s.column.getSize())!=null?o:0}};return r(e),n},e.getStart=()=>{if(e.index>0){const n=e.headerGroup.headers[e.index-1];return n.getStart()+n.getSize()}return 0},e.getResizeHandler=n=>{const r=t.getColumn(e.column.id),s=r?.getCanResize();return o=>{if(!r||!s||(o.persist==null||o.persist(),hy(o)&&o.touches&&o.touches.length>1))return;const l=e.getSize(),u=e?e.getLeafHeaders().map(k=>[k.column.id,k.column.getSize()]):[[r.id,r.getSize()]],d=hy(o)?Math.round(o.touches[0].clientX):o.clientX,f={},h=(k,j)=>{typeof j==\"number\"&&(t.setColumnSizingInfo(M=>{var _,R;const N=t.options.columnResizeDirection===\"rtl\"?-1:1,O=(j-((_=M?.startOffset)!=null?_:0))*N,D=Math.max(O/((R=M?.startSize)!=null?R:0),-.999999);return M.columnSizingStart.forEach(z=>{let[Q,pe]=z;f[Q]=Math.round(Math.max(pe+pe*D,0)*100)/100}),{...M,deltaOffset:O,deltaPercentage:D}}),(t.options.columnResizeMode===\"onChange\"||k===\"end\")&&t.setColumnSizing(M=>({...M,...f})))},m=k=>h(\"move\",k),g=k=>{h(\"end\",k),t.setColumnSizingInfo(j=>({...j,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},x=n||typeof document<\"u\"?document:null,b={moveHandler:k=>m(k.clientX),upHandler:k=>{x?.removeEventListener(\"mousemove\",b.moveHandler),x?.removeEventListener(\"mouseup\",b.upHandler),g(k.clientX)}},w={moveHandler:k=>(k.cancelable&&(k.preventDefault(),k.stopPropagation()),m(k.touches[0].clientX),!1),upHandler:k=>{var j;x?.removeEventListener(\"touchmove\",w.moveHandler),x?.removeEventListener(\"touchend\",w.upHandler),k.cancelable&&(k.preventDefault(),k.stopPropagation()),g((j=k.touches[0])==null?void 0:j.clientX)}},C=hee()?{passive:!1}:!1;hy(o)?(x?.addEventListener(\"touchmove\",w.moveHandler,C),x?.addEventListener(\"touchend\",w.upHandler,C)):(x?.addEventListener(\"mousemove\",b.moveHandler,C),x?.addEventListener(\"mouseup\",b.upHandler,C)),t.setColumnSizingInfo(k=>({...k,startOffset:d,startSize:l,deltaOffset:0,deltaPercentage:0,columnSizingStart:u,isResizingColumn:r.id}))}}},createTable:e=>{e.setColumnSizing=t=>e.options.onColumnSizingChange==null?void 0:e.options.onColumnSizingChange(t),e.setColumnSizingInfo=t=>e.options.onColumnSizingInfoChange==null?void 0:e.options.onColumnSizingInfoChange(t),e.resetColumnSizing=t=>{var n;e.setColumnSizing(t?{}:(n=e.initialState.columnSizing)!=null?n:{})},e.resetHeaderSizeInfo=t=>{var n;e.setColumnSizingInfo(t?py():(n=e.initialState.columnSizingInfo)!=null?n:py())},e.getTotalSize=()=>{var t,n;return(t=(n=e.getHeaderGroups()[0])==null?void 0:n.headers.reduce((r,s)=>r+s.getSize(),0))!=null?t:0},e.getLeftTotalSize=()=>{var t,n;return(t=(n=e.getLeftHeaderGroups()[0])==null?void 0:n.headers.reduce((r,s)=>r+s.getSize(),0))!=null?t:0},e.getCenterTotalSize=()=>{var t,n;return(t=(n=e.getCenterHeaderGroups()[0])==null?void 0:n.headers.reduce((r,s)=>r+s.getSize(),0))!=null?t:0},e.getRightTotalSize=()=>{var t,n;return(t=(n=e.getRightHeaderGroups()[0])==null?void 0:n.headers.reduce((r,s)=>r+s.getSize(),0))!=null?t:0}}};let ip=null;function hee(){if(typeof ip==\"boolean\")return ip;let e=!1;try{const t={get passive(){return e=!0,!1}},n=()=>{};window.addEventListener(\"test\",n,t),window.removeEventListener(\"test\",n)}catch{e=!1}return ip=e,ip}function hy(e){return e.type===\"touchstart\"}const gee={getInitialState:e=>({columnVisibility:{},...e}),getDefaultOptions:e=>({onColumnVisibilityChange:qr(\"columnVisibility\",e)}),createColumn:(e,t)=>{e.toggleVisibility=n=>{e.getCanHide()&&t.setColumnVisibility(r=>({...r,[e.id]:n??!e.getIsVisible()}))},e.getIsVisible=()=>{var n,r;const s=e.columns;return(n=s.length?s.some(o=>o.getIsVisible()):(r=t.getState().columnVisibility)==null?void 0:r[e.id])!=null?n:!0},e.getCanHide=()=>{var n,r;return((n=e.columnDef.enableHiding)!=null?n:!0)&&((r=t.options.enableHiding)!=null?r:!0)},e.getToggleVisibilityHandler=()=>n=>{e.toggleVisibility==null||e.toggleVisibility(n.target.checked)}},createRow:(e,t)=>{e._getAllVisibleCells=ot(()=>[e.getAllCells(),t.getState().columnVisibility],n=>n.filter(r=>r.column.getIsVisible()),at(t.options,\"debugRows\")),e.getVisibleCells=ot(()=>[e.getLeftVisibleCells(),e.getCenterVisibleCells(),e.getRightVisibleCells()],(n,r,s)=>[...n,...r,...s],at(t.options,\"debugRows\"))},createTable:e=>{const t=(n,r)=>ot(()=>[r(),r().filter(s=>s.getIsVisible()).map(s=>s.id).join(\"_\")],s=>s.filter(o=>o.getIsVisible==null?void 0:o.getIsVisible()),at(e.options,\"debugColumns\"));e.getVisibleFlatColumns=t(\"getVisibleFlatColumns\",()=>e.getAllFlatColumns()),e.getVisibleLeafColumns=t(\"getVisibleLeafColumns\",()=>e.getAllLeafColumns()),e.getLeftVisibleLeafColumns=t(\"getLeftVisibleLeafColumns\",()=>e.getLeftLeafColumns()),e.getRightVisibleLeafColumns=t(\"getRightVisibleLeafColumns\",()=>e.getRightLeafColumns()),e.getCenterVisibleLeafColumns=t(\"getCenterVisibleLeafColumns\",()=>e.getCenterLeafColumns()),e.setColumnVisibility=n=>e.options.onColumnVisibilityChange==null?void 0:e.options.onColumnVisibilityChange(n),e.resetColumnVisibility=n=>{var r;e.setColumnVisibility(n?{}:(r=e.initialState.columnVisibility)!=null?r:{})},e.toggleAllColumnsVisible=n=>{var r;n=(r=n)!=null?r:!e.getIsAllColumnsVisible(),e.setColumnVisibility(e.getAllLeafColumns().reduce((s,o)=>({...s,[o.id]:n||!(o.getCanHide!=null&&o.getCanHide())}),{}))},e.getIsAllColumnsVisible=()=>!e.getAllLeafColumns().some(n=>!(n.getIsVisible!=null&&n.getIsVisible())),e.getIsSomeColumnsVisible=()=>e.getAllLeafColumns().some(n=>n.getIsVisible==null?void 0:n.getIsVisible()),e.getToggleAllColumnsVisibilityHandler=()=>n=>{var r;e.toggleAllColumnsVisible((r=n.target)==null?void 0:r.checked)}}};function Ru(e,t){return t?t===\"center\"?e.getCenterVisibleLeafColumns():t===\"left\"?e.getLeftVisibleLeafColumns():e.getRightVisibleLeafColumns():e.getVisibleLeafColumns()}const mee={createTable:e=>{e._getGlobalFacetedRowModel=e.options.getFacetedRowModel&&e.options.getFacetedRowModel(e,\"__global__\"),e.getGlobalFacetedRowModel=()=>e.options.manualFiltering||!e._getGlobalFacetedRowModel?e.getPreFilteredRowModel():e._getGlobalFacetedRowModel(),e._getGlobalFacetedUniqueValues=e.options.getFacetedUniqueValues&&e.options.getFacetedUniqueValues(e,\"__global__\"),e.getGlobalFacetedUniqueValues=()=>e._getGlobalFacetedUniqueValues?e._getGlobalFacetedUniqueValues():new Map,e._getGlobalFacetedMinMaxValues=e.options.getFacetedMinMaxValues&&e.options.getFacetedMinMaxValues(e,\"__global__\"),e.getGlobalFacetedMinMaxValues=()=>{if(e._getGlobalFacetedMinMaxValues)return e._getGlobalFacetedMinMaxValues()}}},vee={getInitialState:e=>({globalFilter:void 0,...e}),getDefaultOptions:e=>({onGlobalFilterChange:qr(\"globalFilter\",e),globalFilterFn:\"auto\",getColumnCanGlobalFilter:t=>{var n;const r=(n=e.getCoreRowModel().flatRows[0])==null||(n=n._getAllCellsByColumnId()[t.id])==null?void 0:n.getValue();return typeof r==\"string\"||typeof r==\"number\"}}),createColumn:(e,t)=>{e.getCanGlobalFilter=()=>{var n,r,s,o;return((n=e.columnDef.enableGlobalFilter)!=null?n:!0)&&((r=t.options.enableGlobalFilter)!=null?r:!0)&&((s=t.options.enableFilters)!=null?s:!0)&&((o=t.options.getColumnCanGlobalFilter==null?void 0:t.options.getColumnCanGlobalFilter(e))!=null?o:!0)&&!!e.accessorFn}},createTable:e=>{e.getGlobalAutoFilterFn=()=>yo.includesString,e.getGlobalFilterFn=()=>{var t,n;const{globalFilterFn:r}=e.options;return yg(r)?r:r===\"auto\"?e.getGlobalAutoFilterFn():(t=(n=e.options.filterFns)==null?void 0:n[r])!=null?t:yo[r]},e.setGlobalFilter=t=>{e.options.onGlobalFilterChange==null||e.options.onGlobalFilterChange(t)},e.resetGlobalFilter=t=>{e.setGlobalFilter(t?void 0:e.initialState.globalFilter)}}},yee={getInitialState:e=>({expanded:{},...e}),getDefaultOptions:e=>({onExpandedChange:qr(\"expanded\",e),paginateExpandedRows:!0}),createTable:e=>{let t=!1,n=!1;e._autoResetExpanded=()=>{var r,s;if(!t){e._queue(()=>{t=!0});return}if((r=(s=e.options.autoResetAll)!=null?s:e.options.autoResetExpanded)!=null?r:!e.options.manualExpanding){if(n)return;n=!0,e._queue(()=>{e.resetExpanded(),n=!1})}},e.setExpanded=r=>e.options.onExpandedChange==null?void 0:e.options.onExpandedChange(r),e.toggleAllRowsExpanded=r=>{r??!e.getIsAllRowsExpanded()?e.setExpanded(!0):e.setExpanded({})},e.resetExpanded=r=>{var s,o;e.setExpanded(r?{}:(s=(o=e.initialState)==null?void 0:o.expanded)!=null?s:{})},e.getCanSomeRowsExpand=()=>e.getPrePaginationRowModel().flatRows.some(r=>r.getCanExpand()),e.getToggleAllRowsExpandedHandler=()=>r=>{r.persist==null||r.persist(),e.toggleAllRowsExpanded()},e.getIsSomeRowsExpanded=()=>{const r=e.getState().expanded;return r===!0||Object.values(r).some(Boolean)},e.getIsAllRowsExpanded=()=>{const r=e.getState().expanded;return typeof r==\"boolean\"?r===!0:!(!Object.keys(r).length||e.getRowModel().flatRows.some(s=>!s.getIsExpanded()))},e.getExpandedDepth=()=>{let r=0;return(e.getState().expanded===!0?Object.keys(e.getRowModel().rowsById):Object.keys(e.getState().expanded)).forEach(o=>{const l=o.split(\".\");r=Math.max(r,l.length)}),r},e.getPreExpandedRowModel=()=>e.getSortedRowModel(),e.getExpandedRowModel=()=>(!e._getExpandedRowModel&&e.options.getExpandedRowModel&&(e._getExpandedRowModel=e.options.getExpandedRowModel(e)),e.options.manualExpanding||!e._getExpandedRowModel?e.getPreExpandedRowModel():e._getExpandedRowModel())},createRow:(e,t)=>{e.toggleExpanded=n=>{t.setExpanded(r=>{var s;const o=r===!0?!0:!!(r!=null&&r[e.id]);let l={};if(r===!0?Object.keys(t.getRowModel().rowsById).forEach(u=>{l[u]=!0}):l=r,n=(s=n)!=null?s:!o,!o&&n)return{...l,[e.id]:!0};if(o&&!n){const{[e.id]:u,...d}=l;return d}return r})},e.getIsExpanded=()=>{var n;const r=t.getState().expanded;return!!((n=t.options.getIsRowExpanded==null?void 0:t.options.getIsRowExpanded(e))!=null?n:r===!0||r?.[e.id])},e.getCanExpand=()=>{var n,r,s;return(n=t.options.getRowCanExpand==null?void 0:t.options.getRowCanExpand(e))!=null?n:((r=t.options.enableExpanding)!=null?r:!0)&&!!((s=e.subRows)!=null&&s.length)},e.getIsAllParentsExpanded=()=>{let n=!0,r=e;for(;n&&r.parentId;)r=t.getRow(r.parentId,!0),n=r.getIsExpanded();return n},e.getToggleExpandedHandler=()=>{const n=e.getCanExpand();return()=>{n&&e.toggleExpanded()}}}},Eb=0,kb=10,gy=()=>({pageIndex:Eb,pageSize:kb}),bee={getInitialState:e=>({...e,pagination:{...gy(),...e?.pagination}}),getDefaultOptions:e=>({onPaginationChange:qr(\"pagination\",e)}),createTable:e=>{let t=!1,n=!1;e._autoResetPageIndex=()=>{var r,s;if(!t){e._queue(()=>{t=!0});return}if((r=(s=e.options.autoResetAll)!=null?s:e.options.autoResetPageIndex)!=null?r:!e.options.manualPagination){if(n)return;n=!0,e._queue(()=>{e.resetPageIndex(),n=!1})}},e.setPagination=r=>{const s=o=>ma(r,o);return e.options.onPaginationChange==null?void 0:e.options.onPaginationChange(s)},e.resetPagination=r=>{var s;e.setPagination(r?gy():(s=e.initialState.pagination)!=null?s:gy())},e.setPageIndex=r=>{e.setPagination(s=>{let o=ma(r,s.pageIndex);const l=typeof e.options.pageCount>\"u\"||e.options.pageCount===-1?Number.MAX_SAFE_INTEGER:e.options.pageCount-1;return o=Math.max(0,Math.min(o,l)),{...s,pageIndex:o}})},e.resetPageIndex=r=>{var s,o;e.setPageIndex(r?Eb:(s=(o=e.initialState)==null||(o=o.pagination)==null?void 0:o.pageIndex)!=null?s:Eb)},e.resetPageSize=r=>{var s,o;e.setPageSize(r?kb:(s=(o=e.initialState)==null||(o=o.pagination)==null?void 0:o.pageSize)!=null?s:kb)},e.setPageSize=r=>{e.setPagination(s=>{const o=Math.max(1,ma(r,s.pageSize)),l=s.pageSize*s.pageIndex,u=Math.floor(l/o);return{...s,pageIndex:u,pageSize:o}})},e.setPageCount=r=>e.setPagination(s=>{var o;let l=ma(r,(o=e.options.pageCount)!=null?o:-1);return typeof l==\"number\"&&(l=Math.max(-1,l)),{...s,pageCount:l}}),e.getPageOptions=ot(()=>[e.getPageCount()],r=>{let s=[];return r&&r>0&&(s=[...new Array(r)].fill(null).map((o,l)=>l)),s},at(e.options,\"debugTable\")),e.getCanPreviousPage=()=>e.getState().pagination.pageIndex>0,e.getCanNextPage=()=>{const{pageIndex:r}=e.getState().pagination,s=e.getPageCount();return s===-1?!0:s===0?!1:r<s-1},e.previousPage=()=>e.setPageIndex(r=>r-1),e.nextPage=()=>e.setPageIndex(r=>r+1),e.firstPage=()=>e.setPageIndex(0),e.lastPage=()=>e.setPageIndex(e.getPageCount()-1),e.getPrePaginationRowModel=()=>e.getExpandedRowModel(),e.getPaginationRowModel=()=>(!e._getPaginationRowModel&&e.options.getPaginationRowModel&&(e._getPaginationRowModel=e.options.getPaginationRowModel(e)),e.options.manualPagination||!e._getPaginationRowModel?e.getPrePaginationRowModel():e._getPaginationRowModel()),e.getPageCount=()=>{var r;return(r=e.options.pageCount)!=null?r:Math.ceil(e.getRowCount()/e.getState().pagination.pageSize)},e.getRowCount=()=>{var r;return(r=e.options.rowCount)!=null?r:e.getPrePaginationRowModel().rows.length}}},my=()=>({top:[],bottom:[]}),xee={getInitialState:e=>({rowPinning:my(),...e}),getDefaultOptions:e=>({onRowPinningChange:qr(\"rowPinning\",e)}),createRow:(e,t)=>{e.pin=(n,r,s)=>{const o=r?e.getLeafRows().map(d=>{let{id:f}=d;return f}):[],l=s?e.getParentRows().map(d=>{let{id:f}=d;return f}):[],u=new Set([...l,e.id,...o]);t.setRowPinning(d=>{var f,h;if(n===\"bottom\"){var m,g;return{top:((m=d?.top)!=null?m:[]).filter(w=>!(u!=null&&u.has(w))),bottom:[...((g=d?.bottom)!=null?g:[]).filter(w=>!(u!=null&&u.has(w))),...Array.from(u)]}}if(n===\"top\"){var x,b;return{top:[...((x=d?.top)!=null?x:[]).filter(w=>!(u!=null&&u.has(w))),...Array.from(u)],bottom:((b=d?.bottom)!=null?b:[]).filter(w=>!(u!=null&&u.has(w)))}}return{top:((f=d?.top)!=null?f:[]).filter(w=>!(u!=null&&u.has(w))),bottom:((h=d?.bottom)!=null?h:[]).filter(w=>!(u!=null&&u.has(w)))}})},e.getCanPin=()=>{var n;const{enableRowPinning:r,enablePinning:s}=t.options;return typeof r==\"function\"?r(e):(n=r??s)!=null?n:!0},e.getIsPinned=()=>{const n=[e.id],{top:r,bottom:s}=t.getState().rowPinning,o=n.some(u=>r?.includes(u)),l=n.some(u=>s?.includes(u));return o?\"top\":l?\"bottom\":!1},e.getPinnedIndex=()=>{var n,r;const s=e.getIsPinned();if(!s)return-1;const o=(n=s===\"top\"?t.getTopRows():t.getBottomRows())==null?void 0:n.map(l=>{let{id:u}=l;return u});return(r=o?.indexOf(e.id))!=null?r:-1}},createTable:e=>{e.setRowPinning=t=>e.options.onRowPinningChange==null?void 0:e.options.onRowPinningChange(t),e.resetRowPinning=t=>{var n,r;return e.setRowPinning(t?my():(n=(r=e.initialState)==null?void 0:r.rowPinning)!=null?n:my())},e.getIsSomeRowsPinned=t=>{var n;const r=e.getState().rowPinning;if(!t){var s,o;return!!((s=r.top)!=null&&s.length||(o=r.bottom)!=null&&o.length)}return!!((n=r[t])!=null&&n.length)},e._getPinnedRows=(t,n,r)=>{var s;return((s=e.options.keepPinnedRows)==null||s?(n??[]).map(l=>{const u=e.getRow(l,!0);return u.getIsAllParentsExpanded()?u:null}):(n??[]).map(l=>t.find(u=>u.id===l))).filter(Boolean).map(l=>({...l,position:r}))},e.getTopRows=ot(()=>[e.getRowModel().rows,e.getState().rowPinning.top],(t,n)=>e._getPinnedRows(t,n,\"top\"),at(e.options,\"debugRows\")),e.getBottomRows=ot(()=>[e.getRowModel().rows,e.getState().rowPinning.bottom],(t,n)=>e._getPinnedRows(t,n,\"bottom\"),at(e.options,\"debugRows\")),e.getCenterRows=ot(()=>[e.getRowModel().rows,e.getState().rowPinning.top,e.getState().rowPinning.bottom],(t,n,r)=>{const s=new Set([...n??[],...r??[]]);return t.filter(o=>!s.has(o.id))},at(e.options,\"debugRows\"))}},wee={getInitialState:e=>({rowSelection:{},...e}),getDefaultOptions:e=>({onRowSelectionChange:qr(\"rowSelection\",e),enableRowSelection:!0,enableMultiRowSelection:!0,enableSubRowSelection:!0}),createTable:e=>{e.setRowSelection=t=>e.options.onRowSelectionChange==null?void 0:e.options.onRowSelectionChange(t),e.resetRowSelection=t=>{var n;return e.setRowSelection(t?{}:(n=e.initialState.rowSelection)!=null?n:{})},e.toggleAllRowsSelected=t=>{e.setRowSelection(n=>{t=typeof t<\"u\"?t:!e.getIsAllRowsSelected();const r={...n},s=e.getPreGroupedRowModel().flatRows;return t?s.forEach(o=>{o.getCanSelect()&&(r[o.id]=!0)}):s.forEach(o=>{delete r[o.id]}),r})},e.toggleAllPageRowsSelected=t=>e.setRowSelection(n=>{const r=typeof t<\"u\"?t:!e.getIsAllPageRowsSelected(),s={...n};return e.getRowModel().rows.forEach(o=>{jb(s,o.id,r,!0,e)}),s}),e.getPreSelectedRowModel=()=>e.getCoreRowModel(),e.getSelectedRowModel=ot(()=>[e.getState().rowSelection,e.getCoreRowModel()],(t,n)=>Object.keys(t).length?vy(e,n):{rows:[],flatRows:[],rowsById:{}},at(e.options,\"debugTable\")),e.getFilteredSelectedRowModel=ot(()=>[e.getState().rowSelection,e.getFilteredRowModel()],(t,n)=>Object.keys(t).length?vy(e,n):{rows:[],flatRows:[],rowsById:{}},at(e.options,\"debugTable\")),e.getGroupedSelectedRowModel=ot(()=>[e.getState().rowSelection,e.getSortedRowModel()],(t,n)=>Object.keys(t).length?vy(e,n):{rows:[],flatRows:[],rowsById:{}},at(e.options,\"debugTable\")),e.getIsAllRowsSelected=()=>{const t=e.getFilteredRowModel().flatRows,{rowSelection:n}=e.getState();let r=!!(t.length&&Object.keys(n).length);return r&&t.some(s=>s.getCanSelect()&&!n[s.id])&&(r=!1),r},e.getIsAllPageRowsSelected=()=>{const t=e.getPaginationRowModel().flatRows.filter(s=>s.getCanSelect()),{rowSelection:n}=e.getState();let r=!!t.length;return r&&t.some(s=>!n[s.id])&&(r=!1),r},e.getIsSomeRowsSelected=()=>{var t;const n=Object.keys((t=e.getState().rowSelection)!=null?t:{}).length;return n>0&&n<e.getFilteredRowModel().flatRows.length},e.getIsSomePageRowsSelected=()=>{const t=e.getPaginationRowModel().flatRows;return e.getIsAllPageRowsSelected()?!1:t.filter(n=>n.getCanSelect()).some(n=>n.getIsSelected()||n.getIsSomeSelected())},e.getToggleAllRowsSelectedHandler=()=>t=>{e.toggleAllRowsSelected(t.target.checked)},e.getToggleAllPageRowsSelectedHandler=()=>t=>{e.toggleAllPageRowsSelected(t.target.checked)}},createRow:(e,t)=>{e.toggleSelected=(n,r)=>{const s=e.getIsSelected();t.setRowSelection(o=>{var l;if(n=typeof n<\"u\"?n:!s,e.getCanSelect()&&s===n)return o;const u={...o};return jb(u,e.id,n,(l=r?.selectChildren)!=null?l:!0,t),u})},e.getIsSelected=()=>{const{rowSelection:n}=t.getState();return iw(e,n)},e.getIsSomeSelected=()=>{const{rowSelection:n}=t.getState();return Tb(e,n)===\"some\"},e.getIsAllSubRowsSelected=()=>{const{rowSelection:n}=t.getState();return Tb(e,n)===\"all\"},e.getCanSelect=()=>{var n;return typeof t.options.enableRowSelection==\"function\"?t.options.enableRowSelection(e):(n=t.options.enableRowSelection)!=null?n:!0},e.getCanSelectSubRows=()=>{var n;return typeof t.options.enableSubRowSelection==\"function\"?t.options.enableSubRowSelection(e):(n=t.options.enableSubRowSelection)!=null?n:!0},e.getCanMultiSelect=()=>{var n;return typeof t.options.enableMultiRowSelection==\"function\"?t.options.enableMultiRowSelection(e):(n=t.options.enableMultiRowSelection)!=null?n:!0},e.getToggleSelectedHandler=()=>{const n=e.getCanSelect();return r=>{var s;n&&e.toggleSelected((s=r.target)==null?void 0:s.checked)}}}},jb=(e,t,n,r,s)=>{var o;const l=s.getRow(t,!0);n?(l.getCanMultiSelect()||Object.keys(e).forEach(u=>delete e[u]),l.getCanSelect()&&(e[t]=!0)):delete e[t],r&&(o=l.subRows)!=null&&o.length&&l.getCanSelectSubRows()&&l.subRows.forEach(u=>jb(e,u.id,n,r,s))};function vy(e,t){const n=e.getState().rowSelection,r=[],s={},o=function(l,u){return l.map(d=>{var f;const h=iw(d,n);if(h&&(r.push(d),s[d.id]=d),(f=d.subRows)!=null&&f.length&&(d={...d,subRows:o(d.subRows)}),h)return d}).filter(Boolean)};return{rows:o(t.rows),flatRows:r,rowsById:s}}function iw(e,t){var n;return(n=t[e.id])!=null?n:!1}function Tb(e,t,n){var r;if(!((r=e.subRows)!=null&&r.length))return!1;let s=!0,o=!1;return e.subRows.forEach(l=>{if(!(o&&!s)&&(l.getCanSelect()&&(iw(l,t)?o=!0:s=!1),l.subRows&&l.subRows.length)){const u=Tb(l,t);u===\"all\"?o=!0:(u===\"some\"&&(o=!0),s=!1)}}),s?\"all\":o?\"some\":!1}const Nb=/([0-9]+)/gm,See=(e,t,n)=>vI(Na(e.getValue(n)).toLowerCase(),Na(t.getValue(n)).toLowerCase()),Cee=(e,t,n)=>vI(Na(e.getValue(n)),Na(t.getValue(n))),Eee=(e,t,n)=>lw(Na(e.getValue(n)).toLowerCase(),Na(t.getValue(n)).toLowerCase()),kee=(e,t,n)=>lw(Na(e.getValue(n)),Na(t.getValue(n))),jee=(e,t,n)=>{const r=e.getValue(n),s=t.getValue(n);return r>s?1:r<s?-1:0},Tee=(e,t,n)=>lw(e.getValue(n),t.getValue(n));function lw(e,t){return e===t?0:e>t?1:-1}function Na(e){return typeof e==\"number\"?isNaN(e)||e===1/0||e===-1/0?\"\":String(e):typeof e==\"string\"?e:\"\"}function vI(e,t){const n=e.split(Nb).filter(Boolean),r=t.split(Nb).filter(Boolean);for(;n.length&&r.length;){const s=n.shift(),o=r.shift(),l=parseInt(s,10),u=parseInt(o,10),d=[l,u].sort();if(isNaN(d[0])){if(s>o)return 1;if(o>s)return-1;continue}if(isNaN(d[1]))return isNaN(l)?-1:1;if(l>u)return 1;if(u>l)return-1}return n.length-r.length}const pu={alphanumeric:See,alphanumericCaseSensitive:Cee,text:Eee,textCaseSensitive:kee,datetime:jee,basic:Tee},Nee={getInitialState:e=>({sorting:[],...e}),getDefaultColumnDef:()=>({sortingFn:\"auto\",sortUndefined:1}),getDefaultOptions:e=>({onSortingChange:qr(\"sorting\",e),isMultiSortEvent:t=>t.shiftKey}),createColumn:(e,t)=>{e.getAutoSortingFn=()=>{const n=t.getFilteredRowModel().flatRows.slice(10);let r=!1;for(const s of n){const o=s?.getValue(e.id);if(Object.prototype.toString.call(o)===\"[object Date]\")return pu.datetime;if(typeof o==\"string\"&&(r=!0,o.split(Nb).length>1))return pu.alphanumeric}return r?pu.text:pu.basic},e.getAutoSortDir=()=>{const n=t.getFilteredRowModel().flatRows[0];return typeof n?.getValue(e.id)==\"string\"?\"asc\":\"desc\"},e.getSortingFn=()=>{var n,r;if(!e)throw new Error;return yg(e.columnDef.sortingFn)?e.columnDef.sortingFn:e.columnDef.sortingFn===\"auto\"?e.getAutoSortingFn():(n=(r=t.options.sortingFns)==null?void 0:r[e.columnDef.sortingFn])!=null?n:pu[e.columnDef.sortingFn]},e.toggleSorting=(n,r)=>{const s=e.getNextSortingOrder(),o=typeof n<\"u\"&&n!==null;t.setSorting(l=>{const u=l?.find(x=>x.id===e.id),d=l?.findIndex(x=>x.id===e.id);let f=[],h,m=o?n:s===\"desc\";if(l!=null&&l.length&&e.getCanMultiSort()&&r?u?h=\"toggle\":h=\"add\":l!=null&&l.length&&d!==l.length-1?h=\"replace\":u?h=\"toggle\":h=\"replace\",h===\"toggle\"&&(o||s||(h=\"remove\")),h===\"add\"){var g;f=[...l,{id:e.id,desc:m}],f.splice(0,f.length-((g=t.options.maxMultiSortColCount)!=null?g:Number.MAX_SAFE_INTEGER))}else h===\"toggle\"?f=l.map(x=>x.id===e.id?{...x,desc:m}:x):h===\"remove\"?f=l.filter(x=>x.id!==e.id):f=[{id:e.id,desc:m}];return f})},e.getFirstSortDir=()=>{var n,r;return((n=(r=e.columnDef.sortDescFirst)!=null?r:t.options.sortDescFirst)!=null?n:e.getAutoSortDir()===\"desc\")?\"desc\":\"asc\"},e.getNextSortingOrder=n=>{var r,s;const o=e.getFirstSortDir(),l=e.getIsSorted();return l?l!==o&&((r=t.options.enableSortingRemoval)==null||r)&&(!(n&&(s=t.options.enableMultiRemove)!=null)||s)?!1:l===\"desc\"?\"asc\":\"desc\":o},e.getCanSort=()=>{var n,r;return((n=e.columnDef.enableSorting)!=null?n:!0)&&((r=t.options.enableSorting)!=null?r:!0)&&!!e.accessorFn},e.getCanMultiSort=()=>{var n,r;return(n=(r=e.columnDef.enableMultiSort)!=null?r:t.options.enableMultiSort)!=null?n:!!e.accessorFn},e.getIsSorted=()=>{var n;const r=(n=t.getState().sorting)==null?void 0:n.find(s=>s.id===e.id);return r?r.desc?\"desc\":\"asc\":!1},e.getSortIndex=()=>{var n,r;return(n=(r=t.getState().sorting)==null?void 0:r.findIndex(s=>s.id===e.id))!=null?n:-1},e.clearSorting=()=>{t.setSorting(n=>n!=null&&n.length?n.filter(r=>r.id!==e.id):[])},e.getToggleSortingHandler=()=>{const n=e.getCanSort();return r=>{n&&(r.persist==null||r.persist(),e.toggleSorting==null||e.toggleSorting(void 0,e.getCanMultiSort()?t.options.isMultiSortEvent==null?void 0:t.options.isMultiSortEvent(r):!1))}}},createTable:e=>{e.setSorting=t=>e.options.onSortingChange==null?void 0:e.options.onSortingChange(t),e.resetSorting=t=>{var n,r;e.setSorting(t?[]:(n=(r=e.initialState)==null?void 0:r.sorting)!=null?n:[])},e.getPreSortedRowModel=()=>e.getGroupedRowModel(),e.getSortedRowModel=()=>(!e._getSortedRowModel&&e.options.getSortedRowModel&&(e._getSortedRowModel=e.options.getSortedRowModel(e)),e.options.manualSorting||!e._getSortedRowModel?e.getPreSortedRowModel():e._getSortedRowModel())}},Mee=[ZX,gee,dee,fee,YX,XX,mee,vee,Nee,cee,yee,bee,xee,wee,pee];function _ee(e){var t,n;const r=[...Mee,...(t=e._features)!=null?t:[]];let s={_features:r};const o=s._features.reduce((g,x)=>Object.assign(g,x.getDefaultOptions==null?void 0:x.getDefaultOptions(s)),{}),l=g=>s.options.mergeOptions?s.options.mergeOptions(o,g):{...o,...g};let d={...{},...(n=e.initialState)!=null?n:{}};s._features.forEach(g=>{var x;d=(x=g.getInitialState==null?void 0:g.getInitialState(d))!=null?x:d});const f=[];let h=!1;const m={_features:r,options:{...o,...e},initialState:d,_queue:g=>{f.push(g),h||(h=!0,Promise.resolve().then(()=>{for(;f.length;)f.shift()();h=!1}).catch(x=>setTimeout(()=>{throw x})))},reset:()=>{s.setState(s.initialState)},setOptions:g=>{const x=ma(g,s.options);s.options=l(x)},getState:()=>s.options.state,setState:g=>{s.options.onStateChange==null||s.options.onStateChange(g)},_getRowId:(g,x,b)=>{var w;return(w=s.options.getRowId==null?void 0:s.options.getRowId(g,x,b))!=null?w:`${b?[b.id,x].join(\".\"):x}`},getCoreRowModel:()=>(s._getCoreRowModel||(s._getCoreRowModel=s.options.getCoreRowModel(s)),s._getCoreRowModel()),getRowModel:()=>s.getPaginationRowModel(),getRow:(g,x)=>{let b=(x?s.getPrePaginationRowModel():s.getRowModel()).rowsById[g];if(!b&&(b=s.getCoreRowModel().rowsById[g],!b))throw new Error;return b},_getDefaultColumnDef:ot(()=>[s.options.defaultColumn],g=>{var x;return g=(x=g)!=null?x:{},{header:b=>{const w=b.header.column.columnDef;return w.accessorKey?w.accessorKey:w.accessorFn?w.id:null},cell:b=>{var w,C;return(w=(C=b.renderValue())==null||C.toString==null?void 0:C.toString())!=null?w:null},...s._features.reduce((b,w)=>Object.assign(b,w.getDefaultColumnDef==null?void 0:w.getDefaultColumnDef()),{}),...g}},at(e,\"debugColumns\")),_getColumnDefs:()=>s.options.columns,getAllColumns:ot(()=>[s._getColumnDefs()],g=>{const x=function(b,w,C){return C===void 0&&(C=0),b.map(k=>{const j=QX(s,k,C,w),M=k;return j.columns=M.columns?x(M.columns,j,C+1):[],j})};return x(g)},at(e,\"debugColumns\")),getAllFlatColumns:ot(()=>[s.getAllColumns()],g=>g.flatMap(x=>x.getFlatColumns()),at(e,\"debugColumns\")),_getAllFlatColumnsById:ot(()=>[s.getAllFlatColumns()],g=>g.reduce((x,b)=>(x[b.id]=b,x),{}),at(e,\"debugColumns\")),getAllLeafColumns:ot(()=>[s.getAllColumns(),s._getOrderColumnsFn()],(g,x)=>{let b=g.flatMap(w=>w.getLeafColumns());return x(b)},at(e,\"debugColumns\")),getColumn:g=>s._getAllFlatColumnsById()[g]};Object.assign(s,m);for(let g=0;g<s._features.length;g++){const x=s._features[g];x==null||x.createTable==null||x.createTable(s)}return s}function Ree(){return e=>ot(()=>[e.options.data],t=>{const n={rows:[],flatRows:[],rowsById:{}},r=function(s,o,l){o===void 0&&(o=0);const u=[];for(let f=0;f<s.length;f++){const h=bg(e,e._getRowId(s[f],f,l),s[f],f,o,void 0,l?.id);if(n.flatRows.push(h),n.rowsById[h.id]=h,u.push(h),e.options.getSubRows){var d;h.originalSubRows=e.options.getSubRows(s[f],f),(d=h.originalSubRows)!=null&&d.length&&(h.subRows=r(h.originalSubRows,o+1,h))}}return u};return n.rows=r(t),n},at(e.options,\"debugTable\",\"getRowModel\",()=>e._autoResetPageIndex()))}function Pee(e,t,n){return n.options.filterFromLeafRows?Oee(e,t,n):Iee(e,t,n)}function Oee(e,t,n){var r;const s=[],o={},l=(r=n.options.maxLeafRowFilterDepth)!=null?r:100,u=function(d,f){f===void 0&&(f=0);const h=[];for(let g=0;g<d.length;g++){var m;let x=d[g];const b=bg(n,x.id,x.original,x.index,x.depth,void 0,x.parentId);if(b.columnFilters=x.columnFilters,(m=x.subRows)!=null&&m.length&&f<l){if(b.subRows=u(x.subRows,f+1),x=b,t(x)&&!b.subRows.length){h.push(x),o[x.id]=x,s.push(x);continue}if(t(x)||b.subRows.length){h.push(x),o[x.id]=x,s.push(x);continue}}else x=b,t(x)&&(h.push(x),o[x.id]=x,s.push(x))}return h};return{rows:u(e),flatRows:s,rowsById:o}}function Iee(e,t,n){var r;const s=[],o={},l=(r=n.options.maxLeafRowFilterDepth)!=null?r:100,u=function(d,f){f===void 0&&(f=0);const h=[];for(let g=0;g<d.length;g++){let x=d[g];if(t(x)){var m;if((m=x.subRows)!=null&&m.length&&f<l){const w=bg(n,x.id,x.original,x.index,x.depth,void 0,x.parentId);w.subRows=u(x.subRows,f+1),x=w}h.push(x),s.push(x),o[x.id]=x}}return h};return{rows:u(e),flatRows:s,rowsById:o}}function Aee(){return e=>ot(()=>[e.getPreFilteredRowModel(),e.getState().columnFilters,e.getState().globalFilter],(t,n,r)=>{if(!t.rows.length||!(n!=null&&n.length)&&!r){for(let g=0;g<t.flatRows.length;g++)t.flatRows[g].columnFilters={},t.flatRows[g].columnFiltersMeta={};return t}const s=[],o=[];(n??[]).forEach(g=>{var x;const b=e.getColumn(g.id);if(!b)return;const w=b.getFilterFn();w&&s.push({id:g.id,filterFn:w,resolvedValue:(x=w.resolveFilterValue==null?void 0:w.resolveFilterValue(g.value))!=null?x:g.value})});const l=(n??[]).map(g=>g.id),u=e.getGlobalFilterFn(),d=e.getAllLeafColumns().filter(g=>g.getCanGlobalFilter());r&&u&&d.length&&(l.push(\"__global__\"),d.forEach(g=>{var x;o.push({id:g.id,filterFn:u,resolvedValue:(x=u.resolveFilterValue==null?void 0:u.resolveFilterValue(r))!=null?x:r})}));let f,h;for(let g=0;g<t.flatRows.length;g++){const x=t.flatRows[g];if(x.columnFilters={},s.length)for(let b=0;b<s.length;b++){f=s[b];const w=f.id;x.columnFilters[w]=f.filterFn(x,w,f.resolvedValue,C=>{x.columnFiltersMeta[w]=C})}if(o.length){for(let b=0;b<o.length;b++){h=o[b];const w=h.id;if(h.filterFn(x,w,h.resolvedValue,C=>{x.columnFiltersMeta[w]=C})){x.columnFilters.__global__=!0;break}}x.columnFilters.__global__!==!0&&(x.columnFilters.__global__=!1)}}const m=g=>{for(let x=0;x<l.length;x++)if(g.columnFilters[l[x]]===!1)return!1;return!0};return Pee(t.rows,m,e)},at(e.options,\"debugTable\",\"getFilteredRowModel\",()=>e._autoResetPageIndex()))}function Dee(){return e=>ot(()=>[e.getState().grouping,e.getPreGroupedRowModel()],(t,n)=>{if(!n.rows.length||!t.length)return n.rows.forEach(d=>{d.depth=0,d.parentId=void 0}),n;const r=t.filter(d=>e.getColumn(d)),s=[],o={},l=function(d,f,h){if(f===void 0&&(f=0),f>=r.length)return d.map(b=>(b.depth=f,s.push(b),o[b.id]=b,b.subRows&&(b.subRows=l(b.subRows,f+1,b.id)),b));const m=r[f],g=Fee(d,m);return Array.from(g.entries()).map((b,w)=>{let[C,k]=b,j=`${m}:${C}`;j=h?`${h}>${j}`:j;const M=l(k,f+1,j);M.forEach(N=>{N.parentId=j});const _=f?lI(k,N=>N.subRows):k,R=bg(e,j,_[0].original,w,f,void 0,h);return Object.assign(R,{groupingColumnId:m,groupingValue:C,subRows:M,leafRows:_,getValue:N=>{if(r.includes(N)){if(R._valuesCache.hasOwnProperty(N))return R._valuesCache[N];if(k[0]){var O;R._valuesCache[N]=(O=k[0].getValue(N))!=null?O:void 0}return R._valuesCache[N]}if(R._groupingValuesCache.hasOwnProperty(N))return R._groupingValuesCache[N];const D=e.getColumn(N),z=D?.getAggregationFn();if(z)return R._groupingValuesCache[N]=z(N,_,k),R._groupingValuesCache[N]}}),M.forEach(N=>{s.push(N),o[N.id]=N}),R})},u=l(n.rows,0);return u.forEach(d=>{s.push(d),o[d.id]=d}),{rows:u,flatRows:s,rowsById:o}},at(e.options,\"debugTable\",\"getGroupedRowModel\",()=>{e._queue(()=>{e._autoResetExpanded(),e._autoResetPageIndex()})}))}function Fee(e,t){const n=new Map;return e.reduce((r,s)=>{const o=`${s.getGroupingValue(t)}`,l=r.get(o);return l?l.push(s):r.set(o,[s]),r},n)}function Lee(){return e=>ot(()=>[e.getState().sorting,e.getPreSortedRowModel()],(t,n)=>{if(!n.rows.length||!(t!=null&&t.length))return n;const r=e.getState().sorting,s=[],o=r.filter(d=>{var f;return(f=e.getColumn(d.id))==null?void 0:f.getCanSort()}),l={};o.forEach(d=>{const f=e.getColumn(d.id);f&&(l[d.id]={sortUndefined:f.columnDef.sortUndefined,invertSorting:f.columnDef.invertSorting,sortingFn:f.getSortingFn()})});const u=d=>{const f=d.map(h=>({...h}));return f.sort((h,m)=>{for(let x=0;x<o.length;x+=1){var g;const b=o[x],w=l[b.id],C=w.sortUndefined,k=(g=b?.desc)!=null?g:!1;let j=0;if(C){const M=h.getValue(b.id),_=m.getValue(b.id),R=M===void 0,N=_===void 0;if(R||N){if(C===\"first\")return R?-1:1;if(C===\"last\")return R?1:-1;j=R&&N?0:R?C:-C}}if(j===0&&(j=w.sortingFn(h,m,b.id)),j!==0)return k&&(j*=-1),w.invertSorting&&(j*=-1),j}return h.index-m.index}),f.forEach(h=>{var m;s.push(h),(m=h.subRows)!=null&&m.length&&(h.subRows=u(h.subRows))}),f};return{rows:u(n.rows),flatRows:s,rowsById:n.rowsById}},at(e.options,\"debugTable\",\"getSortedRowModel\",()=>e._autoResetPageIndex()))}/**\n   * react-table\n   *\n   * Copyright (c) TanStack\n   *\n   * This source code is licensed under the MIT license found in the\n   * LICENSE.md file in the root directory of this source tree.\n   *\n   * @license MIT\n   */function bk(e,t){return e?$ee(e)?y.createElement(e,t):e:null}function $ee(e){return Bee(e)||typeof e==\"function\"||zee(e)}function Bee(e){return typeof e==\"function\"&&(()=>{const t=Object.getPrototypeOf(e);return t.prototype&&t.prototype.isReactComponent})()}function zee(e){return typeof e==\"object\"&&typeof e.$$typeof==\"symbol\"&&[\"react.memo\",\"react.forward_ref\"].includes(e.$$typeof.description)}function Uee(e){const t={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[n]=y.useState(()=>({current:_ee(t)})),[r,s]=y.useState(()=>n.current.initialState);return n.current.setOptions(o=>({...o,...e,state:{...r,...e.state},onStateChange:l=>{s(l),e.onStateChange==null||e.onStateChange(l)}})),n.current}const yI=y.forwardRef(({className:e,...t},n)=>i.jsx(\"div\",{className:\"relative w-full overflow-auto\",children:i.jsx(\"table\",{ref:n,className:Ie(\"w-full caption-bottom text-sm\",e),...t})}));yI.displayName=\"Table\";const bI=y.forwardRef(({className:e,...t},n)=>i.jsx(\"thead\",{ref:n,className:Ie(\"[&_tr]:border-b\",e),...t}));bI.displayName=\"TableHeader\";const xI=y.forwardRef(({className:e,...t},n)=>i.jsx(\"tbody\",{ref:n,className:Ie(\"[&_tr:last-child]:border-0\",e),...t}));xI.displayName=\"TableBody\";const Vee=y.forwardRef(({className:e,...t},n)=>i.jsx(\"tfoot\",{ref:n,className:Ie(\"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\",e),...t}));Vee.displayName=\"TableFooter\";const Eu=y.forwardRef(({className:e,...t},n)=>i.jsx(\"tr\",{ref:n,className:Ie(\"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted\",e),...t}));Eu.displayName=\"TableRow\";const wI=y.forwardRef(({className:e,...t},n)=>i.jsx(\"th\",{ref:n,className:Ie(\"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0\",e),...t}));wI.displayName=\"TableHead\";const Np=y.forwardRef(({className:e,...t},n)=>i.jsx(\"td\",{ref:n,className:Ie(\"p-4 align-middle [&:has([role=checkbox])]:pr-0\",e),...t}));Np.displayName=\"TableCell\";const Hee=y.forwardRef(({className:e,...t},n)=>i.jsx(\"caption\",{ref:n,className:Ie(\"mt-4 text-sm text-muted-foreground\",e),...t}));Hee.displayName=\"TableCaption\";function $a({columns:e,data:t,isLoading:n,loadingMessage:r,noResultsMessage:s,enableHeaders:o=!0,className:l,highlightedRows:u,...d}){const f=Uee({...d,data:t,columns:e,getCoreRowModel:Ree(),getFilteredRowModel:Aee(),getGroupedRowModel:Dee(),getSortedRowModel:Lee()});return i.jsx(\"div\",{className:Ie(\"rounded-md border\",l),children:i.jsxs(yI,{children:[o&&i.jsx(bI,{children:f.getHeaderGroups().map(h=>i.jsx(Eu,{children:h.headers.map(m=>i.jsx(wI,{children:m.isPlaceholder?null:bk(m.column.columnDef.header,m.getContext())},m.id))},h.id))}),i.jsx(xI,{children:n?i.jsx(Eu,{children:i.jsx(Np,{colSpan:e.length,className:\"h-24 text-center text-muted-foreground\",children:r??\"Carregando...\"})}):i.jsx(i.Fragment,{children:f.getRowModel().rows?.length?f.getRowModel().rows.map(h=>i.jsx(Eu,{\"data-state\":h.getIsSelected()?\"selected\":u?.includes(h.id)?\"highlighted\":\"\",children:h.getVisibleCells().map(m=>i.jsx(Np,{children:bk(m.column.columnDef.cell,m.getContext())},m.id))},h.id)):i.jsx(Eu,{children:i.jsx(Np,{colSpan:e.length,className:\"h-24 text-center\",children:s??\"Nenhum resultado encontrado!\"})})})})]})})}const qee=e=>[\"dify\",\"fetchSessions\",JSON.stringify(e)],Kee=async({difyId:e,instanceName:t})=>(await Ee.get(`/dify/fetchSessions/${e}/${t}`)).data,Wee=e=>{const{difyId:t,instanceName:n,...r}=e;return mt({...r,queryKey:qee({difyId:t,instanceName:n}),queryFn:()=>Kee({difyId:t,instanceName:n}),enabled:!!n&&!!t&&(e.enabled??!0),staleTime:1e3*10})};function SI({difyId:e}){const{t}=Ve(),{instance:n}=ct(),{changeStatusDify:r}=vg(),[s,o]=y.useState([]),{data:l,refetch:u}=Wee({difyId:e,instanceName:n?.name}),[d,f]=y.useState(!1),[h,m]=y.useState(\"\");function g(){u()}const x=async(w,C)=>{try{if(!n)return;await r({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"dify.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"dify.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"dify.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"dify.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"dify.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"dify.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:t(\"dify.sessions.table.actions.title\")}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"dify.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"dify.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"dify.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"dify.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:d,onOpenChange:f,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"dify.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"dify.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"dify.sessions.search\"),value:h,onChange:w=>m(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{})})]}),i.jsx($a,{columns:b,data:l??[],onSortingChange:o,state:{sorting:s,globalFilter:h},onGlobalFilterChange:m,enableGlobalFilter:!0,noResultsMessage:t(\"dify.sessions.table.none\")})]})]})]})}const Gee=P.object({enabled:P.boolean(),description:P.string(),botType:P.string(),apiUrl:P.string(),apiKey:P.string(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function CI({initialData:e,onSubmit:t,handleDelete:n,difyId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{}}){const{t:d}=Ve(),f=on({resolver:an(Gee),defaultValues:e||{enabled:!0,description:\"\",botType:\"chatBot\",apiUrl:\"\",apiKey:\"\",triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,splitMessages:!1,timePerChar:0}}),h=f.watch(\"triggerType\");return i.jsx(Gn,{...f,children:i.jsxs(\"form\",{onSubmit:f.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:d(\"dify.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:d(\"dify.form.description.label\"),required:!0,children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"dify.form.difySettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"botType\",label:d(\"dify.form.botType.label\"),options:[{label:d(\"dify.form.botType.chatBot\"),value:\"chatBot\"},{label:d(\"dify.form.botType.textGenerator\"),value:\"textGenerator\"},{label:d(\"dify.form.botType.agent\"),value:\"agent\"},{label:d(\"dify.form.botType.workflow\"),value:\"workflow\"}]}),i.jsx(le,{name:\"apiUrl\",label:d(\"dify.form.apiUrl.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(le,{name:\"apiKey\",label:d(\"dify.form.apiKey.label\"),required:!0,children:i.jsx(ne,{type:\"password\"})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"dify.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:d(\"dify.form.triggerType.label\"),options:[{label:d(\"dify.form.triggerType.keyword\"),value:\"keyword\"},{label:d(\"dify.form.triggerType.all\"),value:\"all\"},{label:d(\"dify.form.triggerType.advanced\"),value:\"advanced\"},{label:d(\"dify.form.triggerType.none\"),value:\"none\"}]}),h===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:d(\"dify.form.triggerOperator.label\"),options:[{label:d(\"dify.form.triggerOperator.contains\"),value:\"contains\"},{label:d(\"dify.form.triggerOperator.equals\"),value:\"equals\"},{label:d(\"dify.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:d(\"dify.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:d(\"dify.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:d(\"dify.form.triggerValue.label\"),children:i.jsx(ne,{})})]}),h===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:d(\"dify.form.triggerConditions.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"dify.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:d(\"dify.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:d(\"dify.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:d(\"dify.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:d(\"dify.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:d(\"dify.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:d(\"dify.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:d(\"dify.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:d(\"dify.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:d(\"dify.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:d(\"dify.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"dify.button.saving\":\"dify.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx(SI,{difyId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:d(\"dify.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:d(\"modal.delete.title\")}),i.jsx(eo,{children:d(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:d(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:d(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"dify.button.saving\":\"dify.button.update\")})]})]})]})})}function Jee({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),[r,s]=y.useState(!1),[o,l]=y.useState(!1),{createDify:u}=vg(),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");s(!0);const h={enabled:f.enabled,description:f.description,botType:f.botType,apiUrl:f.apiUrl,apiKey:f.apiKey,triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0,splitMessages:f.splitMessages||!1,timePerChar:f.timePerChar||0};await u({instanceName:n.name,token:n.token,data:h}),me.success(t(\"dify.toast.success.create\")),l(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{s(!1)}};return i.jsxs(Pt,{open:o,onOpenChange:l,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"dify.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"dify.form.title\")})}),i.jsx(CI,{onSubmit:d,isModal:!0,isLoading:r})]})]})}const Qee=e=>[\"dify\",\"getDify\",JSON.stringify(e)],Zee=async({difyId:e,instanceName:t})=>(await Ee.get(`/dify/fetch/${e}/${t}`)).data,Yee=e=>{const{difyId:t,instanceName:n,...r}=e;return mt({...r,queryKey:Qee({difyId:t,instanceName:n}),queryFn:()=>Zee({difyId:t,instanceName:n}),enabled:!!n&&!!t&&(e.enabled??!0)})};function Xee({difyId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteDify:u,updateDify:d}=vg(),{data:f,isLoading:h}=Yee({difyId:e,instanceName:r?.name}),m=y.useMemo(()=>({enabled:!!f?.enabled,description:f?.description??\"\",botType:f?.botType??\"\",apiUrl:f?.apiUrl??\"\",apiKey:f?.apiKey??\"\",triggerType:f?.triggerType??\"\",triggerOperator:f?.triggerOperator??\"\",triggerValue:f?.triggerValue??\"\",expire:f?.expire??0,keywordFinish:f?.keywordFinish??\"\",delayMessage:f?.delayMessage??0,unknownMessage:f?.unknownMessage??\"\",listeningFromMe:!!f?.listeningFromMe,stopBotFromMe:!!f?.stopBotFromMe,keepOpen:!!f?.keepOpen,debounceTime:f?.debounceTime??0,splitMessages:f?.splitMessages??!1,timePerChar:f?.timePerChar??0}),[f?.apiKey,f?.apiUrl,f?.botType,f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.stopBotFromMe,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.unknownMessage,f?.splitMessages,f?.timePerChar]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,botType:b.botType,apiUrl:b.apiUrl,apiKey:b.apiKey,triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0,splitMessages:b.splitMessages||!1,timePerChar:b.timePerChar||0};await d({instanceName:r.name,difyId:e,data:w}),me.success(n(\"dify.toast.success.update\")),t(),s(`/manager/instance/${r.id}/dify/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,difyId:e}),me.success(n(\"dify.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/dify`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir dify:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(CI,{initialData:m,onSubmit:g,difyId:e,handleDelete:x,isModal:!1,isLoading:h,openDeletionDialog:o,setOpenDeletionDialog:l})})}function xk(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{difyId:r}=ls(),{data:s,refetch:o,isLoading:l}=iI({instanceName:n?.name}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/dify/${h}`)},f=()=>{o()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"dify.title\")}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-2\",children:[i.jsx(SI,{}),i.jsx(WX,{}),i.jsx(Jee,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:l?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsxs(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:[i.jsx(\"h4\",{className:\"text-base\",children:h.description||h.id}),i.jsx(\"p\",{className:\"text-sm font-normal text-muted-foreground\",children:h.botType})]},h.id)):i.jsx(se,{variant:\"link\",children:e(\"dify.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-border\"}),i.jsx(Hn,{children:i.jsx(Xee,{difyId:r,resetTable:f})})]})]})]})}const EI=y.createContext({instance:null,isLoading:!0,error:null});function ete({children:e}){const[t]=hd(),[n,r]=y.useState(null),[s,o]=y.useState(!0),[l,u]=y.useState(null);return y.useEffect(()=>{(async()=>{const f=t.get(\"token\"),h=t.get(\"instanceName\"),m=t.get(\"apiUrl\");if(!f||!h||!m){u(\"Token, instanceName e apiUrl são obrigatórios\"),o(!1);return}try{const g=m.endsWith(\"/\")?m.slice(0,-1):m;localStorage.setItem(jn.API_URL,g),localStorage.setItem(jn.INSTANCE_TOKEN,f);const{data:x}=await sn.get(`${g}/instance/fetchInstances?instanceName=${h}`,{headers:{apikey:f}});console.log(\"API Response:\",x),x&&Array.isArray(x)&&x.length>0?r(x[0]):u(\"Instância não encontrada\")}catch{u(\"Erro ao validar token ou buscar instância\")}finally{o(!1)}})()},[t]),i.jsx(EI.Provider,{value:{instance:n,isLoading:s,error:l},children:e})}const cw=()=>y.useContext(EI),uw=y.createContext({}),tte=({children:e})=>{const[t,n]=y.useState(null);return i.jsx(uw.Provider,{value:{replyingMessage:t,setReplyingMessage:n},children:e})},nte=e=>{const t=Math.floor(e/60),n=e%60,r=t<10?`${t}`:t,s=n<10?`0${n}`:n;return`${r}:${s}`},wk=200,rte=({imageMessage:e})=>i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(\"img\",{src:e?.mediaUrl,alt:\"Quoted message\",width:100,height:100}),i.jsx(cB,{className:\"mr-2 h-4 w-4 text-muted-foreground\"})]}),i.jsx(\"span\",{className:\"inline-block max-w-40 overflow-hidden overflow-ellipsis whitespace-nowrap text-sm text-muted-foreground\",children:e.caption})]}),ste=({videoMessage:e})=>i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(\"img\",{src:e?.mediaUrl,alt:\"Quoted message\",width:100,height:100}),i.jsx(TB,{className:\"mr-2 h-4 w-4 text-muted-foreground\"})]}),i.jsx(\"span\",{className:\"inline-block max-w-40 overflow-hidden overflow-ellipsis whitespace-nowrap text-sm text-muted-foreground\",children:e.caption})]}),ote=({audioMessage:e})=>i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(hT,{className:\"h-6 w-6 text-muted-foreground\"}),i.jsx(\"span\",{className:\"text-sm text-muted-foreground\",children:nte(e.seconds)})]}),i.jsx(\"span\",{className:\"inline-block max-w-40 overflow-hidden overflow-ellipsis whitespace-nowrap text-sm text-muted-foreground\",children:e.fileName})]}),ate=({stickerMessage:e})=>i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(\"img\",{src:e.mediaUrl,alt:\"Sticker\",width:100,height:100}),i.jsx(CB,{className:\"h-6 w-6 text-muted-foreground\"})]}),ite=({documentMessage:e})=>i.jsx(\"div\",{className:\"flex flex-col gap-2\",children:i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(Hb,{className:\"h-6 w-6 text-muted-foreground\"}),i.jsx(\"span\",{className:\"text-sm text-muted-foreground\",children:e.fileName})]})}),lte=({documentMessage:e})=>i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(Hb,{className:\"h-6 w-6 text-muted-foreground\"}),i.jsx(\"span\",{className:\"text-sm text-muted-foreground\",children:e.fileName})]}),i.jsx(\"span\",{className:\"inline-block max-w-40 overflow-hidden overflow-ellipsis whitespace-nowrap text-sm text-muted-foreground\",children:e.caption})]}),cte=({contactMessage:e})=>i.jsx(\"div\",{className:\"flex flex-col gap-2\",children:i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(Ap,{className:\"h-6 w-6 text-muted-foreground\"}),i.jsx(\"span\",{className:\"text-sm text-muted-foreground\",children:e.displayName})]})}),ute=({locationMessage:e})=>i.jsxs(\"div\",{className:\"flex flex-col gap-2\",children:[i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(yB,{className:\"h-6 w-6 text-muted-foreground\"}),i.jsx(\"span\",{className:\"text-sm text-muted-foreground\",children:e.name})]}),i.jsx(\"span\",{className:\"inline-block max-w-40 text-sm text-muted-foreground\",children:e.address})]}),dte=({conversation:e})=>i.jsx(\"span\",{className:\"overflow-hidden text-ellipsis whitespace-nowrap text-sm text-muted-foreground\",children:e.length>wk?`${e.substring(0,wk)}...`:e}),fte=({chat:e})=>{const{replyingMessage:t,setReplyingMessage:n}=y.useContext(uw),r=()=>{n(null)},s=f=>f?.conversation?f.conversation:f?.viewOnceMessage?.message?.interactiveMessage?.body?.text?f.viewOnceMessage.message.interactiveMessage.body.text:\"\",o=()=>t?.key.fromMe?\"Você\":e?.pushName,l=()=>{if(t?.messageType===\"imageMessage\")return i.jsx(rte,{imageMessage:{caption:t?.message.imageMessage.caption,mediaUrl:t?.message.mediaUrl}});if(t?.messageType===\"videoMessage\")return i.jsx(ste,{videoMessage:{caption:t?.message.videoMessage.caption,mediaUrl:t?.message.mediaUrl}});if(t?.messageType===\"audioMessage\")return i.jsx(ote,{audioMessage:t?.message.audioMessage});if(t?.messageType===\"stickerMessage\")return i.jsx(ate,{stickerMessage:t?.message});if(t?.messageType===\"documentMessage\")return i.jsx(ite,{documentMessage:{name:t?.message.documentMessage.name,mediaUrl:t?.message.mediaUrl}});if(t?.messageType===\"documentWithCaptionMessage\")return i.jsx(lte,{documentMessage:{name:t?.message.documentWithCaptionMessage.message.documentMessage.name,caption:t?.message.documentWithCaptionMessage.message.documentMessage.caption,mediaUrl:t?.message.mediaUrl}});if(t?.messageType===\"contactMessage\")return i.jsx(cte,{contactMessage:t?.message.contactMessage});if(t?.messageType===\"locationMessage\")return i.jsx(ute,{locationMessage:t?.message.locationMessage});if(t?.messageType===\"conversation\"||t?.messageType===\"interactiveMessage\"||t?.messageType===\"extendedTextMessage\")return i.jsx(dte,{conversation:s(t?.message)})},{inputIconsMainColor:u,inputBackgroundColor:d}=La();return i.jsxs(\"div\",{className:\"relative flex items-center overflow-hidden rounded-lg dark:text-white\",style:{backgroundColor:d},children:[i.jsx(\"div\",{className:`absolute h-full w-1 rounded-l-lg ${t?.key.fromMe?\"bg-blue-700 dark:bg-blue-300\":\"bg-blue-100\"}`}),i.jsxs(\"div\",{className:\"flex min-w-0 flex-1 flex-col gap-2 p-2 pl-4\",children:[i.jsx(\"span\",{className:`text-sm font-bold ${t?.key.fromMe?\"text-blue-700 dark:text-blue-300\":\"text-blue-600\"}`,children:o()}),l()]}),i.jsx(se,{size:\"icon\",variant:\"ghost\",className:\"ml-auto h-10 w-10 shrink-0 rounded-full\",onClick:r,style:{backgroundColor:d,color:u},children:i.jsx(qb,{className:\"h-6 w-6\"})})]})},yy=[{name:\"Smileys\",icon:gT,emojis:[\"😀\",\"😃\",\"😄\",\"😁\",\"😆\",\"😅\",\"😂\",\"🤣\",\"😊\",\"😇\"]},{name:\"Natureza\",icon:HC,emojis:[\"🌿\",\"🌱\",\"🌳\",\"🌴\",\"🌵\",\"🌷\",\"🌸\",\"🌹\",\"🌺\",\"🌻\"]},{name:\"Comida\",icon:HC,emojis:[\"🍎\",\"🍐\",\"🍊\",\"🍋\",\"🍌\",\"🍉\",\"🍇\",\"🍓\",\"🍒\",\"🍑\"]},{name:\"Atividades\",icon:Y$,emojis:[\"⚽️\",\"🏀\",\"🏈\",\"⚾️\",\"🎾\",\"🏐\",\"🏉\",\"🎱\",\"🏓\",\"🏸\"]},{name:\"Viagem\",icon:K$,emojis:[\"🚗\",\"🚕\",\"🚙\",\"🚌\",\"🚎\",\"🏎\",\"🚓\",\"🚑\",\"🚒\",\"🚐\"]},{name:\"Objetos\",icon:gB,emojis:[\"💡\",\"🔦\",\"🕯\",\"🧳\",\"⌛️\",\"⏳\",\"🌡\",\"🧪\",\"🧬\",\"🔬\"]},{name:\"Símbolos\",icon:oB,emojis:[\"❤️\",\"🧡\",\"💛\",\"💚\",\"💙\",\"💜\",\"🖤\",\"🤍\",\"🤎\",\"💔\"]}];function pte({handleEmojiClick:e}){const{inputIconsMainColor:t}=La(),n=r=>yy.find(o=>o.name===r)?.emojis||[];return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{type:\"button\",variant:\"ghost\",size:\"icon\",className:\"rounded-full p-2\",children:[i.jsx(gT,{className:\"h-6 w-6\",style:{color:t}}),i.jsx(\"span\",{className:\"sr-only\",children:\"Emojis\"})]})}),i.jsx(hr,{className:\"bg-background p-2\",align:\"end\",children:i.jsxs(Yx,{defaultValue:\"Smileys\",className:\"w-full\",children:[i.jsx(hg,{className:\"grid grid-cols-8 gap-2\",children:yy.map(r=>i.jsx(Jl,{value:r.name,children:i.jsx(r.icon,{className:\"h-5 w-5\"})},r.name))}),yy.map(r=>i.jsx(Ql,{value:r.name,children:i.jsx(\"div\",{className:\"grid grid-cols-8 gap-2\",children:n(r.name).map((s,o)=>i.jsx(se,{variant:\"ghost\",className:\"h-12 p-2 text-2xl\",onClick:()=>e(s),children:s},o))})},r.name))]})})]})}const hte=({isSendingMessage:e,isRecording:t,audioBlob:n,elapsedTime:r,startRecording:s,stopRecording:o,clearRecording:l,sendAudioMessage:u,disabled:d})=>{const{inputIconsMainColor:f}=La();return i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[t&&i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(se,{type:\"button\",size:\"icon\",variant:\"ghost\",className:\"rounded-full p-2\",onClick:o,children:i.jsx(SB,{className:\"h-6 w-6 text-[#b03f3f]\"})}),i.jsxs(\"span\",{children:[r,\"s\"]})]}),n&&i.jsxs(\"div\",{className:\"flex items-center gap-2\",children:[i.jsx(se,{type:\"button\",size:\"icon\",variant:\"ghost\",className:\"rounded-full p-2\",disabled:e,onClick:l,children:i.jsx(kB,{className:\"h-6 w-6 text-[#b03f3f]\"})}),i.jsx(\"audio\",{controls:!0,src:URL.createObjectURL(n)})]}),i.jsx(se,{type:\"button\",size:\"icon\",variant:\"ghost\",className:\"rounded-full p-2\",disabled:e||t||d,onClick:n?u:s,children:e?i.jsx(On,{className:\"h-6 w-6\",style:{color:f}}):n?i.jsx(Th,{className:\"h-6 w-6\",style:{color:f}}):i.jsx(hT,{className:\"h-6 w-6\",style:{color:f}})})]})},gte=({isSendingMessage:e,sendMessage:t,disabled:n})=>{const{inputIconsMainColor:r}=La();return i.jsx(se,{type:\"button\",size:\"icon\",variant:\"ghost\",className:\"rounded-full p-2\",onClick:t,disabled:e||n,children:e?i.jsx(On,{className:\"h-6 w-6\",style:{color:r}}):i.jsx(Th,{className:\"h-6 w-6\",style:{color:r}})})},mte=({chat:e})=>{const[t]=hd(),{inputBackgroundColor:n,inputTextForegroundColor:r}=La(),s=t.get(\"remoteJid\"),{instance:o}=cw(),{sendText:l}=KO(),{sendMedia:u}=WO(),{sendAudio:d}=iX(),{replyingMessage:f,setReplyingMessage:h}=y.useContext(uw),m=y.useRef(null),g=y.useRef(null),x=y.useRef(null),[b,w]=y.useState(\"\"),[C,k]=y.useState(!1),[j,M]=y.useState(null),[_,R]=y.useState(!1),[N,O]=y.useState(null),[D,z]=y.useState(0),{t:Q}=Ve();y.useEffect(()=>{h(null),M(null)},[s,h,M]);const pe=te=>{if(w(te.target.value),m.current){m.current.style.height=\"auto\";const de=m.current.scrollHeight,Z=parseInt(getComputedStyle(m.current).lineHeight)*10;m.current.style.height=`${Math.min(de,Z)}px`}},V=te=>{if(w(de=>de+te),m.current){m.current.style.height=\"auto\";const de=m.current.scrollHeight,Z=parseInt(getComputedStyle(m.current).lineHeight)*10;m.current.style.height=`${Math.min(de,Z)}px`}},G=async()=>{try{R(!0);const te=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,sampleRate:44100,echoCancellation:!0,noiseSuppression:!0}});let de=\"\";const ge=[\"audio/aac\",\"audio/mp4\",\"audio/mpeg\",\"audio/amr\",\"audio/ogg\",\"audio/opus\"];for(const Re of ge)if(MediaRecorder.isTypeSupported(Re)){de=Re;break}if(!de)throw new Error(\"Nenhum formato aceito pela Meta disponível\");const Z=new MediaRecorder(te,{mimeType:de,audioBitsPerSecond:128e3});x.current=Z;const ye=[];Z.ondataavailable=Re=>{Re.data.size>0&&ye.push(Re.data)},Z.onstop=()=>{const Re=new Blob(ye,{type:de}),$e=new File([Re],`audio.${de.split(\"/\")[1]}`,{type:de,lastModified:Date.now()});O($e)},Z.start(),g.current=setInterval(()=>{z(Re=>Re+1)},1e3)}catch(te){console.error(\"Erro ao iniciar gravação:\",te),me.error(Q(\"chat.toast.recordingError\")),R(!1)}},W=()=>{x.current&&(x.current.stop(),g.current&&clearInterval(g.current),R(!1))},ie=()=>{O(null),z(0)},re=te=>{console.error(\"Error to send message\",te),me.error(rT(te)?`${Q(\"chat.toast.error\")}: ${te?.response?.data?.response?.message}`:Q(\"chat.toast.sendError\"))},Y=()=>{k(!1),h(null)},H=async()=>{if(!o?.name||!o?.token||!s)return;const te={instanceName:o.name,token:o.token,data:{number:s,text:b}};await l(te,{onSuccess:()=>{w(\"\"),m.current&&(m.current.style.height=\"auto\")},onError:re,onSettled:Y})},q=async()=>{if(!(!o?.name||!o?.token||!j||!s)){k(!0);try{const te=await new Promise((ge,Z)=>{const ye=new FileReader;ye.readAsDataURL(j),ye.onload=()=>{const $e=ye.result.split(\",\")[1];ge($e)},ye.onerror=Z}),de={instanceName:o.name,token:o.token,data:{number:s,mediaMessage:{mediatype:j.type.split(\"/\")[0]===\"application\"?\"document\":j.type.split(\"/\")[0],mimetype:j.type,caption:b,media:te,fileName:j.name}}};await u(de,{onSuccess:()=>{M(null),w(\"\"),m.current&&(m.current.style.height=\"auto\")},onError:re,onSettled:Y})}catch(te){console.error(\"Error converting media to base64:\",te),re(te),k(!1)}}},he=async()=>{if(!(!o?.name||!o?.token||!N||!s)){k(!0);try{const te=await new Promise((ge,Z)=>{const ye=new FileReader;ye.readAsDataURL(N),ye.onload=()=>{const $e=ye.result.split(\",\")[1];ge($e)},ye.onerror=Z}),de={instanceName:o.name,token:o.token,data:{number:s,audioMessage:{audio:te}}};await d(de,{onSuccess:()=>{O(null),z(0)},onError:re,onSettled:Y})}catch(te){console.error(\"Error converting audio to base64:\",te),re(te),k(!1)}}},A=async()=>{k(!0),j?await q():await H()},F=()=>!b&&!j?i.jsx(hte,{isSendingMessage:C,isRecording:_,audioBlob:N,elapsedTime:D,startRecording:G,stopRecording:W,clearRecording:ie,sendAudioMessage:he}):i.jsx(gte,{isSendingMessage:C,sendMessage:A}),fe=()=>_||N?F():i.jsxs(i.Fragment,{children:[i.jsx(pte,{handleEmojiClick:V}),i.jsx(JO,{instance:o,setSelectedMedia:M}),i.jsx(bi,{placeholder:Q(\"chat.message.placeholder\"),name:\"message\",id:\"message\",rows:1,ref:m,value:b,onChange:pe,onKeyDown:te=>{!te.shiftKey&&te.key===\"Enter\"&&!C&&(te.preventDefault(),A())},className:\"min-h-0 w-full resize-none rounded-lg border-none p-3 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 focus-visible:ring-offset-transparent\",style:{backgroundColor:n,color:r}}),F()]});return o?i.jsxs(\"div\",{className:\"input-container\",children:[j&&i.jsx(QO,{selectedMedia:j,setSelectedMedia:M}),f&&i.jsx(fte,{chat:e}),i.jsx(\"div\",{className:`flex items-end ${(_||N)&&\"justify-end\"} rounded-3xl px-4 py-1`,style:{backgroundColor:n,color:r},children:fe()})]}):i.jsx(\"div\",{className:\"flex h-full items-center justify-center\",children:i.jsx(\"p\",{className:\"text-muted-foreground\",children:Q(\"chat.noInstance\")||\"Nenhuma instância selecionada\"})})},vte=P.object({remoteJid:P.string().min(1)});function yte({onSuccess:e}){const{t}=Ve(),{primaryColor:n}=La(),r=on({resolver:an(vte),defaultValues:{remoteJid:\"\"}}),s=o=>{e(o)};return i.jsx(Fo,{...r,children:i.jsxs(\"form\",{onSubmit:r.handleSubmit(s),children:[i.jsx(Lo,{control:r.control,name:\"remoteJid\",render:({field:o})=>i.jsxs(no,{children:[i.jsx(Nr,{children:t(\"chat.newChat.contact\")}),i.jsx(_s,{children:i.jsx(ne,{type:\"text\",placeholder:t(\"chat.newChat.placeholder\"),...o})})]})}),i.jsx(\"div\",{className:\"flex justify-end\",children:i.jsx(se,{type:\"submit\",className:\"mt-4\",style:{backgroundColor:n},children:t(\"chat.newChat.submit\")})})]})})}function bte({isOpen:e,setIsOpen:t}){const[n]=hd(),{t:r}=Ve(),s=dn(),o=l=>{const u=new URLSearchParams(n);u.set(\"remoteJid\",l.remoteJid),s(`/manager/embed-chat?${u.toString()}`),t(!1)};return i.jsx(Pt,{open:e,onOpenChange:t,children:i.jsxs(Nt,{className:\"max-w-2xl\",children:[i.jsxs(Mt,{children:[i.jsx(zt,{children:r(\"chat.newChat.title\")}),i.jsx(eo,{children:r(\"chat.newChat.description\")})]}),i.jsx(yte,{onSuccess:o})]})})}const by=e=>e?e.replace(\"@s.whatsapp.net\",\"\").replace(\"@g.us\",\"\"):\"\";function xte(){const[e]=hd(),{backgroundColor:t,textForegroundColor:n,primaryColor:r}=La(),s=zo(\"(min-width: 768px)\"),{t:o}=Ve(),l=dn(),u=e.get(\"token\"),{remoteJid:d}=ls(),f=d||e.get(\"remoteJid\"),[h,m]=y.useState([]),g=y.useRef(null),x=y.useRef(null),[b,w]=y.useState(null),[C,k]=y.useState(!1),{instance:j}=cw(),M=R=>{const N=new URLSearchParams(e);l(`/manager/embed-chat/${encodeURIComponent(R.remoteJid||R.id)}?${N.toString()}`)};y.useEffect(()=>{if(!j?.name)return;let R=!0;return(async()=>{try{const{data:O}=await Ee.post(`/chat/findChats/${j.name}`,{where:{}},{headers:{apikey:u||j.token}});R&&m(O||[])}catch(O){R&&(console.error(\"Erro ao buscar chats:\",O),me.error(\"Erro ao buscar chats\"))}})(),()=>{R=!1}},[j?.name,u]),y.useEffect(()=>{if(!j)return;const R=dr(jn.API_URL);if(!R){console.error(\"API URL not found in localStorage\");return}const N=localStorage.getItem(\"accessToken\");u&&localStorage.setItem(\"accessToken\",u);const O=sw(R);function D(z,Q){j&&Q.instance===j.name&&m(pe=>{const V=Q?.data?.key?.remoteJid,G=pe.findIndex(re=>re.remoteJid&&re.remoteJid===V||re.id&&re.id===V),W=G!==-1?pe[G]:null,ie={id:V,remoteJid:V,pushName:W?.pushName||Q?.data?.pushName||by(V),profilePicUrl:W?.profilePicUrl||Q?.data?.key?.profilePictureUrl||\"https://as2.ftcdn.net/jpg/05/89/93/27/1000_F_589932782_vQAEAZhHnq1QCGu5ikwrYaQD0Mmurm0N.jpg\",updatedAt:new Date().toISOString(),labels:W?.labels||[],createdAt:W?.createdAt||new Date().toISOString(),instanceId:j.id};if(G!==-1){const re=[...pe];return re[G]={...W,updatedAt:ie.updatedAt},re}else return[...pe,ie]})}return O.on(\"messages.upsert\",z=>{D(\"messages.upsert\",z)}),O.on(\"send.message\",z=>{D(\"send.message\",z)}),O.on(\"messages.update\",z=>{}),O.connect(),()=>{O.off(\"messages.upsert\"),O.off(\"send.message\"),O.off(\"messages.update\"),ow(O),u?localStorage.setItem(\"accessToken\",N||\"\"):localStorage.removeItem(\"accessToken\")}},[j,f,u]),y.useEffect(()=>{if(f){const R=h.find(N=>N.id===f);w(R||null)}},[f,h]);const _={backgroundColor:t,color:n};return i.jsx(\"div\",{className:\"relative h-full\",style:_,children:i.jsxs($o,{direction:s?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:30,minSize:20,maxSize:60,children:i.jsxs(\"div\",{className:\"hidden flex-col gap-2 text-foreground md:flex\",style:_,children:[i.jsx(\"div\",{className:\"sticky top-0 p-2\",children:i.jsxs(se,{variant:\"ghost\",className:\"w-full justify-start gap-2 px-2 text-left\",onClick:()=>k(!0),style:{backgroundColor:r,color:n},children:[i.jsx(\"div\",{className:\"flex h-7 w-7 items-center justify-center rounded-full\",children:i.jsx(Bl,{className:\"h-4 w-4\"})}),i.jsx(\"div\",{className:\"grow overflow-hidden text-ellipsis whitespace-nowrap text-sm\",children:o(\"chat.title\")}),i.jsx(cs,{className:\"h-4 w-4\"})]})}),i.jsxs(Yx,{defaultValue:\"contacts\",children:[i.jsxs(hg,{className:\"tabs-chat\",children:[i.jsx(Jl,{value:\"contacts\",className:\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground\",style:{\"--primary\":r||\"#e2e8f0\",\"--primary-foreground\":n||\"#000000\"},children:o(\"chat.contacts\")}),i.jsx(Jl,{value:\"groups\",className:\"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground\",style:{\"--primary\":r||\"#e2e8f0\",\"--primary-foreground\":n||\"#000000\"},children:o(\"chat.groups\")})]}),i.jsx(Ql,{value:\"contacts\",children:i.jsx(\"div\",{className:\"contacts-container\",children:i.jsxs(\"div\",{className:\"grid gap-1 p-2 text-foreground\",children:[i.jsx(\"div\",{className:\"px-2 text-xs font-medium text-muted-foreground\",children:o(\"chat.contacts\")}),h?.sort((R,N)=>new Date(N.lastMessage.messageTimestamp).getTime()-new Date(R.lastMessage.messageTimestamp).getTime()).map(R=>R?.id&&!R.id.includes(\"@g.us\")&&i.jsxs(\"div\",{onClick:()=>M(R),className:\"chat-item flex cursor-pointer items-center overflow-hidden rounded-md p-2 text-sm transition-colors\",style:{backgroundColor:f===R.id?r:\"\"},children:[i.jsx(\"span\",{className:\"chat-avatar mr-2\",children:i.jsx(\"img\",{src:R.profilePicUrl||\"https://as2.ftcdn.net/jpg/05/89/93/27/1000_F_589932782_vQAEAZhHnq1QCGu5ikwrYaQD0Mmurm0N.jpg\",alt:\"Avatar\",className:\"h-12 w-12 rounded-full\"})}),i.jsxs(\"div\",{className:\"min-w-0 flex-1\",children:[i.jsxs(\"div\",{className:\"flex items-center justify-between\",children:[i.jsx(\"span\",{className:\"chat-title font-medium\",style:{color:n},children:R.pushName||by(R.id)}),i.jsx(\"span\",{className:\"text-xs\",style:{color:n}})]}),i.jsxs(\"div\",{className:\"flex items-center gap-1\",children:[i.jsxs(\"span\",{className:\"text-xs font-bold\",style:{color:n},children:[o(\"chat.recent\"),\":\",\" \"]}),i.jsx(\"span\",{className:\"block truncate text-xs\",style:{color:n}})]})]})]},R.id))]})})}),i.jsx(Ql,{value:\"groups\",children:i.jsx(\"div\",{className:\"contacts-container\",children:i.jsxs(\"div\",{className:\"grid gap-1 p-2 text-foreground\",children:[i.jsx(\"div\",{className:\"px-2 text-xs font-medium text-muted-foreground\",children:o(\"chat.groups\")}),h?.sort((R,N)=>new Date(N.lastMessage.messageTimestamp).getTime()-new Date(R.lastMessage.messageTimestamp).getTime()).map(R=>R?.id&&R.id.includes(\"@g.us\")&&i.jsxs(\"div\",{onClick:()=>M(R),className:\"chat-item flex cursor-pointer items-center overflow-hidden rounded-md p-2 text-sm transition-colors\",style:{backgroundColor:f===R.id?r:\"\"},children:[i.jsx(\"span\",{className:\"chat-avatar mr-2\",children:i.jsx(\"img\",{src:R.profilePicUrl||\"https://as2.ftcdn.net/jpg/05/89/93/27/1000_F_589932782_vQAEAZhHnq1QCGu5ikwrYaQD0Mmurm0N.jpg\",alt:\"Avatar\",className:\"h-12 w-12 rounded-full\"})}),i.jsxs(\"div\",{className:\"min-w-0 flex-1\",children:[i.jsxs(\"div\",{className:\"flex items-center justify-between\",children:[i.jsx(\"span\",{className:\"chat-title font-medium\",children:R.pushName}),i.jsx(\"span\",{className:\"text-xs text-gray-500 dark:text-gray-400\"})]}),i.jsxs(\"div\",{className:\"flex items-center gap-1\",children:[i.jsxs(\"span\",{className:\"text-xs font-bold text-gray-500 dark:text-gray-400\",children:[o(\"chat.recent\"),\" \"]}),i.jsx(\"span\",{className:\"block truncate text-xs text-gray-500\"})]})]})]},R.id))]})})})]})]})}),i.jsx(Bo,{withHandle:!0}),i.jsxs(Hn,{style:_,children:[f&&i.jsx(tte,{children:i.jsxs(\"div\",{className:\"flex h-full flex-col justify-between\",style:_,children:[i.jsx(\"div\",{className:\"flex items-center gap-3 p-3\",children:i.jsxs(\"div\",{className:\"flex flex-1 items-center gap-3\",children:[i.jsx(\"img\",{src:b?.profilePicUrl||\"https://as2.ftcdn.net/jpg/05/89/93/27/1000_F_589932782_vQAEAZhHnq1QCGu5ikwrYaQD0Mmurm0N.jpg\",alt:\"Avatar\",className:\"h-10 w-10 rounded-full\"}),i.jsx(\"div\",{className:\"flex flex-col\",children:i.jsx(\"span\",{className:\"font-medium\",children:b?.pushName||by(f)})})]})}),i.jsx(ZO,{textareaRef:g,handleTextareaChange:()=>{},textareaHeight:\"auto\",lastMessageRef:x,scrollToBottom:()=>{x.current&&x.current.scrollIntoView({behavior:\"smooth\"})}}),i.jsx(mte,{chat:b})]})}),i.jsx(bte,{isOpen:C,setIsOpen:k})]})]})})}function wte(){const{instance:e,isLoading:t,error:n}=cw();return t?i.jsx(\"div\",{className:\"flex h-screen items-center justify-center\",children:i.jsx(On,{})}):n?i.jsx(\"div\",{className:\"flex h-screen items-center justify-center\",children:i.jsx(\"div\",{className:\"rounded-md bg-red-50 p-4 dark:bg-red-900\",children:i.jsx(\"span\",{className:\"text-red-800 dark:text-red-200\",children:n})})}):e?i.jsx(\"div\",{className:\"h-screen\",children:i.jsx(xte,{})}):null}function Sk(){return i.jsx(Yk,{client:_j,children:i.jsx(VM,{children:i.jsx(ete,{children:i.jsx(lX,{children:i.jsx(wte,{})})})})})}const Ste=e=>[\"evoai\",\"fetchEvoai\",JSON.stringify(e)],Cte=async({instanceName:e,token:t})=>(await Ee.get(`/evoai/find/${e}`,{headers:{apikey:t}})).data,kI=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Ste({instanceName:t,token:n}),queryFn:()=>Cte({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},Ete=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/evoai/create/${e}`,n,{headers:{apikey:t}})).data,kte=async({instanceName:e,evoaiId:t,data:n})=>(await Ee.put(`/evoai/update/${t}/${e}`,n)).data,jte=async({instanceName:e,evoaiId:t})=>(await Ee.delete(`/evoai/delete/${t}/${e}`)).data,Tte=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/evoai/settings/${e}`,n,{headers:{apikey:t}})).data,Nte=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/evoai/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data;function xg(){const e=nt(Tte,{invalidateKeys:[[\"evoai\",\"fetchDefaultSettings\"]]}),t=nt(Nte,{invalidateKeys:[[\"evoai\",\"getEvoai\"],[\"evoai\",\"fetchSessions\"]]}),n=nt(jte,{invalidateKeys:[[\"evoai\",\"getEvoai\"],[\"evoai\",\"fetchEvoai\"],[\"evoai\",\"fetchSessions\"]]}),r=nt(kte,{invalidateKeys:[[\"evoai\",\"getEvoai\"],[\"evoai\",\"fetchEvoai\"],[\"evoai\",\"fetchSessions\"]]}),s=nt(Ete,{invalidateKeys:[[\"evoai\",\"fetchEvoai\"]]});return{setDefaultSettingsEvoai:e,changeStatusEvoai:t,deleteEvoai:n,updateEvoai:r,createEvoai:s}}const Mte=e=>[\"evoai\",\"fetchDefaultSettings\",JSON.stringify(e)],_te=async({instanceName:e,token:t})=>(await Ee.get(`/evoai/fetchSettings/${e}`,{headers:{apikey:t}})).data,Rte=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Mte({instanceName:t,token:n}),queryFn:()=>_te({instanceName:t,token:n}),enabled:!!t})},Pte=P.object({expire:P.string(),keywordFinish:P.string(),delayMessage:P.string(),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.string(),ignoreJids:P.array(P.string()).default([]),evoaiIdFallback:P.union([P.null(),P.string()]).optional(),splitMessages:P.boolean(),timePerChar:P.string()});function Ote(){const{t:e}=Ve(),{instance:t}=ct(),{setDefaultSettingsEvoai:n}=xg(),[r,s]=y.useState(!1),{data:o,refetch:l}=kI({instanceName:t?.name,token:t?.token,enabled:r}),{data:u,refetch:d}=Rte({instanceName:t?.name,token:t?.token}),f=on({resolver:an(Pte),defaultValues:{expire:\"0\",keywordFinish:e(\"evoai.form.examples.keywordFinish\"),delayMessage:\"1000\",unknownMessage:e(\"evoai.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:\"0\",ignoreJids:[],evoaiIdFallback:void 0,splitMessages:!1,timePerChar:\"0\"}});y.useEffect(()=>{u&&f.reset({expire:u?.expire?u.expire.toString():\"0\",keywordFinish:u.keywordFinish,delayMessage:u.delayMessage?u.delayMessage.toString():\"0\",unknownMessage:u.unknownMessage,listeningFromMe:u.listeningFromMe,stopBotFromMe:u.stopBotFromMe,keepOpen:u.keepOpen,debounceTime:u.debounceTime?u.debounceTime.toString():\"0\",ignoreJids:u.ignoreJids,evoaiIdFallback:u.evoaiIdFallback,splitMessages:u.splitMessages,timePerChar:u.timePerChar?u.timePerChar.toString():\"0\"})},[u]);const h=async g=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const x={expire:parseInt(g.expire),keywordFinish:g.keywordFinish,delayMessage:parseInt(g.delayMessage),unknownMessage:g.unknownMessage,listeningFromMe:g.listeningFromMe,stopBotFromMe:g.stopBotFromMe,keepOpen:g.keepOpen,debounceTime:parseInt(g.debounceTime),evoaiIdFallback:g.evoaiIdFallback||void 0,ignoreJids:g.ignoreJids,splitMessages:g.splitMessages,timePerChar:parseInt(g.timePerChar)};await n({instanceName:t.name,token:t.token,data:x}),me.success(e(\"evoai.toast.defaultSettings.success\"))}catch(x){console.error(\"Error:\",x),me.error(`Error: ${x?.response?.data?.response?.message}`)}};function m(){d(),l()}return i.jsxs(Pt,{open:r,onOpenChange:s,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:e(\"evoai.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:m,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"evoai.defaultSettings\")})}),i.jsx(Gn,{...f,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:f.handleSubmit(h),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"evoaiIdFallback\",label:e(\"evoai.form.evoaiIdFallback.label\"),options:o?.filter(g=>!!g.id).map(g=>({label:g.description,value:g.id}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"evoai.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"evoai.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"evoai.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"evoai.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"evoai.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"evoai.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"evoai.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"evoai.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:e(\"evoai.form.splitMessages.label\"),reverse:!0}),i.jsx(le,{name:\"timePerChar\",label:e(\"evoai.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"evoai.form.ignoreJids.label\"),placeholder:e(\"evoai.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"evoai.button.save\")})})]})})]})]})}const Ite=e=>[\"evoai\",\"fetchSessions\",JSON.stringify(e)],Ate=async({evoaiId:e,instanceName:t})=>(await Ee.get(`/evoai/fetchSessions/${e}/${t}`)).data,Dte=e=>{const{evoaiId:t,instanceName:n,...r}=e;return mt({...r,queryKey:Ite({evoaiId:t,instanceName:n}),queryFn:()=>Ate({evoaiId:t,instanceName:n}),enabled:!!n&&!!t&&(e.enabled??!0),staleTime:1e3*10})};function jI({evoaiId:e}){const{t}=Ve(),{instance:n}=ct(),{changeStatusEvoai:r}=xg(),[s,o]=y.useState([]),{data:l,refetch:u}=Dte({evoaiId:e,instanceName:n?.name}),[d,f]=y.useState(!1),[h,m]=y.useState(\"\");function g(){u()}const x=async(w,C)=>{try{if(!n)return;await r({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"evoai.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evoai.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evoai.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evoai.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evoai.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"evoai.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:t(\"evoai.sessions.table.actions.title\")}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"evoai.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"evoai.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"evoai.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"evoai.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:d,onOpenChange:f,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"evoai.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"evoai.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"evoai.sessions.search\"),value:h,onChange:w=>m(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{})})]}),i.jsx($a,{columns:b,data:l??[],onSortingChange:o,state:{sorting:s,globalFilter:h},onGlobalFilterChange:m,enableGlobalFilter:!0,noResultsMessage:t(\"evoai.sessions.table.none\")})]})]})]})}const Fte=P.object({enabled:P.boolean(),description:P.string(),agentUrl:P.string(),apiKey:P.string(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function TI({initialData:e,onSubmit:t,handleDelete:n,evoaiId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{}}){const{t:d}=Ve(),f=on({resolver:an(Fte),defaultValues:e||{enabled:!0,description:\"\",agentUrl:\"\",apiKey:\"\",triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,splitMessages:!1,timePerChar:0}}),h=f.watch(\"triggerType\");return i.jsx(Gn,{...f,children:i.jsxs(\"form\",{onSubmit:f.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:d(\"evoai.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:d(\"evoai.form.description.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"evoai.form.evoaiSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"agentUrl\",label:d(\"evoai.form.agentUrl.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(le,{name:\"apiKey\",label:d(\"evoai.form.apiKey.label\"),className:\"flex-1\",children:i.jsx(ne,{type:\"password\"})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"evoai.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:d(\"evoai.form.triggerType.label\"),options:[{label:d(\"evoai.form.triggerType.keyword\"),value:\"keyword\"},{label:d(\"evoai.form.triggerType.all\"),value:\"all\"},{label:d(\"evoai.form.triggerType.advanced\"),value:\"advanced\"},{label:d(\"evoai.form.triggerType.none\"),value:\"none\"}]}),h===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:d(\"evoai.form.triggerOperator.label\"),options:[{label:d(\"evoai.form.triggerOperator.contains\"),value:\"contains\"},{label:d(\"evoai.form.triggerOperator.equals\"),value:\"equals\"},{label:d(\"evoai.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:d(\"evoai.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:d(\"evoai.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:d(\"evoai.form.triggerValue.label\"),children:i.jsx(ne,{})})]}),h===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:d(\"evoai.form.triggerConditions.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"evoai.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:d(\"evoai.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:d(\"evoai.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:d(\"evoai.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:d(\"evoai.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:d(\"evoai.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:d(\"evoai.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:d(\"evoai.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:d(\"evoai.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:d(\"evoai.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:d(\"evoai.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"evoai.button.saving\":\"evoai.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx(jI,{evoaiId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:d(\"evoai.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:d(\"modal.delete.title\")}),i.jsx(eo,{children:d(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:d(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:d(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"evoai.button.saving\":\"evoai.button.update\")})]})]})]})})}function Lte({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),[r,s]=y.useState(!1),[o,l]=y.useState(!1),{createEvoai:u}=xg(),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");s(!0);const h={enabled:f.enabled,description:f.description,agentUrl:f.agentUrl,apiKey:f.apiKey,triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0,splitMessages:f.splitMessages||!1,timePerChar:f.timePerChar||0};await u({instanceName:n.name,token:n.token,data:h}),me.success(t(\"evoai.toast.success.create\")),l(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{s(!1)}};return i.jsxs(Pt,{open:o,onOpenChange:l,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"evoai.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"evoai.form.title\")})}),i.jsx(TI,{onSubmit:d,isModal:!0,isLoading:r})]})]})}const $te=e=>[\"evoai\",\"getEvoai\",JSON.stringify(e)],Bte=async({evoaiId:e,instanceName:t})=>(await Ee.get(`/evoai/fetch/${e}/${t}`)).data,zte=e=>{const{evoaiId:t,instanceName:n,...r}=e;return mt({...r,queryKey:$te({evoaiId:t,instanceName:n}),queryFn:()=>Bte({evoaiId:t,instanceName:n}),enabled:!!n&&!!t&&(e.enabled??!0)})};function Ute({evoaiId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteEvoai:u,updateEvoai:d}=xg(),{data:f,isLoading:h}=zte({evoaiId:e,instanceName:r?.name}),m=y.useMemo(()=>({enabled:!!f?.enabled,description:f?.description??\"\",agentUrl:f?.agentUrl??\"\",apiKey:f?.apiKey??\"\",triggerType:f?.triggerType??\"\",triggerOperator:f?.triggerOperator??\"\",triggerValue:f?.triggerValue??\"\",expire:f?.expire??0,keywordFinish:f?.keywordFinish??\"\",delayMessage:f?.delayMessage??0,unknownMessage:f?.unknownMessage??\"\",listeningFromMe:!!f?.listeningFromMe,stopBotFromMe:!!f?.stopBotFromMe,keepOpen:!!f?.keepOpen,debounceTime:f?.debounceTime??0,splitMessages:f?.splitMessages??!1,timePerChar:f?.timePerChar??0}),[f?.agentUrl,f?.apiKey,f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.stopBotFromMe,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.unknownMessage,f?.splitMessages,f?.timePerChar]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,agentUrl:b.agentUrl,apiKey:b.apiKey,triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0,splitMessages:b.splitMessages||!1,timePerChar:b.timePerChar||0};await d({instanceName:r.name,evoaiId:e,data:w}),me.success(n(\"evoai.toast.success.update\")),t(),s(`/manager/instance/${r.id}/evoai/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,evoaiId:e}),me.success(n(\"evoai.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/evoai`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir evoai:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(TI,{initialData:m,onSubmit:g,evoaiId:e,handleDelete:x,isModal:!1,isLoading:h,openDeletionDialog:o,setOpenDeletionDialog:l})})}function Ck(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{evoaiId:r}=ls(),{data:s,refetch:o,isLoading:l}=kI({instanceName:n?.name}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/evoai/${h}`)},f=()=>{o()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"evoai.title\")}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-2\",children:[i.jsx(jI,{}),i.jsx(Ote,{}),i.jsx(Lte,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:l?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsx(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:i.jsx(\"h4\",{className:\"text-base\",children:h.description||h.id})},h.id)):i.jsx(se,{variant:\"link\",children:e(\"evoai.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-border\"}),i.jsx(Hn,{children:i.jsx(Ute,{evoaiId:r,resetTable:f})})]})]})]})}const Vte=e=>[\"evolutionBot\",\"findEvolutionBot\",JSON.stringify(e)],Hte=async({instanceName:e,token:t})=>(await Ee.get(`/evolutionBot/find/${e}`,{headers:{apiKey:t}})).data,NI=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Vte({instanceName:t}),queryFn:()=>Hte({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},qte=e=>[\"evolutionBot\",\"fetchDefaultSettings\",JSON.stringify(e)],Kte=async({instanceName:e,token:t})=>{const n=await Ee.get(`/evolutionBot/fetchSettings/${e}`,{headers:{apiKey:t}});return Array.isArray(n.data)?n.data[0]:n.data},Wte=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:qte({instanceName:t}),queryFn:()=>Kte({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},Gte=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/evolutionBot/create/${e}`,n,{headers:{apikey:t}})).data,Jte=async({instanceName:e,token:t,evolutionBotId:n,data:r})=>(await Ee.put(`/evolutionBot/update/${n}/${e}`,r,{headers:{apikey:t}})).data,Qte=async({instanceName:e,evolutionBotId:t})=>(await Ee.delete(`/evolutionBot/delete/${t}/${e}`)).data,Zte=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/evolutionBot/settings/${e}`,n,{headers:{apikey:t}})).data,Yte=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/evolutionBot/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data;function wg(){const e=nt(Zte,{invalidateKeys:[[\"evolutionBot\",\"fetchDefaultSettings\"]]}),t=nt(Yte,{invalidateKeys:[[\"evolutionBot\",\"getEvolutionBot\"],[\"evolutionBot\",\"fetchSessions\"]]}),n=nt(Qte,{invalidateKeys:[[\"evolutionBot\",\"getEvolutionBot\"],[\"evolutionBot\",\"findEvolutionBot\"],[\"evolutionBot\",\"fetchSessions\"]]}),r=nt(Jte,{invalidateKeys:[[\"evolutionBot\",\"getEvolutionBot\"],[\"evolutionBot\",\"findEvolutionBot\"],[\"evolutionBot\",\"fetchSessions\"]]}),s=nt(Gte,{invalidateKeys:[[\"evolutionBot\",\"findEvolutionBot\"]]});return{setDefaultSettingsEvolutionBot:e,changeStatusEvolutionBot:t,deleteEvolutionBot:n,updateEvolutionBot:r,createEvolutionBot:s}}const Xte=P.object({expire:P.string(),keywordFinish:P.string(),delayMessage:P.string(),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.string(),ignoreJids:P.array(P.string()).default([]),botIdFallback:P.union([P.null(),P.string()]).optional(),splitMessages:P.boolean(),timePerChar:P.string()});function ene(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{data:s,refetch:o}=Wte({instanceName:t?.name,enabled:n}),{data:l,refetch:u}=NI({instanceName:t?.name,enabled:n}),{setDefaultSettingsEvolutionBot:d}=wg(),f=on({resolver:an(Xte),defaultValues:{expire:\"0\",keywordFinish:e(\"evolutionBot.form.examples.keywordFinish\"),delayMessage:\"1000\",unknownMessage:e(\"evolutionBot.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:\"0\",ignoreJids:[],botIdFallback:void 0,splitMessages:!1,timePerChar:\"0\"}});y.useEffect(()=>{s&&f.reset({expire:s?.expire?s.expire.toString():\"0\",keywordFinish:s.keywordFinish,delayMessage:s.delayMessage?s.delayMessage.toString():\"0\",unknownMessage:s.unknownMessage,listeningFromMe:s.listeningFromMe,stopBotFromMe:s.stopBotFromMe,keepOpen:s.keepOpen,debounceTime:s.debounceTime?s.debounceTime.toString():\"0\",ignoreJids:s.ignoreJids,botIdFallback:s.botIdFallback,splitMessages:s.splitMessages,timePerChar:s.timePerChar?s.timePerChar.toString():\"0\"})},[s]);const h=async g=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const x={expire:parseInt(g.expire),keywordFinish:g.keywordFinish,delayMessage:parseInt(g.delayMessage),unknownMessage:g.unknownMessage,listeningFromMe:g.listeningFromMe,stopBotFromMe:g.stopBotFromMe,keepOpen:g.keepOpen,debounceTime:parseInt(g.debounceTime),botIdFallback:g.botIdFallback||void 0,ignoreJids:g.ignoreJids,splitMessages:g.splitMessages,timePerChar:parseInt(g.timePerChar)};await d({instanceName:t.name,token:t.token,data:x}),me.success(e(\"evolutionBot.toast.defaultSettings.success\"))}catch(x){console.error(\"Error:\",x),me.error(`Error: ${x?.response?.data?.response?.message}`)}};function m(){o(),u()}return i.jsxs(Pt,{open:n,onOpenChange:r,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:e(\"evolutionBot.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:m,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"evolutionBot.defaultSettings\")})}),i.jsx(Gn,{...f,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:f.handleSubmit(h),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"botIdFallback\",label:e(\"evolutionBot.form.botIdFallback.label\"),options:l?.filter(g=>!!g.id).map(g=>({label:g.description,value:g.id}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"evolutionBot.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"evolutionBot.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"evolutionBot.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"evolutionBot.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"evolutionBot.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"evolutionBot.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"evolutionBot.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"evolutionBot.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:e(\"evolutionBot.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:e(\"evolutionBot.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"evolutionBot.form.ignoreJids.label\"),placeholder:e(\"evolutionBot.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"evolutionBot.button.save\")})})]})})]})]})}const tne=e=>[\"evolutionBot\",\"fetchSessions\",JSON.stringify(e)],nne=async({instanceName:e,evolutionBotId:t,token:n})=>(await Ee.get(`/evolutionBot/fetchSessions/${t}/${e}`,{headers:{apiKey:n}})).data,rne=e=>{const{instanceName:t,token:n,evolutionBotId:r,...s}=e;return mt({...s,queryKey:tne({instanceName:t}),queryFn:()=>nne({instanceName:t,token:n,evolutionBotId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function MI({evolutionBotId:e}){const{t}=Ve(),{instance:n}=ct(),[r,s]=y.useState([]),[o,l]=y.useState(!1),[u,d]=y.useState(\"\"),{data:f,refetch:h}=rne({instanceName:n?.name,evolutionBotId:e,enabled:o}),{changeStatusEvolutionBot:m}=wg();function g(){h()}const x=async(w,C)=>{try{if(!n)return;await m({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"evolutionBot.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evolutionBot.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evolutionBot.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evolutionBot.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"evolutionBot.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"evolutionBot.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:t(\"evolutionBot.sessions.table.actions.title\")}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"evolutionBot.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"evolutionBot.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"evolutionBot.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"evolutionBot.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:o,onOpenChange:l,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"evolutionBot.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"evolutionBot.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"evolutionBot.sessions.search\"),value:u,onChange:w=>d(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{})})]}),i.jsx($a,{columns:b,data:f??[],onSortingChange:s,state:{sorting:r,globalFilter:u},onGlobalFilterChange:d,enableGlobalFilter:!0,noResultsMessage:t(\"evolutionBot.sessions.table.none\")})]})]})]})}const sne=P.object({enabled:P.boolean(),description:P.string(),apiUrl:P.string(),apiKey:P.string().optional(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function _I({initialData:e,onSubmit:t,handleDelete:n,evolutionBotId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{}}){const{t:d}=Ve(),f=on({resolver:an(sne),defaultValues:e||{enabled:!0,description:\"\",apiUrl:\"\",apiKey:\"\",triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,splitMessages:!1,timePerChar:0}}),h=f.watch(\"triggerType\");return i.jsx(Gn,{...f,children:i.jsxs(\"form\",{onSubmit:f.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:d(\"evolutionBot.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:d(\"evolutionBot.form.description.label\"),required:!0,children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"evolutionBot.form.evolutionBotSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"apiUrl\",label:d(\"evolutionBot.form.apiUrl.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(le,{name:\"apiKey\",label:d(\"evolutionBot.form.apiKey.label\"),children:i.jsx(ne,{type:\"password\"})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"evolutionBot.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:d(\"evolutionBot.form.triggerType.label\"),options:[{label:d(\"evolutionBot.form.triggerType.keyword\"),value:\"keyword\"},{label:d(\"evolutionBot.form.triggerType.all\"),value:\"all\"},{label:d(\"evolutionBot.form.triggerType.advanced\"),value:\"advanced\"},{label:d(\"evolutionBot.form.triggerType.none\"),value:\"none\"}]}),h===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:d(\"evolutionBot.form.triggerOperator.label\"),options:[{label:d(\"evolutionBot.form.triggerOperator.contains\"),value:\"contains\"},{label:d(\"evolutionBot.form.triggerOperator.equals\"),value:\"equals\"},{label:d(\"evolutionBot.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:d(\"evolutionBot.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:d(\"evolutionBot.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:d(\"evolutionBot.form.triggerValue.label\"),children:i.jsx(ne,{})})]}),h===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:d(\"evolutionBot.form.triggerConditions.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"evolutionBot.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:d(\"evolutionBot.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:d(\"evolutionBot.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:d(\"evolutionBot.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:d(\"evolutionBot.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:d(\"evolutionBot.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:d(\"evolutionBot.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:d(\"evolutionBot.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:d(\"evolutionBot.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:d(\"evolutionBot.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:d(\"evolutionBot.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"evolutionBot.button.saving\":\"evolutionBot.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx(MI,{evolutionBotId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:d(\"dify.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:d(\"modal.delete.title\")}),i.jsx(eo,{children:d(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:d(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:d(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"evolutionBot.button.saving\":\"evolutionBot.button.update\")})]})]})]})})}function one({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),[r,s]=y.useState(!1),[o,l]=y.useState(!1),{createEvolutionBot:u}=wg(),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");s(!0);const h={enabled:f.enabled,description:f.description,apiUrl:f.apiUrl,apiKey:f.apiKey,triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0,splitMessages:f.splitMessages||!1,timePerChar:f.timePerChar?f.timePerChar:0};await u({instanceName:n.name,token:n.token,data:h}),me.success(t(\"evolutionBot.toast.success.create\")),l(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{s(!1)}};return i.jsxs(Pt,{open:o,onOpenChange:l,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"evolutionBot.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"evolutionBot.form.title\")})}),i.jsx(_I,{onSubmit:d,isModal:!0,isLoading:r})]})]})}const ane=e=>[\"evolutionBot\",\"getEvolutionBot\",JSON.stringify(e)],ine=async({instanceName:e,token:t,evolutionBotId:n})=>{const r=await Ee.get(`/evolutionBot/fetch/${n}/${e}`,{headers:{apiKey:t}});return Array.isArray(r.data)?r.data[0]:r.data},lne=e=>{const{instanceName:t,token:n,evolutionBotId:r,...s}=e;return mt({...s,queryKey:ane({instanceName:t}),queryFn:()=>ine({instanceName:t,token:n,evolutionBotId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function cne({evolutionBotId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteEvolutionBot:u,updateEvolutionBot:d}=wg(),{data:f,isLoading:h}=lne({instanceName:r?.name,evolutionBotId:e}),m=y.useMemo(()=>({enabled:f?.enabled??!0,description:f?.description??\"\",apiUrl:f?.apiUrl??\"\",apiKey:f?.apiKey??\"\",triggerType:f?.triggerType??\"\",triggerOperator:f?.triggerOperator??\"\",triggerValue:f?.triggerValue,expire:f?.expire??0,keywordFinish:f?.keywordFinish,delayMessage:f?.delayMessage??0,unknownMessage:f?.unknownMessage,listeningFromMe:f?.listeningFromMe,stopBotFromMe:!!f?.stopBotFromMe,keepOpen:!!f?.keepOpen,debounceTime:f?.debounceTime??0,splitMessages:f?.splitMessages??!1,timePerChar:f?.timePerChar?f?.timePerChar:0}),[f?.apiKey,f?.apiUrl,f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.stopBotFromMe,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.unknownMessage,f?.splitMessages,f?.timePerChar]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,apiUrl:b.apiUrl,apiKey:b.apiKey,triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0,splitMessages:b.splitMessages||!1,timePerChar:b.timePerChar?b.timePerChar:0};await d({instanceName:r.name,evolutionBotId:e,data:w}),me.success(n(\"evolutionBot.toast.success.update\")),t(),s(`/manager/instance/${r.id}/evolutionBot/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,evolutionBotId:e}),me.success(n(\"evolutionBot.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/evolutionBot`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir evolutionBot:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(_I,{initialData:m,onSubmit:g,evolutionBotId:e,handleDelete:x,isModal:!1,openDeletionDialog:o,setOpenDeletionDialog:l})})}function Ek(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{evolutionBotId:r}=ls(),{data:s,isLoading:o,refetch:l}=NI({instanceName:n?.name}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/evolutionBot/${h}`)},f=()=>{l()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"evolutionBot.title\")}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-2\",children:[i.jsx(MI,{}),i.jsx(ene,{}),i.jsx(one,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:o?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsx(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:i.jsx(\"h4\",{className:\"text-base\",children:h.description||h.id})},h.id)):i.jsx(se,{variant:\"link\",children:e(\"evolutionBot.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-border\"}),i.jsx(Hn,{children:i.jsx(cne,{evolutionBotId:r,resetTable:f})})]})]})]})}const une=e=>[\"flowise\",\"findFlowise\",JSON.stringify(e)],dne=async({instanceName:e,token:t})=>(await Ee.get(`/flowise/find/${e}`,{headers:{apiKey:t}})).data,RI=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:une({instanceName:t}),queryFn:()=>dne({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},fne=e=>[\"flowise\",\"fetchDefaultSettings\",JSON.stringify(e)],pne=async({instanceName:e,token:t})=>{const n=await Ee.get(`/flowise/fetchSettings/${e}`,{headers:{apiKey:t}});return Array.isArray(n.data)?n.data[0]:n.data},hne=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:fne({instanceName:t}),queryFn:()=>pne({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},gne=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/flowise/create/${e}`,n,{headers:{apikey:t}})).data,mne=async({instanceName:e,flowiseId:t,data:n})=>(await Ee.put(`/flowise/update/${t}/${e}`,n)).data,vne=async({instanceName:e,flowiseId:t})=>(await Ee.delete(`/flowise/delete/${t}/${e}`)).data,yne=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/flowise/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data,bne=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/flowise/settings/${e}`,n,{headers:{apikey:t}})).data;function Sg(){const e=nt(bne,{invalidateKeys:[[\"flowise\",\"fetchDefaultSettings\"]]}),t=nt(yne,{invalidateKeys:[[\"flowise\",\"getFlowise\"],[\"flowise\",\"fetchSessions\"]]}),n=nt(vne,{invalidateKeys:[[\"flowise\",\"getFlowise\"],[\"flowise\",\"findFlowise\"],[\"flowise\",\"fetchSessions\"]]}),r=nt(mne,{invalidateKeys:[[\"flowise\",\"getFlowise\"],[\"flowise\",\"findFlowise\"],[\"flowise\",\"fetchSessions\"]]}),s=nt(gne,{invalidateKeys:[[\"flowise\",\"findFlowise\"]]});return{setDefaultSettingsFlowise:e,changeStatusFlowise:t,deleteFlowise:n,updateFlowise:r,createFlowise:s}}const xne=P.object({expire:P.string(),keywordFinish:P.string(),delayMessage:P.string(),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.string(),ignoreJids:P.array(P.string()).default([]),flowiseIdFallback:P.union([P.null(),P.string()]).optional(),splitMessages:P.boolean(),timePerChar:P.string()});function wne(){const{t:e}=Ve(),{instance:t}=ct(),{setDefaultSettingsFlowise:n}=Sg(),[r,s]=y.useState(!1),{data:o,refetch:l}=hne({instanceName:t?.name,enabled:r}),{data:u,refetch:d}=RI({instanceName:t?.name,enabled:r}),f=on({resolver:an(xne),defaultValues:{expire:\"0\",keywordFinish:e(\"flowise.form.examples.keywordFinish\"),delayMessage:\"1000\",unknownMessage:e(\"flowise.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:\"0\",ignoreJids:[],flowiseIdFallback:void 0,splitMessages:!1,timePerChar:\"0\"}});y.useEffect(()=>{o&&f.reset({expire:o?.expire?o.expire.toString():\"0\",keywordFinish:o.keywordFinish,delayMessage:o.delayMessage?o.delayMessage.toString():\"0\",unknownMessage:o.unknownMessage,listeningFromMe:o.listeningFromMe,stopBotFromMe:o.stopBotFromMe,keepOpen:o.keepOpen,debounceTime:o.debounceTime?o.debounceTime.toString():\"0\",ignoreJids:o.ignoreJids,flowiseIdFallback:o.flowiseIdFallback,splitMessages:o.splitMessages,timePerChar:o.timePerChar?o.timePerChar.toString():\"0\"})},[o]);const h=async g=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const x={expire:parseInt(g.expire),keywordFinish:g.keywordFinish,delayMessage:parseInt(g.delayMessage),unknownMessage:g.unknownMessage,listeningFromMe:g.listeningFromMe,stopBotFromMe:g.stopBotFromMe,keepOpen:g.keepOpen,debounceTime:parseInt(g.debounceTime),flowiseIdFallback:g.flowiseIdFallback||void 0,ignoreJids:g.ignoreJids,splitMessages:g.splitMessages,timePerChar:parseInt(g.timePerChar)};await n({instanceName:t.name,token:t.token,data:x}),me.success(e(\"flowise.toast.defaultSettings.success\"))}catch(x){console.error(\"Error:\",x),me.error(`Error: ${x?.response?.data?.response?.message}`)}};function m(){l(),d()}return i.jsxs(Pt,{open:r,onOpenChange:s,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:e(\"flowise.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:m,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"flowise.defaultSettings\")})}),i.jsx(Gn,{...f,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:f.handleSubmit(h),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"flowiseIdFallback\",label:e(\"flowise.form.flowiseIdFallback.label\"),options:u?.filter(g=>!!g.id).map(g=>({label:g.description,value:g.id}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"flowise.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"flowise.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"flowise.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"flowise.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"flowise.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"flowise.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"flowise.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"flowise.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:e(\"flowise.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:e(\"flowise.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"flowise.form.ignoreJids.label\"),placeholder:e(\"flowise.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"flowise.button.save\")})})]})})]})]})}const Sne=e=>[\"flowise\",\"fetchSessions\",JSON.stringify(e)],Cne=async({instanceName:e,flowiseId:t,token:n})=>(await Ee.get(`/flowise/fetchSessions/${t}/${e}`,{headers:{apiKey:n}})).data,Ene=e=>{const{instanceName:t,token:n,flowiseId:r,...s}=e;return mt({...s,queryKey:Sne({instanceName:t}),queryFn:()=>Cne({instanceName:t,token:n,flowiseId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function PI({flowiseId:e}){const{t}=Ve(),{instance:n}=ct(),{changeStatusFlowise:r}=Sg(),[s,o]=y.useState([]),[l,u]=y.useState(!1),[d,f]=y.useState(\"\"),{data:h,refetch:m}=Ene({instanceName:n?.name,flowiseId:e,enabled:l});function g(){m()}const x=async(w,C)=>{try{if(!n)return;await r({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"flowise.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"flowise.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"flowise.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"flowise.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"flowise.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"flowise.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:t(\"flowise.sessions.table.actions.title\")}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"flowise.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"flowise.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"flowise.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"flowise.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"flowise.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"flowise.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"flowise.sessions.search\"),value:d,onChange:w=>f(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{})})]}),i.jsx($a,{columns:b,data:h??[],onSortingChange:o,state:{sorting:s,globalFilter:d},onGlobalFilterChange:f,enableGlobalFilter:!0,noResultsMessage:t(\"flowise.sessions.table.none\")})]})]})]})}const kne=P.object({enabled:P.boolean(),description:P.string(),apiUrl:P.string(),apiKey:P.string().optional(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function OI({initialData:e,onSubmit:t,handleDelete:n,flowiseId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{}}){const{t:d}=Ve(),f=on({resolver:an(kne),defaultValues:e||{enabled:!0,description:\"\",apiUrl:\"\",apiKey:\"\",triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,splitMessages:!1,timePerChar:0}}),h=f.watch(\"triggerType\");return i.jsx(Gn,{...f,children:i.jsxs(\"form\",{onSubmit:f.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:d(\"flowise.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:d(\"flowise.form.description.label\"),required:!0,children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"flowise.form.flowiseSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"apiUrl\",label:d(\"flowise.form.apiUrl.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(le,{name:\"apiKey\",label:d(\"flowise.form.apiKey.label\"),children:i.jsx(ne,{type:\"password\"})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"flowise.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:d(\"flowise.form.triggerType.label\"),options:[{label:d(\"flowise.form.triggerType.keyword\"),value:\"keyword\"},{label:d(\"flowise.form.triggerType.all\"),value:\"all\"},{label:d(\"flowise.form.triggerType.advanced\"),value:\"advanced\"},{label:d(\"flowise.form.triggerType.none\"),value:\"none\"}]}),h===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:d(\"flowise.form.triggerOperator.label\"),options:[{label:d(\"flowise.form.triggerOperator.contains\"),value:\"contains\"},{label:d(\"flowise.form.triggerOperator.equals\"),value:\"equals\"},{label:d(\"flowise.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:d(\"flowise.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:d(\"flowise.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:d(\"flowise.form.triggerValue.label\"),children:i.jsx(ne,{})})]}),h===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:d(\"flowise.form.triggerConditions.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"flowise.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:d(\"flowise.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:d(\"flowise.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:d(\"flowise.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:d(\"flowise.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:d(\"flowise.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:d(\"flowise.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:d(\"flowise.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:d(\"flowise.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:d(\"flowise.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:d(\"flowise.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"flowise.button.saving\":\"flowise.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx(PI,{flowiseId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:d(\"dify.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:d(\"modal.delete.title\")}),i.jsx(eo,{children:d(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:d(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:d(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"flowise.button.saving\":\"flowise.button.update\")})]})]})]})})}function jne({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),{createFlowise:r}=Sg(),[s,o]=y.useState(!1),[l,u]=y.useState(!1),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");o(!0);const h={enabled:f.enabled,description:f.description,apiUrl:f.apiUrl,apiKey:f.apiKey,triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0,splitMessages:f.splitMessages||!1,timePerChar:f.timePerChar||0};await r({instanceName:n.name,token:n.token,data:h}),me.success(t(\"flowise.toast.success.create\")),u(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{o(!1)}};return i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"flowise.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"flowise.form.title\")})}),i.jsx(OI,{onSubmit:d,isModal:!0,isLoading:s})]})]})}const Tne=e=>[\"flowise\",\"getFlowise\",JSON.stringify(e)],Nne=async({instanceName:e,token:t,flowiseId:n})=>{const r=await Ee.get(`/flowise/fetch/${n}/${e}`,{headers:{apiKey:t}});return Array.isArray(r.data)?r.data[0]:r.data},Mne=e=>{const{instanceName:t,token:n,flowiseId:r,...s}=e;return mt({...s,queryKey:Tne({instanceName:t}),queryFn:()=>Nne({instanceName:t,token:n,flowiseId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function _ne({flowiseId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteFlowise:u,updateFlowise:d}=Sg(),{data:f,isLoading:h}=Mne({instanceName:r?.name,flowiseId:e}),m=y.useMemo(()=>({enabled:f?.enabled??!0,description:f?.description??\"\",apiUrl:f?.apiUrl??\"\",apiKey:f?.apiKey??\"\",triggerType:f?.triggerType??\"\",triggerOperator:f?.triggerOperator??\"\",triggerValue:f?.triggerValue,expire:f?.expire??0,keywordFinish:f?.keywordFinish,delayMessage:f?.delayMessage??0,unknownMessage:f?.unknownMessage,listeningFromMe:f?.listeningFromMe,stopBotFromMe:f?.stopBotFromMe,keepOpen:f?.keepOpen,debounceTime:f?.debounceTime??0,splitMessages:f?.splitMessages??!1,timePerChar:f?.timePerChar??0}),[f?.apiKey,f?.apiUrl,f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.stopBotFromMe,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.unknownMessage,f?.splitMessages,f?.timePerChar]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,apiUrl:b.apiUrl,apiKey:b.apiKey,triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0,splitMessages:b.splitMessages||!1,timePerChar:b.timePerChar||0};await d({instanceName:r.name,flowiseId:e,data:w}),me.success(n(\"flowise.toast.success.update\")),t(),s(`/manager/instance/${r.id}/flowise/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,flowiseId:e}),me.success(n(\"flowise.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/flowise`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir dify:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(OI,{initialData:m,onSubmit:g,flowiseId:e,handleDelete:x,isModal:!1,isLoading:h,openDeletionDialog:o,setOpenDeletionDialog:l})})}function kk(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{flowiseId:r}=ls(),{data:s,isLoading:o,refetch:l}=RI({instanceName:n?.name}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/flowise/${h}`)},f=()=>{l()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"flowise.title\")}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-2\",children:[i.jsx(PI,{}),i.jsx(wne,{}),i.jsx(jne,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:o?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsx(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:i.jsx(\"h4\",{className:\"text-base\",children:h.description||h.id})},h.id)):i.jsx(se,{variant:\"link\",children:e(\"flowise.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-border\"}),i.jsx(Hn,{children:i.jsx(_ne,{flowiseId:r,resetTable:f})})]})]})]})}const Rne=e=>[\"n8n\",\"fetchN8n\",JSON.stringify(e)],Pne=async({instanceName:e,token:t})=>(await Ee.get(`/n8n/find/${e}`,{headers:{apikey:t}})).data,II=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Rne({instanceName:t,token:n}),queryFn:()=>Pne({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},One=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/n8n/create/${e}`,n,{headers:{apikey:t}})).data,Ine=async({instanceName:e,n8nId:t,data:n})=>(await Ee.put(`/n8n/update/${t}/${e}`,n)).data,Ane=async({instanceName:e,n8nId:t})=>(await Ee.delete(`/n8n/delete/${t}/${e}`)).data,Dne=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/n8n/settings/${e}`,n,{headers:{apikey:t}})).data,Fne=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/n8n/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data;function Cg(){const e=nt(Dne,{invalidateKeys:[[\"n8n\",\"fetchDefaultSettings\"]]}),t=nt(Fne,{invalidateKeys:[[\"n8n\",\"getN8n\"],[\"n8n\",\"fetchSessions\"]]}),n=nt(Ane,{invalidateKeys:[[\"n8n\",\"getN8n\"],[\"n8n\",\"fetchN8n\"],[\"n8n\",\"fetchSessions\"]]}),r=nt(Ine,{invalidateKeys:[[\"n8n\",\"getN8n\"],[\"n8n\",\"fetchN8n\"],[\"n8n\",\"fetchSessions\"]]}),s=nt(One,{invalidateKeys:[[\"n8n\",\"fetchN8n\"]]});return{setDefaultSettingsN8n:e,changeStatusN8n:t,deleteN8n:n,updateN8n:r,createN8n:s}}const Lne=e=>[\"n8n\",\"fetchDefaultSettings\",JSON.stringify(e)],$ne=async({instanceName:e,token:t})=>(await Ee.get(`/n8n/fetchSettings/${e}`,{headers:{apikey:t}})).data,Bne=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Lne({instanceName:t,token:n}),queryFn:()=>$ne({instanceName:t,token:n}),enabled:!!t})},zne=P.object({expire:P.string(),keywordFinish:P.string(),delayMessage:P.string(),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.string(),ignoreJids:P.array(P.string()).default([]),n8nIdFallback:P.union([P.null(),P.string()]).optional(),splitMessages:P.boolean(),timePerChar:P.string()});function Une(){const{t:e}=Ve(),{instance:t}=ct(),{setDefaultSettingsN8n:n}=Cg(),[r,s]=y.useState(!1),{data:o,refetch:l}=II({instanceName:t?.name,token:t?.token,enabled:r}),{data:u,refetch:d}=Bne({instanceName:t?.name,token:t?.token}),f=on({resolver:an(zne),defaultValues:{expire:\"0\",keywordFinish:e(\"n8n.form.examples.keywordFinish\"),delayMessage:\"1000\",unknownMessage:e(\"n8n.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:\"0\",ignoreJids:[],n8nIdFallback:void 0,splitMessages:!1,timePerChar:\"0\"}});y.useEffect(()=>{u&&f.reset({expire:u?.expire?u.expire.toString():\"0\",keywordFinish:u.keywordFinish,delayMessage:u.delayMessage?u.delayMessage.toString():\"0\",unknownMessage:u.unknownMessage,listeningFromMe:u.listeningFromMe,stopBotFromMe:u.stopBotFromMe,keepOpen:u.keepOpen,debounceTime:u.debounceTime?u.debounceTime.toString():\"0\",ignoreJids:u.ignoreJids,n8nIdFallback:u.n8nIdFallback,splitMessages:u.splitMessages,timePerChar:u.timePerChar?u.timePerChar.toString():\"0\"})},[u]);const h=async g=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const x={expire:parseInt(g.expire),keywordFinish:g.keywordFinish,delayMessage:parseInt(g.delayMessage),unknownMessage:g.unknownMessage,listeningFromMe:g.listeningFromMe,stopBotFromMe:g.stopBotFromMe,keepOpen:g.keepOpen,debounceTime:parseInt(g.debounceTime),n8nIdFallback:g.n8nIdFallback||void 0,ignoreJids:g.ignoreJids,splitMessages:g.splitMessages,timePerChar:parseInt(g.timePerChar)};await n({instanceName:t.name,token:t.token,data:x}),me.success(e(\"n8n.toast.defaultSettings.success\"))}catch(x){console.error(\"Error:\",x),me.error(`Error: ${x?.response?.data?.response?.message}`)}};function m(){d(),l()}return i.jsxs(Pt,{open:r,onOpenChange:s,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:e(\"n8n.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:m,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"n8n.defaultSettings\")})}),i.jsx(Gn,{...f,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:f.handleSubmit(h),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"n8nIdFallback\",label:e(\"n8n.form.n8nIdFallback.label\"),options:o?.filter(g=>!!g.id).map(g=>({label:g.description,value:g.id}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"n8n.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"n8n.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"n8n.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"n8n.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"n8n.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"n8n.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"n8n.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"n8n.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:e(\"n8n.form.splitMessages.label\"),reverse:!0}),i.jsx(le,{name:\"timePerChar\",label:e(\"n8n.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"n8n.form.ignoreJids.label\"),placeholder:e(\"n8n.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"n8n.button.save\")})})]})})]})]})}const Vne=e=>[\"n8n\",\"fetchSessions\",JSON.stringify(e)],Hne=async({n8nId:e,instanceName:t})=>(await Ee.get(`/n8n/fetchSessions/${e}/${t}`)).data,qne=e=>{const{n8nId:t,instanceName:n,...r}=e;return mt({...r,queryKey:Vne({n8nId:t,instanceName:n}),queryFn:()=>Hne({n8nId:t,instanceName:n}),enabled:!!n&&!!t&&(e.enabled??!0),staleTime:1e3*10})};function AI({n8nId:e}){const{t}=Ve(),{instance:n}=ct(),{changeStatusN8n:r}=Cg(),[s,o]=y.useState([]),{data:l,refetch:u}=qne({n8nId:e,instanceName:n?.name}),[d,f]=y.useState(!1),[h,m]=y.useState(\"\");function g(){u()}const x=async(w,C)=>{try{if(!n)return;await r({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"n8n.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"n8n.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"n8n.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"n8n.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"n8n.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"n8n.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:t(\"n8n.sessions.table.actions.title\")}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"n8n.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"n8n.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"n8n.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"n8n.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:d,onOpenChange:f,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"n8n.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"n8n.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"n8n.sessions.search\"),value:h,onChange:w=>m(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{})})]}),i.jsx($a,{columns:b,data:l??[],onSortingChange:o,state:{sorting:s,globalFilter:h},onGlobalFilterChange:m,enableGlobalFilter:!0,noResultsMessage:t(\"n8n.sessions.table.none\")})]})]})]})}const Kne=P.object({enabled:P.boolean(),description:P.string(),webhookUrl:P.string(),basicAuthUser:P.string(),basicAuthPass:P.string(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function DI({initialData:e,onSubmit:t,handleDelete:n,n8nId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{}}){const{t:d}=Ve(),f=on({resolver:an(Kne),defaultValues:e||{enabled:!0,description:\"\",webhookUrl:\"\",basicAuthUser:\"\",basicAuthPass:\"\",triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,splitMessages:!1,timePerChar:0}}),h=f.watch(\"triggerType\");return i.jsx(Gn,{...f,children:i.jsxs(\"form\",{onSubmit:f.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:d(\"n8n.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:d(\"n8n.form.description.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"n8n.form.n8nSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"webhookUrl\",label:d(\"n8n.form.webhookUrl.label\"),required:!0,children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"n8n.form.basicAuth.label\")}),i.jsx($t,{})]}),i.jsxs(\"div\",{className:\"flex w-full flex-row gap-4\",children:[i.jsx(le,{name:\"basicAuthUser\",label:d(\"n8n.form.basicAuthUser.label\"),className:\"flex-1\",children:i.jsx(ne,{})}),i.jsx(le,{name:\"basicAuthPass\",label:d(\"n8n.form.basicAuthPass.label\"),className:\"flex-1\",children:i.jsx(ne,{type:\"password\"})})]}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"n8n.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:d(\"n8n.form.triggerType.label\"),options:[{label:d(\"n8n.form.triggerType.keyword\"),value:\"keyword\"},{label:d(\"n8n.form.triggerType.all\"),value:\"all\"},{label:d(\"n8n.form.triggerType.advanced\"),value:\"advanced\"},{label:d(\"n8n.form.triggerType.none\"),value:\"none\"}]}),h===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:d(\"n8n.form.triggerOperator.label\"),options:[{label:d(\"n8n.form.triggerOperator.contains\"),value:\"contains\"},{label:d(\"n8n.form.triggerOperator.equals\"),value:\"equals\"},{label:d(\"n8n.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:d(\"n8n.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:d(\"n8n.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:d(\"n8n.form.triggerValue.label\"),children:i.jsx(ne,{})})]}),h===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:d(\"n8n.form.triggerConditions.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"n8n.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:d(\"n8n.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:d(\"n8n.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:d(\"n8n.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:d(\"n8n.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:d(\"n8n.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:d(\"n8n.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:d(\"n8n.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:d(\"n8n.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:d(\"n8n.form.splitMessages.label\"),reverse:!0}),f.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:d(\"n8n.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"n8n.button.saving\":\"n8n.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx(AI,{n8nId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:d(\"n8n.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:d(\"modal.delete.title\")}),i.jsx(eo,{children:d(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:d(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:d(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"n8n.button.saving\":\"n8n.button.update\")})]})]})]})})}function Wne({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),[r,s]=y.useState(!1),[o,l]=y.useState(!1),{createN8n:u}=Cg(),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");s(!0);const h={enabled:f.enabled,description:f.description,webhookUrl:f.webhookUrl,basicAuthUser:f.basicAuthUser,basicAuthPass:f.basicAuthPass,triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0,splitMessages:f.splitMessages||!1,timePerChar:f.timePerChar||0};await u({instanceName:n.name,token:n.token,data:h}),me.success(t(\"n8n.toast.success.create\")),l(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{s(!1)}};return i.jsxs(Pt,{open:o,onOpenChange:l,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"n8n.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"n8n.form.title\")})}),i.jsx(DI,{onSubmit:d,isModal:!0,isLoading:r})]})]})}const Gne=e=>[\"n8n\",\"getN8n\",JSON.stringify(e)],Jne=async({n8nId:e,instanceName:t})=>(await Ee.get(`/n8n/fetch/${e}/${t}`)).data,Qne=e=>{const{n8nId:t,instanceName:n,...r}=e;return mt({...r,queryKey:Gne({n8nId:t,instanceName:n}),queryFn:()=>Jne({n8nId:t,instanceName:n}),enabled:!!n&&!!t&&(e.enabled??!0)})};function Zne({n8nId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteN8n:u,updateN8n:d}=Cg(),{data:f,isLoading:h}=Qne({n8nId:e,instanceName:r?.name}),m=y.useMemo(()=>({enabled:!!f?.enabled,description:f?.description??\"\",webhookUrl:f?.webhookUrl??\"\",basicAuthUser:f?.basicAuthUser??\"\",basicAuthPass:f?.basicAuthPass??\"\",triggerType:f?.triggerType??\"\",triggerOperator:f?.triggerOperator??\"\",triggerValue:f?.triggerValue??\"\",expire:f?.expire??0,keywordFinish:f?.keywordFinish??\"\",delayMessage:f?.delayMessage??0,unknownMessage:f?.unknownMessage??\"\",listeningFromMe:!!f?.listeningFromMe,stopBotFromMe:!!f?.stopBotFromMe,keepOpen:!!f?.keepOpen,debounceTime:f?.debounceTime??0,splitMessages:f?.splitMessages??!1,timePerChar:f?.timePerChar??0}),[f?.webhookUrl,f?.basicAuthUser,f?.basicAuthPass,f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.stopBotFromMe,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.unknownMessage,f?.splitMessages,f?.timePerChar]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,webhookUrl:b.webhookUrl,basicAuthUser:b.basicAuthUser,basicAuthPass:b.basicAuthPass,triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0,splitMessages:b.splitMessages||!1,timePerChar:b.timePerChar||0};await d({instanceName:r.name,n8nId:e,data:w}),me.success(n(\"n8n.toast.success.update\")),t(),s(`/manager/instance/${r.id}/n8n/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,n8nId:e}),me.success(n(\"n8n.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/n8n`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir n8n:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(DI,{initialData:m,onSubmit:g,n8nId:e,handleDelete:x,isModal:!1,isLoading:h,openDeletionDialog:o,setOpenDeletionDialog:l})})}function jk(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{n8nId:r}=ls(),{data:s,refetch:o,isLoading:l}=II({instanceName:n?.name}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/n8n/${h}`)},f=()=>{o()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"n8n.title\")}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-2\",children:[i.jsx(AI,{}),i.jsx(Une,{}),i.jsx(Wne,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:l?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsx(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:i.jsx(\"h4\",{className:\"text-base\",children:h.description||h.id})},h.id)):i.jsx(se,{variant:\"link\",children:e(\"n8n.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-border\"}),i.jsx(Hn,{children:i.jsx(Zne,{n8nId:r,resetTable:f})})]})]})]})}const Yne=e=>[\"openai\",\"findOpenai\",JSON.stringify(e)],Xne=async({instanceName:e,token:t})=>(await Ee.get(`/openai/find/${e}`,{headers:{apiKey:t}})).data,FI=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Yne({instanceName:t}),queryFn:()=>Xne({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},ere=e=>[\"openai\",\"findOpenaiCreds\",JSON.stringify(e)],tre=async({instanceName:e,token:t})=>(await Ee.get(`/openai/creds/${e}`,{headers:{apiKey:t}})).data,dw=e=>{const{instanceName:t,token:n,...r}=e;return mt({staleTime:1e3*60*60*6,...r,queryKey:ere({instanceName:t}),queryFn:()=>tre({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},nre=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/openai/creds/${e}`,n,{headers:{apikey:t}})).data,rre=async({openaiCredsId:e,instanceName:t})=>(await Ee.delete(`/openai/creds/${e}/${t}`)).data,sre=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/openai/create/${e}`,n,{headers:{apikey:t}})).data,ore=async({instanceName:e,token:t,openaiId:n,data:r})=>(await Ee.put(`/openai/update/${n}/${e}`,r,{headers:{apikey:t}})).data,are=async({instanceName:e,token:t,openaiId:n})=>(await Ee.delete(`/openai/delete/${n}/${e}`,{headers:{apikey:t}})).data,ire=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/openai/settings/${e}`,n,{headers:{apikey:t}})).data,lre=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/openai/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data;function Md(){const e=nt(ire,{invalidateKeys:[[\"openai\",\"fetchDefaultSettings\"]]}),t=nt(lre,{invalidateKeys:[[\"openai\",\"getOpenai\"],[\"openai\",\"fetchSessions\"]]}),n=nt(are,{invalidateKeys:[[\"openai\",\"getOpenai\"],[\"openai\",\"findOpenai\"],[\"openai\",\"fetchSessions\"]]}),r=nt(ore,{invalidateKeys:[[\"openai\",\"getOpenai\"],[\"openai\",\"findOpenai\"],[\"openai\",\"fetchSessions\"]]}),s=nt(sre,{invalidateKeys:[[\"openai\",\"findOpenai\"]]}),o=nt(nre,{invalidateKeys:[[\"openai\",\"findOpenaiCreds\"]]}),l=nt(rre,{invalidateKeys:[[\"openai\",\"findOpenaiCreds\"]]});return{setDefaultSettingsOpenai:e,changeStatusOpenai:t,deleteOpenai:n,updateOpenai:r,createOpenai:s,createOpenaiCreds:o,deleteOpenaiCreds:l}}const cre=P.object({name:P.string(),apiKey:P.string()});function LI({onCredentialsUpdate:e,showText:t=!0}){const{t:n}=Ve(),{instance:r}=ct(),{createOpenaiCreds:s,deleteOpenaiCreds:o}=Md(),[l,u]=y.useState(!1),[d,f]=y.useState([]),{data:h}=dw({instanceName:r?.name,enabled:l}),m=on({resolver:an(cre),defaultValues:{name:\"\",apiKey:\"\"}}),g=async w=>{try{if(!r||!r.name)throw new Error(\"instance not found.\");const C={name:w.name,apiKey:w.apiKey};await s({instanceName:r.name,token:r.token,data:C}),me.success(n(\"openai.toast.success.credentialsCreate\")),m.reset(),e&&e()}catch(C){console.error(\"Error:\",C),me.error(`Error: ${C?.response?.data?.response?.message}`)}},x=async w=>{if(!r?.name){me.error(\"Instance not found.\");return}try{await o({openaiCredsId:w,instanceName:r?.name}),me.success(n(\"openai.toast.success.credentialsDelete\")),e&&e()}catch(C){console.error(\"Error:\",C),me.error(`Error: ${C?.response?.data?.response?.message}`)}},b=[{accessorKey:\"name\",header:({column:w})=>i.jsxs(se,{variant:\"ghost\",onClick:()=>w.toggleSorting(w.getIsSorted()===\"asc\"),children:[n(\"openai.credentials.table.name\"),i.jsx(q$,{className:\"ml-2 h-4 w-4\"})]}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"name\")})},{accessorKey:\"apiKey\",header:()=>i.jsx(\"div\",{className:\"text-right\",children:n(\"openai.credentials.table.apiKey\")}),cell:({row:w})=>i.jsxs(\"div\",{children:[`${w.getValue(\"apiKey\")}`.slice(0,20),\"...\"]})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:n(\"openai.credentials.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:n(\"openai.credentials.table.actions.title\")}),i.jsx(Xs,{}),i.jsx(wt,{onClick:()=>x(C.id),children:n(\"openai.credentials.table.actions.delete\")})]})]})}}];return i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"secondary\",size:\"sm\",type:\"button\",children:t?i.jsxs(i.Fragment,{children:[i.jsx(mB,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden md:inline\",children:n(\"openai.credentials.title\")})]}):i.jsx(cs,{size:16})})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:n(\"openai.credentials.title\")})}),i.jsx(Gn,{...m,children:i.jsx(\"div\",{onClick:w=>w.stopPropagation(),onSubmit:w=>w.stopPropagation(),onKeyDown:w=>w.stopPropagation(),children:i.jsxs(\"form\",{onSubmit:w=>{w.preventDefault(),w.stopPropagation(),m.handleSubmit(g)(w)},className:\"w-full space-y-6\",children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"grid gap-3 md:grid-cols-2\",children:[i.jsx(le,{name:\"name\",label:n(\"openai.credentials.table.name\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"apiKey\",label:n(\"openai.credentials.table.apiKey\"),children:i.jsx(ne,{type:\"password\"})})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:n(\"openai.button.save\")})})]})})}),i.jsx($t,{}),i.jsx(\"div\",{children:i.jsx($a,{columns:b,data:h??[],onSortingChange:f,state:{sorting:d},noResultsMessage:n(\"openai.credentials.table.none\")})})]})]})}const ure=e=>[\"openai\",\"fetchDefaultSettings\",JSON.stringify(e)],dre=async({instanceName:e,token:t})=>{const n=await Ee.get(`/openai/fetchSettings/${e}`,{headers:{apiKey:t}});return Array.isArray(n.data)?n.data[0]:n.data},fre=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:ure({instanceName:t}),queryFn:()=>dre({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},pre=P.object({openaiCredsId:P.string(),expire:P.coerce.number(),keywordFinish:P.string(),delayMessage:P.coerce.number().default(0),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.coerce.number(),speechToText:P.boolean(),ignoreJids:P.array(P.string()).default([]),openaiIdFallback:P.union([P.null(),P.string()]).optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function hre(){const{t:e}=Ve(),{instance:t}=ct(),{setDefaultSettingsOpenai:n}=Md(),[r,s]=y.useState(!1),{data:o,refetch:l}=fre({instanceName:t?.name,enabled:r}),{data:u,refetch:d}=FI({instanceName:t?.name,enabled:r}),{data:f}=dw({instanceName:t?.name,enabled:r}),h=on({resolver:an(pre),defaultValues:{openaiCredsId:\"\",expire:0,keywordFinish:e(\"openai.form.examples.keywordFinish\"),delayMessage:1e3,unknownMessage:e(\"openai.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,speechToText:!1,ignoreJids:[],openaiIdFallback:void 0,splitMessages:!1,timePerChar:0}});y.useEffect(()=>{o&&h.reset({openaiCredsId:o.openaiCredsId,expire:o?.expire??0,keywordFinish:o.keywordFinish,delayMessage:o.delayMessage??0,unknownMessage:o.unknownMessage,listeningFromMe:o.listeningFromMe,stopBotFromMe:o.stopBotFromMe,keepOpen:o.keepOpen,debounceTime:o.debounceTime??0,speechToText:o.speechToText,ignoreJids:o.ignoreJids,openaiIdFallback:o.openaiIdFallback,splitMessages:o.splitMessages,timePerChar:o.timePerChar??0})},[o]);const m=async x=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const b={openaiCredsId:x.openaiCredsId,expire:x.expire,keywordFinish:x.keywordFinish,delayMessage:x.delayMessage,unknownMessage:x.unknownMessage,listeningFromMe:x.listeningFromMe,stopBotFromMe:x.stopBotFromMe,keepOpen:x.keepOpen,debounceTime:x.debounceTime,speechToText:x.speechToText,openaiIdFallback:x.openaiIdFallback||void 0,ignoreJids:x.ignoreJids,splitMessages:x.splitMessages,timePerChar:x.timePerChar};await n({instanceName:t.name,token:t.token,data:b}),me.success(e(\"openai.toast.defaultSettings.success\"))}catch(b){console.error(\"Error:\",b),me.error(`Error: ${b?.response?.data?.response?.message}`)}};function g(){l(),d()}return i.jsxs(Pt,{open:r,onOpenChange:s,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden md:inline\",children:e(\"openai.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"openai.defaultSettings\")})}),i.jsx(Gn,{...h,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:h.handleSubmit(m),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"openaiCredsId\",label:e(\"openai.form.openaiCredsId.label\"),options:f?.filter(x=>!!x.id).map(x=>({label:x.name?x.name:x.apiKey.substring(0,15)+\"...\",value:x.id}))||[]}),i.jsx(Jt,{name:\"openaiIdFallback\",label:e(\"openai.form.openaiIdFallback.label\"),options:u?.filter(x=>!!x.id).map(x=>({label:x.description,value:x.id}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"openai.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"openai.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"openai.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"openai.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"openai.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"openai.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"openai.form.keepOpen.label\"),reverse:!0}),i.jsx(Pe,{name:\"speechToText\",label:e(\"openai.form.speechToText.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"openai.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:e(\"openai.form.splitMessages.label\"),reverse:!0}),h.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:e(\"openai.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"openai.form.ignoreJids.label\"),placeholder:e(\"openai.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"openai.button.save\")})})]})})]})]})}const gre=e=>[\"openai\",\"getModels\",JSON.stringify(e)],mre=async({instanceName:e,openaiCredsId:t,token:n})=>{const r=t?{openaiCredsId:t}:{};return(await Ee.get(`/openai/getModels/${e}`,{headers:{apiKey:n},params:r})).data},vre=e=>{const{instanceName:t,openaiCredsId:n,token:r,...s}=e;return mt({staleTime:1e3*60*60*6,...s,queryKey:gre({instanceName:t,openaiCredsId:n}),queryFn:()=>mre({instanceName:t,openaiCredsId:n,token:r}),enabled:!!t&&!!n&&(e.enabled??!0)})},yre=e=>[\"openai\",\"fetchSessions\",JSON.stringify(e)],bre=async({instanceName:e,openaiId:t,token:n})=>(await Ee.get(`/openai/fetchSessions/${t}/${e}`,{headers:{apiKey:n}})).data,xre=e=>{const{instanceName:t,token:n,openaiId:r,...s}=e;return mt({...s,queryKey:yre({instanceName:t}),queryFn:()=>bre({instanceName:t,token:n,openaiId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function $I({openaiId:e}){const{t}=Ve(),{instance:n}=ct(),{changeStatusOpenai:r}=Md(),[s,o]=y.useState([]),[l,u]=y.useState(!1),{data:d,refetch:f}=xre({instanceName:n?.name,openaiId:e,enabled:l}),[h,m]=y.useState(\"\");function g(){f()}const x=async(w,C)=>{try{if(!n)return;await r({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"openai.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"openai.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"openai.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"openai.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"openai.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",size:\"icon\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"openai.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:t(\"openai.sessions.table.actions.title\")}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"openai.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"openai.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"openai.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"openai.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden md:inline\",children:t(\"openai.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"openai.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"openai.sessions.search\"),value:h,onChange:w=>m(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{size:16})})]}),i.jsx($a,{columns:b,data:d??[],onSortingChange:o,state:{sorting:s,globalFilter:h},onGlobalFilterChange:m,enableGlobalFilter:!0,noResultsMessage:t(\"openai.sessions.table.none\")})]})]})]})}const wre=P.object({enabled:P.boolean(),description:P.string(),openaiCredsId:P.string(),botType:P.string(),assistantId:P.string().optional(),functionUrl:P.string().optional(),model:P.string().optional(),systemMessages:P.string().optional(),assistantMessages:P.string().optional(),userMessages:P.string().optional(),maxTokens:P.coerce.number().optional(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional(),splitMessages:P.boolean().optional(),timePerChar:P.coerce.number().optional()});function BI({initialData:e,onSubmit:t,handleDelete:n,openaiId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{},open:d}){const{t:f}=Ve(),{instance:h}=ct(),[m,g]=y.useState(!1),{data:x,refetch:b}=dw({instanceName:h?.name,enabled:d}),w=on({resolver:an(wre),defaultValues:e||{enabled:!0,description:\"\",openaiCredsId:\"\",botType:\"assistant\",assistantId:\"\",functionUrl:\"\",model:\"\",systemMessages:\"\",assistantMessages:\"\",userMessages:\"\",maxTokens:0,triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0,splitMessages:!1,timePerChar:0}}),C=w.watch(\"botType\"),k=w.watch(\"triggerType\"),j=w.watch(\"openaiCredsId\"),{data:M,isLoading:_,refetch:R}=vre({instanceName:h?.name,openaiCredsId:j,token:h?.token,enabled:m&&!!j}),N=()=>{j&&(g(!0),R())},O=()=>{b()};return i.jsx(Gn,{...w,children:i.jsxs(\"form\",{onSubmit:w.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:f(\"openai.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:f(\"openai.form.description.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(\"div\",{className:\"space-y-2\",children:i.jsxs(\"div\",{className:\"flex items-end gap-2\",children:[i.jsx(\"div\",{className:\"flex-1\",children:i.jsx(Jt,{name:\"openaiCredsId\",label:f(\"openai.form.openaiCredsId.label\"),required:!0,options:x?.filter(D=>!!D.id).map(D=>({label:D.name?D.name:D.apiKey.substring(0,15)+\"...\",value:D.id}))??[]})}),i.jsx(LI,{onCredentialsUpdate:O,showText:!1})]})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:f(\"openai.form.openaiSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"botType\",label:f(\"openai.form.botType.label\"),required:!0,options:[{label:f(\"openai.form.botType.assistant\"),value:\"assistant\"},{label:f(\"openai.form.botType.chatCompletion\"),value:\"chatCompletion\"}]}),C===\"assistant\"&&i.jsxs(i.Fragment,{children:[i.jsx(le,{name:\"assistantId\",label:f(\"openai.form.assistantId.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(le,{name:\"functionUrl\",label:f(\"openai.form.functionUrl.label\"),required:!0,children:i.jsx(ne,{})})]}),C===\"chatCompletion\"&&i.jsxs(i.Fragment,{children:[i.jsx(\"div\",{className:\"space-y-2\",children:i.jsxs(\"div\",{className:\"flex items-end gap-2\",children:[i.jsx(\"div\",{className:\"flex-1\",children:i.jsx(Jt,{name:\"model\",label:f(\"openai.form.model.label\"),required:!0,disabled:!M||M.length===0,options:M?.map(D=>({label:D.id,value:D.id}))??[]})}),i.jsx(se,{type:\"button\",variant:\"outline\",size:\"sm\",disabled:!j||_,onClick:N,className:\"mb-2\",children:_?i.jsxs(i.Fragment,{children:[i.jsx(Ip,{className:\"mr-2 h-4 w-4 animate-spin\"}),f(\"openai.button.loading\")]}):i.jsxs(i.Fragment,{children:[i.jsx(Ip,{className:\"mr-2 h-4 w-4\"}),f(\"openai.button.loadModels\")]})})]})}),i.jsx(le,{name:\"systemMessages\",label:f(\"openai.form.systemMessages.label\"),children:i.jsx(bi,{})}),i.jsx(le,{name:\"assistantMessages\",label:f(\"openai.form.assistantMessages.label\"),children:i.jsx(bi,{})}),i.jsx(le,{name:\"userMessages\",label:f(\"openai.form.userMessages.label\"),children:i.jsx(bi,{})}),i.jsx(le,{name:\"maxTokens\",label:f(\"openai.form.maxTokens.label\"),children:i.jsx(ne,{type:\"number\"})})]}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:f(\"openai.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:f(\"openai.form.triggerType.label\"),required:!0,options:[{label:f(\"openai.form.triggerType.keyword\"),value:\"keyword\"},{label:f(\"openai.form.triggerType.all\"),value:\"all\"},{label:f(\"openai.form.triggerType.advanced\"),value:\"advanced\"},{label:f(\"openai.form.triggerType.none\"),value:\"none\"}]}),k===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:f(\"openai.form.triggerOperator.label\"),required:!0,options:[{label:f(\"openai.form.triggerOperator.contains\"),value:\"contains\"},{label:f(\"openai.form.triggerOperator.equals\"),value:\"equals\"},{label:f(\"openai.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:f(\"openai.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:f(\"openai.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:f(\"openai.form.triggerValue.label\"),required:!0,children:i.jsx(ne,{})})]}),k===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:f(\"openai.form.triggerConditions.label\"),required:!0,children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:f(\"openai.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:f(\"openai.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:f(\"openai.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:f(\"openai.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:f(\"openai.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:f(\"openai.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:f(\"openai.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:f(\"openai.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:f(\"openai.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Pe,{name:\"splitMessages\",label:f(\"openai.form.splitMessages.label\"),reverse:!0}),w.watch(\"splitMessages\")&&i.jsx(le,{name:\"timePerChar\",label:f(\"openai.form.timePerChar.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:f(o?\"openai.button.saving\":\"openai.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx($I,{openaiId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:f(\"dify.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:f(\"modal.delete.title\")}),i.jsx(eo,{children:f(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:f(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:f(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:f(o?\"openai.button.saving\":\"openai.button.update\")})]})]})]})})}function Sre({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),{createOpenai:r}=Md(),[s,o]=y.useState(!1),[l,u]=y.useState(!1),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");o(!0);const h={enabled:f.enabled,description:f.description,openaiCredsId:f.openaiCredsId,botType:f.botType,assistantId:f.assistantId||\"\",functionUrl:f.functionUrl||\"\",model:f.model||\"\",systemMessages:[f.systemMessages||\"\"],assistantMessages:[f.assistantMessages||\"\"],userMessages:[f.userMessages||\"\"],maxTokens:f.maxTokens||0,triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0,splitMessages:f.splitMessages||!1,timePerChar:f.timePerChar||0};await r({instanceName:n.name,token:n.token,data:h}),me.success(t(\"openai.toast.success.create\")),u(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{o(!1)}};return i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"openai.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"openai.form.title\")})}),i.jsx(BI,{onSubmit:d,isModal:!0,isLoading:s,open:l})]})]})}const Cre=e=>[\"openai\",\"getOpenai\",JSON.stringify(e)],Ere=async({instanceName:e,token:t,openaiId:n})=>{const r=await Ee.get(`/openai/fetch/${n}/${e}`,{headers:{apiKey:t}});return Array.isArray(r.data)?r.data[0]:r.data},kre=e=>{const{instanceName:t,token:n,openaiId:r,...s}=e;return mt({...s,queryKey:Cre({instanceName:t}),queryFn:()=>Ere({instanceName:t,token:n,openaiId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function jre({openaiId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteOpenai:u,updateOpenai:d}=Md(),{data:f,isLoading:h}=kre({instanceName:r?.name,openaiId:e}),m=y.useMemo(()=>({enabled:f?.enabled??!0,description:f?.description??\"\",openaiCredsId:f?.openaiCredsId??\"\",botType:f?.botType??\"\",assistantId:f?.assistantId||\"\",functionUrl:f?.functionUrl||\"\",model:f?.model||\"\",systemMessages:Array.isArray(f?.systemMessages)?f?.systemMessages.join(\", \"):f?.systemMessages||\"\",assistantMessages:Array.isArray(f?.assistantMessages)?f?.assistantMessages.join(\", \"):f?.assistantMessages||\"\",userMessages:Array.isArray(f?.userMessages)?f?.userMessages.join(\", \"):f?.userMessages||\"\",maxTokens:f?.maxTokens||0,triggerType:f?.triggerType||\"\",triggerOperator:f?.triggerOperator||\"\",triggerValue:f?.triggerValue,expire:f?.expire||0,keywordFinish:f?.keywordFinish,delayMessage:f?.delayMessage||0,unknownMessage:f?.unknownMessage,listeningFromMe:f?.listeningFromMe,stopBotFromMe:f?.stopBotFromMe,keepOpen:f?.keepOpen,debounceTime:f?.debounceTime||0,splitMessages:f?.splitMessages||!1,timePerChar:f?.timePerChar||0}),[f?.assistantId,f?.assistantMessages,f?.botType,f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.functionUrl,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.maxTokens,f?.model,f?.openaiCredsId,f?.stopBotFromMe,f?.systemMessages,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.unknownMessage,f?.userMessages,f?.splitMessages,f?.timePerChar]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,openaiCredsId:b.openaiCredsId,botType:b.botType,assistantId:b.assistantId||\"\",functionUrl:b.functionUrl||\"\",model:b.model||\"\",systemMessages:[b.systemMessages||\"\"],assistantMessages:[b.assistantMessages||\"\"],userMessages:[b.userMessages||\"\"],maxTokens:b.maxTokens||0,triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0,splitMessages:b.splitMessages||!1,timePerChar:b.timePerChar||0};await d({instanceName:r.name,openaiId:e,data:w}),me.success(n(\"openai.toast.success.update\")),t(),s(`/manager/instance/${r.id}/openai/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,openaiId:e}),me.success(n(\"openai.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/openai`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir dify:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(BI,{initialData:m,onSubmit:g,openaiId:e,handleDelete:x,isModal:!1,isLoading:h,openDeletionDialog:o,setOpenDeletionDialog:l})})}function Tk(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{botId:r}=ls(),{data:s,isLoading:o,refetch:l}=FI({instanceName:n?.name}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/openai/${h}`)},f=()=>{l()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"openai.title\")}),i.jsxs(\"div\",{className:\"flex items-center justify-end gap-2\",children:[i.jsx($I,{}),i.jsx(hre,{}),i.jsx(LI,{}),i.jsx(Sre,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:o?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsxs(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:[i.jsx(\"h4\",{className:\"text-base\",children:h.description||h.id}),i.jsx(\"p\",{className:\"text-sm font-normal text-muted-foreground\",children:h.botType})]},h.id)):i.jsx(se,{variant:\"link\",children:e(\"openai.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-border\"}),i.jsx(Hn,{children:i.jsx(jre,{openaiId:r,resetTable:f})})]})]})]})}const Tre=e=>[\"proxy\",\"fetchProxy\",JSON.stringify(e)],Nre=async({instanceName:e,token:t})=>(await Ee.get(`/proxy/find/${e}`,{headers:{apiKey:t}})).data,Mre=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Tre({instanceName:t,token:n}),queryFn:()=>Nre({instanceName:t,token:n}),enabled:!!t})},_re=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/proxy/set/${e}`,n,{headers:{apikey:t}})).data;function Rre(){return{createProxy:nt(_re,{invalidateKeys:[[\"proxy\",\"fetchProxy\"]]})}}const Pre=P.object({enabled:P.boolean(),host:P.string(),port:P.string(),protocol:P.string(),username:P.string(),password:P.string()});function Ore(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{createProxy:s}=Rre(),{data:o}=Mre({instanceName:t?.name}),l=on({resolver:an(Pre),defaultValues:{enabled:!1,host:\"\",port:\"\",protocol:\"http\",username:\"\",password:\"\"}});y.useEffect(()=>{o&&l.reset({enabled:o.enabled,host:o.host,port:o.port,protocol:o.protocol,username:o.username,password:o.password})},[o]);const u=async d=>{if(t){r(!0);try{const f={enabled:d.enabled,host:d.host,port:d.port,protocol:d.protocol,username:d.username,password:d.password};await s({instanceName:t.name,token:t.token,data:f}),me.success(e(\"proxy.toast.success\"))}catch(f){console.error(e(\"proxy.toast.error\"),f),me.error(`Error : ${f?.response?.data?.response?.message}`)}finally{r(!1)}}};return i.jsx(i.Fragment,{children:i.jsx(Fo,{...l,children:i.jsx(\"form\",{onSubmit:l.handleSubmit(u),className:\"w-full space-y-6\",children:i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"proxy.title\")}),i.jsx(Oa,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y [&>*]:p-4\",children:[i.jsx(Pe,{name:\"enabled\",label:e(\"proxy.form.enabled.label\"),className:\"w-full justify-between\",helper:e(\"proxy.form.enabled.description\")}),i.jsxs(\"div\",{className:\"grid gap-4 sm:grid-cols-[10rem_1fr_10rem] md:gap-8\",children:[i.jsx(le,{name:\"protocol\",label:e(\"proxy.form.protocol.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"host\",label:e(\"proxy.form.host.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"port\",label:e(\"proxy.form.port.label\"),children:i.jsx(ne,{type:\"number\"})})]}),i.jsxs(\"div\",{className:\"grid gap-4 sm:grid-cols-2 md:gap-8\",children:[i.jsx(le,{name:\"username\",label:e(\"proxy.form.username.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"password\",label:e(\"proxy.form.password.label\"),children:i.jsx(ne,{type:\"password\"})})]}),i.jsx(\"div\",{className:\"flex justify-end px-4 pt-6\",children:i.jsx(se,{type:\"submit\",disabled:n,children:e(n?\"proxy.button.saving\":\"proxy.button.save\")})})]})]})})})})}const Ire=e=>[\"rabbitmq\",\"fetchRabbitmq\",JSON.stringify(e)],Are=async({instanceName:e,token:t})=>(await Ee.get(`/rabbitmq/find/${e}`,{headers:{apiKey:t}})).data,Dre=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Ire({instanceName:t,token:n}),queryFn:()=>Are({instanceName:t,token:n}),enabled:!!t})},Fre=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/rabbitmq/set/${e}`,{rabbitmq:n},{headers:{apikey:t}})).data;function Lre(){return{createRabbitmq:nt(Fre,{invalidateKeys:[[\"rabbitmq\",\"fetchRabbitmq\"]]})}}const $re=P.object({enabled:P.boolean(),events:P.array(P.string())});function Bre(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{createRabbitmq:s}=Lre(),{data:o}=Dre({instanceName:t?.name,token:t?.token}),l=on({resolver:an($re),defaultValues:{enabled:!1,events:[]}});y.useEffect(()=>{o&&l.reset({enabled:o.enabled,events:o.events})},[o]);const u=async m=>{if(t){r(!0);try{const g={enabled:m.enabled,events:m.events};await s({instanceName:t.name,token:t.token,data:g}),me.success(e(\"rabbitmq.toast.success\"))}catch(g){console.error(e(\"rabbitmq.toast.error\"),g),me.error(`Error: ${g?.response?.data?.response?.message}`)}finally{r(!1)}}},d=[\"APPLICATION_STARTUP\",\"QRCODE_UPDATED\",\"MESSAGES_SET\",\"MESSAGES_UPSERT\",\"MESSAGES_UPDATE\",\"MESSAGES_DELETE\",\"SEND_MESSAGE\",\"CONTACTS_SET\",\"CONTACTS_UPSERT\",\"CONTACTS_UPDATE\",\"PRESENCE_UPDATE\",\"CHATS_SET\",\"CHATS_UPSERT\",\"CHATS_UPDATE\",\"CHATS_DELETE\",\"GROUPS_UPSERT\",\"GROUP_UPDATE\",\"GROUP_PARTICIPANTS_UPDATE\",\"CONNECTION_UPDATE\",\"REMOVE_INSTANCE\",\"LOGOUT_INSTANCE\",\"LABELS_EDIT\",\"LABELS_ASSOCIATION\",\"CALL\",\"TYPEBOT_START\",\"TYPEBOT_CHANGE_STATUS\"],f=()=>{l.setValue(\"events\",d)},h=()=>{l.setValue(\"events\",[])};return i.jsx(i.Fragment,{children:i.jsx(Fo,{...l,children:i.jsx(\"form\",{onSubmit:l.handleSubmit(u),className:\"w-full space-y-6\",children:i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"rabbitmq.title\")}),i.jsx(Oa,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y [&>*]:p-4\",children:[i.jsx(Pe,{name:\"enabled\",label:e(\"rabbitmq.form.enabled.label\"),className:\"w-full justify-between\",helper:e(\"rabbitmq.form.enabled.description\")}),i.jsxs(\"div\",{className:\"mb-4 flex justify-between\",children:[i.jsx(se,{variant:\"outline\",type:\"button\",onClick:f,children:e(\"button.markAll\")}),i.jsx(se,{variant:\"outline\",type:\"button\",onClick:h,children:e(\"button.unMarkAll\")})]}),i.jsx(Lo,{control:l.control,name:\"events\",render:({field:m})=>i.jsxs(no,{className:\"flex flex-col\",children:[i.jsx(Nr,{className:\"my-2 text-lg\",children:e(\"rabbitmq.form.events.label\")}),i.jsx(_s,{children:i.jsx(\"div\",{className:\"flex flex-col gap-2 space-y-1 divide-y\",children:d.sort((g,x)=>g.localeCompare(x)).map(g=>i.jsxs(\"div\",{className:\"flex items-center justify-between gap-3 pt-3\",children:[i.jsx(Nr,{className:Ie(\"break-all\",m.value.includes(g)?\"text-foreground\":\"text-muted-foreground\"),children:g}),i.jsx(gc,{checked:m.value.includes(g),onCheckedChange:x=>{x?m.onChange([...m.value,g]):m.onChange(m.value.filter(b=>b!==g))}})]},g))})})]})})]}),i.jsx(\"div\",{className:\"mx-4 flex justify-end pt-6\",children:i.jsx(se,{type:\"submit\",disabled:n,children:e(n?\"rabbitmq.button.saving\":\"rabbitmq.button.save\")})})]})})})})}const zre=e=>[\"instance\",\"fetchSettings\",JSON.stringify(e)],Ure=async({instanceName:e,token:t})=>(await Ee.get(`/settings/find/${e}`,{headers:{apikey:t}})).data,Vre=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:zre({instanceName:t,token:n}),queryFn:()=>Ure({instanceName:t,token:n}),enabled:!!t})},Hre=P.object({rejectCall:P.boolean(),msgCall:P.string().optional(),groupsIgnore:P.boolean(),alwaysOnline:P.boolean(),readMessages:P.boolean(),syncFullHistory:P.boolean(),readStatus:P.boolean()});function qre(){const{t:e}=Ve(),[t,n]=y.useState(!1),{instance:r}=ct(),{updateSettings:s}=Hh(),{data:o,isLoading:l}=Vre({instanceName:r?.name,token:r?.token}),u=on({resolver:an(Hre),defaultValues:{rejectCall:!1,msgCall:\"\",groupsIgnore:!1,alwaysOnline:!1,readMessages:!1,syncFullHistory:!1,readStatus:!1}});y.useEffect(()=>{o&&u.reset({rejectCall:o.rejectCall,msgCall:o.msgCall||\"\",groupsIgnore:o.groupsIgnore,alwaysOnline:o.alwaysOnline,readMessages:o.readMessages,syncFullHistory:o.syncFullHistory,readStatus:o.readStatus})},[u,o]);const d=async m=>{try{if(!r||!r.name)throw new Error(\"instance not found\");n(!0);const g={rejectCall:m.rejectCall,msgCall:m.msgCall,groupsIgnore:m.groupsIgnore,alwaysOnline:m.alwaysOnline,readMessages:m.readMessages,syncFullHistory:m.syncFullHistory,readStatus:m.readStatus};await s({instanceName:r.name,token:r.token,data:g}),me.success(e(\"settings.toast.success\"))}catch(g){console.error(e(\"settings.toast.success\"),g),me.error(e(\"settings.toast.error\"))}finally{n(!1)}},f=[{name:\"groupsIgnore\",label:e(\"settings.form.groupsIgnore.label\"),description:e(\"settings.form.groupsIgnore.description\")},{name:\"alwaysOnline\",label:e(\"settings.form.alwaysOnline.label\"),description:e(\"settings.form.alwaysOnline.description\")},{name:\"readMessages\",label:e(\"settings.form.readMessages.label\"),description:e(\"settings.form.readMessages.description\")},{name:\"syncFullHistory\",label:e(\"settings.form.syncFullHistory.label\"),description:e(\"settings.form.syncFullHistory.description\")},{name:\"readStatus\",label:e(\"settings.form.readStatus.label\"),description:e(\"settings.form.readStatus.description\")}],h=u.watch(\"rejectCall\");return l?i.jsx(On,{}):i.jsx(i.Fragment,{children:i.jsx(Fo,{...u,children:i.jsx(\"form\",{onSubmit:u.handleSubmit(d),className:\"w-full space-y-6\",children:i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"settings.title\")}),i.jsx($t,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y\",children:[i.jsxs(\"div\",{className:\"flex flex-col p-4\",children:[i.jsx(Pe,{name:\"rejectCall\",label:e(\"settings.form.rejectCall.label\"),className:\"w-full justify-between\",helper:e(\"settings.form.rejectCall.description\")}),h&&i.jsx(\"div\",{className:\"mr-16 mt-2\",children:i.jsx(le,{name:\"msgCall\",children:i.jsx(bi,{placeholder:e(\"settings.form.msgCall.description\")})})})]}),f.map(m=>i.jsx(\"div\",{className:\"flex p-4\",children:i.jsx(Pe,{name:m.name,label:m.label,className:\"w-full justify-between\",helper:m.description})},m.name)),i.jsx(\"div\",{className:\"flex justify-end pt-6\",children:i.jsx(se,{type:\"submit\",disabled:t,children:e(t?\"settings.button.saving\":\"settings.button.save\")})})]})]})})})})}const Kre=e=>[\"sqs\",\"fetchSqs\",JSON.stringify(e)],Wre=async({instanceName:e,token:t})=>(await Ee.get(`/sqs/find/${e}`,{headers:{apiKey:t}})).data,Gre=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Kre({instanceName:t,token:n}),queryFn:()=>Wre({instanceName:t,token:n}),enabled:!!t})},Jre=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/sqs/set/${e}`,{sqs:n},{headers:{apikey:t}})).data;function Qre(){return{createSqs:nt(Jre,{invalidateKeys:[[\"sqs\",\"fetchSqs\"]]})}}const Zre=P.object({enabled:P.boolean(),events:P.array(P.string())});function Yre(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{createSqs:s}=Qre(),{data:o}=Gre({instanceName:t?.name,token:t?.token}),l=on({resolver:an(Zre),defaultValues:{enabled:!1,events:[]}});y.useEffect(()=>{o&&l.reset({enabled:o.enabled,events:o.events})},[o]);const u=async m=>{if(t){r(!0);try{const g={enabled:m.enabled,events:m.events};await s({instanceName:t.name,token:t.token,data:g}),me.success(e(\"sqs.toast.success\"))}catch(g){console.error(e(\"sqs.toast.error\"),g),me.error(`Error: ${g?.response?.data?.response?.message}`)}finally{r(!1)}}},d=[\"APPLICATION_STARTUP\",\"QRCODE_UPDATED\",\"MESSAGES_SET\",\"MESSAGES_UPSERT\",\"MESSAGES_UPDATE\",\"MESSAGES_DELETE\",\"SEND_MESSAGE\",\"CONTACTS_SET\",\"CONTACTS_UPSERT\",\"CONTACTS_UPDATE\",\"PRESENCE_UPDATE\",\"CHATS_SET\",\"CHATS_UPSERT\",\"CHATS_UPDATE\",\"CHATS_DELETE\",\"GROUPS_UPSERT\",\"GROUP_UPDATE\",\"GROUP_PARTICIPANTS_UPDATE\",\"CONNECTION_UPDATE\",\"REMOVE_INSTANCE\",\"LOGOUT_INSTANCE\",\"LABELS_EDIT\",\"LABELS_ASSOCIATION\",\"CALL\",\"TYPEBOT_START\",\"TYPEBOT_CHANGE_STATUS\"],f=()=>{l.setValue(\"events\",d)},h=()=>{l.setValue(\"events\",[])};return i.jsx(i.Fragment,{children:i.jsx(Fo,{...l,children:i.jsx(\"form\",{onSubmit:l.handleSubmit(u),className:\"w-full space-y-6\",children:i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"sqs.title\")}),i.jsx(Oa,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y [&>*]:p-4\",children:[i.jsx(Pe,{name:\"enabled\",label:e(\"sqs.form.enabled.label\"),className:\"w-full justify-between\",helper:e(\"sqs.form.enabled.description\")}),i.jsxs(\"div\",{className:\"mb-4 flex justify-between\",children:[i.jsx(se,{variant:\"outline\",type:\"button\",onClick:f,children:e(\"button.markAll\")}),i.jsx(se,{variant:\"outline\",type:\"button\",onClick:h,children:e(\"button.unMarkAll\")})]}),i.jsx(Lo,{control:l.control,name:\"events\",render:({field:m})=>i.jsxs(no,{className:\"flex flex-col\",children:[i.jsx(Nr,{className:\"my-2 text-lg\",children:e(\"sqs.form.events.label\")}),i.jsx(_s,{children:i.jsx(\"div\",{className:\"flex flex-col gap-2 space-y-1 divide-y\",children:d.sort((g,x)=>g.localeCompare(x)).map(g=>i.jsxs(\"div\",{className:\"flex items-center justify-between gap-3 pt-3\",children:[i.jsx(Nr,{className:Ie(\"break-all\",m.value.includes(g)?\"text-foreground\":\"text-muted-foreground\"),children:g}),i.jsx(gc,{checked:m.value.includes(g),onCheckedChange:x=>{x?m.onChange([...m.value,g]):m.onChange(m.value.filter(b=>b!==g))}})]},g))})})]})})]}),i.jsx(\"div\",{className:\"mx-4 flex justify-end pt-6\",children:i.jsx(se,{type:\"submit\",disabled:n,children:e(n?\"sqs.button.saving\":\"sqs.button.save\")})})]})})})})}const Xre=e=>[\"typebot\",\"findTypebot\",JSON.stringify(e)],ese=async({instanceName:e,token:t})=>(await Ee.get(`/typebot/find/${e}`,{headers:{apiKey:t}})).data,zI=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Xre({instanceName:t}),queryFn:()=>ese({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},tse=e=>[\"typebot\",\"fetchDefaultSettings\",JSON.stringify(e)],nse=async({instanceName:e,token:t})=>{const n=await Ee.get(`/typebot/fetchSettings/${e}`,{headers:{apiKey:t}});return Array.isArray(n.data)?n.data[0]:n.data},rse=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:tse({instanceName:t}),queryFn:()=>nse({instanceName:t,token:n}),enabled:!!t&&(e.enabled??!0)})},sse=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/typebot/create/${e}`,n,{headers:{apikey:t}})).data,ose=async({instanceName:e,token:t,typebotId:n,data:r})=>(await Ee.put(`/typebot/update/${n}/${e}`,r,{headers:{apikey:t}})).data,ase=async({instanceName:e,typebotId:t})=>(await Ee.delete(`/typebot/delete/${t}/${e}`)).data,ise=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/typebot/settings/${e}`,n,{headers:{apikey:t}})).data,lse=async({instanceName:e,token:t,remoteJid:n,status:r})=>(await Ee.post(`/typebot/changeStatus/${e}`,{remoteJid:n,status:r},{headers:{apikey:t}})).data;function Eg(){const e=nt(ise,{invalidateKeys:[[\"typebot\",\"fetchDefaultSettings\"]]}),t=nt(lse,{invalidateKeys:[[\"typebot\",\"getTypebot\"],[\"typebot\",\"fetchSessions\"]]}),n=nt(ase,{invalidateKeys:[[\"typebot\",\"getTypebot\"],[\"typebot\",\"findTypebot\"],[\"typebot\",\"fetchSessions\"]]}),r=nt(ose,{invalidateKeys:[[\"typebot\",\"getTypebot\"],[\"typebot\",\"findTypebot\"],[\"typebot\",\"fetchSessions\"]]}),s=nt(sse,{invalidateKeys:[[\"typebot\",\"findTypebot\"]]});return{setDefaultSettingsTypebot:e,changeStatusTypebot:t,deleteTypebot:n,updateTypebot:r,createTypebot:s}}const cse=P.object({expire:P.coerce.number(),keywordFinish:P.string(),delayMessage:P.coerce.number(),unknownMessage:P.string(),listeningFromMe:P.boolean(),stopBotFromMe:P.boolean(),keepOpen:P.boolean(),debounceTime:P.coerce.number()});function use(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{setDefaultSettingsTypebot:s}=Eg(),{data:o,refetch:l}=rse({instanceName:t?.name,token:t?.token,enabled:n}),{data:u,refetch:d}=zI({instanceName:t?.name,token:t?.token,enabled:n}),f=on({resolver:an(cse),defaultValues:{expire:0,keywordFinish:e(\"typebot.form.examples.keywordFinish\"),delayMessage:1e3,unknownMessage:e(\"typebot.form.examples.unknownMessage\"),listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0}});y.useEffect(()=>{o&&f.reset({expire:o?.expire??0,keywordFinish:o.keywordFinish,delayMessage:o.delayMessage??0,unknownMessage:o.unknownMessage,listeningFromMe:o.listeningFromMe,stopBotFromMe:o.stopBotFromMe,keepOpen:o.keepOpen,debounceTime:o.debounceTime??0})},[o]);const h=async g=>{try{if(!t||!t.name)throw new Error(\"instance not found.\");const x={expire:g.expire,keywordFinish:g.keywordFinish,delayMessage:g.delayMessage,unknownMessage:g.unknownMessage,listeningFromMe:g.listeningFromMe,stopBotFromMe:g.stopBotFromMe,keepOpen:g.keepOpen,debounceTime:g.debounceTime};await s({instanceName:t.name,token:t.token,data:x}),me.success(e(\"typebot.toast.defaultSettings.success\"))}catch(x){console.error(e(\"typebot.toast.defaultSettings.error\"),x),me.error(`Error: ${x?.response?.data?.response?.message}`)}};function m(){l(),d()}return i.jsxs(Pt,{open:n,onOpenChange:r,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Oo,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:e(\"typebot.button.defaultSettings\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",onCloseAutoFocus:m,children:[i.jsx(Mt,{children:i.jsx(zt,{children:e(\"typebot.modal.defaultSettings.title\")})}),i.jsx(Gn,{...f,children:i.jsxs(\"form\",{className:\"w-full space-y-6\",onSubmit:f.handleSubmit(h),children:[i.jsx(\"div\",{children:i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Jt,{name:\"typebotIdFallback\",label:e(\"typebot.form.typebotIdFallback.label\"),options:u?.filter(g=>!!g.id).map(g=>({label:g.typebot,value:g.description}))??[]}),i.jsx(le,{name:\"expire\",label:e(\"typebot.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:e(\"typebot.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:e(\"typebot.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:e(\"typebot.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:e(\"typebot.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:e(\"typebot.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:e(\"typebot.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:e(\"typebot.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(Da,{name:\"ignoreJids\",label:e(\"typebot.form.ignoreJids.label\"),placeholder:e(\"typebot.form.ignoreJids.placeholder\")})]})}),i.jsx(Yt,{children:i.jsx(se,{type:\"submit\",children:e(\"typebot.button.save\")})})]})})]})]})}const dse=e=>[\"typebot\",\"fetchSessions\",JSON.stringify(e)],fse=async({instanceName:e,typebotId:t,token:n})=>(await Ee.get(`/typebot/fetchSessions/${t}/${e}`,{headers:{apiKey:n}})).data,pse=e=>{const{instanceName:t,token:n,typebotId:r,...s}=e;return mt({...s,queryKey:dse({instanceName:t}),queryFn:()=>fse({instanceName:t,token:n,typebotId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function UI({typebotId:e}){const{t}=Ve(),{instance:n}=ct(),[r,s]=y.useState([]),[o,l]=y.useState(!1),[u,d]=y.useState(\"\"),{changeStatusTypebot:f}=Eg(),{data:h,refetch:m}=pse({instanceName:n?.name,token:n?.token,typebotId:e});function g(){m()}const x=async(w,C)=>{try{if(!n)return;await f({instanceName:n.name,token:n.token,remoteJid:w,status:C}),me.success(t(\"typebot.toast.success.status\")),g()}catch(k){console.error(\"Error:\",k),me.error(`Error : ${k?.response?.data?.response?.message}`)}},b=[{accessorKey:\"remoteJid\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"typebot.sessions.table.remoteJid\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"remoteJid\")})},{accessorKey:\"pushName\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"typebot.sessions.table.pushName\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"pushName\")})},{accessorKey:\"sessionId\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"typebot.sessions.table.sessionId\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"sessionId\")})},{accessorKey:\"status\",header:()=>i.jsx(\"div\",{className:\"text-center\",children:t(\"typebot.sessions.table.status\")}),cell:({row:w})=>i.jsx(\"div\",{children:w.getValue(\"status\")})},{id:\"actions\",enableHiding:!1,cell:({row:w})=>{const C=w.original;return i.jsxs(Kr,{children:[i.jsx(Wr,{asChild:!0,children:i.jsxs(se,{variant:\"ghost\",className:\"h-8 w-8 p-0\",children:[i.jsx(\"span\",{className:\"sr-only\",children:t(\"typebot.sessions.table.actions.title\")}),i.jsx(Pa,{className:\"h-4 w-4\"})]})}),i.jsxs(hr,{align:\"end\",children:[i.jsx(Ao,{children:\"Actions\"}),i.jsx(Xs,{}),C.status!==\"opened\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"opened\"),children:[i.jsx(Fi,{className:\"mr-2 h-4 w-4\"}),t(\"typebot.sessions.table.actions.open\")]}),C.status!==\"paused\"&&C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"paused\"),children:[i.jsx(Di,{className:\"mr-2 h-4 w-4\"}),t(\"typebot.sessions.table.actions.pause\")]}),C.status!==\"closed\"&&i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"closed\"),children:[i.jsx(Oi,{className:\"mr-2 h-4 w-4\"}),t(\"typebot.sessions.table.actions.close\")]}),i.jsxs(wt,{onClick:()=>x(C.remoteJid,\"delete\"),children:[i.jsx(Ii,{className:\"mr-2 h-4 w-4\"}),t(\"typebot.sessions.table.actions.delete\")]})]})]})}}];return i.jsxs(Pt,{open:o,onOpenChange:l,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{variant:\"secondary\",size:\"sm\",children:[i.jsx(Ai,{size:16,className:\"mr-1\"}),\" \",i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"typebot.sessions.label\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-w-[950px]\",onCloseAutoFocus:g,children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"typebot.sessions.label\")})}),i.jsxs(\"div\",{children:[i.jsxs(\"div\",{className:\"flex items-center justify-between gap-6 p-5\",children:[i.jsx(ne,{placeholder:t(\"typebot.sessions.search\"),value:u,onChange:w=>d(w.target.value)}),i.jsx(se,{variant:\"outline\",onClick:g,size:\"icon\",children:i.jsx(Li,{size:16})})]}),i.jsx($a,{columns:b,data:h??[],onSortingChange:s,state:{sorting:r,globalFilter:u},onGlobalFilterChange:d,enableGlobalFilter:!0,noResultsMessage:t(\"typebot.sessions.table.none\")})]})]})]})}const hse=P.object({enabled:P.boolean(),description:P.string(),url:P.string(),typebot:P.string().optional(),triggerType:P.string(),triggerOperator:P.string().optional(),triggerValue:P.string().optional(),expire:P.coerce.number().optional(),keywordFinish:P.string().optional(),delayMessage:P.coerce.number().optional(),unknownMessage:P.string().optional(),listeningFromMe:P.boolean().optional(),stopBotFromMe:P.boolean().optional(),keepOpen:P.boolean().optional(),debounceTime:P.coerce.number().optional()});function VI({initialData:e,onSubmit:t,handleDelete:n,typebotId:r,isModal:s=!1,isLoading:o=!1,openDeletionDialog:l=!1,setOpenDeletionDialog:u=()=>{}}){const{t:d}=Ve(),f=on({resolver:an(hse),defaultValues:e||{enabled:!0,description:\"\",url:\"\",typebot:\"\",triggerType:\"keyword\",triggerOperator:\"contains\",triggerValue:\"\",expire:0,keywordFinish:\"\",delayMessage:0,unknownMessage:\"\",listeningFromMe:!1,stopBotFromMe:!1,keepOpen:!1,debounceTime:0}}),h=f.watch(\"triggerType\");return i.jsx(Gn,{...f,children:i.jsxs(\"form\",{onSubmit:f.handleSubmit(t),className:\"w-full space-y-6\",children:[i.jsxs(\"div\",{className:\"space-y-4\",children:[i.jsx(Pe,{name:\"enabled\",label:d(\"typebot.form.enabled.label\"),reverse:!0}),i.jsx(le,{name:\"description\",label:d(\"typebot.form.description.label\"),required:!0,children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"typebot.form.typebotSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"url\",label:d(\"typebot.form.url.label\"),required:!0,children:i.jsx(ne,{})}),i.jsx(le,{name:\"typebot\",label:d(\"typebot.form.typebot.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"typebot.form.triggerSettings.label\")}),i.jsx($t,{})]}),i.jsx(Jt,{name:\"triggerType\",label:d(\"typebot.form.triggerType.label\"),options:[{label:d(\"typebot.form.triggerType.keyword\"),value:\"keyword\"},{label:d(\"typebot.form.triggerType.all\"),value:\"all\"},{label:d(\"typebot.form.triggerType.advanced\"),value:\"advanced\"},{label:d(\"typebot.form.triggerType.none\"),value:\"none\"}]}),h===\"keyword\"&&i.jsxs(i.Fragment,{children:[i.jsx(Jt,{name:\"triggerOperator\",label:d(\"typebot.form.triggerOperator.label\"),options:[{label:d(\"typebot.form.triggerOperator.contains\"),value:\"contains\"},{label:d(\"typebot.form.triggerOperator.equals\"),value:\"equals\"},{label:d(\"typebot.form.triggerOperator.startsWith\"),value:\"startsWith\"},{label:d(\"typebot.form.triggerOperator.endsWith\"),value:\"endsWith\"},{label:d(\"typebot.form.triggerOperator.regex\"),value:\"regex\"}]}),i.jsx(le,{name:\"triggerValue\",label:d(\"typebot.form.triggerValue.label\"),children:i.jsx(ne,{})})]}),h===\"advanced\"&&i.jsx(le,{name:\"triggerValue\",label:d(\"typebot.form.triggerConditions.label\"),children:i.jsx(ne,{})}),i.jsxs(\"div\",{className:\"flex flex-col\",children:[i.jsx(\"h3\",{className:\"my-4 text-lg font-medium\",children:d(\"typebot.form.generalSettings.label\")}),i.jsx($t,{})]}),i.jsx(le,{name:\"expire\",label:d(\"typebot.form.expire.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"keywordFinish\",label:d(\"typebot.form.keywordFinish.label\"),children:i.jsx(ne,{})}),i.jsx(le,{name:\"delayMessage\",label:d(\"typebot.form.delayMessage.label\"),children:i.jsx(ne,{type:\"number\"})}),i.jsx(le,{name:\"unknownMessage\",label:d(\"typebot.form.unknownMessage.label\"),children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"listeningFromMe\",label:d(\"typebot.form.listeningFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"stopBotFromMe\",label:d(\"typebot.form.stopBotFromMe.label\"),reverse:!0}),i.jsx(Pe,{name:\"keepOpen\",label:d(\"typebot.form.keepOpen.label\"),reverse:!0}),i.jsx(le,{name:\"debounceTime\",label:d(\"typebot.form.debounceTime.label\"),children:i.jsx(ne,{type:\"number\"})})]}),s&&i.jsx(Yt,{children:i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"typebot.button.saving\":\"typebot.button.save\")})}),!s&&i.jsxs(\"div\",{children:[i.jsx(UI,{typebotId:r}),i.jsxs(\"div\",{className:\"mt-5 flex items-center gap-3\",children:[i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsx(se,{variant:\"destructive\",size:\"sm\",children:d(\"dify.button.delete\")})}),i.jsx(Nt,{children:i.jsxs(Mt,{children:[i.jsx(zt,{children:d(\"modal.delete.title\")}),i.jsx(eo,{children:d(\"modal.delete.messageSingle\")}),i.jsxs(Yt,{children:[i.jsx(se,{size:\"sm\",variant:\"outline\",onClick:()=>u(!1),children:d(\"button.cancel\")}),i.jsx(se,{variant:\"destructive\",onClick:n,children:d(\"button.delete\")})]})]})})]}),i.jsx(se,{disabled:o,type:\"submit\",children:d(o?\"typebot.button.saving\":\"typebot.button.update\")})]})]})]})})}function gse({resetTable:e}){const{t}=Ve(),{instance:n}=ct(),{createTypebot:r}=Eg(),[s,o]=y.useState(!1),[l,u]=y.useState(!1),d=async f=>{try{if(!n||!n.name)throw new Error(\"instance not found\");o(!0);const h={enabled:f.enabled,description:f.description,url:f.url,typebot:f.typebot||\"\",triggerType:f.triggerType,triggerOperator:f.triggerOperator||\"\",triggerValue:f.triggerValue||\"\",expire:f.expire||0,keywordFinish:f.keywordFinish||\"\",delayMessage:f.delayMessage||0,unknownMessage:f.unknownMessage||\"\",listeningFromMe:f.listeningFromMe||!1,stopBotFromMe:f.stopBotFromMe||!1,keepOpen:f.keepOpen||!1,debounceTime:f.debounceTime||0};await r({instanceName:n.name,token:n.token,data:h}),me.success(t(\"typebot.toast.success.create\")),u(!1),e()}catch(h){console.error(\"Error:\",h),me.error(`Error: ${h?.response?.data?.response?.message}`)}finally{o(!1)}};return i.jsxs(Pt,{open:l,onOpenChange:u,children:[i.jsx(Bt,{asChild:!0,children:i.jsxs(se,{size:\"sm\",children:[i.jsx(cs,{size:16,className:\"mr-1\"}),i.jsx(\"span\",{className:\"hidden sm:inline\",children:t(\"typebot.button.create\")})]})}),i.jsxs(Nt,{className:\"overflow-y-auto sm:max-h-[600px] sm:max-w-[740px]\",children:[i.jsx(Mt,{children:i.jsx(zt,{children:t(\"typebot.form.title\")})}),i.jsx(VI,{onSubmit:d,isModal:!0,isLoading:s})]})]})}const mse=e=>[\"typebot\",\"getTypebot\",JSON.stringify(e)],vse=async({instanceName:e,token:t,typebotId:n})=>{const r=await Ee.get(`/typebot/fetch/${n}/${e}`,{headers:{apiKey:t}});return Array.isArray(r.data)?r.data[0]:r.data},yse=e=>{const{instanceName:t,token:n,typebotId:r,...s}=e;return mt({...s,queryKey:mse({instanceName:t}),queryFn:()=>vse({instanceName:t,token:n,typebotId:r}),enabled:!!t&&!!r&&(e.enabled??!0)})};function bse({typebotId:e,resetTable:t}){const{t:n}=Ve(),{instance:r}=ct(),s=dn(),[o,l]=y.useState(!1),{deleteTypebot:u,updateTypebot:d}=Eg(),{data:f,isLoading:h}=yse({instanceName:r?.name,typebotId:e}),m=y.useMemo(()=>({enabled:!!f?.enabled,description:f?.description??\"\",url:f?.url??\"\",typebot:f?.typebot??\"\",triggerType:f?.triggerType??\"\",triggerOperator:f?.triggerOperator??\"\",triggerValue:f?.triggerValue,expire:f?.expire??0,keywordFinish:f?.keywordFinish,delayMessage:f?.delayMessage??0,unknownMessage:f?.unknownMessage,listeningFromMe:!!f?.listeningFromMe,stopBotFromMe:!!f?.stopBotFromMe,keepOpen:!!f?.keepOpen,debounceTime:f?.debounceTime??0}),[f?.debounceTime,f?.delayMessage,f?.description,f?.enabled,f?.expire,f?.keepOpen,f?.keywordFinish,f?.listeningFromMe,f?.stopBotFromMe,f?.triggerOperator,f?.triggerType,f?.triggerValue,f?.typebot,f?.unknownMessage,f?.url]),g=async b=>{try{if(r&&r.name&&e){const w={enabled:b.enabled,description:b.description,url:b.url,typebot:b.typebot||\"\",triggerType:b.triggerType,triggerOperator:b.triggerOperator||\"\",triggerValue:b.triggerValue||\"\",expire:b.expire||0,keywordFinish:b.keywordFinish||\"\",delayMessage:b.delayMessage||1e3,unknownMessage:b.unknownMessage||\"\",listeningFromMe:b.listeningFromMe||!1,stopBotFromMe:b.stopBotFromMe||!1,keepOpen:b.keepOpen||!1,debounceTime:b.debounceTime||0};await d({instanceName:r.name,typebotId:e,data:w}),me.success(n(\"typebot.toast.success.update\")),t(),s(`/manager/instance/${r.id}/typebot/${e}`)}else console.error(\"Token not found\")}catch(w){console.error(\"Error:\",w),me.error(`Error: ${w?.response?.data?.response?.message}`)}},x=async()=>{try{r&&r.name&&e?(await u({instanceName:r.name,typebotId:e}),me.success(n(\"typebot.toast.success.delete\")),l(!1),t(),s(`/manager/instance/${r.id}/typebot`)):console.error(\"instance not found\")}catch(b){console.error(\"Erro ao excluir dify:\",b)}};return h?i.jsx(On,{}):i.jsx(\"div\",{className:\"m-4\",children:i.jsx(VI,{initialData:m,onSubmit:g,typebotId:e,handleDelete:x,isModal:!1,isLoading:h,openDeletionDialog:o,setOpenDeletionDialog:l})})}function Nk(){const{t:e}=Ve(),t=zo(\"(min-width: 768px)\"),{instance:n}=ct(),{typebotId:r}=ls(),{data:s,isLoading:o,refetch:l}=zI({instanceName:n?.name,token:n?.token}),u=dn(),d=h=>{n&&u(`/manager/instance/${n.id}/typebot/${h}`)},f=()=>{l()};return i.jsxs(\"main\",{className:\"pt-5\",children:[i.jsxs(\"div\",{className:\"mb-1 flex items-center justify-between\",children:[i.jsx(\"h3\",{className:\"text-lg font-medium\",children:e(\"typebot.title\")}),i.jsxs(\"div\",{className:\"flex flex-wrap items-center justify-end gap-2\",children:[i.jsx(UI,{}),i.jsx(use,{}),i.jsx(gse,{resetTable:f})]})]}),i.jsx($t,{className:\"my-4\"}),i.jsxs($o,{direction:t?\"horizontal\":\"vertical\",children:[i.jsx(Hn,{defaultSize:35,className:\"pr-4\",children:i.jsx(\"div\",{className:\"flex flex-col gap-3\",children:o?i.jsx(On,{}):i.jsx(i.Fragment,{children:s&&s.length>0&&Array.isArray(s)?s.map(h=>i.jsx(se,{className:\"flex h-auto flex-col items-start justify-start\",onClick:()=>d(`${h.id}`),variant:r===h.id?\"secondary\":\"outline\",children:h.description?i.jsxs(i.Fragment,{children:[i.jsx(\"h4\",{className:\"text-base\",children:h.description}),i.jsxs(\"p\",{className:\"text-wrap text-sm font-normal text-muted-foreground\",children:[h.url,\" - \",h.typebot]})]}):i.jsxs(i.Fragment,{children:[i.jsx(\"h4\",{className:\"text-base\",children:h.url}),i.jsx(\"p\",{className:\"text-wrap text-sm font-normal text-muted-foreground\",children:h.typebot})]})},h.id)):i.jsx(se,{variant:\"link\",children:e(\"typebot.table.none\")})})})}),r&&i.jsxs(i.Fragment,{children:[i.jsx(Bo,{withHandle:!0,className:\"border border-black\"}),i.jsx(Hn,{children:i.jsx(bse,{typebotId:r,resetTable:f})})]})]})]})}const xse=e=>[\"webhook\",\"fetchWebhook\",JSON.stringify(e)],wse=async({instanceName:e,token:t})=>(await Ee.get(`/webhook/find/${e}`,{headers:{apiKey:t}})).data,Sse=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:xse({instanceName:t,token:n}),queryFn:()=>wse({instanceName:t,token:n}),enabled:!!t})},Cse=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/webhook/set/${e}`,{webhook:n},{headers:{apikey:t}})).data;function Ese(){return{createWebhook:nt(Cse,{invalidateKeys:[[\"webhook\",\"fetchWebhook\"]]})}}const kse=P.object({enabled:P.boolean(),url:P.string().url(\"Invalid URL format\"),events:P.array(P.string()),base64:P.boolean(),byEvents:P.boolean()});function jse(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{createWebhook:s}=Ese(),{data:o}=Sse({instanceName:t?.name,token:t?.token}),l=on({resolver:an(kse),defaultValues:{enabled:!1,url:\"\",events:[],base64:!1,byEvents:!1}});y.useEffect(()=>{o&&l.reset({enabled:o.enabled,url:o.url,events:o.events,base64:o.webhookBase64,byEvents:o.webhookByEvents})},[o]);const u=async m=>{if(t){r(!0);try{const g={enabled:m.enabled,url:m.url,events:m.events,base64:m.base64,byEvents:m.byEvents};await s({instanceName:t.name,token:t.token,data:g}),me.success(e(\"webhook.toast.success\"))}catch(g){console.error(e(\"webhook.toast.error\"),g),me.error(`Error: ${g?.response?.data?.response?.message}`)}finally{r(!1)}}},d=[\"APPLICATION_STARTUP\",\"QRCODE_UPDATED\",\"MESSAGES_SET\",\"MESSAGES_UPSERT\",\"MESSAGES_UPDATE\",\"MESSAGES_DELETE\",\"SEND_MESSAGE\",\"CONTACTS_SET\",\"CONTACTS_UPSERT\",\"CONTACTS_UPDATE\",\"PRESENCE_UPDATE\",\"CHATS_SET\",\"CHATS_UPSERT\",\"CHATS_UPDATE\",\"CHATS_DELETE\",\"GROUPS_UPSERT\",\"GROUP_UPDATE\",\"GROUP_PARTICIPANTS_UPDATE\",\"CONNECTION_UPDATE\",\"REMOVE_INSTANCE\",\"LOGOUT_INSTANCE\",\"LABELS_EDIT\",\"LABELS_ASSOCIATION\",\"CALL\",\"TYPEBOT_START\",\"TYPEBOT_CHANGE_STATUS\"],f=()=>{l.setValue(\"events\",d)},h=()=>{l.setValue(\"events\",[])};return i.jsx(i.Fragment,{children:i.jsx(Fo,{...l,children:i.jsx(\"form\",{onSubmit:l.handleSubmit(u),className:\"w-full space-y-6\",children:i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"webhook.title\")}),i.jsx(Oa,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y [&>*]:p-4\",children:[i.jsx(Pe,{name:\"enabled\",label:e(\"webhook.form.enabled.label\"),className:\"w-full justify-between\",helper:e(\"webhook.form.enabled.description\")}),i.jsx(le,{name:\"url\",label:\"URL\",children:i.jsx(ne,{})}),i.jsx(Pe,{name:\"byEvents\",label:e(\"webhook.form.byEvents.label\"),className:\"w-full justify-between\",helper:e(\"webhook.form.byEvents.description\")}),i.jsx(Pe,{name:\"base64\",label:e(\"webhook.form.base64.label\"),className:\"w-full justify-between\",helper:e(\"webhook.form.base64.description\")}),i.jsxs(\"div\",{className:\"mb-4 flex justify-between\",children:[i.jsx(se,{variant:\"outline\",type:\"button\",onClick:f,children:e(\"button.markAll\")}),i.jsx(se,{variant:\"outline\",type:\"button\",onClick:h,children:e(\"button.unMarkAll\")})]}),i.jsx(Lo,{control:l.control,name:\"events\",render:({field:m})=>i.jsxs(no,{className:\"flex flex-col\",children:[i.jsx(Nr,{className:\"my-2 text-lg\",children:e(\"webhook.form.events.label\")}),i.jsx(_s,{children:i.jsx(\"div\",{className:\"flex flex-col gap-2 space-y-1 divide-y\",children:d.sort((g,x)=>g.localeCompare(x)).map(g=>i.jsxs(\"div\",{className:\"flex items-center justify-between gap-3 pt-3\",children:[i.jsx(Nr,{className:Ie(\"break-all\",m.value.includes(g)?\"text-foreground\":\"text-muted-foreground\"),children:g}),i.jsx(gc,{checked:m.value.includes(g),onCheckedChange:x=>{x?m.onChange([...m.value,g]):m.onChange(m.value.filter(b=>b!==g))}})]},g))})})]})})]}),i.jsx(\"div\",{className:\"mx-4 flex justify-end pt-6\",children:i.jsx(se,{type:\"submit\",disabled:n,children:e(n?\"webhook.button.saving\":\"webhook.button.save\")})})]})})})})}const Tse=e=>[\"websocket\",\"fetchWebsocket\",JSON.stringify(e)],Nse=async({instanceName:e,token:t})=>(await Ee.get(`/websocket/find/${e}`,{headers:{apiKey:t}})).data,Mse=e=>{const{instanceName:t,token:n,...r}=e;return mt({...r,queryKey:Tse({instanceName:t,token:n}),queryFn:()=>Nse({instanceName:t,token:n}),enabled:!!t})},_se=async({instanceName:e,token:t,data:n})=>(await Ee.post(`/websocket/set/${e}`,{websocket:n},{headers:{apikey:t}})).data;function Rse(){return{createWebsocket:nt(_se,{invalidateKeys:[[\"websocket\",\"fetchWebsocket\"]]})}}const Pse=P.object({enabled:P.boolean(),events:P.array(P.string())});function Ose(){const{t:e}=Ve(),{instance:t}=ct(),[n,r]=y.useState(!1),{createWebsocket:s}=Rse(),{data:o}=Mse({instanceName:t?.name,token:t?.token}),l=on({resolver:an(Pse),defaultValues:{enabled:!1,events:[]}});y.useEffect(()=>{o&&l.reset({enabled:o.enabled,events:o.events})},[o]);const u=async m=>{if(t){r(!0);try{const g={enabled:m.enabled,events:m.events};await s({instanceName:t.name,token:t.token,data:g}),me.success(e(\"websocket.toast.success\"))}catch(g){console.error(e(\"websocket.toast.error\"),g),me.error(`Error: ${g?.response?.data?.response?.message}`)}finally{r(!1)}}},d=[\"APPLICATION_STARTUP\",\"QRCODE_UPDATED\",\"MESSAGES_SET\",\"MESSAGES_UPSERT\",\"MESSAGES_UPDATE\",\"MESSAGES_DELETE\",\"SEND_MESSAGE\",\"CONTACTS_SET\",\"CONTACTS_UPSERT\",\"CONTACTS_UPDATE\",\"PRESENCE_UPDATE\",\"CHATS_SET\",\"CHATS_UPSERT\",\"CHATS_UPDATE\",\"CHATS_DELETE\",\"GROUPS_UPSERT\",\"GROUP_UPDATE\",\"GROUP_PARTICIPANTS_UPDATE\",\"CONNECTION_UPDATE\",\"REMOVE_INSTANCE\",\"LOGOUT_INSTANCE\",\"LABELS_EDIT\",\"LABELS_ASSOCIATION\",\"CALL\",\"TYPEBOT_START\",\"TYPEBOT_CHANGE_STATUS\"],f=()=>{l.setValue(\"events\",d)},h=()=>{l.setValue(\"events\",[])};return i.jsx(i.Fragment,{children:i.jsx(Fo,{...l,children:i.jsx(\"form\",{onSubmit:l.handleSubmit(u),className:\"w-full space-y-6\",children:i.jsxs(\"div\",{children:[i.jsx(\"h3\",{className:\"mb-1 text-lg font-medium\",children:e(\"websocket.title\")}),i.jsx(Oa,{className:\"my-4\"}),i.jsxs(\"div\",{className:\"mx-4 space-y-2 divide-y [&>*]:p-4\",children:[i.jsx(Pe,{name:\"enabled\",label:e(\"websocket.form.enabled.label\"),className:\"w-full justify-between\",helper:e(\"websocket.form.enabled.description\")}),i.jsxs(\"div\",{className:\"mb-4 flex justify-between\",children:[i.jsx(se,{variant:\"outline\",type:\"button\",onClick:f,children:e(\"button.markAll\")}),i.jsx(se,{variant:\"outline\",type:\"button\",onClick:h,children:e(\"button.unMarkAll\")})]}),i.jsx(Lo,{control:l.control,name:\"events\",render:({field:m})=>i.jsxs(no,{className:\"flex flex-col\",children:[i.jsx(Nr,{className:\"my-2 text-lg\",children:e(\"websocket.form.events.label\")}),i.jsx(_s,{children:i.jsx(\"div\",{className:\"flex flex-col gap-2 space-y-1 divide-y\",children:d.sort((g,x)=>g.localeCompare(x)).map(g=>i.jsxs(\"div\",{className:\"flex items-center justify-between gap-3 pt-3\",children:[i.jsx(Nr,{className:Ie(\"break-all\",m.value.includes(g)?\"text-foreground\":\"text-muted-foreground\"),children:g}),i.jsx(gc,{checked:m.value.includes(g),onCheckedChange:x=>{x?m.onChange([...m.value,g]):m.onChange(m.value.filter(b=>b!==g))}})]},g))})})]})})]}),i.jsx(\"div\",{className:\"mx-4 flex justify-end pt-6\",children:i.jsx(se,{type:\"submit\",disabled:n,children:e(n?\"websocket.button.saving\":\"websocket.button.save\")})})]})})})})}const Ise=async({url:e,token:t})=>{try{const{data:n}=await sn.post(`${e}/verify-creds`,{},{headers:{apikey:t}});return Rj({facebookAppId:n.facebookAppId,facebookConfigId:n.facebookConfigId,facebookUserToken:n.facebookUserToken}),n}catch{return null}},Ase=P.object({serverUrl:P.string({required_error:\"serverUrl is required\"}).url(\"URL inválida\"),apiKey:P.string({required_error:\"ApiKey is required\"})});function Dse(){const{t:e}=Ve(),t=dn(),{theme:n}=tc(),r=on({resolver:an(Ase),defaultValues:{serverUrl:window.location.protocol+\"//\"+window.location.host,apiKey:\"\"}}),s=async o=>{const l=await sT({url:o.serverUrl});if(!l||!l.version){Pj(),r.setError(\"serverUrl\",{type:\"manual\",message:e(\"login.message.invalidServer\")});return}if(!await Ise({token:o.apiKey,url:o.serverUrl})){r.setError(\"apiKey\",{type:\"manual\",message:e(\"login.message.invalidCredentials\")});return}Rj({version:l.version,clientName:l.clientName,url:o.serverUrl,token:o.apiKey}),t(\"/manager/\")};return i.jsxs(\"div\",{className:\"flex min-h-screen flex-col\",children:[i.jsx(\"div\",{className:\"flex items-center justify-center pt-2\",children:i.jsx(\"img\",{className:\"h-10\",src:n===\"dark\"?\"https://evolution-api.com/files/evo/evolution-logo-white.svg\":\"https://evolution-api.com/files/evo/evolution-logo.svg\",alt:\"logo\"})}),i.jsx(\"div\",{className:\"flex flex-1 items-center justify-center p-8\",children:i.jsxs(So,{className:\"b-none w-[350px] shadow-none\",children:[i.jsxs(Co,{children:[i.jsx(gi,{className:\"text-center\",children:e(\"login.title\")}),i.jsx(Kp,{className:\"text-center\",children:e(\"login.description\")})]}),i.jsx(Fo,{...r,children:i.jsxs(\"form\",{onSubmit:r.handleSubmit(s),children:[i.jsx(Eo,{children:i.jsxs(\"div\",{className:\"grid w-full items-center gap-4\",children:[i.jsx(le,{required:!0,name:\"serverUrl\",label:e(\"login.form.serverUrl\"),children:i.jsx(ne,{})}),i.jsx(le,{required:!0,name:\"apiKey\",label:e(\"login.form.apiKey\"),children:i.jsx(ne,{type:\"password\"})})]})}),i.jsx(Vh,{className:\"flex justify-center\",children:i.jsx(se,{className:\"w-full\",type:\"submit\",children:e(\"login.button.login\")})})]})})]})}),i.jsx(Vb,{})]})}function Fse(){const e=dn(),{theme:t}=tc(),n=()=>{e(\"/manager\")};return i.jsxs(\"div\",{className:\"min-h-screen bg-background\",children:[i.jsxs(\"header\",{className:\"flex items-center justify-between px-4 py-2\",children:[i.jsx(\"div\",{className:\"flex items-center\",children:i.jsx(\"img\",{src:t===\"dark\"?\"https://evolution-api.com/files/evo/evolution-logo-white.svg\":\"https://evolution-api.com/files/evo/evolution-logo.svg\",alt:\"Evolution API Logo\",className:\"h-8\"})}),i.jsxs(\"div\",{className:\"flex items-center gap-4\",children:[i.jsx(iM,{}),i.jsx(lM,{})]})]}),i.jsx(\"div\",{className:\"container mx-auto px-4 py-16\",children:i.jsxs(\"div\",{className:\"max-w-4xl mx-auto\",children:[i.jsxs(\"div\",{className:\"text-center mb-12\",children:[i.jsx(\"div\",{className:\"flex items-center justify-center mb-6\",children:i.jsx(\"img\",{src:t===\"dark\"?\"https://evolution-api.com/files/evo/evolution-logo-white.svg\":\"https://evolution-api.com/files/evo/evolution-logo.svg\",alt:\"Evolution Manager Logo\",className:\"h-10\"})}),i.jsx(\"h1\",{className:\"text-4xl font-bold text-foreground mb-4\",children:\"Evolution Manager v2\"}),i.jsx(\"p\",{className:\"text-xl text-muted-foreground mb-6\",children:\"Modern web interface for Evolution API management\"}),i.jsx(vu,{variant:\"secondary\",className:\"text-sm px-3 py-1\",children:\"Version 2.0.0\"})]}),i.jsxs(So,{className:\"mb-8\",children:[i.jsxs(Co,{children:[i.jsxs(gi,{className:\"flex items-center gap-2\",children:[i.jsx(xB,{className:\"w-5 h-5 text-primary\"}),\"Welcome to Evolution Manager\"]}),i.jsx(Kp,{children:\"A powerful, modern dashboard for managing your WhatsApp API instances with Evolution API\"})]}),i.jsx(Eo,{className:\"space-y-6\",children:i.jsx(\"div\",{className:\"pt-6 border-t border-border\",children:i.jsx(\"div\",{className:\"flex flex-col sm:flex-row gap-4 justify-center items-center\",children:i.jsxs(se,{onClick:n,size:\"lg\",className:\"px-8 py-3\",children:[\"Access Manager Dashboard\",i.jsx(Th,{className:\"w-4 h-4 ml-2\"})]})})})})]}),i.jsxs(So,{children:[i.jsxs(Co,{children:[i.jsx(gi,{children:\"Resources & Support\"}),i.jsx(Kp,{children:\"Get help, contribute, or learn more about Evolution API\"})]}),i.jsx(Eo,{children:i.jsxs(\"div\",{className:\"grid md:grid-cols-3 gap-4\",children:[i.jsxs(\"a\",{href:\"https://github.com/EvolutionAPI/evolution-manager-v2\",target:\"_blank\",rel:\"noopener noreferrer\",className:\"flex items-center gap-3 p-4 rounded-lg border border-border hover:bg-accent transition-colors\",children:[i.jsx(aB,{className:\"w-5 h-5 text-muted-foreground\"}),i.jsxs(\"div\",{children:[i.jsx(\"div\",{className:\"font-medium text-foreground\",children:\"GitHub\"}),i.jsx(\"div\",{className:\"text-sm text-muted-foreground\",children:\"Source code\"})]})]}),i.jsxs(\"a\",{href:\"https://evolution-api.com\",target:\"_blank\",rel:\"noopener noreferrer\",className:\"flex items-center gap-3 p-4 rounded-lg border border-border hover:bg-accent transition-colors\",children:[i.jsx(iB,{className:\"w-5 h-5 text-muted-foreground\"}),i.jsxs(\"div\",{children:[i.jsx(\"div\",{className:\"font-medium text-foreground\",children:\"Website\"}),i.jsx(\"div\",{className:\"text-sm text-muted-foreground\",children:\"Official site\"})]})]}),i.jsxs(\"a\",{href:\"mailto:contato@evolution-api.com\",className:\"flex items-center gap-3 p-4 rounded-lg border border-border hover:bg-accent transition-colors\",children:[i.jsx(vB,{className:\"w-5 h-5 text-muted-foreground\"}),i.jsxs(\"div\",{children:[i.jsx(\"div\",{className:\"font-medium text-foreground\",children:\"Contact\"}),i.jsx(\"div\",{className:\"text-sm text-muted-foreground\",children:\"Get support\"})]})]})]})})]}),i.jsx(\"div\",{className:\"text-center mt-12 text-sm text-muted-foreground\",children:i.jsx(\"p\",{children:\"© 2025 Evolution API. Licensed under Apache 2.0 with Evolution API custom conditions.\"})})]})})]})}const Lse=Z2([{path:\"/\",element:i.jsx(Fse,{})},{path:\"/manager/login\",element:i.jsx(jL,{children:i.jsx(Dse,{})})},{path:\"/manager/\",element:i.jsx(tn,{children:i.jsx(B5,{children:i.jsx(CZ,{})})})},{path:\"/manager/instance/:instanceId/dashboard\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(PX,{})})})},{path:\"/manager/instance/:instanceId/chat\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(tk,{})})})},{path:\"/manager/instance/:instanceId/chat/:remoteJid\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(tk,{})})})},{path:\"/manager/instance/:instanceId/settings\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(qre,{})})})},{path:\"/manager/instance/:instanceId/openai\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Tk,{})})})},{path:\"/manager/instance/:instanceId/openai/:botId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Tk,{})})})},{path:\"/manager/instance/:instanceId/webhook\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(jse,{})})})},{path:\"/manager/instance/:instanceId/websocket\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Ose,{})})})},{path:\"/manager/instance/:instanceId/rabbitmq\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Bre,{})})})},{path:\"/manager/instance/:instanceId/sqs\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Yre,{})})})},{path:\"/manager/instance/:instanceId/chatwoot\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(yX,{})})})},{path:\"/manager/instance/:instanceId/typebot\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Nk,{})})})},{path:\"/manager/instance/:instanceId/typebot/:typebotId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Nk,{})})})},{path:\"/manager/instance/:instanceId/dify\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(xk,{})})})},{path:\"/manager/instance/:instanceId/dify/:difyId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(xk,{})})})},{path:\"/manager/instance/:instanceId/n8n\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(jk,{})})})},{path:\"/manager/instance/:instanceId/n8n/:n8nId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(jk,{})})})},{path:\"/manager/instance/:instanceId/evoai\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Ck,{})})})},{path:\"/manager/instance/:instanceId/evoai/:evoaiId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Ck,{})})})},{path:\"/manager/instance/:instanceId/evolutionBot\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Ek,{})})})},{path:\"/manager/instance/:instanceId/evolutionBot/:evolutionBotId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Ek,{})})})},{path:\"/manager/instance/:instanceId/flowise\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(kk,{})})})},{path:\"/manager/instance/:instanceId/flowise/:flowiseId\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(kk,{})})})},{path:\"/manager/instance/:instanceId/proxy\",element:i.jsx(tn,{children:i.jsx(un,{children:i.jsx(Ore,{})})})},{path:\"/manager/embed-chat\",element:i.jsx(Sk,{})},{path:\"/manager/embed-chat/:remoteJid\",element:i.jsx(Sk,{})}]),$se={type:\"logger\",log(e){this.output(\"log\",e)},warn(e){this.output(\"warn\",e)},error(e){this.output(\"error\",e)},output(e,t){console&&console[e]&&console[e].apply(console,t)}};class uh{constructor(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.init(t,n)}init(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.prefix=n.prefix||\"i18next:\",this.logger=t||$se,this.options=n,this.debug=n.debug}log(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return this.forward(n,\"log\",\"\",!0)}warn(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return this.forward(n,\"warn\",\"\",!0)}error(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return this.forward(n,\"error\",\"\")}deprecate(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return this.forward(n,\"warn\",\"WARNING DEPRECATED: \",!0)}forward(t,n,r,s){return s&&!this.debug?null:(typeof t[0]==\"string\"&&(t[0]=`${r}${this.prefix} ${t[0]}`),this.logger[n](t))}create(t){return new uh(this.logger,{prefix:`${this.prefix}:${t}:`,...this.options})}clone(t){return t=t||this.options,t.prefix=t.prefix||this.prefix,new uh(this.logger,t)}}var Ks=new uh;class kg{constructor(){this.observers={}}on(t,n){return t.split(\" \").forEach(r=>{this.observers[r]||(this.observers[r]=new Map);const s=this.observers[r].get(n)||0;this.observers[r].set(n,s+1)}),this}off(t,n){if(this.observers[t]){if(!n){delete this.observers[t];return}this.observers[t].delete(n)}}emit(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),s=1;s<n;s++)r[s-1]=arguments[s];this.observers[t]&&Array.from(this.observers[t].entries()).forEach(l=>{let[u,d]=l;for(let f=0;f<d;f++)u(...r)}),this.observers[\"*\"]&&Array.from(this.observers[\"*\"].entries()).forEach(l=>{let[u,d]=l;for(let f=0;f<d;f++)u.apply(u,[t,...r])})}}const hu=()=>{let e,t;const n=new Promise((r,s)=>{e=r,t=s});return n.resolve=e,n.reject=t,n},Mk=e=>e==null?\"\":\"\"+e,Bse=(e,t,n)=>{e.forEach(r=>{t[r]&&(n[r]=t[r])})},zse=/###/g,_k=e=>e&&e.indexOf(\"###\")>-1?e.replace(zse,\".\"):e,Rk=e=>!e||typeof e==\"string\",Pu=(e,t,n)=>{const r=typeof t!=\"string\"?t:t.split(\".\");let s=0;for(;s<r.length-1;){if(Rk(e))return{};const o=_k(r[s]);!e[o]&&n&&(e[o]=new n),Object.prototype.hasOwnProperty.call(e,o)?e=e[o]:e={},++s}return Rk(e)?{}:{obj:e,k:_k(r[s])}},Pk=(e,t,n)=>{const{obj:r,k:s}=Pu(e,t,Object);if(r!==void 0||t.length===1){r[s]=n;return}let o=t[t.length-1],l=t.slice(0,t.length-1),u=Pu(e,l,Object);for(;u.obj===void 0&&l.length;)o=`${l[l.length-1]}.${o}`,l=l.slice(0,l.length-1),u=Pu(e,l,Object),u&&u.obj&&typeof u.obj[`${u.k}.${o}`]<\"u\"&&(u.obj=void 0);u.obj[`${u.k}.${o}`]=n},Use=(e,t,n,r)=>{const{obj:s,k:o}=Pu(e,t,Object);s[o]=s[o]||[],s[o].push(n)},dh=(e,t)=>{const{obj:n,k:r}=Pu(e,t);if(n)return n[r]},Vse=(e,t,n)=>{const r=dh(e,n);return r!==void 0?r:dh(t,n)},HI=(e,t,n)=>{for(const r in t)r!==\"__proto__\"&&r!==\"constructor\"&&(r in e?typeof e[r]==\"string\"||e[r]instanceof String||typeof t[r]==\"string\"||t[r]instanceof String?n&&(e[r]=t[r]):HI(e[r],t[r],n):e[r]=t[r]);return e},Sl=e=>e.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g,\"\\\\$&\");var Hse={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#39;\",\"/\":\"&#x2F;\"};const qse=e=>typeof e==\"string\"?e.replace(/[&<>\"'\\/]/g,t=>Hse[t]):e;class Kse{constructor(t){this.capacity=t,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(t){const n=this.regExpMap.get(t);if(n!==void 0)return n;const r=new RegExp(t);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(t,r),this.regExpQueue.push(t),r}}const Wse=[\" \",\",\",\"?\",\"!\",\";\"],Gse=new Kse(20),Jse=(e,t,n)=>{t=t||\"\",n=n||\"\";const r=Wse.filter(l=>t.indexOf(l)<0&&n.indexOf(l)<0);if(r.length===0)return!0;const s=Gse.getRegExp(`(${r.map(l=>l===\"?\"?\"\\\\?\":l).join(\"|\")})`);let o=!s.test(e);if(!o){const l=e.indexOf(n);l>0&&!s.test(e.substring(0,l))&&(o=!0)}return o},Mb=function(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:\".\";if(!e)return;if(e[t])return e[t];const r=t.split(n);let s=e;for(let o=0;o<r.length;){if(!s||typeof s!=\"object\")return;let l,u=\"\";for(let d=o;d<r.length;++d)if(d!==o&&(u+=n),u+=r[d],l=s[u],l!==void 0){if([\"string\",\"number\",\"boolean\"].indexOf(typeof l)>-1&&d<r.length-1)continue;o+=d-o+1;break}s=l}return s},fh=e=>e&&e.indexOf(\"_\")>0?e.replace(\"_\",\"-\"):e;class Ok extends kg{constructor(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{ns:[\"translation\"],defaultNS:\"translation\"};super(),this.data=t||{},this.options=n,this.options.keySeparator===void 0&&(this.options.keySeparator=\".\"),this.options.ignoreJSONStructure===void 0&&(this.options.ignoreJSONStructure=!0)}addNamespaces(t){this.options.ns.indexOf(t)<0&&this.options.ns.push(t)}removeNamespaces(t){const n=this.options.ns.indexOf(t);n>-1&&this.options.ns.splice(n,1)}getResource(t,n,r){let s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};const o=s.keySeparator!==void 0?s.keySeparator:this.options.keySeparator,l=s.ignoreJSONStructure!==void 0?s.ignoreJSONStructure:this.options.ignoreJSONStructure;let u;t.indexOf(\".\")>-1?u=t.split(\".\"):(u=[t,n],r&&(Array.isArray(r)?u.push(...r):typeof r==\"string\"&&o?u.push(...r.split(o)):u.push(r)));const d=dh(this.data,u);return!d&&!n&&!r&&t.indexOf(\".\")>-1&&(t=u[0],n=u[1],r=u.slice(2).join(\".\")),d||!l||typeof r!=\"string\"?d:Mb(this.data&&this.data[t]&&this.data[t][n],r,o)}addResource(t,n,r,s){let o=arguments.length>4&&arguments[4]!==void 0?arguments[4]:{silent:!1};const l=o.keySeparator!==void 0?o.keySeparator:this.options.keySeparator;let u=[t,n];r&&(u=u.concat(l?r.split(l):r)),t.indexOf(\".\")>-1&&(u=t.split(\".\"),s=n,n=u[1]),this.addNamespaces(n),Pk(this.data,u,s),o.silent||this.emit(\"added\",t,n,r,s)}addResources(t,n,r){let s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{silent:!1};for(const o in r)(typeof r[o]==\"string\"||Array.isArray(r[o]))&&this.addResource(t,n,o,r[o],{silent:!0});s.silent||this.emit(\"added\",t,n,r)}addResourceBundle(t,n,r,s,o){let l=arguments.length>5&&arguments[5]!==void 0?arguments[5]:{silent:!1,skipCopy:!1},u=[t,n];t.indexOf(\".\")>-1&&(u=t.split(\".\"),s=r,r=n,n=u[1]),this.addNamespaces(n);let d=dh(this.data,u)||{};l.skipCopy||(r=JSON.parse(JSON.stringify(r))),s?HI(d,r,o):d={...d,...r},Pk(this.data,u,d),l.silent||this.emit(\"added\",t,n,r)}removeResourceBundle(t,n){this.hasResourceBundle(t,n)&&delete this.data[t][n],this.removeNamespaces(n),this.emit(\"removed\",t,n)}hasResourceBundle(t,n){return this.getResource(t,n)!==void 0}getResourceBundle(t,n){return n||(n=this.options.defaultNS),this.options.compatibilityAPI===\"v1\"?{...this.getResource(t,n)}:this.getResource(t,n)}getDataByLanguage(t){return this.data[t]}hasLanguageSomeTranslations(t){const n=this.getDataByLanguage(t);return!!(n&&Object.keys(n)||[]).find(s=>n[s]&&Object.keys(n[s]).length>0)}toJSON(){return this.data}}var qI={processors:{},addPostProcessor(e){this.processors[e.name]=e},handle(e,t,n,r,s){return e.forEach(o=>{this.processors[o]&&(t=this.processors[o].process(t,n,r,s))}),t}};const Ik={};class ph extends kg{constructor(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};super(),Bse([\"resourceStore\",\"languageUtils\",\"pluralResolver\",\"interpolator\",\"backendConnector\",\"i18nFormat\",\"utils\"],t,this),this.options=n,this.options.keySeparator===void 0&&(this.options.keySeparator=\".\"),this.logger=Ks.create(\"translator\")}changeLanguage(t){t&&(this.language=t)}exists(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{interpolation:{}};if(t==null)return!1;const r=this.resolve(t,n);return r&&r.res!==void 0}extractFromKey(t,n){let r=n.nsSeparator!==void 0?n.nsSeparator:this.options.nsSeparator;r===void 0&&(r=\":\");const s=n.keySeparator!==void 0?n.keySeparator:this.options.keySeparator;let o=n.ns||this.options.defaultNS||[];const l=r&&t.indexOf(r)>-1,u=!this.options.userDefinedKeySeparator&&!n.keySeparator&&!this.options.userDefinedNsSeparator&&!n.nsSeparator&&!Jse(t,r,s);if(l&&!u){const d=t.match(this.interpolator.nestingRegexp);if(d&&d.length>0)return{key:t,namespaces:o};const f=t.split(r);(r!==s||r===s&&this.options.ns.indexOf(f[0])>-1)&&(o=f.shift()),t=f.join(s)}return typeof o==\"string\"&&(o=[o]),{key:t,namespaces:o}}translate(t,n,r){if(typeof n!=\"object\"&&this.options.overloadTranslationOptionHandler&&(n=this.options.overloadTranslationOptionHandler(arguments)),typeof n==\"object\"&&(n={...n}),n||(n={}),t==null)return\"\";Array.isArray(t)||(t=[String(t)]);const s=n.returnDetails!==void 0?n.returnDetails:this.options.returnDetails,o=n.keySeparator!==void 0?n.keySeparator:this.options.keySeparator,{key:l,namespaces:u}=this.extractFromKey(t[t.length-1],n),d=u[u.length-1],f=n.lng||this.language,h=n.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(f&&f.toLowerCase()===\"cimode\"){if(h){const _=n.nsSeparator||this.options.nsSeparator;return s?{res:`${d}${_}${l}`,usedKey:l,exactUsedKey:l,usedLng:f,usedNS:d,usedParams:this.getUsedParamsDetails(n)}:`${d}${_}${l}`}return s?{res:l,usedKey:l,exactUsedKey:l,usedLng:f,usedNS:d,usedParams:this.getUsedParamsDetails(n)}:l}const m=this.resolve(t,n);let g=m&&m.res;const x=m&&m.usedKey||l,b=m&&m.exactUsedKey||l,w=Object.prototype.toString.apply(g),C=[\"[object Number]\",\"[object Function]\",\"[object RegExp]\"],k=n.joinArrays!==void 0?n.joinArrays:this.options.joinArrays,j=!this.i18nFormat||this.i18nFormat.handleAsObject;if(j&&g&&(typeof g!=\"string\"&&typeof g!=\"boolean\"&&typeof g!=\"number\")&&C.indexOf(w)<0&&!(typeof k==\"string\"&&Array.isArray(g))){if(!n.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn(\"accessing an object - but returnObjects options is not enabled!\");const _=this.options.returnedObjectHandler?this.options.returnedObjectHandler(x,g,{...n,ns:u}):`key '${l} (${this.language})' returned an object instead of string.`;return s?(m.res=_,m.usedParams=this.getUsedParamsDetails(n),m):_}if(o){const _=Array.isArray(g),R=_?[]:{},N=_?b:x;for(const O in g)if(Object.prototype.hasOwnProperty.call(g,O)){const D=`${N}${o}${O}`;R[O]=this.translate(D,{...n,joinArrays:!1,ns:u}),R[O]===D&&(R[O]=g[O])}g=R}}else if(j&&typeof k==\"string\"&&Array.isArray(g))g=g.join(k),g&&(g=this.extendTranslation(g,t,n,r));else{let _=!1,R=!1;const N=n.count!==void 0&&typeof n.count!=\"string\",O=ph.hasDefaultValue(n),D=N?this.pluralResolver.getSuffix(f,n.count,n):\"\",z=n.ordinal&&N?this.pluralResolver.getSuffix(f,n.count,{ordinal:!1}):\"\",Q=N&&!n.ordinal&&n.count===0&&this.pluralResolver.shouldUseIntlApi(),pe=Q&&n[`defaultValue${this.options.pluralSeparator}zero`]||n[`defaultValue${D}`]||n[`defaultValue${z}`]||n.defaultValue;!this.isValidLookup(g)&&O&&(_=!0,g=pe),this.isValidLookup(g)||(R=!0,g=l);const G=(n.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&R?void 0:g,W=O&&pe!==g&&this.options.updateMissing;if(R||_||W){if(this.logger.log(W?\"updateKey\":\"missingKey\",f,d,l,W?pe:g),o){const H=this.resolve(l,{...n,keySeparator:!1});H&&H.res&&this.logger.warn(\"Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.\")}let ie=[];const re=this.languageUtils.getFallbackCodes(this.options.fallbackLng,n.lng||this.language);if(this.options.saveMissingTo===\"fallback\"&&re&&re[0])for(let H=0;H<re.length;H++)ie.push(re[H]);else this.options.saveMissingTo===\"all\"?ie=this.languageUtils.toResolveHierarchy(n.lng||this.language):ie.push(n.lng||this.language);const Y=(H,q,he)=>{const A=O&&he!==g?he:G;this.options.missingKeyHandler?this.options.missingKeyHandler(H,d,q,A,W,n):this.backendConnector&&this.backendConnector.saveMissing&&this.backendConnector.saveMissing(H,d,q,A,W,n),this.emit(\"missingKey\",H,d,q,g)};this.options.saveMissing&&(this.options.saveMissingPlurals&&N?ie.forEach(H=>{const q=this.pluralResolver.getSuffixes(H,n);Q&&n[`defaultValue${this.options.pluralSeparator}zero`]&&q.indexOf(`${this.options.pluralSeparator}zero`)<0&&q.push(`${this.options.pluralSeparator}zero`),q.forEach(he=>{Y([H],l+he,n[`defaultValue${he}`]||pe)})}):Y(ie,l,pe))}g=this.extendTranslation(g,t,n,m,r),R&&g===l&&this.options.appendNamespaceToMissingKey&&(g=`${d}:${l}`),(R||_)&&this.options.parseMissingKeyHandler&&(this.options.compatibilityAPI!==\"v1\"?g=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${d}:${l}`:l,_?g:void 0):g=this.options.parseMissingKeyHandler(g))}return s?(m.res=g,m.usedParams=this.getUsedParamsDetails(n),m):g}extendTranslation(t,n,r,s,o){var l=this;if(this.i18nFormat&&this.i18nFormat.parse)t=this.i18nFormat.parse(t,{...this.options.interpolation.defaultVariables,...r},r.lng||this.language||s.usedLng,s.usedNS,s.usedKey,{resolved:s});else if(!r.skipInterpolation){r.interpolation&&this.interpolator.init({...r,interpolation:{...this.options.interpolation,...r.interpolation}});const f=typeof t==\"string\"&&(r&&r.interpolation&&r.interpolation.skipOnVariables!==void 0?r.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let h;if(f){const g=t.match(this.interpolator.nestingRegexp);h=g&&g.length}let m=r.replace&&typeof r.replace!=\"string\"?r.replace:r;if(this.options.interpolation.defaultVariables&&(m={...this.options.interpolation.defaultVariables,...m}),t=this.interpolator.interpolate(t,m,r.lng||this.language||s.usedLng,r),f){const g=t.match(this.interpolator.nestingRegexp),x=g&&g.length;h<x&&(r.nest=!1)}!r.lng&&this.options.compatibilityAPI!==\"v1\"&&s&&s.res&&(r.lng=this.language||s.usedLng),r.nest!==!1&&(t=this.interpolator.nest(t,function(){for(var g=arguments.length,x=new Array(g),b=0;b<g;b++)x[b]=arguments[b];return o&&o[0]===x[0]&&!r.context?(l.logger.warn(`It seems you are nesting recursively key: ${x[0]} in key: ${n[0]}`),null):l.translate(...x,n)},r)),r.interpolation&&this.interpolator.reset()}const u=r.postProcess||this.options.postProcess,d=typeof u==\"string\"?[u]:u;return t!=null&&d&&d.length&&r.applyPostProcessor!==!1&&(t=qI.handle(d,t,n,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...s,usedParams:this.getUsedParamsDetails(r)},...r}:r,this)),t}resolve(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r,s,o,l,u;return typeof t==\"string\"&&(t=[t]),t.forEach(d=>{if(this.isValidLookup(r))return;const f=this.extractFromKey(d,n),h=f.key;s=h;let m=f.namespaces;this.options.fallbackNS&&(m=m.concat(this.options.fallbackNS));const g=n.count!==void 0&&typeof n.count!=\"string\",x=g&&!n.ordinal&&n.count===0&&this.pluralResolver.shouldUseIntlApi(),b=n.context!==void 0&&(typeof n.context==\"string\"||typeof n.context==\"number\")&&n.context!==\"\",w=n.lngs?n.lngs:this.languageUtils.toResolveHierarchy(n.lng||this.language,n.fallbackLng);m.forEach(C=>{this.isValidLookup(r)||(u=C,!Ik[`${w[0]}-${C}`]&&this.utils&&this.utils.hasLoadedNamespace&&!this.utils.hasLoadedNamespace(u)&&(Ik[`${w[0]}-${C}`]=!0,this.logger.warn(`key \"${s}\" for languages \"${w.join(\", \")}\" won't get resolved as namespace \"${u}\" was not yet loaded`,\"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!\")),w.forEach(k=>{if(this.isValidLookup(r))return;l=k;const j=[h];if(this.i18nFormat&&this.i18nFormat.addLookupKeys)this.i18nFormat.addLookupKeys(j,h,k,C,n);else{let _;g&&(_=this.pluralResolver.getSuffix(k,n.count,n));const R=`${this.options.pluralSeparator}zero`,N=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(g&&(j.push(h+_),n.ordinal&&_.indexOf(N)===0&&j.push(h+_.replace(N,this.options.pluralSeparator)),x&&j.push(h+R)),b){const O=`${h}${this.options.contextSeparator}${n.context}`;j.push(O),g&&(j.push(O+_),n.ordinal&&_.indexOf(N)===0&&j.push(O+_.replace(N,this.options.pluralSeparator)),x&&j.push(O+R))}}let M;for(;M=j.pop();)this.isValidLookup(r)||(o=M,r=this.getResource(k,C,M,n))}))})}),{res:r,usedKey:s,exactUsedKey:o,usedLng:l,usedNS:u}}isValidLookup(t){return t!==void 0&&!(!this.options.returnNull&&t===null)&&!(!this.options.returnEmptyString&&t===\"\")}getResource(t,n,r){let s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};return this.i18nFormat&&this.i18nFormat.getResource?this.i18nFormat.getResource(t,n,r,s):this.resourceStore.getResource(t,n,r,s)}getUsedParamsDetails(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};const n=[\"defaultValue\",\"ordinal\",\"context\",\"replace\",\"lng\",\"lngs\",\"fallbackLng\",\"ns\",\"keySeparator\",\"nsSeparator\",\"returnObjects\",\"returnDetails\",\"joinArrays\",\"postProcess\",\"interpolation\"],r=t.replace&&typeof t.replace!=\"string\";let s=r?t.replace:t;if(r&&typeof t.count<\"u\"&&(s.count=t.count),this.options.interpolation.defaultVariables&&(s={...this.options.interpolation.defaultVariables,...s}),!r){s={...s};for(const o of n)delete s[o]}return s}static hasDefaultValue(t){const n=\"defaultValue\";for(const r in t)if(Object.prototype.hasOwnProperty.call(t,r)&&n===r.substring(0,n.length)&&t[r]!==void 0)return!0;return!1}}const xy=e=>e.charAt(0).toUpperCase()+e.slice(1);class Ak{constructor(t){this.options=t,this.supportedLngs=this.options.supportedLngs||!1,this.logger=Ks.create(\"languageUtils\")}getScriptPartFromCode(t){if(t=fh(t),!t||t.indexOf(\"-\")<0)return null;const n=t.split(\"-\");return n.length===2||(n.pop(),n[n.length-1].toLowerCase()===\"x\")?null:this.formatLanguageCode(n.join(\"-\"))}getLanguagePartFromCode(t){if(t=fh(t),!t||t.indexOf(\"-\")<0)return t;const n=t.split(\"-\");return this.formatLanguageCode(n[0])}formatLanguageCode(t){if(typeof t==\"string\"&&t.indexOf(\"-\")>-1){const n=[\"hans\",\"hant\",\"latn\",\"cyrl\",\"cans\",\"mong\",\"arab\"];let r=t.split(\"-\");return this.options.lowerCaseLng?r=r.map(s=>s.toLowerCase()):r.length===2?(r[0]=r[0].toLowerCase(),r[1]=r[1].toUpperCase(),n.indexOf(r[1].toLowerCase())>-1&&(r[1]=xy(r[1].toLowerCase()))):r.length===3&&(r[0]=r[0].toLowerCase(),r[1].length===2&&(r[1]=r[1].toUpperCase()),r[0]!==\"sgn\"&&r[2].length===2&&(r[2]=r[2].toUpperCase()),n.indexOf(r[1].toLowerCase())>-1&&(r[1]=xy(r[1].toLowerCase())),n.indexOf(r[2].toLowerCase())>-1&&(r[2]=xy(r[2].toLowerCase()))),r.join(\"-\")}return this.options.cleanCode||this.options.lowerCaseLng?t.toLowerCase():t}isSupportedCode(t){return(this.options.load===\"languageOnly\"||this.options.nonExplicitSupportedLngs)&&(t=this.getLanguagePartFromCode(t)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(t)>-1}getBestMatchFromCodes(t){if(!t)return null;let n;return t.forEach(r=>{if(n)return;const s=this.formatLanguageCode(r);(!this.options.supportedLngs||this.isSupportedCode(s))&&(n=s)}),!n&&this.options.supportedLngs&&t.forEach(r=>{if(n)return;const s=this.getLanguagePartFromCode(r);if(this.isSupportedCode(s))return n=s;n=this.options.supportedLngs.find(o=>{if(o===s)return o;if(!(o.indexOf(\"-\")<0&&s.indexOf(\"-\")<0)&&(o.indexOf(\"-\")>0&&s.indexOf(\"-\")<0&&o.substring(0,o.indexOf(\"-\"))===s||o.indexOf(s)===0&&s.length>1))return o})}),n||(n=this.getFallbackCodes(this.options.fallbackLng)[0]),n}getFallbackCodes(t,n){if(!t)return[];if(typeof t==\"function\"&&(t=t(n)),typeof t==\"string\"&&(t=[t]),Array.isArray(t))return t;if(!n)return t.default||[];let r=t[n];return r||(r=t[this.getScriptPartFromCode(n)]),r||(r=t[this.formatLanguageCode(n)]),r||(r=t[this.getLanguagePartFromCode(n)]),r||(r=t.default),r||[]}toResolveHierarchy(t,n){const r=this.getFallbackCodes(n||this.options.fallbackLng||[],t),s=[],o=l=>{l&&(this.isSupportedCode(l)?s.push(l):this.logger.warn(`rejecting language code not found in supportedLngs: ${l}`))};return typeof t==\"string\"&&(t.indexOf(\"-\")>-1||t.indexOf(\"_\")>-1)?(this.options.load!==\"languageOnly\"&&o(this.formatLanguageCode(t)),this.options.load!==\"languageOnly\"&&this.options.load!==\"currentOnly\"&&o(this.getScriptPartFromCode(t)),this.options.load!==\"currentOnly\"&&o(this.getLanguagePartFromCode(t))):typeof t==\"string\"&&o(this.formatLanguageCode(t)),r.forEach(l=>{s.indexOf(l)<0&&o(this.formatLanguageCode(l))}),s}}let Qse=[{lngs:[\"ach\",\"ak\",\"am\",\"arn\",\"br\",\"fil\",\"gun\",\"ln\",\"mfe\",\"mg\",\"mi\",\"oc\",\"pt\",\"pt-BR\",\"tg\",\"tl\",\"ti\",\"tr\",\"uz\",\"wa\"],nr:[1,2],fc:1},{lngs:[\"af\",\"an\",\"ast\",\"az\",\"bg\",\"bn\",\"ca\",\"da\",\"de\",\"dev\",\"el\",\"en\",\"eo\",\"es\",\"et\",\"eu\",\"fi\",\"fo\",\"fur\",\"fy\",\"gl\",\"gu\",\"ha\",\"hi\",\"hu\",\"hy\",\"ia\",\"it\",\"kk\",\"kn\",\"ku\",\"lb\",\"mai\",\"ml\",\"mn\",\"mr\",\"nah\",\"nap\",\"nb\",\"ne\",\"nl\",\"nn\",\"no\",\"nso\",\"pa\",\"pap\",\"pms\",\"ps\",\"pt-PT\",\"rm\",\"sco\",\"se\",\"si\",\"so\",\"son\",\"sq\",\"sv\",\"sw\",\"ta\",\"te\",\"tk\",\"ur\",\"yo\"],nr:[1,2],fc:2},{lngs:[\"ay\",\"bo\",\"cgg\",\"fa\",\"ht\",\"id\",\"ja\",\"jbo\",\"ka\",\"km\",\"ko\",\"ky\",\"lo\",\"ms\",\"sah\",\"su\",\"th\",\"tt\",\"ug\",\"vi\",\"wo\",\"zh\"],nr:[1],fc:3},{lngs:[\"be\",\"bs\",\"cnr\",\"dz\",\"hr\",\"ru\",\"sr\",\"uk\"],nr:[1,2,5],fc:4},{lngs:[\"ar\"],nr:[0,1,2,3,11,100],fc:5},{lngs:[\"cs\",\"sk\"],nr:[1,2,5],fc:6},{lngs:[\"csb\",\"pl\"],nr:[1,2,5],fc:7},{lngs:[\"cy\"],nr:[1,2,3,8],fc:8},{lngs:[\"fr\"],nr:[1,2],fc:9},{lngs:[\"ga\"],nr:[1,2,3,7,11],fc:10},{lngs:[\"gd\"],nr:[1,2,3,20],fc:11},{lngs:[\"is\"],nr:[1,2],fc:12},{lngs:[\"jv\"],nr:[0,1],fc:13},{lngs:[\"kw\"],nr:[1,2,3,4],fc:14},{lngs:[\"lt\"],nr:[1,2,10],fc:15},{lngs:[\"lv\"],nr:[1,2,0],fc:16},{lngs:[\"mk\"],nr:[1,2],fc:17},{lngs:[\"mnk\"],nr:[0,1,2],fc:18},{lngs:[\"mt\"],nr:[1,2,11,20],fc:19},{lngs:[\"or\"],nr:[2,1],fc:2},{lngs:[\"ro\"],nr:[1,2,20],fc:20},{lngs:[\"sl\"],nr:[5,1,2,3],fc:21},{lngs:[\"he\",\"iw\"],nr:[1,2,20,21],fc:22}],Zse={1:e=>+(e>1),2:e=>+(e!=1),3:e=>0,4:e=>e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2,5:e=>e==0?0:e==1?1:e==2?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5,6:e=>e==1?0:e>=2&&e<=4?1:2,7:e=>e==1?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2,8:e=>e==1?0:e==2?1:e!=8&&e!=11?2:3,9:e=>+(e>=2),10:e=>e==1?0:e==2?1:e<7?2:e<11?3:4,11:e=>e==1||e==11?0:e==2||e==12?1:e>2&&e<20?2:3,12:e=>+(e%10!=1||e%100==11),13:e=>+(e!==0),14:e=>e==1?0:e==2?1:e==3?2:3,15:e=>e%10==1&&e%100!=11?0:e%10>=2&&(e%100<10||e%100>=20)?1:2,16:e=>e%10==1&&e%100!=11?0:e!==0?1:2,17:e=>e==1||e%10==1&&e%100!=11?0:1,18:e=>e==0?0:e==1?1:2,19:e=>e==1?0:e==0||e%100>1&&e%100<11?1:e%100>10&&e%100<20?2:3,20:e=>e==1?0:e==0||e%100>0&&e%100<20?1:2,21:e=>e%100==1?1:e%100==2?2:e%100==3||e%100==4?3:0,22:e=>e==1?0:e==2?1:(e<0||e>10)&&e%10==0?2:3};const Yse=[\"v1\",\"v2\",\"v3\"],Xse=[\"v4\"],Dk={zero:0,one:1,two:2,few:3,many:4,other:5},eoe=()=>{const e={};return Qse.forEach(t=>{t.lngs.forEach(n=>{e[n]={numbers:t.nr,plurals:Zse[t.fc]}})}),e};class toe{constructor(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};this.languageUtils=t,this.options=n,this.logger=Ks.create(\"pluralResolver\"),(!this.options.compatibilityJSON||Xse.includes(this.options.compatibilityJSON))&&(typeof Intl>\"u\"||!Intl.PluralRules)&&(this.options.compatibilityJSON=\"v3\",this.logger.error(\"Your environment seems not to be Intl API compatible, use an Intl.PluralRules polyfill. Will fallback to the compatibilityJSON v3 format handling.\")),this.rules=eoe(),this.pluralRulesCache={}}addRule(t,n){this.rules[t]=n}clearCache(){this.pluralRulesCache={}}getRule(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(this.shouldUseIntlApi())try{const r=fh(t===\"dev\"?\"en\":t),s=n.ordinal?\"ordinal\":\"cardinal\",o=JSON.stringify({cleanedCode:r,type:s});if(o in this.pluralRulesCache)return this.pluralRulesCache[o];const l=new Intl.PluralRules(r,{type:s});return this.pluralRulesCache[o]=l,l}catch{return}return this.rules[t]||this.rules[this.languageUtils.getLanguagePartFromCode(t)]}needsPlural(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const r=this.getRule(t,n);return this.shouldUseIntlApi()?r&&r.resolvedOptions().pluralCategories.length>1:r&&r.numbers.length>1}getPluralFormsOfKey(t,n){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return this.getSuffixes(t,r).map(s=>`${n}${s}`)}getSuffixes(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const r=this.getRule(t,n);return r?this.shouldUseIntlApi()?r.resolvedOptions().pluralCategories.sort((s,o)=>Dk[s]-Dk[o]).map(s=>`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:\"\"}${s}`):r.numbers.map(s=>this.getSuffix(t,s,n)):[]}getSuffix(t,n){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};const s=this.getRule(t,r);return s?this.shouldUseIntlApi()?`${this.options.prepend}${r.ordinal?`ordinal${this.options.prepend}`:\"\"}${s.select(n)}`:this.getSuffixRetroCompatible(s,n):(this.logger.warn(`no plural rule found for: ${t}`),\"\")}getSuffixRetroCompatible(t,n){const r=t.noAbs?t.plurals(n):t.plurals(Math.abs(n));let s=t.numbers[r];this.options.simplifyPluralSuffix&&t.numbers.length===2&&t.numbers[0]===1&&(s===2?s=\"plural\":s===1&&(s=\"\"));const o=()=>this.options.prepend&&s.toString()?this.options.prepend+s.toString():s.toString();return this.options.compatibilityJSON===\"v1\"?s===1?\"\":typeof s==\"number\"?`_plural_${s.toString()}`:o():this.options.compatibilityJSON===\"v2\"||this.options.simplifyPluralSuffix&&t.numbers.length===2&&t.numbers[0]===1?o():this.options.prepend&&r.toString()?this.options.prepend+r.toString():r.toString()}shouldUseIntlApi(){return!Yse.includes(this.options.compatibilityJSON)}}const Fk=function(e,t,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:\".\",s=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,o=Vse(e,t,n);return!o&&s&&typeof n==\"string\"&&(o=Mb(e,n,r),o===void 0&&(o=Mb(t,n,r))),o},wy=e=>e.replace(/\\$/g,\"$$$$\");class noe{constructor(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.logger=Ks.create(\"interpolator\"),this.options=t,this.format=t.interpolation&&t.interpolation.format||(n=>n),this.init(t)}init(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};t.interpolation||(t.interpolation={escapeValue:!0});const{escape:n,escapeValue:r,useRawValueToEscape:s,prefix:o,prefixEscaped:l,suffix:u,suffixEscaped:d,formatSeparator:f,unescapeSuffix:h,unescapePrefix:m,nestingPrefix:g,nestingPrefixEscaped:x,nestingSuffix:b,nestingSuffixEscaped:w,nestingOptionsSeparator:C,maxReplaces:k,alwaysFormat:j}=t.interpolation;this.escape=n!==void 0?n:qse,this.escapeValue=r!==void 0?r:!0,this.useRawValueToEscape=s!==void 0?s:!1,this.prefix=o?Sl(o):l||\"{{\",this.suffix=u?Sl(u):d||\"}}\",this.formatSeparator=f||\",\",this.unescapePrefix=h?\"\":m||\"-\",this.unescapeSuffix=this.unescapePrefix?\"\":h||\"\",this.nestingPrefix=g?Sl(g):x||Sl(\"$t(\"),this.nestingSuffix=b?Sl(b):w||Sl(\")\"),this.nestingOptionsSeparator=C||\",\",this.maxReplaces=k||1e3,this.alwaysFormat=j!==void 0?j:!1,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const t=(n,r)=>n&&n.source===r?(n.lastIndex=0,n):new RegExp(r,\"g\");this.regexp=t(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=t(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=t(this.nestingRegexp,`${this.nestingPrefix}(.+?)${this.nestingSuffix}`)}interpolate(t,n,r,s){let o,l,u;const d=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},f=x=>{if(x.indexOf(this.formatSeparator)<0){const k=Fk(n,d,x,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(k,void 0,r,{...s,...n,interpolationkey:x}):k}const b=x.split(this.formatSeparator),w=b.shift().trim(),C=b.join(this.formatSeparator).trim();return this.format(Fk(n,d,w,this.options.keySeparator,this.options.ignoreJSONStructure),C,r,{...s,...n,interpolationkey:w})};this.resetRegExp();const h=s&&s.missingInterpolationHandler||this.options.missingInterpolationHandler,m=s&&s.interpolation&&s.interpolation.skipOnVariables!==void 0?s.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:x=>wy(x)},{regex:this.regexp,safeValue:x=>this.escapeValue?wy(this.escape(x)):wy(x)}].forEach(x=>{for(u=0;o=x.regex.exec(t);){const b=o[1].trim();if(l=f(b),l===void 0)if(typeof h==\"function\"){const C=h(t,o,s);l=typeof C==\"string\"?C:\"\"}else if(s&&Object.prototype.hasOwnProperty.call(s,b))l=\"\";else if(m){l=o[0];continue}else this.logger.warn(`missed to pass in variable ${b} for interpolating ${t}`),l=\"\";else typeof l!=\"string\"&&!this.useRawValueToEscape&&(l=Mk(l));const w=x.safeValue(l);if(t=t.replace(o[0],w),m?(x.regex.lastIndex+=l.length,x.regex.lastIndex-=o[0].length):x.regex.lastIndex=0,u++,u>=this.maxReplaces)break}}),t}nest(t,n){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},s,o,l;const u=(d,f)=>{const h=this.nestingOptionsSeparator;if(d.indexOf(h)<0)return d;const m=d.split(new RegExp(`${h}[ ]*{`));let g=`{${m[1]}`;d=m[0],g=this.interpolate(g,l);const x=g.match(/'/g),b=g.match(/\"/g);(x&&x.length%2===0&&!b||b.length%2!==0)&&(g=g.replace(/'/g,'\"'));try{l=JSON.parse(g),f&&(l={...f,...l})}catch(w){return this.logger.warn(`failed parsing options string in nesting for key ${d}`,w),`${d}${h}${g}`}return l.defaultValue&&l.defaultValue.indexOf(this.prefix)>-1&&delete l.defaultValue,d};for(;s=this.nestingRegexp.exec(t);){let d=[];l={...r},l=l.replace&&typeof l.replace!=\"string\"?l.replace:l,l.applyPostProcessor=!1,delete l.defaultValue;let f=!1;if(s[0].indexOf(this.formatSeparator)!==-1&&!/{.*}/.test(s[1])){const h=s[1].split(this.formatSeparator).map(m=>m.trim());s[1]=h.shift(),d=h,f=!0}if(o=n(u.call(this,s[1].trim(),l),l),o&&s[0]===t&&typeof o!=\"string\")return o;typeof o!=\"string\"&&(o=Mk(o)),o||(this.logger.warn(`missed to resolve ${s[1]} for nesting ${t}`),o=\"\"),f&&(o=d.reduce((h,m)=>this.format(h,m,r.lng,{...r,interpolationkey:s[1].trim()}),o.trim())),t=t.replace(s[0],o),this.regexp.lastIndex=0}return t}}const roe=e=>{let t=e.toLowerCase().trim();const n={};if(e.indexOf(\"(\")>-1){const r=e.split(\"(\");t=r[0].toLowerCase().trim();const s=r[1].substring(0,r[1].length-1);t===\"currency\"&&s.indexOf(\":\")<0?n.currency||(n.currency=s.trim()):t===\"relativetime\"&&s.indexOf(\":\")<0?n.range||(n.range=s.trim()):s.split(\";\").forEach(l=>{if(l){const[u,...d]=l.split(\":\"),f=d.join(\":\").trim().replace(/^'+|'+$/g,\"\"),h=u.trim();n[h]||(n[h]=f),f===\"false\"&&(n[h]=!1),f===\"true\"&&(n[h]=!0),isNaN(f)||(n[h]=parseInt(f,10))}})}return{formatName:t,formatOptions:n}},Cl=e=>{const t={};return(n,r,s)=>{let o=s;s&&s.interpolationkey&&s.formatParams&&s.formatParams[s.interpolationkey]&&s[s.interpolationkey]&&(o={...o,[s.interpolationkey]:void 0});const l=r+JSON.stringify(o);let u=t[l];return u||(u=e(fh(r),s),t[l]=u),u(n)}};class soe{constructor(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.logger=Ks.create(\"formatter\"),this.options=t,this.formats={number:Cl((n,r)=>{const s=new Intl.NumberFormat(n,{...r});return o=>s.format(o)}),currency:Cl((n,r)=>{const s=new Intl.NumberFormat(n,{...r,style:\"currency\"});return o=>s.format(o)}),datetime:Cl((n,r)=>{const s=new Intl.DateTimeFormat(n,{...r});return o=>s.format(o)}),relativetime:Cl((n,r)=>{const s=new Intl.RelativeTimeFormat(n,{...r});return o=>s.format(o,r.range||\"day\")}),list:Cl((n,r)=>{const s=new Intl.ListFormat(n,{...r});return o=>s.format(o)})},this.init(t)}init(t){const r=(arguments.length>1&&arguments[1]!==void 0?arguments[1]:{interpolation:{}}).interpolation;this.formatSeparator=r.formatSeparator?r.formatSeparator:r.formatSeparator||\",\"}add(t,n){this.formats[t.toLowerCase().trim()]=n}addCached(t,n){this.formats[t.toLowerCase().trim()]=Cl(n)}format(t,n,r){let s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};const o=n.split(this.formatSeparator);if(o.length>1&&o[0].indexOf(\"(\")>1&&o[0].indexOf(\")\")<0&&o.find(u=>u.indexOf(\")\")>-1)){const u=o.findIndex(d=>d.indexOf(\")\")>-1);o[0]=[o[0],...o.splice(1,u)].join(this.formatSeparator)}return o.reduce((u,d)=>{const{formatName:f,formatOptions:h}=roe(d);if(this.formats[f]){let m=u;try{const g=s&&s.formatParams&&s.formatParams[s.interpolationkey]||{},x=g.locale||g.lng||s.locale||s.lng||r;m=this.formats[f](u,x,{...h,...s,...g})}catch(g){this.logger.warn(g)}return m}else this.logger.warn(`there was no format function for ${f}`);return u},t)}}const ooe=(e,t)=>{e.pending[t]!==void 0&&(delete e.pending[t],e.pendingCount--)};class aoe extends kg{constructor(t,n,r){let s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};super(),this.backend=t,this.store=n,this.services=r,this.languageUtils=r.languageUtils,this.options=s,this.logger=Ks.create(\"backendConnector\"),this.waitingReads=[],this.maxParallelReads=s.maxParallelReads||10,this.readingCalls=0,this.maxRetries=s.maxRetries>=0?s.maxRetries:5,this.retryTimeout=s.retryTimeout>=1?s.retryTimeout:350,this.state={},this.queue=[],this.backend&&this.backend.init&&this.backend.init(r,s.backend,s)}queueLoad(t,n,r,s){const o={},l={},u={},d={};return t.forEach(f=>{let h=!0;n.forEach(m=>{const g=`${f}|${m}`;!r.reload&&this.store.hasResourceBundle(f,m)?this.state[g]=2:this.state[g]<0||(this.state[g]===1?l[g]===void 0&&(l[g]=!0):(this.state[g]=1,h=!1,l[g]===void 0&&(l[g]=!0),o[g]===void 0&&(o[g]=!0),d[m]===void 0&&(d[m]=!0)))}),h||(u[f]=!0)}),(Object.keys(o).length||Object.keys(l).length)&&this.queue.push({pending:l,pendingCount:Object.keys(l).length,loaded:{},errors:[],callback:s}),{toLoad:Object.keys(o),pending:Object.keys(l),toLoadLanguages:Object.keys(u),toLoadNamespaces:Object.keys(d)}}loaded(t,n,r){const s=t.split(\"|\"),o=s[0],l=s[1];n&&this.emit(\"failedLoading\",o,l,n),!n&&r&&this.store.addResourceBundle(o,l,r,void 0,void 0,{skipCopy:!0}),this.state[t]=n?-1:2,n&&r&&(this.state[t]=0);const u={};this.queue.forEach(d=>{Use(d.loaded,[o],l),ooe(d,t),n&&d.errors.push(n),d.pendingCount===0&&!d.done&&(Object.keys(d.loaded).forEach(f=>{u[f]||(u[f]={});const h=d.loaded[f];h.length&&h.forEach(m=>{u[f][m]===void 0&&(u[f][m]=!0)})}),d.done=!0,d.errors.length?d.callback(d.errors):d.callback())}),this.emit(\"loaded\",u),this.queue=this.queue.filter(d=>!d.done)}read(t,n,r){let s=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0,o=arguments.length>4&&arguments[4]!==void 0?arguments[4]:this.retryTimeout,l=arguments.length>5?arguments[5]:void 0;if(!t.length)return l(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:t,ns:n,fcName:r,tried:s,wait:o,callback:l});return}this.readingCalls++;const u=(f,h)=>{if(this.readingCalls--,this.waitingReads.length>0){const m=this.waitingReads.shift();this.read(m.lng,m.ns,m.fcName,m.tried,m.wait,m.callback)}if(f&&h&&s<this.maxRetries){setTimeout(()=>{this.read.call(this,t,n,r,s+1,o*2,l)},o);return}l(f,h)},d=this.backend[r].bind(this.backend);if(d.length===2){try{const f=d(t,n);f&&typeof f.then==\"function\"?f.then(h=>u(null,h)).catch(u):u(null,f)}catch(f){u(f)}return}return d(t,n,u)}prepareLoading(t,n){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},s=arguments.length>3?arguments[3]:void 0;if(!this.backend)return this.logger.warn(\"No backend was added via i18next.use. Will not load resources.\"),s&&s();typeof t==\"string\"&&(t=this.languageUtils.toResolveHierarchy(t)),typeof n==\"string\"&&(n=[n]);const o=this.queueLoad(t,n,r,s);if(!o.toLoad.length)return o.pending.length||s(),null;o.toLoad.forEach(l=>{this.loadOne(l)})}load(t,n,r){this.prepareLoading(t,n,{},r)}reload(t,n,r){this.prepareLoading(t,n,{reload:!0},r)}loadOne(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:\"\";const r=t.split(\"|\"),s=r[0],o=r[1];this.read(s,o,\"read\",void 0,void 0,(l,u)=>{l&&this.logger.warn(`${n}loading namespace ${o} for language ${s} failed`,l),!l&&u&&this.logger.log(`${n}loaded namespace ${o} for language ${s}`,u),this.loaded(t,l,u)})}saveMissing(t,n,r,s,o){let l=arguments.length>5&&arguments[5]!==void 0?arguments[5]:{},u=arguments.length>6&&arguments[6]!==void 0?arguments[6]:()=>{};if(this.services.utils&&this.services.utils.hasLoadedNamespace&&!this.services.utils.hasLoadedNamespace(n)){this.logger.warn(`did not save key \"${r}\" as the namespace \"${n}\" was not yet loaded`,\"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!\");return}if(!(r==null||r===\"\")){if(this.backend&&this.backend.create){const d={...l,isUpdate:o},f=this.backend.create.bind(this.backend);if(f.length<6)try{let h;f.length===5?h=f(t,n,r,s,d):h=f(t,n,r,s),h&&typeof h.then==\"function\"?h.then(m=>u(null,m)).catch(u):u(null,h)}catch(h){u(h)}else f(t,n,r,s,u,d)}!t||!t[0]||this.store.addResource(t[0],n,r,s)}}}const Lk=()=>({debug:!1,initImmediate:!0,ns:[\"translation\"],defaultNS:[\"translation\"],fallbackLng:[\"dev\"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:\"all\",preload:!1,simplifyPluralSuffix:!0,keySeparator:\".\",nsSeparator:\":\",pluralSeparator:\"_\",contextSeparator:\"_\",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:\"fallback\",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:e=>{let t={};if(typeof e[1]==\"object\"&&(t=e[1]),typeof e[1]==\"string\"&&(t.defaultValue=e[1]),typeof e[2]==\"string\"&&(t.tDescription=e[2]),typeof e[2]==\"object\"||typeof e[3]==\"object\"){const n=e[3]||e[2];Object.keys(n).forEach(r=>{t[r]=n[r]})}return t},interpolation:{escapeValue:!0,format:e=>e,prefix:\"{{\",suffix:\"}}\",formatSeparator:\",\",unescapePrefix:\"-\",nestingPrefix:\"$t(\",nestingSuffix:\")\",nestingOptionsSeparator:\",\",maxReplaces:1e3,skipOnVariables:!0}}),$k=e=>(typeof e.ns==\"string\"&&(e.ns=[e.ns]),typeof e.fallbackLng==\"string\"&&(e.fallbackLng=[e.fallbackLng]),typeof e.fallbackNS==\"string\"&&(e.fallbackNS=[e.fallbackNS]),e.supportedLngs&&e.supportedLngs.indexOf(\"cimode\")<0&&(e.supportedLngs=e.supportedLngs.concat([\"cimode\"])),e),lp=()=>{},ioe=e=>{Object.getOwnPropertyNames(Object.getPrototypeOf(e)).forEach(n=>{typeof e[n]==\"function\"&&(e[n]=e[n].bind(e))})};class dd extends kg{constructor(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;if(super(),this.options=$k(t),this.services={},this.logger=Ks,this.modules={external:[]},ioe(this),n&&!this.isInitialized&&!t.isClone){if(!this.options.initImmediate)return this.init(t,n),this;setTimeout(()=>{this.init(t,n)},0)}}init(){var t=this;let n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0;this.isInitializing=!0,typeof n==\"function\"&&(r=n,n={}),!n.defaultNS&&n.defaultNS!==!1&&n.ns&&(typeof n.ns==\"string\"?n.defaultNS=n.ns:n.ns.indexOf(\"translation\")<0&&(n.defaultNS=n.ns[0]));const s=Lk();this.options={...s,...this.options,...$k(n)},this.options.compatibilityAPI!==\"v1\"&&(this.options.interpolation={...s.interpolation,...this.options.interpolation}),n.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=n.keySeparator),n.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=n.nsSeparator);const o=h=>h?typeof h==\"function\"?new h:h:null;if(!this.options.isClone){this.modules.logger?Ks.init(o(this.modules.logger),this.options):Ks.init(null,this.options);let h;this.modules.formatter?h=this.modules.formatter:typeof Intl<\"u\"&&(h=soe);const m=new Ak(this.options);this.store=new Ok(this.options.resources,this.options);const g=this.services;g.logger=Ks,g.resourceStore=this.store,g.languageUtils=m,g.pluralResolver=new toe(m,{prepend:this.options.pluralSeparator,compatibilityJSON:this.options.compatibilityJSON,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),h&&(!this.options.interpolation.format||this.options.interpolation.format===s.interpolation.format)&&(g.formatter=o(h),g.formatter.init(g,this.options),this.options.interpolation.format=g.formatter.format.bind(g.formatter)),g.interpolator=new noe(this.options),g.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},g.backendConnector=new aoe(o(this.modules.backend),g.resourceStore,g,this.options),g.backendConnector.on(\"*\",function(x){for(var b=arguments.length,w=new Array(b>1?b-1:0),C=1;C<b;C++)w[C-1]=arguments[C];t.emit(x,...w)}),this.modules.languageDetector&&(g.languageDetector=o(this.modules.languageDetector),g.languageDetector.init&&g.languageDetector.init(g,this.options.detection,this.options)),this.modules.i18nFormat&&(g.i18nFormat=o(this.modules.i18nFormat),g.i18nFormat.init&&g.i18nFormat.init(this)),this.translator=new ph(this.services,this.options),this.translator.on(\"*\",function(x){for(var b=arguments.length,w=new Array(b>1?b-1:0),C=1;C<b;C++)w[C-1]=arguments[C];t.emit(x,...w)}),this.modules.external.forEach(x=>{x.init&&x.init(this)})}if(this.format=this.options.interpolation.format,r||(r=lp),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const h=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);h.length>0&&h[0]!==\"dev\"&&(this.options.lng=h[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn(\"init: no languageDetector is used and no lng is defined\"),[\"getResource\",\"hasResourceBundle\",\"getResourceBundle\",\"getDataByLanguage\"].forEach(h=>{this[h]=function(){return t.store[h](...arguments)}}),[\"addResource\",\"addResources\",\"addResourceBundle\",\"removeResourceBundle\"].forEach(h=>{this[h]=function(){return t.store[h](...arguments),t}});const d=hu(),f=()=>{const h=(m,g)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn(\"init: i18next is already initialized. You should call init just once!\"),this.isInitialized=!0,this.options.isClone||this.logger.log(\"initialized\",this.options),this.emit(\"initialized\",this.options),d.resolve(g),r(m,g)};if(this.languages&&this.options.compatibilityAPI!==\"v1\"&&!this.isInitialized)return h(null,this.t.bind(this));this.changeLanguage(this.options.lng,h)};return this.options.resources||!this.options.initImmediate?f():setTimeout(f,0),d}loadResources(t){let r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:lp;const s=typeof t==\"string\"?t:this.language;if(typeof t==\"function\"&&(r=t),!this.options.resources||this.options.partialBundledLanguages){if(s&&s.toLowerCase()===\"cimode\"&&(!this.options.preload||this.options.preload.length===0))return r();const o=[],l=u=>{if(!u||u===\"cimode\")return;this.services.languageUtils.toResolveHierarchy(u).forEach(f=>{f!==\"cimode\"&&o.indexOf(f)<0&&o.push(f)})};s?l(s):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(d=>l(d)),this.options.preload&&this.options.preload.forEach(u=>l(u)),this.services.backendConnector.load(o,this.options.ns,u=>{!u&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),r(u)})}else r(null)}reloadResources(t,n,r){const s=hu();return typeof t==\"function\"&&(r=t,t=void 0),typeof n==\"function\"&&(r=n,n=void 0),t||(t=this.languages),n||(n=this.options.ns),r||(r=lp),this.services.backendConnector.reload(t,n,o=>{s.resolve(),r(o)}),s}use(t){if(!t)throw new Error(\"You are passing an undefined module! Please check the object you are passing to i18next.use()\");if(!t.type)throw new Error(\"You are passing a wrong module! Please check the object you are passing to i18next.use()\");return t.type===\"backend\"&&(this.modules.backend=t),(t.type===\"logger\"||t.log&&t.warn&&t.error)&&(this.modules.logger=t),t.type===\"languageDetector\"&&(this.modules.languageDetector=t),t.type===\"i18nFormat\"&&(this.modules.i18nFormat=t),t.type===\"postProcessor\"&&qI.addPostProcessor(t),t.type===\"formatter\"&&(this.modules.formatter=t),t.type===\"3rdParty\"&&this.modules.external.push(t),this}setResolvedLanguage(t){if(!(!t||!this.languages)&&!([\"cimode\",\"dev\"].indexOf(t)>-1))for(let n=0;n<this.languages.length;n++){const r=this.languages[n];if(!([\"cimode\",\"dev\"].indexOf(r)>-1)&&this.store.hasLanguageSomeTranslations(r)){this.resolvedLanguage=r;break}}}changeLanguage(t,n){var r=this;this.isLanguageChangingTo=t;const s=hu();this.emit(\"languageChanging\",t);const o=d=>{this.language=d,this.languages=this.services.languageUtils.toResolveHierarchy(d),this.resolvedLanguage=void 0,this.setResolvedLanguage(d)},l=(d,f)=>{f?(o(f),this.translator.changeLanguage(f),this.isLanguageChangingTo=void 0,this.emit(\"languageChanged\",f),this.logger.log(\"languageChanged\",f)):this.isLanguageChangingTo=void 0,s.resolve(function(){return r.t(...arguments)}),n&&n(d,function(){return r.t(...arguments)})},u=d=>{!t&&!d&&this.services.languageDetector&&(d=[]);const f=typeof d==\"string\"?d:this.services.languageUtils.getBestMatchFromCodes(d);f&&(this.language||o(f),this.translator.language||this.translator.changeLanguage(f),this.services.languageDetector&&this.services.languageDetector.cacheUserLanguage&&this.services.languageDetector.cacheUserLanguage(f)),this.loadResources(f,h=>{l(h,f)})};return!t&&this.services.languageDetector&&!this.services.languageDetector.async?u(this.services.languageDetector.detect()):!t&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(u):this.services.languageDetector.detect(u):u(t),s}getFixedT(t,n,r){var s=this;const o=function(l,u){let d;if(typeof u!=\"object\"){for(var f=arguments.length,h=new Array(f>2?f-2:0),m=2;m<f;m++)h[m-2]=arguments[m];d=s.options.overloadTranslationOptionHandler([l,u].concat(h))}else d={...u};d.lng=d.lng||o.lng,d.lngs=d.lngs||o.lngs,d.ns=d.ns||o.ns,d.keyPrefix!==\"\"&&(d.keyPrefix=d.keyPrefix||r||o.keyPrefix);const g=s.options.keySeparator||\".\";let x;return d.keyPrefix&&Array.isArray(l)?x=l.map(b=>`${d.keyPrefix}${g}${b}`):x=d.keyPrefix?`${d.keyPrefix}${g}${l}`:l,s.t(x,d)};return typeof t==\"string\"?o.lng=t:o.lngs=t,o.ns=n,o.keyPrefix=r,o}t(){return this.translator&&this.translator.translate(...arguments)}exists(){return this.translator&&this.translator.exists(...arguments)}setDefaultNamespace(t){this.options.defaultNS=t}hasLoadedNamespace(t){let n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!this.isInitialized)return this.logger.warn(\"hasLoadedNamespace: i18next was not initialized\",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn(\"hasLoadedNamespace: i18n.languages were undefined or empty\",this.languages),!1;const r=n.lng||this.resolvedLanguage||this.languages[0],s=this.options?this.options.fallbackLng:!1,o=this.languages[this.languages.length-1];if(r.toLowerCase()===\"cimode\")return!0;const l=(u,d)=>{const f=this.services.backendConnector.state[`${u}|${d}`];return f===-1||f===0||f===2};if(n.precheck){const u=n.precheck(this,l);if(u!==void 0)return u}return!!(this.hasResourceBundle(r,t)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||l(r,t)&&(!s||l(o,t)))}loadNamespaces(t,n){const r=hu();return this.options.ns?(typeof t==\"string\"&&(t=[t]),t.forEach(s=>{this.options.ns.indexOf(s)<0&&this.options.ns.push(s)}),this.loadResources(s=>{r.resolve(),n&&n(s)}),r):(n&&n(),Promise.resolve())}loadLanguages(t,n){const r=hu();typeof t==\"string\"&&(t=[t]);const s=this.options.preload||[],o=t.filter(l=>s.indexOf(l)<0&&this.services.languageUtils.isSupportedCode(l));return o.length?(this.options.preload=s.concat(o),this.loadResources(l=>{r.resolve(),n&&n(l)}),r):(n&&n(),Promise.resolve())}dir(t){if(t||(t=this.resolvedLanguage||(this.languages&&this.languages.length>0?this.languages[0]:this.language)),!t)return\"rtl\";const n=[\"ar\",\"shu\",\"sqr\",\"ssh\",\"xaa\",\"yhd\",\"yud\",\"aao\",\"abh\",\"abv\",\"acm\",\"acq\",\"acw\",\"acx\",\"acy\",\"adf\",\"ads\",\"aeb\",\"aec\",\"afb\",\"ajp\",\"apc\",\"apd\",\"arb\",\"arq\",\"ars\",\"ary\",\"arz\",\"auz\",\"avl\",\"ayh\",\"ayl\",\"ayn\",\"ayp\",\"bbz\",\"pga\",\"he\",\"iw\",\"ps\",\"pbt\",\"pbu\",\"pst\",\"prp\",\"prd\",\"ug\",\"ur\",\"ydd\",\"yds\",\"yih\",\"ji\",\"yi\",\"hbo\",\"men\",\"xmn\",\"fa\",\"jpr\",\"peo\",\"pes\",\"prs\",\"dv\",\"sam\",\"ckb\"],r=this.services&&this.services.languageUtils||new Ak(Lk());return n.indexOf(r.getLanguagePartFromCode(t))>-1||t.toLowerCase().indexOf(\"-arab\")>1?\"rtl\":\"ltr\"}static createInstance(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;return new dd(t,n)}cloneInstance(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:lp;const r=t.forkResourceStore;r&&delete t.forkResourceStore;const s={...this.options,...t,isClone:!0},o=new dd(s);return(t.debug!==void 0||t.prefix!==void 0)&&(o.logger=o.logger.clone(t)),[\"store\",\"services\",\"language\"].forEach(u=>{o[u]=this[u]}),o.services={...this.services},o.services.utils={hasLoadedNamespace:o.hasLoadedNamespace.bind(o)},r&&(o.store=new Ok(this.store.data,s),o.services.resourceStore=o.store),o.translator=new ph(o.services,s),o.translator.on(\"*\",function(u){for(var d=arguments.length,f=new Array(d>1?d-1:0),h=1;h<d;h++)f[h-1]=arguments[h];o.emit(u,...f)}),o.init(s,n),o.translator.options=s,o.translator.backendConnector.services.utils={hasLoadedNamespace:o.hasLoadedNamespace.bind(o)},o}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}const Jn=dd.createInstance();Jn.createInstance=dd.createInstance;Jn.createInstance;Jn.dir;Jn.init;Jn.loadResources;Jn.reloadResources;Jn.use;Jn.changeLanguage;Jn.getFixedT;Jn.t;Jn.exists;Jn.setDefaultNamespace;Jn.hasLoadedNamespace;Jn.loadNamespaces;Jn.loadLanguages;const loe={title:\"Instances\",search:\"Search\",status:\"Status\",settings:\"Settings\",instancesNotFound:\"No instances found\"},coe={delete:\"Delete\",deleting:\"Deleting...\",cancel:\"Cancel\",markAll:\"Mark All\",unMarkAll:\"Unmark All\"},uoe={delete:{title:\"Delete Record\",message:\"You are about to delete the instance {{instanceName}}, Are you sure you want to continue?\",messageSingle:\"This action cannot be undone\"}},doe={all:\"All\",open:\"Connected\",connecting:\"Connecting\",closed:\"Disconnected\"},foe={clientName:\"Client name\",version:\"Version\"},poe={theme:{label:\"Toggle theme\",light:\"Light\",dark:\"Dark\",system:\"System\"},language:{label:\"Language\",english:\"English\",portuguese:\"Portuguese\",spanish:\"Spanish\",french:\"French\"}},hoe={media:{attach:\"Attach file\",document:\"Document\",photosAndVideos:\"Photos and Videos\",errors:{audioSize:\"Audio file size must be less than 16 MB\",imageSize:\"Image file size must be less than 5 MB\",videoSize:\"Video file size must be less than 16 MB\",documentSize:\"Document file size must be less than 100 MB\",unsupportedType:\"Unsupported file type\"},selectedMedia:{imageAlt:\"Selected image\",file:\"File\",selectedFile:\"Selected file\"}}},goe={dashboard:\"Dashboard\",chat:\"Chat\",configurations:\"Configurations\",settings:\"Settings\",proxy:\"Proxy\",events:\"Events\",webhook:\"Webhook\",websocket:\"WebSocket\",rabbitmq:\"RabbitMQ\",sqs:\"SQS\",integrations:\"Integrations\",chatwoot:\"Chatwoot\",typebot:\"Typebot\",openai:\"OpenAI\",dify:\"Dify\",n8n:\"n8n\",evoai:\"EvoAI\",evolutionBot:\"Evolution Bot\",flowise:\"Flowise\",documentation:\"Documentation\",postman:\"Postman\",discord:\"Discord\",supportPremium:\"Support Premium\"},moe={instance:{created:\"Instance created successfully\",deleted:\"Instance deleted successfully\",error:\"An error occurred while creating the instance\"}},voe={title:\"Evolution Manager\",description:\"Please enter your credentials to continue\",form:{serverUrl:\"Server URL\",apiKey:\"API Key Global\"},message:{invalidServer:\"Invalid server\",invalidCredentials:\"Invalid credentials\"},button:{login:\"Login\"}},yoe={modal:{title:\"New instance\"},form:{name:\"Name\",integration:{label:\"Channel\",baileys:\"Baileys\",whatsapp:\"WhatsApp Cloud API\",facebook:\"Facebook\",instagram:\"Instagram\",evolution:\"Evolution\"},token:\"Token\",number:\"Number\",businessId:\"Business ID\"},button:{save:\"Save\",saving:\"Saving...\",create:\"Instance\",connecting:\"Connecting...\",facebook:\"Connect with Facebook\",instagram:\"Connect with Instagram\",whatsapp:\"Connect with WhatsApp\"},dashboard:{button:{qrcode:{label:\"Get QR Code\",title:\"Scan the QR code with your WhatsApp Web\"},pairingCode:{label:\"Get Pairing Code\",title:\"Get the pairing code to connect with WhatsApp\"},restart:\"Restart\",disconnect:\"Disconnect\"},alert:\"To connect, scan the QR code with your WhatsApp Web\",contacts:\"Contacts\",chats:\"Chats\",messages:\"Messages\"}},boe={title:\"Settings\",toast:{success:\"Settings applied successfully\",error:\"An error occurred while applying the settings\"},form:{rejectCall:{label:\"Reject Calls\",description:\"Reject all incoming calls\"},msgCall:{label:\"Message Reject Call\",description:\"Send a message when rejecting a call\"},groupsIgnore:{label:\"Ignore Groups\",description:\"Ignore all messages from groups\"},alwaysOnline:{label:\"Always Online\",description:\"Keep the whatsapp always online\"},readMessages:{label:\"Read Messages\",description:\"Mark all messages as read\"},syncFullHistory:{label:\"Sync Full History\",description:\"Sync all complete chat history on scan QR code\"},readStatus:{label:\"Read Status\",description:\"Mark all statuses as read\"}},button:{save:\"Save\",saving:\"Saving...\"}},xoe={title:\"Proxy\",toast:{success:\"Proxy applied successfully\",error:\"An error occurred while applying the proxy\"},form:{enabled:{label:\"Enabled\",description:\"Enable or disable the proxy\"},protocol:{label:\"Protocol\"},host:{label:\"Host\"},port:{label:\"Port\"},username:{label:\"Username\"},password:{label:\"Password\"}},button:{save:\"Save\",saving:\"Saving...\"}},woe={title:\"Webhook\",toast:{success:\"Webhook applied successfully\",error:\"An error occurred while applying the webhook\"},form:{enabled:{label:\"Enabled\",description:\"Enable or disable the webhook\"},url:{label:\"URL\"},byEvents:{label:\"Webhook by Events\",description:\"Create a route for each event by adding the event name to the end of the URL\"},base64:{label:\"Webhook Base64\",description:\"Send media base64 data in webhook\"},events:{label:\"Events\"}},button:{save:\"Save\",saving:\"Saving...\"}},Soe={title:\"Websocket\",toast:{success:\"Websocket applied successfully\",error:\"An error occurred while applying the websocket\"},form:{enabled:{label:\"Enabled\",description:\"Enable or disable the websocket\"},events:{label:\"Events\"}},button:{save:\"Save\",saving:\"Saving...\"}},Coe={title:\"RabbitMQ\",toast:{success:\"RabbitMQ applied successfully\",error:\"An error occurred while applying the rabbitmq\"},form:{enabled:{label:\"Enabled\",description:\"Enable or disable the rabbitmq\"},events:{label:\"Events\"}},button:{save:\"Save\",saving:\"Saving...\"}},Eoe={title:\"SQS\",toast:{success:\"SQS applied successfully\",error:\"An error occurred while applying the sqs\"},form:{enabled:{label:\"Enabled\",description:\"Enable or disable the sqs\"},events:{label:\"Events\"}},button:{save:\"Save\",saving:\"Saving...\"}},koe={title:\"Chatwoot\",toast:{success:\"Chatwoot applied successfully\",error:\"An error occurred while applying the Chatwoot\"},form:{enabled:{label:\"Enabled\",description:\"Enable or disable the sqs\"},url:{label:\"Chatwoot URL\"},accountId:{label:\"Account ID\"},token:{label:\"Token\"},signMsg:{label:\"Sign Messages\",description:\"Sign message with chatwoot username\"},signDelimiter:{label:\"Sign Delimiter\"},nameInbox:{label:\"Name Inbox\"},organization:{label:\"Organization\"},logo:{label:\"Logo\"},conversationPending:{label:\"Conversation Pending\",description:\"Conversations start as pending\"},reopenConversation:{label:\"Reopen Conversation\",description:\"Reopen conversation when receiving message\"},importContacts:{label:\"Import Contacts\",description:\"Import contacts from WhatsApp address book by connecting QR Code\"},importMessages:{label:\"Import Messages\",description:\"Import messages from WhatsApp by connecting QR Code\"},daysLimitImportMessages:{label:\"Days Limit Import Messages\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"},autoCreate:{label:\"Auto Create\",description:\"Automatically create chatwoot integration on save\"}},button:{save:\"Save\",saving:\"Saving...\"}},joe={title:\"Typebots\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"Typebot updated successfully\",create:\"Typebot created successfully\",delete:\"Typebot deleted successfully\",status:\"Typebot status updated successfully\"},error:\"An error occurred while creating the Typebot\"},table:{none:\"Nothing to show\"},form:{title:\"New Typebot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},typebotSettings:{label:\"Typebot Settings\"},url:{label:\"Typebot API URL\"},typebot:{label:\"Typebot Public Name\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},typebotIdFallback:{label:\"Typebot Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"Typebot\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\"},modal:{defaultSettings:{title:\"Default Settings\"}}},Toe={title:\"OpenAI\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},credentials:{title:\"Credentials\",table:{name:\"Name\",apiKey:\"API Key\",actions:{title:\"Actions\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"OpenAI updated successfully\",create:\"OpenAI created successfully\",delete:\"OpenAI deleted successfully\",status:\"OpenAI status updated successfully\",credentialsCreate:\"OpenAI credentials created successfully\",credentialsDelete:\"OpenAI credentials deleted successfully\"},error:\"An error occurred while creating the OpenAI\"},table:{none:\"Nothing to show\"},form:{title:\"New OpenAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},openaiCredsId:{label:\"OpenAI Credentials\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},openaiSettings:{label:\"OpenAI Settings\"},botType:{label:\"Bot Type\",assistant:\"Assistant\",chatCompletion:\"Chat Completion\"},assistantId:{label:\"Assistant ID\"},functionUrl:{label:\"Function URL\"},model:{label:\"Language Model\"},systemMessages:{label:\"System Messages\",description:\"Send system messages to OpenAI\"},assistantMessages:{label:\"Assistant Messages\",description:\"Send assistant messages to OpenAI\"},userMessages:{label:\"User Messages\",description:\"Send user messages to OpenAI\"},maxTokens:{label:\"Max Tokens\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},openaiIdFallback:{label:\"OpenAI Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},speechToText:{label:\"Speech to Text\",description:\"Convert voice messages to text\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"OpenAI\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\",loadModels:\"Load Models\",loading:\"Loading...\"},modal:{defaultSettings:{title:\"Default Settings\"}}},Noe={title:\"Dify\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"Dify updated successfully\",create:\"Dify created successfully\",delete:\"Dify deleted successfully\",status:\"Dify status updated successfully\"},error:\"An error occurred while creating the Dify\"},table:{none:\"Nothing to show\"},form:{title:\"New Dify\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},difySettings:{label:\"Dify Settings\"},botType:{label:\"Bot Type\",chatBot:\"Chat Bot\",textGenerator:\"Text Generator\",agent:\"Agent\",workflow:\"Workflow\"},apiUrl:{label:\"API URL\"},apiKey:{label:\"API Key\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},difyIdFallback:{label:\"Dify Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"Dify\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\"},modal:{defaultSettings:{title:\"Default Settings\"}}},Moe={title:\"n8n\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"n8n updated successfully\",create:\"n8n created successfully\",delete:\"n8n deleted successfully\",status:\"n8n status updated successfully\"},error:\"An error occurred while creating the n8n chatbot\"},table:{none:\"Nothing to show\"},form:{title:\"New n8n chatbot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},n8nSettings:{label:\"n8n Settings\"},webhookUrl:{label:\"Webhook URL\"},basicAuth:{label:\"Basic Auth (Optional)\"},basicAuthUser:{label:\"Basic Auth User\"},basicAuthPass:{label:\"Basic Auth Password\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},n8nIdFallback:{label:\"n8n Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"n8n\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\"},modal:{defaultSettings:{title:\"Default Settings\"}}},_oe={title:\"EvoAI\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"EvoAI updated successfully\",create:\"EvoAI created successfully\",delete:\"EvoAI deleted successfully\",status:\"EvoAI status updated successfully\"},error:\"An error occurred while creating the EvoAI chatbot\"},table:{none:\"Nothing to show\"},form:{title:\"New EvoAI chatbot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},evoaiSettings:{label:\"EvoAI Settings\"},agentUrl:{label:\"Agent URL\"},apiKey:{label:\"API Key (Optional)\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},evoaiIdFallback:{label:\"EvoAI Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"EvoAI\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\"},modal:{defaultSettings:{title:\"Default Settings\"}}},Roe={title:\"Evolution Bot\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"Evolution Bot updated successfully\",create:\"Evolution Bot created successfully\",delete:\"Evolution Bot deleted successfully\",status:\"Evolution Bot status updated successfully\"},error:\"An error occurred while creating the Evolution Bot\"},table:{none:\"Nothing to show\"},form:{title:\"New Evolution Bot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},evolutionBotSettings:{label:\"Evolution Bot Settings\"},apiUrl:{label:\"API URL\"},apiKey:{label:\"API Key\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},botIdFallback:{label:\"Evolution Bot Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"Evolution Bot\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\"},modal:{defaultSettings:{title:\"Default Settings\"}}},Poe={title:\"Flowise\",sessions:{label:\"Sessions\",search:\"Search for remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Actions\",open:\"Open\",pause:\"Pause\",close:\"Close\",delete:\"Delete\"},none:\"Nothing to show\"}},defaultSettings:\"Default Settings\",toast:{defaultSettings:{success:\"Default settings applied successfully\",error:\"An error occurred while applying the default settings\"},success:{update:\"Flowise updated successfully\",create:\"Flowise created successfully\",delete:\"Flowise deleted successfully\",status:\"Flowise status updated successfully\"},error:\"An error occurred while creating the Flowise\"},table:{none:\"Nothing to show\"},form:{title:\"New Flowise\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"I'm sorry, I didn't understand. Can you try again?\"},enabled:{label:\"Enabled\"},description:{label:\"Description\"},flowiseSettings:{label:\"Flowise Settings\"},apiUrl:{label:\"API URL\"},apiKey:{label:\"API Key\"},triggerSettings:{label:\"Trigger Settings\"},triggerType:{label:\"Trigger Type\",keyword:\"Keyword\",all:\"All\",advanced:\"Advanced\",none:\"None\"},triggerOperator:{label:\"Trigger Operator\",contains:\"Contains\",equals:\"Equals\",startsWith:\"Starts With\",endsWith:\"Ends With\",regex:\"Regex\"},triggerValue:{label:\"Trigger\"},triggerConditions:{label:\"Conditions\"},flowiseIdFallback:{label:\"Flowise Fallback\"},generalSettings:{label:\"General Settings\"},expire:{label:\"Expire in minutes\"},keywordFinish:{label:\"Keyword Finish\"},delayMessage:{label:\"Default Delay Message\"},unknownMessage:{label:\"Unknown Message\"},listeningFromMe:{label:\"Listening from me\",description:\"Listen to messages sent by me on the bot\"},stopBotFromMe:{label:\"Stop bot from me\",description:\"Pause the bot when I send a message\"},keepOpen:{label:\"Keep open\",description:\"Keep the bot open after the conversation ends\"},debounceTime:{label:\"Debounce Time\"},splitMessages:{label:\"Split Messages\",description:\"Split messages into multiple messages\"},timePerChar:{label:\"Time per character\"},ignoreJids:{label:\"Ignore Jids\",placeholder:\"Add JIDs ex: 1234567890@s.whatsapp.net and press enter\"}},button:{create:\"Flowise\",save:\"Save\",saving:\"Saving...\",update:\"Update\",defaultSettings:\"Default Settings\",delete:\"Delete\"},modal:{defaultSettings:{title:\"Default Settings\"}}},Ooe={dashboard:loe,button:coe,modal:uoe,status:doe,footer:foe,header:poe,chat:hoe,sidebar:goe,toast:moe,login:voe,instance:yoe,settings:boe,proxy:xoe,webhook:woe,websocket:Soe,rabbitmq:Coe,sqs:Eoe,chatwoot:koe,typebot:joe,openai:Toe,dify:Noe,n8n:Moe,evoai:_oe,evolutionBot:Roe,flowise:Poe},Ioe={title:\"Instancias\",search:\"Buscar\",status:\"Estado\",settings:\"Configuraciones\",instancesNotFound:\"No se encontraron instancias\"},Aoe={delete:\"Eliminar\",deleting:\"Eliminando...\",cancel:\"Cancelar\",markAll:\"Marcar Todos\",unMarkAll:\"Desmarcar Todos\"},Doe={delete:{title:\"Eliminar Registro\",message:\"Estás eliminando la instancia {{instanceName}}. ¿Estás seguro de que deseas continuar?\",messageSingle:\"Esta acción no se puede deshacer.\"}},Foe={all:\"Todos\",open:\"Conectado\",connecting:\"Conectando\",closed:\"Desconectado\"},Loe={clientName:\"Nombre del Cliente\",version:\"Versión\"},$oe={theme:{label:\"Cambiar Tema\",light:\"Claro\",dark:\"Oscuro\",system:\"Sistema\"},language:{label:\"Idioma\",english:\"Inglés\",portuguese:\"Portugués\",spanish:\"Español\",french:\"Francés\"}},Boe={dashboard:\"Visión General\",configurations:\"Configuraciones\",settings:\"Comportamiento\",proxy:\"Proxy\",events:\"Eventos\",webhook:\"Webhook\",websocket:\"WebSocket\",rabbitmq:\"RabbitMQ\",sqs:\"SQS\",integrations:\"Integraciones\",chatwoot:\"Chatwoot\",typebot:\"Typebot\",openai:\"OpenAI\",dify:\"Dify\",evoai:\"EvoAI\",n8n:\"n8n\",evolutionBot:\"Bot Evolution\",flowise:\"Flowise\",documentation:\"Documentación\",postman:\"Postman\",discord:\"Discord\",supportPremium:\"Soporte Premium\"},zoe={instance:{created:\"Instancia creada con éxito\",deleted:\"Instancia eliminada con éxito\",error:\"Ocurrió un error al crear la instancia\"}},Uoe={title:\"Evolution Manager\",description:\"Por favor, inicia sesión para continuar\",form:{serverUrl:\"URL del Servidor\",apiKey:\"Clave API Global\"},message:{invalidServer:\"Servidor inválido\",invalidCredentials:\"Credenciales inválidas\"},button:{login:\"Conectar\"}},Voe={modal:{title:\"Nueva Instancia\"},form:{name:\"Nombre\",integration:{label:\"Canal\",baileys:\"Baileys\",whatsapp:\"WhatsApp Cloud API\",facebook:\"Facebook\",instagram:\"Instagram\",evolution:\"Evolution\"},token:\"Token\",number:\"Número\",businessId:\"Business ID\"},button:{save:\"Guardar\",saving:\"Guardando...\",create:\"Instancia\",connecting:\"Conectando...\",facebook:\"Conectar con Facebook\",instagram:\"Conectar con Instagram\",whatsapp:\"Conectar con WhatsApp\"},dashboard:{button:{qrcode:{label:\"Generar Código QR\",title:\"Escanea el Código QR con WhatsApp\"},pairingCode:{label:\"Generar Código de Emparejamiento\",title:\"Emparejar con WhatsApp\"},restart:\"Reiniciar\",disconnect:\"Desconectar\"},alert:\"Para conectar, escanea el Código QR con WhatsApp\",contacts:\"Contactos\",chats:\"Chats\",messages:\"Mensajes\"}},Hoe={title:\"Comportamiento\",toast:{success:\"Comportamiento aplicado con éxito\",error:\"Ocurrió un error al aplicar el comportamiento\"},form:{rejectCall:{label:\"Rechazar Llamadas\",description:\"Rechazar todas las llamadas\"},msgCall:{label:\"Mensaje de Rechazo de Llamada\",description:\"Enviar mensaje de rechazo de llamada\"},groupsIgnore:{label:\"Ignorar Grupos\",description:\"Ignorar todos los mensajes de grupos\"},alwaysOnline:{label:\"Siempre Online\",description:\"Permanecer siempre en línea\"},readMessages:{label:\"Ver Mensajes\",description:\"Marcar todos los mensajes como leídos\"},syncFullHistory:{label:\"Sincronizar Historial Completo\",description:\"Sincronizar todo el historial al leer el Código QR\"},readStatus:{label:\"Ver Estado\",description:\"Marcar todos los estados como vistos\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},qoe={title:\"Proxy\",toast:{success:\"Proxy aplicado con éxito\",error:\"Ocurrió un error al aplicar el proxy\"},form:{enabled:{label:\"Activo\",description:\"Activar o desactivar el proxy\"},protocol:{label:\"Protocolo\"},host:{label:\"Host\"},port:{label:\"Puerto\"},username:{label:\"Usuario\"},password:{label:\"Contraseña\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},Koe={title:\"Webhook\",toast:{success:\"Webhook aplicado con éxito\",error:\"Ocurrió un error al aplicar el webhook\"},form:{enabled:{label:\"Activo\",description:\"Activar o desactivar el webhook\"},url:{label:\"URL\"},byEvents:{label:\"Webhook por Eventos\",description:\"Crear una ruta para cada evento agregando el nombre del evento al final de la URL\"},base64:{label:\"Webhook Base64\",description:\"Enviar datos de medios en base64 en el webhook\"},events:{label:\"Eventos\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},Woe={title:\"WebSocket\",toast:{success:\"WebSocket aplicado con éxito\",error:\"Ocurrió un error al aplicar el WebSocket\"},form:{enabled:{label:\"Activo\",description:\"Activar o desactivar el WebSocket\"},events:{label:\"Eventos\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},Goe={title:\"RabbitMQ\",toast:{success:\"RabbitMQ aplicado con éxito\",error:\"Ocurrió un error al aplicar el RabbitMQ\"},form:{enabled:{label:\"Activo\",description:\"Activar o desactivar el RabbitMQ\"},events:{label:\"Eventos\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},Joe={title:\"SQS\",toast:{success:\"SQS aplicado con éxito\",error:\"Ocurrió un error al aplicar el SQS\"},form:{enabled:{label:\"Activo\",description:\"Activar o desactivar el SQS\"},events:{label:\"Eventos\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},Qoe={title:\"Chatwoot\",toast:{success:\"Chatwoot aplicado con éxito\",error:\"Ocurrió un error al aplicar el Chatwoot\"},form:{enabled:{label:\"Activo\",description:\"Activar o desactivar el Chatwoot\"},url:{label:\"URL de Chatwoot\"},accountId:{label:\"ID de la Cuenta\"},token:{label:\"Token\"},signMsg:{label:\"Firmar Mensajes\",description:\"Firmar mensajes con el nombre de usuario de Chatwoot\"},signDelimiter:{label:\"Delimitador de Firma\"},nameInbox:{label:\"Nombre de la Bandeja de Entrada\"},organization:{label:\"Organización\"},logo:{label:\"Logo\"},conversationPending:{label:\"Conversación Pendiente\",description:\"Las conversaciones comienzan como pendientes\"},reopenConversation:{label:\"Reabrir Conversación\",description:\"Reabrir la conversación al recibir un mensaje\"},importContacts:{label:\"Importar Contactos\",description:\"Importar contactos del libro de direcciones de WhatsApp al conectar el Código QR\"},importMessages:{label:\"Importar Mensajes\",description:\"Importar mensajes de WhatsApp al conectar el Código QR\"},daysLimitImportMessages:{label:\"Límite de Días para Importación de Mensajes\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"},autoCreate:{label:\"Creación Automática\",description:\"Crear automáticamente la integración con Chatwoot al guardar\"}},button:{save:\"Guardar\",saving:\"Guardando...\"}},Zoe={title:\"Typebots\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nombre Visible\",sessionId:\"ID de Sesión\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"Typebot actualizado con éxito\",create:\"Typebot creado con éxito\",delete:\"Typebot eliminado con éxito\",status:\"Estado de Typebot actualizado con éxito\"},error:\"Ocurrió un error al crear el Typebot\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo Typebot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},typebotSettings:{label:\"Configuraciones de Typebot\"},url:{label:\"URL de la API de Typebot\"},typebot:{label:\"Nombre Público de Typebot\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},typebotIdFallback:{label:\"Fallback de Typebot\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes largos en múltiples mensajes\"},timePerChar:{label:\"Tiempo por Carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"Typebot\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},Yoe={title:\"OpenAI\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nombre Visible\",sessionId:\"ID de Sesión\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},credentials:{title:\"Credenciales\",table:{name:\"Nombre\",apiKey:\"Clave API\",actions:{title:\"Acciones\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"OpenAI actualizado con éxito\",create:\"OpenAI creado con éxito\",delete:\"OpenAI eliminado con éxito\",status:\"Estado de OpenAI actualizado con éxito\",credentialsCreate:\"Credenciales de OpenAI creadas con éxito\",credentialsDelete:\"Credenciales de OpenAI eliminadas con éxito\"},error:\"Ocurrió un error al crear el OpenAI\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo OpenAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},openaiCredsId:{label:\"Credenciales de OpenAI\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},openaiSettings:{label:\"Configuraciones de OpenAI\"},botType:{label:\"Tipo de Bot\",assistant:\"Asistente\",chatCompletion:\"Chat Completion\"},assistantId:{label:\"ID del Asistente\"},functionUrl:{label:\"URL de la Función\"},model:{label:\"Modelo de Lenguaje\"},systemMessages:{label:\"Mensajes del Sistema\",description:\"Enviar mensajes del sistema a OpenAI\"},assistantMessages:{label:\"Mensajes del Asistente\",description:\"Enviar mensajes del asistente a OpenAI\"},userMessages:{label:\"Mensajes del Usuario\",description:\"Enviar mensajes del usuario a OpenAI\"},maxTokens:{label:\"Máximo de Tokens\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},openaiIdFallback:{label:\"Fallback de OpenAI\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},speechToText:{label:\"Voz a Texto\",description:\"Convertir mensajes de voz en texto\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes largos en múltiples mensajes\"},timePerChar:{label:\"Tiempo por Carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"OpenAI\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\",loadModels:\"Cargar Modelos\",loading:\"Cargando...\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},Xoe={title:\"Dify\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nombre Visible\",sessionId:\"ID de Sesión\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"Dify actualizado con éxito\",create:\"Dify creado con éxito\",delete:\"Dify eliminado con éxito\",status:\"Estado de Dify actualizado con éxito\"},error:\"Ocurrió un error al crear el Dify\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo Dify\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},difySettings:{label:\"Configuraciones de Dify\"},botType:{label:\"Tipo de Bot\",chatBot:\"Chat Bot\",textGenerator:\"Generador de Texto\",agent:\"Agente\",workflow:\"Flujo de Trabajo\"},apiUrl:{label:\"URL de la API\"},apiKey:{label:\"Clave API\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},difyIdFallback:{label:\"Fallback de Dify\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes largos en múltiples mensajes\"},timePerChar:{label:\"Tiempo por Carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"Dify\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},eae={title:\"n8n\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"n8n actualizado con éxito\",create:\"n8n creado con éxito\",delete:\"n8n eliminado con éxito\",status:\"Estado de n8n actualizado con éxito\"},error:\"Ocurrió un error al crear el chatbot n8n\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo chatbot n8n\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},n8nSettings:{label:\"Configuraciones de n8n\"},webhookUrl:{label:\"URL del Webhook\"},basicAuth:{label:\"Basic Auth (Opcional)\"},basicAuthUser:{label:\"Basic Auth User\"},basicAuthPass:{label:\"Basic Auth Password\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},n8nIdFallback:{label:\"Fallback de n8n\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes en múltiples mensajes\"},timePerChar:{label:\"Tiempo por carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"n8n\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},tae={title:\"EvoAI\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"EvoAI actualizado con éxito\",create:\"EvoAI creado con éxito\",delete:\"EvoAI eliminado con éxito\",status:\"Estado de EvoAI actualizado con éxito\"},error:\"Ocurrió un error al crear el chatbot EvoAI\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo chatbot EvoAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},evoaiSettings:{label:\"Configuraciones de EvoAI\"},agentUrl:{label:\"URL del Agente\"},apiKey:{label:\"API Key (Opcional)\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},evoaiIdFallback:{label:\"Fallback de EvoAI\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes en múltiples mensajes\"},timePerChar:{label:\"Tiempo por carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"EvoAI\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},nae={title:\"Bot Evolution\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nombre Visible\",sessionId:\"ID de Sesión\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"Bot Evolution actualizado con éxito\",create:\"Bot Evolution creado con éxito\",delete:\"Bot Evolution eliminado con éxito\",status:\"Estado de Bot Evolution actualizado con éxito\"},error:\"Ocurrió un error al crear el Bot Evolution\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo Bot Evolution\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},evolutionBotSettings:{label:\"Configuraciones de Bot Evolution\"},apiUrl:{label:\"URL de la API\"},apiKey:{label:\"Clave API\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},botIdFallback:{label:\"Fallback de Bot Evolution\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes largos en múltiples mensajes\"},timePerChar:{label:\"Tiempo por Carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"Bot Evolution\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},rae={title:\"Flowise\",sessions:{label:\"Sesiones\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nombre Visible\",sessionId:\"ID de Sesión\",status:\"Estado\",actions:{title:\"Acciones\",open:\"Abrir\",pause:\"Pausar\",close:\"Cerrar\",delete:\"Eliminar\"},none:\"Nada que mostrar\"}},defaultSettings:\"Configuraciones Predeterminadas\",toast:{defaultSettings:{success:\"Configuraciones predeterminadas aplicadas con éxito\",error:\"Ocurrió un error al aplicar las configuraciones predeterminadas\"},success:{update:\"Flowise actualizado con éxito\",create:\"Flowise creado con éxito\",delete:\"Flowise eliminado con éxito\",status:\"Estado de Flowise actualizado con éxito\"},error:\"Ocurrió un error al crear el Flowise\"},table:{none:\"Nada que mostrar\"},form:{title:\"Nuevo Flowise\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Lo siento, no entendí. ¿Puedes intentar de nuevo?\"},enabled:{label:\"Activo\"},description:{label:\"Descripción\"},flowiseSettings:{label:\"Configuraciones de Flowise\"},apiUrl:{label:\"URL de la API\"},apiKey:{label:\"Clave API\"},triggerSettings:{label:\"Configuraciones de Disparador\"},triggerType:{label:\"Tipo de Disparador\",keyword:\"Palabra clave\",all:\"Todos\",advanced:\"Avanzado\",none:\"Ninguno\"},triggerOperator:{label:\"Operador de Disparador\",contains:\"Contiene\",equals:\"Igual\",startsWith:\"Comienza Con\",endsWith:\"Termina Con\",regex:\"Regex\"},triggerValue:{label:\"Disparador\"},triggerConditions:{label:\"Condiciones\"},flowiseIdFallback:{label:\"Fallback de Flowise\"},generalSettings:{label:\"Configuraciones Generales\"},expire:{label:\"Expirar en minutos\"},keywordFinish:{label:\"Palabra clave de Finalización\"},delayMessage:{label:\"Mensaje de Retraso Predeterminado\"},unknownMessage:{label:\"Mensaje Desconocido\"},listeningFromMe:{label:\"Escuchando de mí\",description:\"Escuchar los mensajes enviados por mí en el bot\"},stopBotFromMe:{label:\"Detener bot por mí\",description:\"Pausar el bot cuando yo envíe un mensaje\"},keepOpen:{label:\"Mantener abierto\",description:\"Mantener el bot abierto después de que termine la conversación\"},debounceTime:{label:\"Tiempo de Debounce\"},splitMessages:{label:\"Dividir Mensajes\",description:\"Dividir mensajes largos en múltiples mensajes\"},timePerChar:{label:\"Tiempo por Carácter\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Agregar JIDs ej: 1234567890@s.whatsapp.net y presiona enter\"}},button:{create:\"Flowise\",save:\"Guardar\",saving:\"Guardando...\",update:\"Actualizar\",defaultSettings:\"Configuraciones Predeterminadas\",delete:\"Eliminar\"},modal:{defaultSettings:{title:\"Configuraciones Predeterminadas\"}}},sae={dashboard:Ioe,button:Aoe,modal:Doe,status:Foe,footer:Loe,header:$oe,sidebar:Boe,toast:zoe,login:Uoe,instance:Voe,settings:Hoe,proxy:qoe,webhook:Koe,websocket:Woe,rabbitmq:Goe,sqs:Joe,chatwoot:Qoe,typebot:Zoe,openai:Yoe,dify:Xoe,n8n:eae,evoai:tae,evolutionBot:nae,flowise:rae},oae={title:\"Instances\",search:\"Rechercher\",status:\"Statut\",settings:\"Paramètres\",instancesNotFound:\"Aucune instance trouvée\"},aae={delete:\"Supprimer\",deleting:\"Suppression...\",cancel:\"Annuler\",markAll:\"Marquer Tous\",unMarkAll:\"Démarquer Tous\"},iae={delete:{title:\"Supprimer l'Enregistrement\",message:\"Vous êtes en train de supprimer l'instance {{instanceName}}. Êtes-vous sûr de vouloir continuer ?\",messageSingle:\"Cette action est irréversible.\"}},lae={all:\"Tous\",open:\"Connecté\",connecting:\"Connexion\",closed:\"Déconnecté\"},cae={clientName:\"Nom du Client\",version:\"Version\"},uae={theme:{label:\"Changer de Thème\",light:\"Clair\",dark:\"Sombre\",system:\"Système\"},language:{label:\"Langue\",english:\"Anglais\",portuguese:\"Portugais\",french:\"Français\"}},dae={dashboard:\"Vue d'ensemble\",configurations:\"Configurations\",settings:\"Comportement\",proxy:\"Proxy\",events:\"Evenements\",webhook:\"Webhook\",websocket:\"WebSocket\",rabbitmq:\"RabbitMQ\",sqs:\"SQS\",integrations:\"Intégrations\",chatwoot:\"Chatwoot\",typebot:\"Typebot\",openai:\"OpenAI\",dify:\"Dify\",evoai:\"EvoAI\",n8n:\"n8n\",evolutionBot:\"Bot Evolution\",flowise:\"Flowise\",documentation:\"Documentation\",postman:\"Postman\",discord:\"Discord\",supportPremium:\"Support Premium\"},fae={instance:{created:\"Instance créée avec succès\",deleted:\"Instance supprimée avec succès\",error:\"Une erreur est survenue lors de la création de l'instance\"}},pae={title:\"Evolution Manager\",description:\"Veuillez vous connecter pour continuer\",form:{serverUrl:\"URL du Serveur\",apiKey:\"Clé API Globale\"},message:{invalidServer:\"Serveur invalide\",invalidCredentials:\"Identifiants invalides\"},button:{login:\"Se connecter\"}},hae={modal:{title:\"Nouvelle Instance\"},form:{name:\"Nom\",integration:{label:\"Canal\",baileys:\"Baileys\",whatsapp:\"WhatsApp Cloud API\",facebook:\"Facebook\",instagram:\"Instagram\",evolution:\"Evolution\"},token:\"Token\",number:\"Numéro\",businessId:\"ID de l'Entreprise\"},button:{save:\"Enregistrer\",saving:\"Enregistrement...\",create:\"Instance\",connecting:\"Connexion...\",facebook:\"Se connecter avec Facebook\",instagram:\"Se connecter avec Instagram\",whatsapp:\"Se connecter avec WhatsApp\"},dashboard:{button:{qrcode:{label:\"Générer un Code QR\",title:\"Scannez le Code QR avec WhatsApp\"},pairingCode:{label:\"Générer un Code d'Appairage\",title:\"Appairez avec WhatsApp\"},restart:\"Redémarrer\",disconnect:\"Déconnecter\"},alert:\"Pour vous connecter, scannez le Code QR avec WhatsApp\",contacts:\"Contacts\",chats:\"Chats\",messages:\"Messages\"}},gae={title:\"Comportement\",toast:{success:\"Comportement appliqué avec succès\",error:\"Une erreur est survenue lors de l'application du comportement\"},form:{rejectCall:{label:\"Rejeter les Appels\",description:\"Rejeter tous les appels\"},msgCall:{label:\"Message de Rejet d'Appel\",description:\"Envoyer un message de rejet d'appel\"},groupsIgnore:{label:\"Ignorer les Groupes\",description:\"Ignorer tous les messages de groupes\"},alwaysOnline:{label:\"Toujours En Ligne\",description:\"Rester toujours en ligne\"},readMessages:{label:\"Lire les Messages\",description:\"Marquer tous les messages comme lus\"},syncFullHistory:{label:\"Synchroniser l'Historique Complet\",description:\"Synchroniser l'historique complet lors de la lecture du Code QR\"},readStatus:{label:\"Lire le Statut\",description:\"Marquer tous les statuts comme vus\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},mae={title:\"Proxy\",toast:{success:\"Proxy appliqué avec succès\",error:\"Une erreur est survenue lors de l'application du proxy\"},form:{enabled:{label:\"Activé\",description:\"Activer ou désactiver le proxy\"},protocol:{label:\"Protocole\"},host:{label:\"Hôte\"},port:{label:\"Port\"},username:{label:\"Utilisateur\"},password:{label:\"Mot de passe\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},vae={title:\"Webhook\",toast:{success:\"Webhook appliqué avec succès\",error:\"Une erreur est survenue lors de l'application du webhook\"},form:{enabled:{label:\"Activé\",description:\"Activer ou désactiver le webhook\"},url:{label:\"URL\"},byEvents:{label:\"Webhook par Événements\",description:\"Créer une route pour chaque événement en ajoutant le nom de l'événement à la fin de l'URL\"},base64:{label:\"Webhook Base64\",description:\"Envoyer des données médias en base64 dans le webhook\"},events:{label:\"Événements\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},yae={title:\"WebSocket\",toast:{success:\"WebSocket appliqué avec succès\",error:\"Une erreur est survenue lors de l'application du WebSocket\"},form:{enabled:{label:\"Activé\",description:\"Activer ou désactiver le WebSocket\"},events:{label:\"Événements\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},bae={title:\"RabbitMQ\",toast:{success:\"RabbitMQ appliqué avec succès\",error:\"Une erreur est survenue lors de l'application de RabbitMQ\"},form:{enabled:{label:\"Activé\",description:\"Activer ou désactiver RabbitMQ\"},events:{label:\"Événements\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},xae={title:\"SQS\",toast:{success:\"SQS appliqué avec succès\",error:\"Une erreur est survenue lors de l'application de SQS\"},form:{enabled:{label:\"Activé\",description:\"Activer ou désactiver SQS\"},events:{label:\"Événements\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},wae={title:\"Chatwoot\",toast:{success:\"Chatwoot appliqué avec succès\",error:\"Une erreur est survenue lors de l'application de Chatwoot\"},form:{enabled:{label:\"Activé\",description:\"Activer ou désactiver Chatwoot\"},url:{label:\"URL de Chatwoot\"},accountId:{label:\"ID du Compte\"},token:{label:\"Token\"},signMsg:{label:\"Signer les Messages\",description:\"Signer les messages avec le nom d'utilisateur Chatwoot\"},signDelimiter:{label:\"Délimiteur de Signature\"},nameInbox:{label:\"Nom de la Boîte de Réception\"},organization:{label:\"Organisation\"},logo:{label:\"Logo\"},conversationPending:{label:\"Conversation en Attente\",description:\"Les conversations commencent en attente\"},reopenConversation:{label:\"Rouvrir la Conversation\",description:\"Rouvrir la conversation lors de la réception d'un message\"},importContacts:{label:\"Importer les Contacts\",description:\"Importer les contacts du carnet d'adresses WhatsApp en scannant le Code QR\"},importMessages:{label:\"Importer les Messages\",description:\"Importer les messages WhatsApp en scannant le Code QR\"},daysLimitImportMessages:{label:\"Limite de Jours pour l'Importation de Messages\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyez sur entrer\"},autoCreate:{label:\"Création Automatique\",description:\"Créer automatiquement l'intégration Chatwoot lors de l'enregistrement\"}},button:{save:\"Enregistrer\",saving:\"Enregistrement...\"}},Sae={title:\"Typebots\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nom d'Affichage\",sessionId:\"ID de Session\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par Défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur est survenue lors de l'application des paramètres par défaut\"},success:{update:\"Typebot mis à jour avec succès\",create:\"Typebot créé avec succès\",delete:\"Typebot supprimé avec succès\",status:\"Statut de Typebot mis à jour avec succès\"},error:\"Une erreur est survenue lors de la création du Typebot\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau Typebot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},typebotSettings:{label:\"Paramètres de Typebot\"},url:{label:\"URL de l'API de Typebot\"},typebot:{label:\"Nom Public de Typebot\"},triggerSettings:{label:\"Paramètres de Déclencheur\"},triggerType:{label:\"Type de Déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de Déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence Par\",endsWith:\"Se Termine Par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},typebotIdFallback:{label:\"Fallback de Typebot\"},generalSettings:{label:\"Paramètres Généraux\"},expire:{label:\"Expirer en minutes\"},keywordFinish:{label:\"Mot-clé de Fin\"},delayMessage:{label:\"Message de Délai par Défaut\"},unknownMessage:{label:\"Message Inconnu\"},listeningFromMe:{label:\"Écouter de Moi\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le Bot de Moi\",description:\"Mettre en pause le bot quand j'envoie un message\"},keepOpen:{label:\"Garder Ouvert\",description:\"Garder le bot ouvert après la fin de la conversation\"},debounceTime:{label:\"Temps de Déclenchement\"},splitMessages:{label:\"Diviser les Messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par Caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyez sur entrer\"}},button:{create:\"Typebot\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par Défaut\",delete:\"Supprimer\"},modal:{defaultSettings:{title:\"Paramètres par Défaut\"}}},Cae={title:\"OpenAI\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nom d'Affichage\",sessionId:\"ID de Session\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},credentials:{title:\"Identifiants\",table:{name:\"Nom\",apiKey:\"Clé API\",actions:{title:\"Actions\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par Défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur est survenue lors de l'application des paramètres par défaut\"},success:{update:\"OpenAI mis à jour avec succès\",create:\"OpenAI créé avec succès\",delete:\"OpenAI supprimé avec succès\",status:\"Statut de OpenAI mis à jour avec succès\",credentialsCreate:\"Identifiants OpenAI créés avec succès\",credentialsDelete:\"Identifiants OpenAI supprimés avec succès\"},error:\"Une erreur est survenue lors de la création de OpenAI\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau OpenAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},openaiCredsId:{label:\"Identifiants OpenAI\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},openaiSettings:{label:\"Paramètres OpenAI\"},botType:{label:\"Type de Bot\",assistant:\"Assistant\",chatCompletion:\"Chat Completion\"},assistantId:{label:\"ID de l'Assistant\"},functionUrl:{label:\"URL de la Fonction\"},model:{label:\"Modèle de Langage\"},systemMessages:{label:\"Messages Système\",description:\"Envoyer des messages système à OpenAI\"},assistantMessages:{label:\"Messages de l'Assistant\",description:\"Envoyer des messages de l'assistant à OpenAI\"},userMessages:{label:\"Messages de l'Utilisateur\",description:\"Envoyer des messages de l'utilisateur à OpenAI\"},maxTokens:{label:\"Nombre Maximum de Tokens\"},triggerSettings:{label:\"Paramètres de Déclencheur\"},triggerType:{label:\"Type de Déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de Déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence Par\",endsWith:\"Se Termine Par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},openaiIdFallback:{label:\"Fallback de OpenAI\"},generalSettings:{label:\"Paramètres Généraux\"},expire:{label:\"Expirer en minutes\"},keywordFinish:{label:\"Mot-clé de Fin\"},delayMessage:{label:\"Message de Délai par Défaut\"},unknownMessage:{label:\"Message Inconnu\"},listeningFromMe:{label:\"Écouter de Moi\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le Bot de Moi\",description:\"Mettre en pause le bot quand j'envoie un message\"},keepOpen:{label:\"Garder Ouvert\",description:\"Garder le bot ouvert après la fin de la conversation\"},speechToText:{label:\"Parole en Texte\",description:\"Convertir les messages vocaux en texte\"},debounceTime:{label:\"Temps de Déclenchement\"},splitMessages:{label:\"Diviser les Messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par Caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyez sur entrer\"}},button:{create:\"OpenAI\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par Défaut\",delete:\"Supprimer\",loadModels:\"Charger les Modèles\",loading:\"Chargement...\"},modal:{defaultSettings:{title:\"Paramètres par Défaut\"}}},Eae={title:\"Dify\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nom d'Affichage\",sessionId:\"ID de Session\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par Défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur est survenue lors de l'application des paramètres par défaut\"},success:{update:\"Dify mis à jour avec succès\",create:\"Dify créé avec succès\",delete:\"Dify supprimé avec succès\",status:\"Statut de Dify mis à jour avec succès\"},error:\"Une erreur est survenue lors de la création de Dify\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau Dify\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},difySettings:{label:\"Paramètres de Dify\"},botType:{label:\"Type de Bot\",chatBot:\"Chat Bot\",textGenerator:\"Générateur de Texte\",agent:\"Agent\",workflow:\"Flux de Travail\"},apiUrl:{label:\"URL de l'API\"},apiKey:{label:\"Clé API\"},triggerSettings:{label:\"Paramètres de Déclencheur\"},triggerType:{label:\"Type de Déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de Déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence Par\",endsWith:\"Se Termine Par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},difyIdFallback:{label:\"Fallback de Dify\"},generalSettings:{label:\"Paramètres Généraux\"},expire:{label:\"Expirer en minutes\"},keywordFinish:{label:\"Mot-clé de Fin\"},delayMessage:{label:\"Message de Délai par Défaut\"},unknownMessage:{label:\"Message Inconnu\"},listeningFromMe:{label:\"Écouter de Moi\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le Bot de Moi\",description:\"Mettre en pause le bot quand j'envoie un message\"},keepOpen:{label:\"Garder Ouvert\",description:\"Garder le bot ouvert après la fin de la conversation\"},debounceTime:{label:\"Temps de Déclenchement\"},splitMessages:{label:\"Diviser les Messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par Caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyez sur entrer\"}},button:{create:\"Dify\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par Défaut\",delete:\"Supprimer\"},modal:{defaultSettings:{title:\"Paramètres par Défaut\"}}},kae={title:\"n8n\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur s'est produite lors de l'application des paramètres par défaut\"},success:{update:\"n8n mis à jour avec succès\",create:\"n8n créé avec succès\",delete:\"n8n supprimé avec succès\",status:\"Statut de n8n mis à jour avec succès\"},error:\"Une erreur s'est produite lors de la création du chatbot n8n\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau chatbot n8n\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},n8nSettings:{label:\"Paramètres n8n\"},webhookUrl:{label:\"URL du Webhook\"},basicAuth:{label:\"Basic Auth (Optionnel)\"},basicAuthUser:{label:\"Basic Auth User\"},basicAuthPass:{label:\"Basic Auth Password\"},triggerSettings:{label:\"Paramètres du déclencheur\"},triggerType:{label:\"Type de déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence par\",endsWith:\"Se termine par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},n8nIdFallback:{label:\"Fallback n8n\"},generalSettings:{label:\"Paramètres généraux\"},expire:{label:\"Expire en minutes\"},keywordFinish:{label:\"Mot-clé de fin\"},delayMessage:{label:\"Message de délai par défaut\"},unknownMessage:{label:\"Message inconnu\"},listeningFromMe:{label:\"Écouter mes messages\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le bot de ma part\",description:\"Mettre en pause le bot lorsque j'envoie un message\"},keepOpen:{label:\"Maintenir ouvert\",description:\"Maintenir le bot ouvert après la fin de la conversation\"},debounceTime:{label:\"Temps de debounce\"},splitMessages:{label:\"Diviser les messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyer sur entrée\"}},button:{create:\"n8n\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par défaut\",delete:\"Supprimer\"},modal:{defaultSettings:{title:\"Paramètres par défaut\"}}},jae={title:\"EvoAI\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur s'est produite lors de l'application des paramètres par défaut\"},success:{update:\"EvoAI mis à jour avec succès\",create:\"EvoAI créé avec succès\",delete:\"EvoAI supprimé avec succès\",status:\"Statut de EvoAI mis à jour avec succès\"},error:\"Une erreur s'est produite lors de la création du chatbot EvoAI\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau chatbot EvoAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},evoaiSettings:{label:\"Paramètres EvoAI\"},agentUrl:{label:\"URL de l'agent\"},apiKey:{label:\"API Key (Optionnel)\"},triggerSettings:{label:\"Paramètres du déclencheur\"},triggerType:{label:\"Type de déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence par\",endsWith:\"Se termine par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},evoaiIdFallback:{label:\"Fallback EvoAI\"},generalSettings:{label:\"Paramètres généraux\"},expire:{label:\"Expire en minutes\"},keywordFinish:{label:\"Mot-clé de fin\"},delayMessage:{label:\"Message de délai par défaut\"},unknownMessage:{label:\"Message inconnu\"},listeningFromMe:{label:\"Écouter mes messages\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le bot de ma part\",description:\"Mettre en pause le bot lorsque j'envoie un message\"},keepOpen:{label:\"Maintenir ouvert\",description:\"Maintenir le bot ouvert après la fin de la conversation\"},debounceTime:{label:\"Temps de debounce\"},splitMessages:{label:\"Diviser les messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyer sur entrée\"}},button:{create:\"EvoAI\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par défaut\",delete:\"Supprimer\"},modal:{defaultSettings:{title:\"Paramètres par défaut\"}}},Tae={title:\"Bots Evolution\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nom d'Affichage\",sessionId:\"ID de Session\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par Défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur est survenue lors de l'application des paramètres par défaut\"},success:{update:\"Bots Evolution mis à jour avec succès\",create:\"Bots Evolution créé avec succès\",delete:\"Bots Evolution supprimé avec succès\",status:\"Statut de Bots Evolution mis à jour avec succès\"},error:\"Une erreur est survenue lors de la création de Bots Evolution\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau Bots Evolution\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},evolutionBotSettings:{label:\"Paramètres de Bots Evolution\"},apiUrl:{label:\"URL de l'API\"},apiKey:{label:\"Clé API\"},triggerSettings:{label:\"Paramètres de Déclencheur\"},triggerType:{label:\"Type de Déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de Déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence Par\",endsWith:\"Se Termine Par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},botIdFallback:{label:\"Fallback de Bots Evolution\"},generalSettings:{label:\"Paramètres Généraux\"},expire:{label:\"Expirer en minutes\"},keywordFinish:{label:\"Mot-clé de Fin\"},delayMessage:{label:\"Message de Délai par Défaut\"},unknownMessage:{label:\"Message Inconnu\"},listeningFromMe:{label:\"Écouter de Moi\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le Bot de Moi\",description:\"Mettre en pause le bot quand j'envoie un message\"},keepOpen:{label:\"Garder Ouvert\",description:\"Garder le bot ouvert après la fin de la conversation\"},debounceTime:{label:\"Temps de Déclenchement\"},splitMessages:{label:\"Diviser les Messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par Caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyez sur entrer\"}},button:{create:\"Bots Evolution\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par Défaut\",delete:\"Supprimer\"},modal:{defaultSettings:{title:\"Paramètres par Défaut\"}}},Nae={title:\"Flowise\",sessions:{label:\"Sessions\",search:\"Rechercher par remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nom d'Affichage\",sessionId:\"ID de Session\",status:\"Statut\",actions:{title:\"Actions\",open:\"Ouvrir\",pause:\"Pause\",close:\"Fermer\",delete:\"Supprimer\"},none:\"Rien à afficher\"}},defaultSettings:\"Paramètres par Défaut\",toast:{defaultSettings:{success:\"Paramètres par défaut appliqués avec succès\",error:\"Une erreur est survenue lors de l'application des paramètres par défaut\"},success:{update:\"Flowise mis à jour avec succès\",create:\"Flowise créé avec succès\",delete:\"Flowise supprimé avec succès\",status:\"Statut de Flowise mis à jour avec succès\"},error:\"Une erreur est survenue lors de la création de Flowise\"},table:{none:\"Rien à afficher\"},form:{title:\"Nouveau Flowise\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Désolé, je n'ai pas compris. Pouvez-vous réessayer ?\"},enabled:{label:\"Activé\"},description:{label:\"Description\"},flowiseSettings:{label:\"Paramètres de Flowise\"},apiUrl:{label:\"URL de l'API\"},apiKey:{label:\"Clé API\"},triggerSettings:{label:\"Paramètres de Déclencheur\"},triggerType:{label:\"Type de Déclencheur\",keyword:\"Mot-clé\",all:\"Tous\",advanced:\"Avancé\",none:\"Aucun\"},triggerOperator:{label:\"Opérateur de Déclencheur\",contains:\"Contient\",equals:\"Égal\",startsWith:\"Commence Par\",endsWith:\"Se Termine Par\",regex:\"Regex\"},triggerValue:{label:\"Déclencheur\"},triggerConditions:{label:\"Conditions\"},flowiseIdFallback:{label:\"Fallback de Flowise\"},generalSettings:{label:\"Paramètres Généraux\"},expire:{label:\"Expirer en minutes\"},keywordFinish:{label:\"Mot-clé de Fin\"},delayMessage:{label:\"Message de Délai par Défaut\"},unknownMessage:{label:\"Message Inconnu\"},listeningFromMe:{label:\"Écouter de Moi\",description:\"Écouter les messages envoyés par moi sur le bot\"},stopBotFromMe:{label:\"Arrêter le Bot de Moi\",description:\"Mettre en pause le bot quand j'envoie un message\"},keepOpen:{label:\"Garder Ouvert\",description:\"Garder le bot ouvert après la fin de la conversation\"},debounceTime:{label:\"Temps de Déclenchement\"},splitMessages:{label:\"Diviser les Messages\",description:\"Diviser les messages en plusieurs messages\"},timePerChar:{label:\"Temps par Caractère\"},ignoreJids:{label:\"Ignorer les JIDs\",placeholder:\"Ajouter des JIDs ex: 1234567890@s.whatsapp.net et appuyez sur entrer\"}},button:{create:\"Flowise\",save:\"Enregistrer\",saving:\"Enregistrement...\",update:\"Mettre à jour\",defaultSettings:\"Paramètres par Défaut\",delete:\"Supprimer\"},modal:{defaultSettings:{title:\"Paramètres par Défaut\"}}},Mae={dashboard:oae,button:aae,modal:iae,status:lae,footer:cae,header:uae,sidebar:dae,toast:fae,login:pae,instance:hae,settings:gae,proxy:mae,webhook:vae,websocket:yae,rabbitmq:bae,sqs:xae,chatwoot:wae,typebot:Sae,openai:Cae,dify:Eae,n8n:kae,evoai:jae,evolutionBot:Tae,flowise:Nae},_ae={title:\"Instâncias\",search:\"Pesquisar\",status:\"Status\",settings:\"Configurações\",instancesNotFound:\"Nenhuma instância encontrada\"},Rae={delete:\"Excluir\",deleting:\"Excluindo...\",cancel:\"Cancelar\",markAll:\"Marcar Todos\",unMarkAll:\"Desmarcar Todos\"},Pae={delete:{title:\"Excluir Registro\",message:\"Você está excluindo a instância {{instanceName}}. Tem certeza que deseja continuar?\",messageSingle:\"Esta ação não pode ser desfeita.\"}},Oae={all:\"Todos\",open:\"Conectado\",connecting:\"Conectando\",closed:\"Desconectado\"},Iae={clientName:\"Nome do Cliente\",version:\"Versão\"},Aae={theme:{label:\"Mudar Tema\",light:\"Claro\",dark:\"Escuro\",system:\"Sistema\"},language:{label:\"Idioma\",english:\"Inglês\",portuguese:\"Português\",spanish:\"Espanhol\",french:\"Francês\"}},Dae={dashboard:\"Visão Geral\",configurations:\"Configurações\",settings:\"Comportamento\",proxy:\"Proxy\",events:\"Eventos\",webhook:\"Webhook\",websocket:\"WebSocket\",rabbitmq:\"RabbitMQ\",sqs:\"SQS\",integrations:\"Integrações\",chatwoot:\"Chatwoot\",typebot:\"Typebot\",openai:\"OpenAI\",dify:\"Dify\",evoai:\"EvoAI\",n8n:\"n8n\",evolutionBot:\"Bot Evolution\",flowise:\"Flowise\",documentation:\"Documentação\",postman:\"Postman\",discord:\"Discord\",supportPremium:\"Suporte Premium\"},Fae={instance:{created:\"Instância criada com sucesso\",deleted:\"Instância excluída com sucesso\",error:\"Ocorreu um erro ao criar a instância\"}},Lae={title:\"Evolution Manager\",description:\"Por favor, faça login para continuar\",form:{serverUrl:\"URL do Servidor\",apiKey:\"Chave de API Global\"},message:{invalidServer:\"Servidor inválido\",invalidCredentials:\"Credenciais inválidas\"},button:{login:\"Conectar\"}},$ae={modal:{title:\"Nova Instância\"},form:{name:\"Nome\",integration:{label:\"Canal\",baileys:\"Baileys\",whatsapp:\"WhatsApp Cloud API\",facebook:\"Facebook\",instagram:\"Instagram\",evolution:\"Evolution\"},token:\"Token\",number:\"Número\",businessId:\"Business ID\"},button:{save:\"Salvar\",saving:\"Salvando...\",create:\"Instância\",connecting:\"Conectando...\",facebook:\"Conectar com Facebook\",instagram:\"Conectar com Instagram\",whatsapp:\"Conectar com WhatsApp\"},dashboard:{button:{qrcode:{label:\"Gerar QR Code\",title:\"Scaneie o QR Code com o WhatsApp\"},pairingCode:{label:\"Gerar Código de Pareamento\",title:\"Faça o pareamento com o WhatsApp\"},restart:\"Reiniciar\",disconnect:\"Desconectar\"},alert:\"Para conectar, escaneie o QR Code com o WhatsApp\",contacts:\"Contatos\",chats:\"Chats\",messages:\"Mensagens\"}},Bae={title:\"Comportamento\",toast:{success:\"Comportamento aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o comportamento\"},form:{rejectCall:{label:\"Rejeitar Chamadas\",description:\"Rejeitar todas as chamadas\"},msgCall:{label:\"Mensagem de Rejeição de Chamada\",description:\"Enviar mensagem de rejeição de chamada\"},groupsIgnore:{label:\"Ignorar Grupos\",description:\"Ignorar todas as mensagens de grupos\"},alwaysOnline:{label:\"Sempre Online\",description:\"Permanecer sempre online\"},readMessages:{label:\"Visualizar Mensagens\",description:\"Marcar todas as mensagens como lidas\"},syncFullHistory:{label:\"Sincronizar Histórico Completo\",description:\"Sincronizar o histórico completo ao ler o QR Code\"},readStatus:{label:\"Visualizar Status\",description:\"Marcar todos os status como visualizados\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},zae={title:\"Proxy\",toast:{success:\"Proxy aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o proxy\"},form:{enabled:{label:\"Ativo\",description:\"Ativar ou desativar o proxy\"},protocol:{label:\"Protocolo\"},host:{label:\"Host\"},port:{label:\"Porta\"},username:{label:\"Usuário\"},password:{label:\"Senha\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},Uae={title:\"Webhook\",toast:{success:\"Webhook aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o webhook\"},form:{enabled:{label:\"Ativo\",description:\"Ativar ou desativar o webhook\"},url:{label:\"URL\"},byEvents:{label:\"Webhook por Eventos\",description:\"Criar uma rota para cada evento adicionando o nome do evento ao final da URL\"},base64:{label:\"Webhook Base64\",description:\"Enviar dados de mídia em base64 no webhook\"},events:{label:\"Eventos\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},Vae={title:\"WebSocket\",toast:{success:\"WebSocket aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o WebSocket\"},form:{enabled:{label:\"Ativo\",description:\"Ativar ou desativar o WebSocket\"},events:{label:\"Eventos\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},Hae={title:\"RabbitMQ\",toast:{success:\"RabbitMQ aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o RabbitMQ\"},form:{enabled:{label:\"Ativo\",description:\"Ativar ou desativar o RabbitMQ\"},events:{label:\"Eventos\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},qae={title:\"SQS\",toast:{success:\"SQS aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o SQS\"},form:{enabled:{label:\"Ativo\",description:\"Ativar ou desativar o SQS\"},events:{label:\"Eventos\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},Kae={title:\"Chatwoot\",toast:{success:\"Chatwoot aplicado com sucesso\",error:\"Ocorreu um erro ao aplicar o Chatwoot\"},form:{enabled:{label:\"Ativo\",description:\"Ativar ou desativar o Chatwoot\"},url:{label:\"URL do Chatwoot\"},accountId:{label:\"ID da Conta\"},token:{label:\"Token\"},signMsg:{label:\"Assinar Mensagens\",description:\"Assinar mensagem com o nome de usuário do Chatwoot\"},signDelimiter:{label:\"Delimitador de Assinatura\"},nameInbox:{label:\"Nome da Caixa de Entrada\"},organization:{label:\"Organização\"},logo:{label:\"Logo\"},conversationPending:{label:\"Conversação Pendente\",description:\"Conversas começam como pendentes\"},reopenConversation:{label:\"Reabrir Conversa\",description:\"Reabrir a conversa ao receber uma mensagem\"},importContacts:{label:\"Importar Contatos\",description:\"Importar contatos da agenda do WhatsApp ao conectar o QR Code\"},importMessages:{label:\"Importar Mensagens\",description:\"Importar mensagens do WhatsApp ao conectar o QR Code\"},daysLimitImportMessages:{label:\"Limite de Dias para Importação de Mensagens\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicione JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"},autoCreate:{label:\"Criação Automática\",description:\"Criar automaticamente a integração com o Chatwoot ao salvar\"}},button:{save:\"Salvar\",saving:\"Salvando...\"}},Wae={title:\"Typebots\",sessions:{label:\"Sessões\",search:\"Pesquisar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nome de Exibição\",sessionId:\"ID da Sessão\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"Typebot atualizado com sucesso\",create:\"Typebot criado com sucesso\",delete:\"Typebot excluído com sucesso\",status:\"Status do Typebot atualizado com sucesso\"},error:\"Ocorreu um erro ao criar o Typebot\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo Typebot\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},enabled:{label:\"Ativo\"},description:{label:\"Descrição\"},typebotSettings:{label:\"Configurações do Typebot\"},url:{label:\"URL da API do Typebot\"},typebot:{label:\"Nome Público do Typebot\"},triggerSettings:{label:\"Configurações de Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},typebotIdFallback:{label:\"Fallback do Typebot\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvindo de mim\",description:\"Ouvir as mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot por mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o término da conversa\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens longas em várias mensagens\"},timePerChar:{label:\"Tempo por Caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicione JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"Typebot\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},Gae={title:\"OpenAI\",sessions:{label:\"Sessões\",search:\"Pesquisar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nome de Exibição\",sessionId:\"ID da Sessão\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},credentials:{title:\"Credenciais\",table:{name:\"Nome\",apiKey:\"Chave de API\",actions:{title:\"Ações\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"OpenAI atualizado com sucesso\",create:\"OpenAI criado com sucesso\",delete:\"OpenAI excluído com sucesso\",status:\"Status do OpenAI atualizado com sucesso\",credentialsCreate:\"Credenciais do OpenAI criadas com sucesso\",credentialsDelete:\"Credenciais do OpenAI excluídas com sucesso\"},error:\"Ocorreu um erro ao criar o OpenAI\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo OpenAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},openaiCredsId:{label:\"Credenciais do OpenAI\"},enabled:{label:\"Ativo\"},description:{label:\"Descrição\"},openaiSettings:{label:\"Configurações do OpenAI\"},botType:{label:\"Tipo de Bot\",assistant:\"Assistente\",chatCompletion:\"Chat Completion\"},assistantId:{label:\"ID do Assistente\"},functionUrl:{label:\"URL da Função\"},model:{label:\"Modelo de Linguagem\"},systemMessages:{label:\"Mensagens do Sistema\",description:\"Enviar mensagens do sistema para o OpenAI\"},assistantMessages:{label:\"Mensagens do Assistente\",description:\"Enviar mensagens do assistente para o OpenAI\"},userMessages:{label:\"Mensagens do Usuário\",description:\"Enviar mensagens do usuário para o OpenAI\"},maxTokens:{label:\"Máximo de Tokens\"},triggerSettings:{label:\"Configurações de Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},openaiIdFallback:{label:\"Fallback do OpenAI\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvindo de mim\",description:\"Ouvir as mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot por mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o término da conversa\"},speechToText:{label:\"Fala para Texto\",description:\"Converter mensagens de voz em texto\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens longas em várias mensagens\"},timePerChar:{label:\"Tempo por Caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicione JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"OpenAI\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\",loadModels:\"Carregar Modelos\",loading:\"Carregando...\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},Jae={title:\"Dify\",sessions:{label:\"Sessões\",search:\"Pesquisar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nome de Exibição\",sessionId:\"ID da Sessão\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"Dify atualizado com sucesso\",create:\"Dify criado com sucesso\",delete:\"Dify excluído com sucesso\",status:\"Status do Dify atualizado com sucesso\"},error:\"Ocorreu um erro ao criar o Dify\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo Dify\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},enabled:{label:\"Ativo\"},description:{label:\"Descrição\"},difySettings:{label:\"Configurações do Dify\"},botType:{label:\"Tipo de Bot\",chatBot:\"Bot de Chat\",textGenerator:\"Gerador de Texto\",agent:\"Agente\",workflow:\"Fluxo de Trabalho\"},apiUrl:{label:\"URL da API\"},apiKey:{label:\"Chave de API\"},triggerSettings:{label:\"Configurações de Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},difyIdFallback:{label:\"Fallback do Dify\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvindo de mim\",description:\"Ouvir as mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot por mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o término da conversa\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens longas em várias mensagens\"},timePerChar:{label:\"Tempo por Caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicione JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"Dify\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},Qae={title:\"n8n\",sessions:{label:\"Sessões\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"n8n atualizado com sucesso\",create:\"n8n criado com sucesso\",delete:\"n8n excluído com sucesso\",status:\"Status do n8n atualizado com sucesso\"},error:\"Ocorreu um erro ao criar o chatbot n8n\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo chatbot n8n\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},enabled:{label:\"Ativado\"},description:{label:\"Descrição\"},n8nSettings:{label:\"Configurações do n8n\"},webhookUrl:{label:\"URL do Webhook\"},basicAuth:{label:\"Basic Auth (Opcional)\"},basicAuthUser:{label:\"Basic Auth User\"},basicAuthPass:{label:\"Basic Auth Password\"},triggerSettings:{label:\"Configurações do Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},n8nIdFallback:{label:\"Fallback do n8n\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvir de mim\",description:\"Ouvir mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot de mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o fim da conversa\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens em múltiplas mensagens\"},timePerChar:{label:\"Tempo por caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicionar JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"n8n\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},Zae={title:\"EvoAI\",sessions:{label:\"Sessões\",search:\"Buscar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Push Name\",sessionId:\"Session ID\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"EvoAI atualizado com sucesso\",create:\"EvoAI criado com sucesso\",delete:\"EvoAI excluído com sucesso\",status:\"Status do EvoAI atualizado com sucesso\"},error:\"Ocorreu um erro ao criar o chatbot EvoAI\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo chatbot EvoAI\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},enabled:{label:\"Ativado\"},description:{label:\"Descrição\"},evoaiSettings:{label:\"Configurações do EvoAI\"},agentUrl:{label:\"URL do Agente\"},apiKey:{label:\"API Key (Opcional)\"},triggerSettings:{label:\"Configurações do Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},evoaiIdFallback:{label:\"Fallback do EvoAI\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvir de mim\",description:\"Ouvir mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot de mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o fim da conversa\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens em múltiplas mensagens\"},timePerChar:{label:\"Tempo por caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicionar JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"EvoAI\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},Yae={title:\"Bot Evolution\",sessions:{label:\"Sessões\",search:\"Pesquisar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nome de Exibição\",sessionId:\"ID da Sessão\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"Bot Evolution atualizado com sucesso\",create:\"Bot Evolution criado com sucesso\",delete:\"Bot Evolution excluído com sucesso\",status:\"Status do Bot Evolution atualizado com sucesso\"},error:\"Ocorreu um erro ao criar o Bot Evolution\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo Bot Evolution\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},enabled:{label:\"Ativo\"},description:{label:\"Descrição\"},evolutionBotSettings:{label:\"Configurações do Bot Evolution\"},apiUrl:{label:\"URL da API\"},apiKey:{label:\"Chave de API\"},triggerSettings:{label:\"Configurações de Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},botIdFallback:{label:\"Fallback do Bot Evolution\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvindo de mim\",description:\"Ouvir as mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot por mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o término da conversa\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens longas em várias mensagens\"},timePerChar:{label:\"Tempo por Caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicione JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"Bot Evolution\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},Xae={title:\"Flowise\",sessions:{label:\"Sessões\",search:\"Pesquisar por remoteJid...\",table:{remoteJid:\"RemoteJid\",pushName:\"Nome de Exibição\",sessionId:\"ID da Sessão\",status:\"Status\",actions:{title:\"Ações\",open:\"Abrir\",pause:\"Pausar\",close:\"Fechar\",delete:\"Excluir\"},none:\"Nada para mostrar\"}},defaultSettings:\"Configurações Padrão\",toast:{defaultSettings:{success:\"Configurações padrão aplicadas com sucesso\",error:\"Ocorreu um erro ao aplicar as configurações padrão\"},success:{update:\"Flowise atualizado com sucesso\",create:\"Flowise criado com sucesso\",delete:\"Flowise excluído com sucesso\",status:\"Status do Flowise atualizado com sucesso\"},error:\"Ocorreu um erro ao criar o Flowise\"},table:{none:\"Nada para mostrar\"},form:{title:\"Novo Flowise\",examples:{keywordFinish:\"#FINISH\",unknownMessage:\"Desculpe, não entendi. Pode tentar novamente?\"},enabled:{label:\"Ativo\"},description:{label:\"Descrição\"},flowiseSettings:{label:\"Configurações do Flowise\"},apiUrl:{label:\"URL da API\"},apiKey:{label:\"Chave de API\"},triggerSettings:{label:\"Configurações de Gatilho\"},triggerType:{label:\"Tipo de Gatilho\",keyword:\"Palavra-chave\",all:\"Todos\",advanced:\"Avançado\",none:\"Nenhum\"},triggerOperator:{label:\"Operador do Gatilho\",contains:\"Contém\",equals:\"Igual\",startsWith:\"Começa Com\",endsWith:\"Termina Com\",regex:\"Regex\"},triggerValue:{label:\"Gatilho\"},triggerConditions:{label:\"Condições\"},flowiseIdFallback:{label:\"Fallback do Flowise\"},generalSettings:{label:\"Configurações Gerais\"},expire:{label:\"Expirar em minutos\"},keywordFinish:{label:\"Palavra-chave de Finalização\"},delayMessage:{label:\"Mensagem de Atraso Padrão\"},unknownMessage:{label:\"Mensagem Desconhecida\"},listeningFromMe:{label:\"Ouvindo de mim\",description:\"Ouvir as mensagens enviadas por mim no bot\"},stopBotFromMe:{label:\"Parar bot por mim\",description:\"Pausar o bot quando eu enviar uma mensagem\"},keepOpen:{label:\"Manter aberto\",description:\"Manter o bot aberto após o término da conversa\"},debounceTime:{label:\"Tempo de Debounce\"},splitMessages:{label:\"Dividir Mensagens\",description:\"Dividir mensagens longas em várias mensagens\"},timePerChar:{label:\"Tempo por Caractere\"},ignoreJids:{label:\"Ignorar JIDs\",placeholder:\"Adicione JIDs ex: 1234567890@s.whatsapp.net e pressione enter\"}},button:{create:\"Flowise\",save:\"Salvar\",saving:\"Salvando...\",update:\"Atualizar\",defaultSettings:\"Configurações Padrão\",delete:\"Excluir\"},modal:{defaultSettings:{title:\"Configurações Padrão\"}}},eie={dashboard:_ae,button:Rae,modal:Pae,status:Oae,footer:Iae,header:Aae,sidebar:Dae,toast:Fae,login:Lae,instance:$ae,settings:Bae,proxy:zae,webhook:Uae,websocket:Vae,rabbitmq:Hae,sqs:qae,chatwoot:Kae,typebot:Wae,openai:Gae,dify:Jae,n8n:Qae,evoai:Zae,evolutionBot:Yae,flowise:Xae};Jn.use(TF).init({resources:{\"en-US\":{translation:Ooe},\"pt-BR\":{translation:eie},\"es-ES\":{translation:sae},\"fr-FR\":{translation:Mae}},lng:localStorage.getItem(\"i18nextLng\")||\"en-US\",fallbackLng:\"en-US\",interpolation:{escapeValue:!1}});gF.createRoot(document.getElementById(\"root\")).render(i.jsxs(qe.StrictMode,{children:[i.jsx(RF,{i18n:Jn,children:i.jsx(kL,{defaultTheme:\"dark\",storageKey:\"vite-ui-theme\",children:i.jsx(Yk,{client:_j,children:i.jsx(aL,{router:Lse})})})}),i.jsx(CL,{theme:\"colored\"})]}))});export default tie();\n"
  },
  {
    "path": "manager/dist/assets/index-DsIrum0U.css",
    "content": "@import\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap\";*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: \"\"}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol,\"Noto Color Emoji\";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}:root{--gradient: #093028;--background: 178 98.4% 98.22%;--foreground: 178 6.800000000000001% .44%;--muted: 178 6.800000000000001% 91.1%;--muted-foreground: 178 3.4000000000000004% 41.1%;--popover: 178 35.599999999999994% 91.1%;--popover-foreground: 178 6.800000000000001% .55%;--card: 178 35.599999999999994% 91.1%;--card-foreground: 178 6.800000000000001% .55%;--border: 178 11.8% 89.44%;--input: 178 11.8% 89.44%;--primary: 178 68% 11%;--primary-foreground: 178 1.36% 91.1%;--secondary: 178 3.4000000000000004% 95.55%;--secondary-foreground: 178 5.08% 11.1%;--accent: 178 3.4000000000000004% 95.55%;--accent-foreground: 178 5.08% 11.1%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 0 0% 98%;--ring: 178 68% 11%;--radius: .5rem}.dark{--gradient: #189d68;--background: 166 47.449999999999996% 2.88%;--foreground: 166 7.3% 96.8%;--muted: 166 36.5% 10.799999999999999%;--muted-foreground: 166 7.3% 53.6%;--popover: 166 50.4% 4.68%;--popover-foreground: 166 7.3% 96.8%;--card: 166 50.4% 4.68%;--card-foreground: 166 7.3% 96.8%;--border: 166 36.5% 10.799999999999999%;--input: 166 36.5% 10.799999999999999%;--primary: 166 73% 36%;--primary-foreground: 166 7.3% 96.8%;--secondary: 166 36.5% 10.799999999999999%;--secondary-foreground: 166 7.3% 96.8%;--accent: 166 36.5% 10.799999999999999%;--accent-foreground: 166 7.3% 96.8%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 166 7.3% 96.8%;--ring: 166 73% 36%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-family:Inter,sans-serif;scrollbar-width:thin;scrollbar-color:transparent transparent}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%;margin-right:auto;margin-left:auto;padding-right:2rem;padding-left:2rem}@media (min-width: 1400px){.container{max-width:1400px}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.-bottom-4{bottom:-1rem}.bottom-0{bottom:0}.left-0{left:0}.left-2{left:.5rem}.right-0{right:0}.right-4{right:1rem}.top-0{top:0}.top-4{top:1rem}.z-10{z-index:10}.z-50{z-index:50}.-m-2{margin:-.5rem}.m-4{margin:1rem}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0\\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-6{margin-left:1.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-16{margin-right:4rem}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-auto{margin-top:auto}.box-border{box-sizing:border-box}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\\.5{height:.625rem}.h-24{height:6rem}.h-3\\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\\[1\\.2rem\\]{height:1.2rem}.h-\\[1px\\]{height:1px}.h-\\[calc\\(100vh-160px\\)\\]{height:calc(100vh - 160px)}.h-\\[var\\(--radix-select-trigger-height\\)\\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-96{max-height:24rem}.max-h-\\[200px\\]{max-height:200px}.max-h-\\[300px\\]{max-height:300px}.min-h-0{min-height:0px}.min-h-\\[80px\\]{min-height:80px}.min-h-\\[calc\\(100vh_-_56px\\)\\]{min-height:calc(100vh - 56px)}.min-h-screen{min-height:100vh}.w-0{width:0px}.w-1{width:.25rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-2{width:.5rem}.w-2\\.5{width:.625rem}.w-3{width:.75rem}.w-3\\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-80{width:20rem}.w-\\[1\\.2rem\\]{width:1.2rem}.w-\\[1px\\]{width:1px}.w-\\[300px\\]{width:300px}.w-\\[350px\\]{width:350px}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0px}.min-w-\\[280px\\]{min-width:280px}.min-w-\\[80px\\]{min-width:80px}.min-w-\\[8rem\\]{min-width:8rem}.min-w-\\[var\\(--radix-select-trigger-width\\)\\]{min-width:var(--radix-select-trigger-width)}.max-w-2xl{max-width:42rem}.max-w-32{max-width:8rem}.max-w-40{max-width:10rem}.max-w-4xl{max-width:56rem}.max-w-\\[300px\\]{max-width:300px}.max-w-\\[320px\\]{max-width:320px}.max-w-\\[60\\%\\]{max-width:60%}.max-w-\\[64rem\\]{max-width:64rem}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.translate-y-1{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-0{--tw-rotate: 0deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-0{--tw-scale-x: 0;--tw-scale-y: 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.grid-cols-\\[repeat\\(auto-fit\\,_minmax\\(15rem\\,_1fr\\)\\)\\]{grid-template-columns:repeat(auto-fit,minmax(15rem,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.75rem * var(--tw-space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse: 0;border-right-width:calc(1px * var(--tw-divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.self-end{align-self:flex-end}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.overflow-ellipsis,.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-3xl{border-radius:1.5rem}.rounded-\\[16px\\]{border-radius:16px}.rounded-\\[2px\\]{border-radius:2px}.rounded-\\[inherit\\]{border-radius:inherit}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-none{border-radius:0}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:.75rem}.rounded-l-lg{border-top-left-radius:var(--radius);border-bottom-left-radius:var(--radius)}.border{border-width:1px}.border-2{border-width:2px}.border-\\[1\\.5px\\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-\\[--color-border\\]{border-color:var(--color-border)}.border-amber-500\\/20{border-color:#f59e0b33}.border-black{--tw-border-opacity: 1;border-color:rgb(0 0 0 / var(--tw-border-opacity))}.border-black\\/10{border-color:#0000001a}.border-border{border-color:hsl(var(--border))}.border-border\\/50{border-color:hsl(var(--border) / .5)}.border-emerald-500\\/20{border-color:#10b98133}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity))}.border-gray-600\\/50{border-color:#4b556380}.border-input{border-color:hsl(var(--input))}.border-muted{border-color:hsl(var(--muted))}.border-red-500\\/20{border-color:#ef444433}.border-sky-500\\/20{border-color:#0ea5e933}.border-slate-600{--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity))}.border-transparent{border-color:transparent}.border-zinc-500\\/20{border-color:#71717a33}.border-l-transparent{border-left-color:transparent}.border-t-transparent{border-top-color:transparent}.bg-\\[\\#b2ece0\\]{--tw-bg-opacity: 1;background-color:rgb(178 236 224 / var(--tw-bg-opacity))}.bg-\\[\\#c8fff2\\]{--tw-bg-opacity: 1;background-color:rgb(200 255 242 / var(--tw-bg-opacity))}.bg-\\[\\#d2e2e2\\]{--tw-bg-opacity: 1;background-color:rgb(210 226 226 / var(--tw-bg-opacity))}.bg-\\[\\#e0f0f0\\]{--tw-bg-opacity: 1;background-color:rgb(224 240 240 / var(--tw-bg-opacity))}.bg-\\[--color-bg\\]{background-color:var(--color-bg)}.bg-amber-50\\/50{background-color:#fffbeb80}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity))}.bg-background{background-color:hsl(var(--background))}.bg-background\\/80{background-color:hsl(var(--background) / .8)}.bg-black\\/10{background-color:#0000001a}.bg-black\\/5{background-color:#0000000d}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity))}.bg-blue-700{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity))}.bg-border{background-color:hsl(var(--border))}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-emerald-50\\/50{background-color:#ecfdf580}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\\/50{background-color:hsl(var(--muted) / .5)}.bg-popover{background-color:hsl(var(--popover))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\\/20{background-color:hsl(var(--primary) / .2)}.bg-primary\\/30{background-color:hsl(var(--primary) / .3)}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity))}.bg-red-50\\/50{background-color:#fef2f280}.bg-secondary{background-color:hsl(var(--secondary))}.bg-sky-50\\/50{background-color:#f0f9ff80}.bg-slate-700{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity))}.bg-zinc-50\\/50{background-color:#fafafa80}.fill-current{fill:currentColor}.fill-gray-100{fill:#f3f4f6}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-1{padding:.25rem}.p-1\\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-\\[0\\.375rem_1rem_0_1rem\\]{padding:.375rem 1rem 0}.p-\\[1px\\]{padding:1px}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\\.5{padding-top:.375rem;padding-bottom:.375rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-3{padding-bottom:.75rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-8{padding-left:2rem}.pr-2{padding-right:.5rem}.pr-4{padding-right:1rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-5{padding-top:1.25rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-widest{letter-spacing:.1em}.text-\\[\\#008069\\]{--tw-text-opacity: 1;color:rgb(0 128 105 / var(--tw-text-opacity))}.text-\\[\\#b03f3f\\]{--tw-text-opacity: 1;color:rgb(176 63 63 / var(--tw-text-opacity))}.text-amber-100{--tw-text-opacity: 1;color:rgb(254 243 199 / var(--tw-text-opacity))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-emerald-900{--tw-text-opacity: 1;color:rgb(6 78 59 / var(--tw-text-opacity))}.text-foreground{color:hsl(var(--foreground))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\\/80{color:hsl(var(--muted-foreground) / .8)}.text-popover-foreground{color:hsl(var(--popover-foreground))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity))}.text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity))}.text-rose-600{--tw-text-opacity: 1;color:rgb(225 29 72 / var(--tw-text-opacity))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-sky-900{--tw-text-opacity: 1;color:rgb(12 74 110 / var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity))}.text-zinc-900{--tw-text-opacity: 1;color:rgb(24 24 27 / var(--tw-text-opacity))}.underline-offset-4{text-underline-offset:4px}.caret-transparent{caret-color:transparent}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-muted-foreground{--tw-ring-color: hsl(var(--muted-foreground))}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.paused{animation-play-state:paused}.file\\:border-0::file-selector-button{border-width:0px}.file\\:bg-transparent::file-selector-button{background-color:transparent}.file\\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\\:font-medium::file-selector-button{font-weight:500}.placeholder\\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.after\\:absolute:after{content:var(--tw-content);position:absolute}.after\\:inset-y-0:after{content:var(--tw-content);top:0;bottom:0}.after\\:bottom-\\[12px\\]:after{content:var(--tw-content);bottom:12px}.after\\:left-1\\/2:after{content:var(--tw-content);left:50%}.after\\:w-1:after{content:var(--tw-content);width:.25rem}.after\\:-translate-x-1\\/2:after{content:var(--tw-content);--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.after\\:border-\\[8px\\]:after{content:var(--tw-content);border-width:8px}.after\\:border-solid:after{content:var(--tw-content);border-style:solid}.after\\:bg-border:after{content:var(--tw-content);background-color:hsl(var(--border))}.hover\\:bg-\\[\\#a4ecde\\]:hover{--tw-bg-opacity: 1;background-color:rgb(164 236 222 / var(--tw-bg-opacity))}.hover\\:bg-\\[\\#b2ece0\\]:hover{--tw-bg-opacity: 1;background-color:rgb(178 236 224 / var(--tw-bg-opacity))}.hover\\:bg-\\[\\#c2d2d2\\]:hover{--tw-bg-opacity: 1;background-color:rgb(194 210 210 / var(--tw-bg-opacity))}.hover\\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\\:bg-amber-600\\/80:hover{background-color:#d97706cc}.hover\\:bg-amber-600\\/90:hover{background-color:#d97706e6}.hover\\:bg-black\\/10:hover{background-color:#0000001a}.hover\\:bg-destructive\\/80:hover{background-color:hsl(var(--destructive) / .8)}.hover\\:bg-destructive\\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\\:bg-muted\\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\\:bg-primary\\/80:hover{background-color:hsl(var(--primary) / .8)}.hover\\:bg-primary\\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\\:bg-secondary\\/80:hover{background-color:hsl(var(--secondary) / .8)}.hover\\:stroke-destructive:hover{stroke:hsl(var(--destructive))}.hover\\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:opacity-100:hover{opacity:1}.focus\\:bg-accent:focus{background-color:hsl(var(--accent))}.focus\\:text-accent-foreground:focus{color:hsl(var(--accent-foreground))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\\:ring-ring:focus{--tw-ring-color: hsl(var(--ring))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.focus-visible\\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\\:ring-0:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\\:ring-transparent:focus-visible{--tw-ring-color: transparent}.focus-visible\\:ring-offset-0:focus-visible{--tw-ring-offset-width: 0px}.focus-visible\\:ring-offset-1:focus-visible{--tw-ring-offset-width: 1px}.focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.focus-visible\\:ring-offset-background:focus-visible{--tw-ring-offset-color: hsl(var(--background))}.focus-visible\\:ring-offset-transparent:focus-visible{--tw-ring-offset-color: transparent}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-default:disabled{cursor:default}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\\:visible{visibility:visible}.group:hover .group-hover\\:opacity-100{opacity:1}.peer:disabled~.peer-disabled\\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\\:opacity-70{opacity:.7}.aria-selected\\:bg-accent[aria-selected=true]{background-color:hsl(var(--accent))}.aria-selected\\:text-accent-foreground[aria-selected=true]{color:hsl(var(--accent-foreground))}.data-\\[disabled\\]\\:pointer-events-none[data-disabled]{pointer-events:none}.data-\\[panel-group-direction\\=vertical\\]\\:h-px[data-panel-group-direction=vertical]{height:1px}.data-\\[panel-group-direction\\=vertical\\]\\:w-full[data-panel-group-direction=vertical]{width:100%}.data-\\[side\\=bottom\\]\\:translate-y-1[data-side=bottom]{--tw-translate-y: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[side\\=left\\]\\:-translate-x-1[data-side=left]{--tw-translate-x: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[side\\=right\\]\\:translate-x-1[data-side=right]{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[side\\=top\\]\\:-translate-y-1[data-side=top]{--tw-translate-y: -.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[state\\=checked\\]\\:translate-x-5[data-state=checked]{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked]{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[panel-group-direction\\=vertical\\]\\:flex-col[data-panel-group-direction=vertical]{flex-direction:column}.data-\\[state\\=active\\]\\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\\[state\\=active\\]\\:bg-primary[data-state=active],.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked]{background-color:hsl(var(--primary))}.data-\\[state\\=open\\]\\:bg-accent[data-state=open]{background-color:hsl(var(--accent))}.data-\\[state\\=selected\\]\\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\\[state\\=unchecked\\]\\:bg-slate-400[data-state=unchecked]{--tw-bg-opacity: 1;background-color:rgb(148 163 184 / var(--tw-bg-opacity))}.data-\\[state\\=active\\]\\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\\[state\\=active\\]\\:text-primary-foreground[data-state=active]{color:hsl(var(--primary-foreground))}.data-\\[state\\=open\\]\\:text-muted-foreground[data-state=open]{color:hsl(var(--muted-foreground))}.data-\\[disabled\\]\\:opacity-50[data-disabled]{opacity:.5}.data-\\[state\\=active\\]\\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.data-\\[state\\=open\\]\\:animate-in[data-state=open]{animation-name:enter;animation-duration:.15s;--tw-enter-opacity: initial;--tw-enter-scale: initial;--tw-enter-rotate: initial;--tw-enter-translate-x: initial;--tw-enter-translate-y: initial}.data-\\[state\\=closed\\]\\:animate-out[data-state=closed]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity: initial;--tw-exit-scale: initial;--tw-exit-rotate: initial;--tw-exit-translate-x: initial;--tw-exit-translate-y: initial}.data-\\[state\\=closed\\]\\:fade-out-0[data-state=closed]{--tw-exit-opacity: 0}.data-\\[state\\=open\\]\\:fade-in-0[data-state=open]{--tw-enter-opacity: 0}.data-\\[state\\=closed\\]\\:zoom-out-95[data-state=closed]{--tw-exit-scale: .95}.data-\\[state\\=open\\]\\:zoom-in-95[data-state=open]{--tw-enter-scale: .95}.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y: -.5rem}.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x: .5rem}.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x: -.5rem}.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y: .5rem}.data-\\[state\\=closed\\]\\:slide-out-to-left-1\\/2[data-state=closed]{--tw-exit-translate-x: -50%}.data-\\[state\\=closed\\]\\:slide-out-to-top-\\[48\\%\\][data-state=closed]{--tw-exit-translate-y: -48%}.data-\\[state\\=open\\]\\:slide-in-from-left-1\\/2[data-state=open]{--tw-enter-translate-x: -50%}.data-\\[state\\=open\\]\\:slide-in-from-top-\\[48\\%\\][data-state=open]{--tw-enter-translate-y: -48%}.data-\\[panel-group-direction\\=vertical\\]\\:after\\:left-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);left:0}.data-\\[panel-group-direction\\=vertical\\]\\:after\\:h-1[data-panel-group-direction=vertical]:after{content:var(--tw-content);height:.25rem}.data-\\[panel-group-direction\\=vertical\\]\\:after\\:w-full[data-panel-group-direction=vertical]:after{content:var(--tw-content);width:100%}.data-\\[panel-group-direction\\=vertical\\]\\:after\\:-translate-y-1\\/2[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.data-\\[panel-group-direction\\=vertical\\]\\:after\\:translate-x-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dark\\:-rotate-90:is(.dark *){--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dark\\:rotate-0:is(.dark *){--tw-rotate: 0deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dark\\:scale-0:is(.dark *){--tw-scale-x: 0;--tw-scale-y: 0;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dark\\:scale-100:is(.dark *){--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dark\\:border-amber-500\\/30:is(.dark *){border-color:#f59e0b4d}.dark\\:border-emerald-500\\/30:is(.dark *){border-color:#10b9814d}.dark\\:border-gray-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity))}.dark\\:border-red-500\\/30:is(.dark *){border-color:#ef44444d}.dark\\:border-sky-500\\/30:is(.dark *){border-color:#0ea5e94d}.dark\\:border-white\\/10:is(.dark *){border-color:#ffffff1a}.dark\\:border-zinc-500\\/30:is(.dark *){border-color:#71717a4d}.dark\\:bg-\\[\\#082720\\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(8 39 32 / var(--tw-bg-opacity))}.dark\\:bg-\\[\\#0b332a\\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(11 51 42 / var(--tw-bg-opacity))}.dark\\:bg-\\[\\#0f1413\\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(15 20 19 / var(--tw-bg-opacity))}.dark\\:bg-\\[\\#1d2724\\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(29 39 36 / var(--tw-bg-opacity))}.dark\\:bg-amber-500\\/10:is(.dark *){background-color:#f59e0b1a}.dark\\:bg-blue-300:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(147 197 253 / var(--tw-bg-opacity))}.dark\\:bg-emerald-500\\/10:is(.dark *){background-color:#10b9811a}.dark\\:bg-gray-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity))}.dark\\:bg-gray-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity))}.dark\\:bg-red-500\\/10:is(.dark *){background-color:#ef44441a}.dark\\:bg-red-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(127 29 29 / var(--tw-bg-opacity))}.dark\\:bg-sky-500\\/10:is(.dark *){background-color:#0ea5e91a}.dark\\:bg-white\\/10:is(.dark *){background-color:#ffffff1a}.dark\\:bg-white\\/5:is(.dark *){background-color:#ffffff0d}.dark\\:bg-yellow-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(66 32 6 / var(--tw-bg-opacity))}.dark\\:bg-zinc-500\\/10:is(.dark *){background-color:#71717a1a}.dark\\:fill-gray-800:is(.dark *){fill:#1f2937}.dark\\:text-\\[\\#00a884\\]:is(.dark *){--tw-text-opacity: 1;color:rgb(0 168 132 / var(--tw-text-opacity))}.dark\\:text-amber-200:is(.dark *){--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity))}.dark\\:text-blue-300:is(.dark *){--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity))}.dark\\:text-emerald-200:is(.dark *){--tw-text-opacity: 1;color:rgb(167 243 208 / var(--tw-text-opacity))}.dark\\:text-gray-100:is(.dark *){--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity))}.dark\\:text-gray-300:is(.dark *){--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity))}.dark\\:text-gray-400:is(.dark *){--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity))}.dark\\:text-red-200:is(.dark *){--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity))}.dark\\:text-sky-200:is(.dark *){--tw-text-opacity: 1;color:rgb(186 230 253 / var(--tw-text-opacity))}.dark\\:text-white:is(.dark *){--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.dark\\:text-zinc-300:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity))}.dark\\:hover\\:bg-\\[\\#071f19\\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(7 31 25 / var(--tw-bg-opacity))}.dark\\:hover\\:bg-\\[\\#082720\\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(8 39 32 / var(--tw-bg-opacity))}.dark\\:hover\\:bg-\\[\\#141a18\\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(20 26 24 / var(--tw-bg-opacity))}.dark\\:hover\\:bg-white\\/10:hover:is(.dark *){background-color:#ffffff1a}@media (min-width: 640px){.sm\\:m-4{margin:1rem}.sm\\:inline{display:inline}.sm\\:max-h-\\[600px\\]{max-height:600px}.sm\\:max-w-\\[650px\\]{max-width:650px}.sm\\:max-w-\\[740px\\]{max-width:740px}.sm\\:max-w-\\[950px\\]{max-width:950px}.sm\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\\:grid-cols-\\[10rem_1fr_10rem\\]{grid-template-columns:10rem 1fr 10rem}.sm\\:flex-row{flex-direction:row}.sm\\:justify-end{justify-content:flex-end}.sm\\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.sm\\:rounded-lg{border-radius:var(--radius)}.sm\\:text-left{text-align:left}}@media (min-width: 768px){.md\\:inline{display:inline}.md\\:flex{display:flex}.md\\:w-64{width:16rem}.md\\:w-full{width:100%}.md\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\\:flex-row{flex-direction:row}.md\\:gap-8{gap:2rem}}@media (min-width: 1024px){.lg\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1280px){.xl\\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.\\[\\&\\:has\\(\\[role\\=checkbox\\]\\)\\]\\:pr-0:has([role=checkbox]){padding-right:0}.\\[\\&\\>\\*\\]\\:p-4>*{padding:1rem}.\\[\\&\\>\\*\\]\\:px-4>*{padding-left:1rem;padding-right:1rem}.\\[\\&\\>\\*\\]\\:py-2>*{padding-top:.5rem;padding-bottom:.5rem}.\\[\\&\\>div\\[style\\]\\]\\:\\!block>div[style]{display:block!important}.\\[\\&\\>div\\[style\\]\\]\\:h-full>div[style]{height:100%}.\\[\\&\\>span\\]\\:line-clamp-1>span{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.\\[\\&\\>svg\\+div\\]\\:translate-y-\\[-3px\\]>svg+div{--tw-translate-y: -3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\\[\\&\\>svg\\]\\:absolute>svg{position:absolute}.\\[\\&\\>svg\\]\\:left-4>svg{left:1rem}.\\[\\&\\>svg\\]\\:top-4>svg{top:1rem}.\\[\\&\\>svg\\]\\:h-2\\.5>svg{height:.625rem}.\\[\\&\\>svg\\]\\:h-3>svg{height:.75rem}.\\[\\&\\>svg\\]\\:w-2\\.5>svg{width:.625rem}.\\[\\&\\>svg\\]\\:w-3>svg{width:.75rem}.\\[\\&\\>svg\\]\\:fill-rose-600>svg{fill:#e11d48}.\\[\\&\\>svg\\]\\:text-amber-500>svg{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity))}.\\[\\&\\>svg\\]\\:text-emerald-600>svg{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity))}.\\[\\&\\>svg\\]\\:text-foreground>svg{color:hsl(var(--foreground))}.\\[\\&\\>svg\\]\\:text-muted-foreground>svg{color:hsl(var(--muted-foreground))}.\\[\\&\\>svg\\]\\:text-red-600>svg{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity))}.\\[\\&\\>svg\\]\\:text-sky-500>svg{--tw-text-opacity: 1;color:rgb(14 165 233 / var(--tw-text-opacity))}.\\[\\&\\>svg\\]\\:text-zinc-400>svg{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity))}.hover\\:\\[\\&\\>svg\\]\\:fill-rose-700>svg:hover{fill:#be123c}.dark\\:\\[\\&\\>svg\\]\\:text-emerald-400\\/80>svg:is(.dark *){color:#34d399cc}.dark\\:\\[\\&\\>svg\\]\\:text-red-400\\/80>svg:is(.dark *){color:#f87171cc}.dark\\:\\[\\&\\>svg\\]\\:text-zinc-300>svg:is(.dark *){--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity))}.\\[\\&\\>svg\\~\\*\\]\\:pl-7>svg~*{padding-left:1.75rem}.\\[\\&\\>tr\\]\\:last\\:border-b-0:last-child>tr{border-bottom-width:0px}.\\[\\&\\[data-panel-group-direction\\=vertical\\]\\>div\\]\\:rotate-90[data-panel-group-direction=vertical]>div{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\\[\\&_\\.recharts-cartesian-axis-tick_text\\]\\:fill-muted-foreground .recharts-cartesian-axis-tick text{fill:hsl(var(--muted-foreground))}.\\[\\&_\\.recharts-cartesian-grid_line\\[stroke\\=\\'\\#ccc\\'\\]\\]\\:stroke-border\\/50 .recharts-cartesian-grid line[stroke=\"#ccc\"]{stroke:hsl(var(--border) / .5)}.\\[\\&_\\.recharts-curve\\.recharts-tooltip-cursor\\]\\:stroke-border .recharts-curve.recharts-tooltip-cursor{stroke:hsl(var(--border))}.\\[\\&_\\.recharts-dot\\[stroke\\=\\'\\#fff\\'\\]\\]\\:stroke-transparent .recharts-dot[stroke=\"#fff\"]{stroke:transparent}.\\[\\&_\\.recharts-layer\\]\\:outline-none .recharts-layer{outline:2px solid transparent;outline-offset:2px}.\\[\\&_\\.recharts-polar-grid_\\[stroke\\=\\'\\#ccc\\'\\]\\]\\:stroke-border .recharts-polar-grid [stroke=\"#ccc\"]{stroke:hsl(var(--border))}.\\[\\&_\\.recharts-radial-bar-background-sector\\]\\:fill-muted .recharts-radial-bar-background-sector,.\\[\\&_\\.recharts-rectangle\\.recharts-tooltip-cursor\\]\\:fill-muted .recharts-rectangle.recharts-tooltip-cursor{fill:hsl(var(--muted))}.\\[\\&_\\.recharts-reference-line_\\[stroke\\=\\'\\#ccc\\'\\]\\]\\:stroke-border .recharts-reference-line [stroke=\"#ccc\"]{stroke:hsl(var(--border))}.\\[\\&_\\.recharts-sector\\[stroke\\=\\'\\#fff\\'\\]\\]\\:stroke-transparent .recharts-sector[stroke=\"#fff\"]{stroke:transparent}.\\[\\&_\\.recharts-sector\\]\\:outline-none .recharts-sector,.\\[\\&_\\.recharts-surface\\]\\:outline-none .recharts-surface{outline:2px solid transparent;outline-offset:2px}.\\[\\&_\\[cmdk-group-heading\\]\\]\\:px-2 [cmdk-group-heading]{padding-left:.5rem;padding-right:.5rem}.\\[\\&_\\[cmdk-group-heading\\]\\]\\:py-1\\.5 [cmdk-group-heading]{padding-top:.375rem;padding-bottom:.375rem}.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-xs [cmdk-group-heading]{font-size:.75rem;line-height:1rem}.\\[\\&_\\[cmdk-group-heading\\]\\]\\:font-medium [cmdk-group-heading]{font-weight:500}.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-muted-foreground [cmdk-group-heading]{color:hsl(var(--muted-foreground))}.\\[\\&_\\[cmdk-group\\]\\:not\\(\\[hidden\\]\\)_\\~\\[cmdk-group\\]\\]\\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:0}.\\[\\&_\\[cmdk-group\\]\\]\\:px-2 [cmdk-group]{padding-left:.5rem;padding-right:.5rem}.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:h-5 [cmdk-input-wrapper] svg{height:1.25rem}.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:w-5 [cmdk-input-wrapper] svg{width:1.25rem}.\\[\\&_\\[cmdk-input\\]\\]\\:h-12 [cmdk-input]{height:3rem}.\\[\\&_\\[cmdk-item\\]\\]\\:px-2 [cmdk-item]{padding-left:.5rem;padding-right:.5rem}.\\[\\&_\\[cmdk-item\\]\\]\\:py-3 [cmdk-item]{padding-top:.75rem;padding-bottom:.75rem}.\\[\\&_\\[cmdk-item\\]_svg\\]\\:h-5 [cmdk-item] svg{height:1.25rem}.\\[\\&_\\[cmdk-item\\]_svg\\]\\:w-5 [cmdk-item] svg{width:1.25rem}.\\[\\&_p\\]\\:leading-relaxed p{line-height:1.625}.\\[\\&_strong\\]\\:text-foreground strong{color:hsl(var(--foreground))}.\\[\\&_tr\\:last-child\\]\\:border-0 tr:last-child{border-width:0px}.\\[\\&_tr\\]\\:border-b tr{border-bottom-width:1px}:root{--toastify-color-light: #fff;--toastify-color-dark: #121212;--toastify-color-info: #3498db;--toastify-color-success: #07bc0c;--toastify-color-warning: #f1c40f;--toastify-color-error: #e74c3c;--toastify-color-transparent: rgba(255, 255, 255, .7);--toastify-icon-color-info: var(--toastify-color-info);--toastify-icon-color-success: var(--toastify-color-success);--toastify-icon-color-warning: var(--toastify-color-warning);--toastify-icon-color-error: var(--toastify-color-error);--toastify-toast-width: 320px;--toastify-toast-offset: 16px;--toastify-toast-top: max(var(--toastify-toast-offset), env(safe-area-inset-top));--toastify-toast-right: max(var(--toastify-toast-offset), env(safe-area-inset-right));--toastify-toast-left: max(var(--toastify-toast-offset), env(safe-area-inset-left));--toastify-toast-bottom: max(var(--toastify-toast-offset), env(safe-area-inset-bottom));--toastify-toast-background: #fff;--toastify-toast-min-height: 64px;--toastify-toast-max-height: 800px;--toastify-toast-bd-radius: 6px;--toastify-font-family: sans-serif;--toastify-z-index: 9999;--toastify-text-color-light: #757575;--toastify-text-color-dark: #fff;--toastify-text-color-info: #fff;--toastify-text-color-success: #fff;--toastify-text-color-warning: #fff;--toastify-text-color-error: #fff;--toastify-spinner-color: #616161;--toastify-spinner-color-empty-area: #e0e0e0;--toastify-color-progress-light: linear-gradient( to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55 );--toastify-color-progress-dark: #bb86fc;--toastify-color-progress-info: var(--toastify-color-info);--toastify-color-progress-success: var(--toastify-color-success);--toastify-color-progress-warning: var(--toastify-color-warning);--toastify-color-progress-error: var(--toastify-color-error);--toastify-color-progress-bgo: .2}.Toastify__toast-container{z-index:var(--toastify-z-index);-webkit-transform:translate3d(0,0,var(--toastify-z-index));position:fixed;padding:4px;width:var(--toastify-toast-width);box-sizing:border-box;color:#fff}.Toastify__toast-container--top-left{top:var(--toastify-toast-top);left:var(--toastify-toast-left)}.Toastify__toast-container--top-center{top:var(--toastify-toast-top);left:50%;transform:translate(-50%)}.Toastify__toast-container--top-right{top:var(--toastify-toast-top);right:var(--toastify-toast-right)}.Toastify__toast-container--bottom-left{bottom:var(--toastify-toast-bottom);left:var(--toastify-toast-left)}.Toastify__toast-container--bottom-center{bottom:var(--toastify-toast-bottom);left:50%;transform:translate(-50%)}.Toastify__toast-container--bottom-right{bottom:var(--toastify-toast-bottom);right:var(--toastify-toast-right)}@media only screen and (max-width : 480px){.Toastify__toast-container{width:100vw;padding:0;left:env(safe-area-inset-left);margin:0}.Toastify__toast-container--top-left,.Toastify__toast-container--top-center,.Toastify__toast-container--top-right{top:env(safe-area-inset-top);transform:translate(0)}.Toastify__toast-container--bottom-left,.Toastify__toast-container--bottom-center,.Toastify__toast-container--bottom-right{bottom:env(safe-area-inset-bottom);transform:translate(0)}.Toastify__toast-container--rtl{right:env(safe-area-inset-right);left:initial}}.Toastify__toast{--y: 0;position:relative;touch-action:none;min-height:var(--toastify-toast-min-height);box-sizing:border-box;margin-bottom:1rem;padding:8px;border-radius:var(--toastify-toast-bd-radius);box-shadow:0 4px 12px #0000001a;display:flex;justify-content:space-between;max-height:var(--toastify-toast-max-height);font-family:var(--toastify-font-family);cursor:default;direction:ltr;z-index:0;overflow:hidden}.Toastify__toast--stacked{position:absolute;width:100%;transform:translate3d(0,var(--y),0) scale(var(--s));transition:transform .3s}.Toastify__toast--stacked[data-collapsed] .Toastify__toast-body,.Toastify__toast--stacked[data-collapsed] .Toastify__close-button{transition:opacity .1s}.Toastify__toast--stacked[data-collapsed=false]{overflow:visible}.Toastify__toast--stacked[data-collapsed=true]:not(:last-child)>*{opacity:0}.Toastify__toast--stacked:after{content:\"\";position:absolute;left:0;right:0;height:calc(var(--g) * 1px);bottom:100%}.Toastify__toast--stacked[data-pos=top]{top:0}.Toastify__toast--stacked[data-pos=bot]{bottom:0}.Toastify__toast--stacked[data-pos=bot].Toastify__toast--stacked:before{transform-origin:top}.Toastify__toast--stacked[data-pos=top].Toastify__toast--stacked:before{transform-origin:bottom}.Toastify__toast--stacked:before{content:\"\";position:absolute;left:0;right:0;bottom:0;height:100%;transform:scaleY(3);z-index:-1}.Toastify__toast--rtl{direction:rtl}.Toastify__toast--close-on-click{cursor:pointer}.Toastify__toast-body{margin:auto 0;flex:1 1 auto;padding:6px;display:flex;align-items:center}.Toastify__toast-body>div:last-child{word-break:break-word;flex:1}.Toastify__toast-icon{margin-inline-end:10px;width:20px;flex-shrink:0;display:flex}.Toastify--animate{animation-fill-mode:both;animation-duration:.5s}.Toastify--animate-icon{animation-fill-mode:both;animation-duration:.3s}@media only screen and (max-width : 480px){.Toastify__toast{margin-bottom:0;border-radius:0}}.Toastify__toast-theme--dark{background:var(--toastify-color-dark);color:var(--toastify-text-color-dark)}.Toastify__toast-theme--light,.Toastify__toast-theme--colored.Toastify__toast--default{background:var(--toastify-color-light);color:var(--toastify-text-color-light)}.Toastify__toast-theme--colored.Toastify__toast--info{color:var(--toastify-text-color-info);background:var(--toastify-color-info)}.Toastify__toast-theme--colored.Toastify__toast--success{color:var(--toastify-text-color-success);background:var(--toastify-color-success)}.Toastify__toast-theme--colored.Toastify__toast--warning{color:var(--toastify-text-color-warning);background:var(--toastify-color-warning)}.Toastify__toast-theme--colored.Toastify__toast--error{color:var(--toastify-text-color-error);background:var(--toastify-color-error)}.Toastify__progress-bar-theme--light{background:var(--toastify-color-progress-light)}.Toastify__progress-bar-theme--dark{background:var(--toastify-color-progress-dark)}.Toastify__progress-bar--info{background:var(--toastify-color-progress-info)}.Toastify__progress-bar--success{background:var(--toastify-color-progress-success)}.Toastify__progress-bar--warning{background:var(--toastify-color-progress-warning)}.Toastify__progress-bar--error{background:var(--toastify-color-progress-error)}.Toastify__progress-bar-theme--colored.Toastify__progress-bar--info,.Toastify__progress-bar-theme--colored.Toastify__progress-bar--success,.Toastify__progress-bar-theme--colored.Toastify__progress-bar--warning,.Toastify__progress-bar-theme--colored.Toastify__progress-bar--error{background:var(--toastify-color-transparent)}.Toastify__close-button{color:#fff;background:transparent;outline:none;border:none;padding:0;cursor:pointer;opacity:.7;transition:.3s ease;align-self:flex-start;z-index:1}.Toastify__close-button--light{color:#000;opacity:.3}.Toastify__close-button>svg{fill:currentColor;height:16px;width:14px}.Toastify__close-button:hover,.Toastify__close-button:focus{opacity:1}@keyframes Toastify__trackProgress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.Toastify__progress-bar{position:absolute;bottom:0;left:0;width:100%;height:100%;z-index:var(--toastify-z-index);opacity:.7;transform-origin:left;border-bottom-left-radius:var(--toastify-toast-bd-radius)}.Toastify__progress-bar--animated{animation:Toastify__trackProgress linear 1 forwards}.Toastify__progress-bar--controlled{transition:transform .2s}.Toastify__progress-bar--rtl{right:0;left:initial;transform-origin:right;border-bottom-left-radius:initial;border-bottom-right-radius:var(--toastify-toast-bd-radius)}.Toastify__progress-bar--wrp{position:absolute;bottom:0;left:0;width:100%;height:5px;border-bottom-left-radius:var(--toastify-toast-bd-radius)}.Toastify__progress-bar--wrp[data-hidden=true]{opacity:0}.Toastify__progress-bar--bg{opacity:var(--toastify-color-progress-bgo);width:100%;height:100%}.Toastify__spinner{width:20px;height:20px;box-sizing:border-box;border:2px solid;border-radius:100%;border-color:var(--toastify-spinner-color-empty-area);border-right-color:var(--toastify-spinner-color);animation:Toastify__spin .65s linear infinite}@keyframes Toastify__bounceInRight{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(3000px,0,0)}60%{opacity:1;transform:translate3d(-25px,0,0)}75%{transform:translate3d(10px,0,0)}90%{transform:translate3d(-5px,0,0)}to{transform:none}}@keyframes Toastify__bounceOutRight{20%{opacity:1;transform:translate3d(-20px,var(--y),0)}to{opacity:0;transform:translate3d(2000px,var(--y),0)}}@keyframes Toastify__bounceInLeft{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(-3000px,0,0)}60%{opacity:1;transform:translate3d(25px,0,0)}75%{transform:translate3d(-10px,0,0)}90%{transform:translate3d(5px,0,0)}to{transform:none}}@keyframes Toastify__bounceOutLeft{20%{opacity:1;transform:translate3d(20px,var(--y),0)}to{opacity:0;transform:translate3d(-2000px,var(--y),0)}}@keyframes Toastify__bounceInUp{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,3000px,0)}60%{opacity:1;transform:translate3d(0,-20px,0)}75%{transform:translate3d(0,10px,0)}90%{transform:translate3d(0,-5px,0)}to{transform:translateZ(0)}}@keyframes Toastify__bounceOutUp{20%{transform:translate3d(0,calc(var(--y) - 10px),0)}40%,45%{opacity:1;transform:translate3d(0,calc(var(--y) + 20px),0)}to{opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes Toastify__bounceInDown{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,-3000px,0)}60%{opacity:1;transform:translate3d(0,25px,0)}75%{transform:translate3d(0,-10px,0)}90%{transform:translate3d(0,5px,0)}to{transform:none}}@keyframes Toastify__bounceOutDown{20%{transform:translate3d(0,calc(var(--y) - 10px),0)}40%,45%{opacity:1;transform:translate3d(0,calc(var(--y) + 20px),0)}to{opacity:0;transform:translate3d(0,2000px,0)}}.Toastify__bounce-enter--top-left,.Toastify__bounce-enter--bottom-left{animation-name:Toastify__bounceInLeft}.Toastify__bounce-enter--top-right,.Toastify__bounce-enter--bottom-right{animation-name:Toastify__bounceInRight}.Toastify__bounce-enter--top-center{animation-name:Toastify__bounceInDown}.Toastify__bounce-enter--bottom-center{animation-name:Toastify__bounceInUp}.Toastify__bounce-exit--top-left,.Toastify__bounce-exit--bottom-left{animation-name:Toastify__bounceOutLeft}.Toastify__bounce-exit--top-right,.Toastify__bounce-exit--bottom-right{animation-name:Toastify__bounceOutRight}.Toastify__bounce-exit--top-center{animation-name:Toastify__bounceOutUp}.Toastify__bounce-exit--bottom-center{animation-name:Toastify__bounceOutDown}@keyframes Toastify__zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes Toastify__zoomOut{0%{opacity:1}50%{opacity:0;transform:translate3d(0,var(--y),0) scale3d(.3,.3,.3)}to{opacity:0}}.Toastify__zoom-enter{animation-name:Toastify__zoomIn}.Toastify__zoom-exit{animation-name:Toastify__zoomOut}@keyframes Toastify__flipIn{0%{transform:perspective(400px) rotateX(90deg);animation-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotateX(-20deg);animation-timing-function:ease-in}60%{transform:perspective(400px) rotateX(10deg);opacity:1}80%{transform:perspective(400px) rotateX(-5deg)}to{transform:perspective(400px)}}@keyframes Toastify__flipOut{0%{transform:translate3d(0,var(--y),0) perspective(400px)}30%{transform:translate3d(0,var(--y),0) perspective(400px) rotateX(-20deg);opacity:1}to{transform:translate3d(0,var(--y),0) perspective(400px) rotateX(90deg);opacity:0}}.Toastify__flip-enter{animation-name:Toastify__flipIn}.Toastify__flip-exit{animation-name:Toastify__flipOut}@keyframes Toastify__slideInRight{0%{transform:translate3d(110%,0,0);visibility:visible}to{transform:translate3d(0,var(--y),0)}}@keyframes Toastify__slideInLeft{0%{transform:translate3d(-110%,0,0);visibility:visible}to{transform:translate3d(0,var(--y),0)}}@keyframes Toastify__slideInUp{0%{transform:translate3d(0,110%,0);visibility:visible}to{transform:translate3d(0,var(--y),0)}}@keyframes Toastify__slideInDown{0%{transform:translate3d(0,-110%,0);visibility:visible}to{transform:translate3d(0,var(--y),0)}}@keyframes Toastify__slideOutRight{0%{transform:translate3d(0,var(--y),0)}to{visibility:hidden;transform:translate3d(110%,var(--y),0)}}@keyframes Toastify__slideOutLeft{0%{transform:translate3d(0,var(--y),0)}to{visibility:hidden;transform:translate3d(-110%,var(--y),0)}}@keyframes Toastify__slideOutDown{0%{transform:translate3d(0,var(--y),0)}to{visibility:hidden;transform:translate3d(0,500px,0)}}@keyframes Toastify__slideOutUp{0%{transform:translate3d(0,var(--y),0)}to{visibility:hidden;transform:translate3d(0,-500px,0)}}.Toastify__slide-enter--top-left,.Toastify__slide-enter--bottom-left{animation-name:Toastify__slideInLeft}.Toastify__slide-enter--top-right,.Toastify__slide-enter--bottom-right{animation-name:Toastify__slideInRight}.Toastify__slide-enter--top-center{animation-name:Toastify__slideInDown}.Toastify__slide-enter--bottom-center{animation-name:Toastify__slideInUp}.Toastify__slide-exit--top-left,.Toastify__slide-exit--bottom-left{animation-name:Toastify__slideOutLeft;animation-timing-function:ease-in;animation-duration:.3s}.Toastify__slide-exit--top-right,.Toastify__slide-exit--bottom-right{animation-name:Toastify__slideOutRight;animation-timing-function:ease-in;animation-duration:.3s}.Toastify__slide-exit--top-center{animation-name:Toastify__slideOutUp;animation-timing-function:ease-in;animation-duration:.3s}.Toastify__slide-exit--bottom-center{animation-name:Toastify__slideOutDown;animation-timing-function:ease-in;animation-duration:.3s}@keyframes Toastify__spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.chat-item{display:flex;padding:10px;cursor:pointer;background-color:hsl(var(--background))}.chat-item:hover,.chat-item.active{background-color:#2f2f2f}.bubble{border-radius:16px;padding:12px;word-wrap:break-word;max-width:100%;overflow:hidden}.bubble-right .bubble{background-color:#0a0a0a;max-width:100%}.bubble-right .bubble>span{text-align:right;display:block}.bubble-left .bubble{background-color:#1b1b1b;max-width:100%}.bubble-right{align-self:flex-end;display:flex;justify-content:flex-end;width:80%}.bubble-left{align-self:flex-start;display:flex;justify-content:flex-start;width:80%}.input-message textarea{background-color:#2f2f2f;padding-left:48px}.input-message textarea:focus{outline:none;border:none;box-shadow:none}.message-container{flex:1;overflow-y:auto;max-height:calc(100vh - 110px);padding-top:50px}.tabs-chat{background-color:transparent;width:100%;border-radius:0}.contacts-container{height:calc(100vh - 180px);overflow-y:auto;display:flex;flex-direction:column}.chat-item{display:flex;padding:10px;cursor:pointer}.custom-scrollbar{scrollbar-width:none}.custom-scrollbar::-webkit-scrollbar{display:none}.input-container{position:sticky;bottom:0;display:flex;flex-direction:column;gap:.375rem;background-color:transparent;padding:.375rem 1rem;width:100%;max-width:48rem;margin:0 auto;box-sizing:border-box}.formatted-message{white-space:pre-wrap}.formatted-message p{margin-bottom:1em}.formatted-message strong{font-weight:700}.formatted-message em{font-style:italic}.formatted-message del{text-decoration:line-through}.formatted-message a{color:#170c96!important;text-decoration:underline!important}.highlight-quoted{animation:highlight 2s ease-out}@keyframes highlight{0%{background-color:#3b82f633}to{background-color:transparent}}\n"
  },
  {
    "path": "manager/dist/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"https://evolution-api.com/files/evo/favicon.svg\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Evolution Manager</title>\n    <script type=\"module\" crossorigin src=\"/assets/index-CO3NSIFj.js\"></script>\n    <link rel=\"stylesheet\" crossorigin href=\"/assets/index-DsIrum0U.css\">\n  </head>\n  <body>\n    <div id=\"root\"></div>\n  </body>\n</html>\n"
  },
  {
    "path": "manager_install.sh",
    "content": "#! /bin/bash\n\ncd evolution-manager-v2\nnpm install\nnpm run build\ncd ..\nrm -rf manager/dist\ncp -r evolution-manager-v2/dist manager/dist"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"evolution-api\",\n  \"version\": \"2.3.7\",\n  \"description\": \"Rest api for communication with WhatsApp\",\n  \"main\": \"./dist/main.js\",\n  \"type\": \"commonjs\",\n  \"scripts\": {\n    \"build\": \"tsc --noEmit && tsup\",\n    \"start\": \"tsx ./src/main.ts\",\n    \"start:prod\": \"node dist/main\",\n    \"dev:server\": \"tsx watch ./src/main.ts\",\n    \"test\": \"tsx watch ./test/all.test.ts\",\n    \"lint\": \"eslint --fix --ext .ts src\",\n    \"lint:check\": \"eslint --ext .ts src\",\n    \"commit\": \"cz\",\n    \"commitlint\": \"commitlint --edit\",\n    \"db:generate\": \"node runWithProvider.js \\\"npx prisma generate --schema ./prisma/DATABASE_PROVIDER-schema.prisma\\\"\",\n    \"db:deploy\": \"node runWithProvider.js \\\"rm -rf ./prisma/migrations && cp -r ./prisma/DATABASE_PROVIDER-migrations ./prisma/migrations && npx prisma migrate deploy --schema ./prisma/DATABASE_PROVIDER-schema.prisma\\\"\",\n    \"db:deploy:win\": \"node runWithProvider.js \\\"xcopy /E /I prisma\\\\DATABASE_PROVIDER-migrations prisma\\\\migrations && npx prisma migrate deploy --schema prisma\\\\DATABASE_PROVIDER-schema.prisma\\\"\",\n    \"db:studio\": \"node runWithProvider.js \\\"npx prisma studio --schema ./prisma/DATABASE_PROVIDER-schema.prisma\\\"\",\n    \"db:migrate:dev\": \"node runWithProvider.js \\\"rm -rf ./prisma/migrations && cp -r ./prisma/DATABASE_PROVIDER-migrations ./prisma/migrations && npx prisma migrate dev --schema ./prisma/DATABASE_PROVIDER-schema.prisma && cp -r ./prisma/migrations/* ./prisma/DATABASE_PROVIDER-migrations\\\"\",\n    \"db:migrate:dev:win\": \"node runWithProvider.js \\\"xcopy /E /I prisma\\\\DATABASE_PROVIDER-migrations prisma\\\\migrations && npx prisma migrate dev --schema prisma\\\\DATABASE_PROVIDER-schema.prisma\\\"\",\n    \"prepare\": \"husky\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/EvolutionAPI/evolution-api.git\"\n  },\n  \"keywords\": [\n    \"chat\",\n    \"communication\",\n    \"message\",\n    \"send message\",\n    \"whatsapp\",\n    \"js-whatsapp\",\n    \"whatsapp-api\",\n    \"whatsapp-web\",\n    \"whatsapp\",\n    \"whatsapp-chat\",\n    \"whatsapp-group\",\n    \"automation\",\n    \"multi-device\",\n    \"bot\"\n  ],\n  \"author\": {\n    \"name\": \"Davidson Gomes\",\n    \"email\": \"contato@evolution-api.com\"\n  },\n  \"license\": \"Apache-2.0\",\n  \"bugs\": {\n    \"url\": \"https://github.com/EvolutionAPI/evolution-api/issues\"\n  },\n  \"homepage\": \"https://github.com/EvolutionAPI/evolution-api#readme\",\n  \"lint-staged\": {\n    \"src/**/*.{ts,js}\": [\n      \"eslint --fix\"\n    ],\n    \"src/**/*.ts\": [\n      \"sh -c 'tsc --noEmit'\"\n    ]\n  },\n  \"config\": {\n    \"commitizen\": {\n      \"path\": \"cz-conventional-changelog\"\n    }\n  },\n  \"dependencies\": {\n    \"@adiwajshing/keyed-db\": \"^0.2.4\",\n    \"@aws-sdk/client-sqs\": \"^3.891.0\",\n    \"@ffmpeg-installer/ffmpeg\": \"^1.1.0\",\n    \"@figuro/chatwoot-sdk\": \"^1.1.16\",\n    \"@hapi/boom\": \"^10.0.1\",\n    \"@paralleldrive/cuid2\": \"^2.2.2\",\n    \"@prisma/client\": \"^6.16.2\",\n    \"@sentry/node\": \"^10.12.0\",\n    \"@types/uuid\": \"^10.0.0\",\n    \"amqplib\": \"^0.10.5\",\n    \"audio-decode\": \"^2.2.3\",\n    \"axios\": \"^1.7.9\",\n    \"baileys\": \"7.0.0-rc.9\",\n    \"class-validator\": \"^0.14.1\",\n    \"compression\": \"^1.7.5\",\n    \"cors\": \"^2.8.5\",\n    \"dayjs\": \"^1.11.13\",\n    \"dotenv\": \"^16.4.7\",\n    \"emoji-regex\": \"^10.4.0\",\n    \"eventemitter2\": \"^6.4.9\",\n    \"express\": \"^4.21.2\",\n    \"express-async-errors\": \"^3.1.1\",\n    \"fluent-ffmpeg\": \"^2.1.3\",\n    \"form-data\": \"^4.0.1\",\n    \"https-proxy-agent\": \"^7.0.6\",\n    \"fetch-socks\": \"^1.3.2\",\n    \"i18next\": \"^23.7.19\",\n    \"jimp\": \"^1.6.0\",\n    \"json-schema\": \"^0.4.0\",\n    \"jsonschema\": \"^1.4.1\",\n    \"jsonwebtoken\": \"^9.0.2\",\n    \"kafkajs\": \"^2.2.4\",\n    \"libphonenumber-js\": \"^1.12.25\",\n    \"link-preview-js\": \"^3.0.13\",\n    \"long\": \"^5.2.3\",\n    \"mediainfo.js\": \"^0.3.4\",\n    \"mime\": \"^4.0.0\",\n    \"mime-types\": \"^2.1.35\",\n    \"minio\": \"^8.0.3\",\n    \"multer\": \"^2.0.2\",\n    \"nats\": \"^2.29.1\",\n    \"node-cache\": \"^5.1.2\",\n    \"node-cron\": \"^3.0.3\",\n    \"openai\": \"^4.77.3\",\n    \"pg\": \"^8.13.1\",\n    \"pino\": \"^9.10.0\",\n    \"prisma\": \"^6.1.0\",\n    \"pusher\": \"^5.2.0\",\n    \"qrcode\": \"^1.5.4\",\n    \"qrcode-terminal\": \"^0.12.0\",\n    \"redis\": \"^4.7.0\",\n    \"rxjs\": \"^7.8.2\",\n    \"sharp\": \"^0.34.2\",\n    \"socket.io\": \"^4.8.1\",\n    \"socket.io-client\": \"^4.8.1\",\n    \"socks-proxy-agent\": \"^8.0.5\",\n    \"swagger-ui-express\": \"^5.0.1\",\n    \"tsup\": \"^8.3.5\",\n    \"undici\": \"^7.16.0\",\n    \"uuid\": \"^13.0.0\"\n  },\n  \"devDependencies\": {\n    \"@commitlint/cli\": \"^19.8.1\",\n    \"@commitlint/config-conventional\": \"^19.8.1\",\n    \"@types/compression\": \"^1.7.5\",\n    \"@types/cors\": \"^2.8.17\",\n    \"@types/express\": \"^4.17.18\",\n    \"@types/json-schema\": \"^7.0.15\",\n    \"@types/mime\": \"^4.0.0\",\n    \"@types/mime-types\": \"^2.1.4\",\n    \"@types/node\": \"^24.5.2\",\n    \"@types/node-cron\": \"^3.0.11\",\n    \"@types/qrcode\": \"^1.5.5\",\n    \"@types/qrcode-terminal\": \"^0.12.2\",\n    \"@typescript-eslint/eslint-plugin\": \"^8.44.0\",\n    \"@typescript-eslint/parser\": \"^8.44.0\",\n    \"commitizen\": \"^4.3.1\",\n    \"cz-conventional-changelog\": \"^3.3.0\",\n    \"eslint\": \"^8.45.0\",\n    \"eslint-config-prettier\": \"^10.1.8\",\n    \"eslint-plugin-import\": \"^2.31.0\",\n    \"eslint-plugin-prettier\": \"^5.2.1\",\n    \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n    \"husky\": \"^9.1.7\",\n    \"lint-staged\": \"^16.1.6\",\n    \"prettier\": \"^3.4.2\",\n    \"tsconfig-paths\": \"^4.2.0\",\n    \"tsx\": \"^4.20.5\",\n    \"typescript\": \"^5.7.2\"\n  }\n}\n"
  },
  {
    "path": "prisma/mysql-migrations/20240809105427_init/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE `Instance` (\n    `id` VARCHAR(191) NOT NULL,\n    `name` VARCHAR(255) NOT NULL,\n    `connectionStatus` ENUM('open', 'close', 'connecting') NOT NULL DEFAULT 'open',\n    `ownerJid` VARCHAR(100) NULL,\n    `profileName` VARCHAR(100) NULL,\n    `profilePicUrl` VARCHAR(500) NULL,\n    `integration` VARCHAR(100) NULL,\n    `number` VARCHAR(100) NULL,\n    `businessId` VARCHAR(100) NULL,\n    `token` VARCHAR(255) NULL,\n    `clientName` VARCHAR(100) NULL,\n    `disconnectionReasonCode` INTEGER NULL,\n    `disconnectionObject` JSON NULL,\n    `disconnectionAt` TIMESTAMP NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NULL,\n\n    UNIQUE INDEX `Instance_name_key`(`name`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Session` (\n    `id` VARCHAR(191) NOT NULL,\n    `sessionId` VARCHAR(191) NOT NULL,\n    `creds` TEXT NULL,\n    `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\n    UNIQUE INDEX `Session_sessionId_key`(`sessionId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Chat` (\n    `id` VARCHAR(191) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `labels` JSON NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Contact` (\n    `id` VARCHAR(191) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `pushName` VARCHAR(100) NULL,\n    `profilePicUrl` VARCHAR(500) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Message` (\n    `id` VARCHAR(191) NOT NULL,\n    `key` JSON NOT NULL,\n    `pushName` VARCHAR(100) NULL,\n    `participant` VARCHAR(100) NULL,\n    `messageType` VARCHAR(100) NOT NULL,\n    `message` JSON NOT NULL,\n    `contextInfo` JSON NULL,\n    `source` ENUM('ios', 'android', 'web', 'unknown', 'desktop') NOT NULL,\n    `messageTimestamp` INTEGER NOT NULL,\n    `chatwootMessageId` INTEGER NULL,\n    `chatwootInboxId` INTEGER NULL,\n    `chatwootConversationId` INTEGER NULL,\n    `chatwootContactInboxSourceId` VARCHAR(100) NULL,\n    `chatwootIsRead` BOOLEAN NULL DEFAULT false,\n    `instanceId` VARCHAR(191) NOT NULL,\n    `typebotSessionId` VARCHAR(191) NULL,\n    `openaiSessionId` VARCHAR(191) NULL,\n    `webhookUrl` VARCHAR(500) NULL,\n    `difySessionId` VARCHAR(191) NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `MessageUpdate` (\n    `id` VARCHAR(191) NOT NULL,\n    `keyId` VARCHAR(100) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `fromMe` BOOLEAN NOT NULL,\n    `participant` VARCHAR(100) NULL,\n    `pollUpdates` JSON NULL,\n    `status` VARCHAR(30) NOT NULL,\n    `messageId` VARCHAR(191) NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Webhook` (\n    `id` VARCHAR(191) NOT NULL,\n    `url` VARCHAR(500) NOT NULL,\n    `enabled` BOOLEAN NULL DEFAULT true,\n    `events` JSON NULL,\n    `webhookByEvents` BOOLEAN NULL DEFAULT false,\n    `webhookBase64` BOOLEAN NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Webhook_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Chatwoot` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NULL DEFAULT true,\n    `accountId` VARCHAR(100) NULL,\n    `token` VARCHAR(100) NULL,\n    `url` VARCHAR(500) NULL,\n    `nameInbox` VARCHAR(100) NULL,\n    `signMsg` BOOLEAN NULL DEFAULT false,\n    `signDelimiter` VARCHAR(100) NULL,\n    `number` VARCHAR(100) NULL,\n    `reopenConversation` BOOLEAN NULL DEFAULT false,\n    `conversationPending` BOOLEAN NULL DEFAULT false,\n    `mergeBrazilContacts` BOOLEAN NULL DEFAULT false,\n    `importContacts` BOOLEAN NULL DEFAULT false,\n    `importMessages` BOOLEAN NULL DEFAULT false,\n    `daysLimitImportMessages` INTEGER NULL,\n    `organization` VARCHAR(100) NULL,\n    `logo` VARCHAR(500) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Chatwoot_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Label` (\n    `id` VARCHAR(191) NOT NULL,\n    `labelId` VARCHAR(100) NULL,\n    `name` VARCHAR(100) NOT NULL,\n    `color` VARCHAR(100) NOT NULL,\n    `predefinedId` VARCHAR(100) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Label_labelId_key`(`labelId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Proxy` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `host` VARCHAR(100) NOT NULL,\n    `port` VARCHAR(100) NOT NULL,\n    `protocol` VARCHAR(100) NOT NULL,\n    `username` VARCHAR(100) NOT NULL,\n    `password` VARCHAR(100) NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Proxy_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Setting` (\n    `id` VARCHAR(191) NOT NULL,\n    `rejectCall` BOOLEAN NOT NULL DEFAULT false,\n    `msgCall` VARCHAR(100) NULL,\n    `groupsIgnore` BOOLEAN NOT NULL DEFAULT false,\n    `alwaysOnline` BOOLEAN NOT NULL DEFAULT false,\n    `readMessages` BOOLEAN NOT NULL DEFAULT false,\n    `readStatus` BOOLEAN NOT NULL DEFAULT false,\n    `syncFullHistory` BOOLEAN NOT NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Setting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Rabbitmq` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `events` JSON NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Rabbitmq_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Sqs` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `events` JSON NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Sqs_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Websocket` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `events` JSON NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Websocket_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Typebot` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255) NULL,\n    `url` VARCHAR(500) NOT NULL,\n    `typebot` VARCHAR(100) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NULL,\n    `ignoreJids` JSON NULL,\n    `triggerType` ENUM('all', 'keyword', 'none') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `TypebotSession` (\n    `id` VARCHAR(191) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `pushName` VARCHAR(100) NULL,\n    `sessionId` VARCHAR(100) NOT NULL,\n    `status` ENUM('opened', 'closed', 'paused') NOT NULL,\n    `prefilledVariables` JSON NULL,\n    `awaitUser` BOOLEAN NOT NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `typebotId` VARCHAR(191) NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `TypebotSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `typebotIdFallback` VARCHAR(100) NULL,\n    `ignoreJids` JSON NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `TypebotSetting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Media` (\n    `id` VARCHAR(191) NOT NULL,\n    `fileName` VARCHAR(500) NOT NULL,\n    `type` VARCHAR(100) NOT NULL,\n    `mimetype` VARCHAR(100) NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `messageId` VARCHAR(191) NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Media_fileName_key`(`fileName`),\n    UNIQUE INDEX `Media_messageId_key`(`messageId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `OpenaiCreds` (\n    `id` VARCHAR(191) NOT NULL,\n    `name` VARCHAR(255) NULL,\n    `apiKey` VARCHAR(255) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `OpenaiCreds_name_key`(`name`),\n    UNIQUE INDEX `OpenaiCreds_apiKey_key`(`apiKey`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `OpenaiBot` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255) NULL,\n    `botType` ENUM('assistant', 'chatCompletion') NOT NULL,\n    `assistantId` VARCHAR(255) NULL,\n    `functionUrl` VARCHAR(500) NULL,\n    `model` VARCHAR(100) NULL,\n    `systemMessages` JSON NULL,\n    `assistantMessages` JSON NULL,\n    `userMessages` JSON NULL,\n    `maxTokens` INTEGER NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `triggerType` ENUM('all', 'keyword', 'none') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `openaiCredsId` VARCHAR(191) NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `OpenaiSession` (\n    `id` VARCHAR(191) NOT NULL,\n    `sessionId` VARCHAR(255) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `status` ENUM('opened', 'closed', 'paused') NOT NULL,\n    `awaitUser` BOOLEAN NOT NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `openaiBotId` VARCHAR(191) NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `OpenaiSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `speechToText` BOOLEAN NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `openaiCredsId` VARCHAR(191) NOT NULL,\n    `openaiIdFallback` VARCHAR(100) NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `OpenaiSetting_openaiCredsId_key`(`openaiCredsId`),\n    UNIQUE INDEX `OpenaiSetting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Template` (\n    `id` VARCHAR(191) NOT NULL,\n    `templateId` VARCHAR(255) NOT NULL,\n    `name` VARCHAR(255) NOT NULL,\n    `template` JSON NOT NULL,\n    `webhookUrl` VARCHAR(500) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Template_templateId_key`(`templateId`),\n    UNIQUE INDEX `Template_name_key`(`name`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Dify` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255) NULL,\n    `botType` ENUM('chatBot', 'textGenerator', 'agent', 'workflow') NOT NULL,\n    `apiUrl` VARCHAR(255) NULL,\n    `apiKey` VARCHAR(255) NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `triggerType` ENUM('all', 'keyword', 'none') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `DifySession` (\n    `id` VARCHAR(191) NOT NULL,\n    `sessionId` VARCHAR(255) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `status` ENUM('opened', 'closed', 'paused') NOT NULL,\n    `awaitUser` BOOLEAN NOT NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `difyId` VARCHAR(191) NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `DifySetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `difyIdFallback` VARCHAR(100) NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `DifySetting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- AddForeignKey\nALTER TABLE `Session` ADD CONSTRAINT `Session_sessionId_fkey` FOREIGN KEY (`sessionId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Chat` ADD CONSTRAINT `Chat_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Contact` ADD CONSTRAINT `Contact_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Message` ADD CONSTRAINT `Message_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Message` ADD CONSTRAINT `Message_typebotSessionId_fkey` FOREIGN KEY (`typebotSessionId`) REFERENCES `TypebotSession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Message` ADD CONSTRAINT `Message_openaiSessionId_fkey` FOREIGN KEY (`openaiSessionId`) REFERENCES `OpenaiSession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Message` ADD CONSTRAINT `Message_difySessionId_fkey` FOREIGN KEY (`difySessionId`) REFERENCES `DifySession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `MessageUpdate` ADD CONSTRAINT `MessageUpdate_messageId_fkey` FOREIGN KEY (`messageId`) REFERENCES `Message`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `MessageUpdate` ADD CONSTRAINT `MessageUpdate_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Webhook` ADD CONSTRAINT `Webhook_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Chatwoot` ADD CONSTRAINT `Chatwoot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Label` ADD CONSTRAINT `Label_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Proxy` ADD CONSTRAINT `Proxy_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Setting` ADD CONSTRAINT `Setting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Rabbitmq` ADD CONSTRAINT `Rabbitmq_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Sqs` ADD CONSTRAINT `Sqs_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Websocket` ADD CONSTRAINT `Websocket_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Typebot` ADD CONSTRAINT `Typebot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `TypebotSession` ADD CONSTRAINT `TypebotSession_typebotId_fkey` FOREIGN KEY (`typebotId`) REFERENCES `Typebot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `TypebotSession` ADD CONSTRAINT `TypebotSession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `TypebotSetting` ADD CONSTRAINT `TypebotSetting_typebotIdFallback_fkey` FOREIGN KEY (`typebotIdFallback`) REFERENCES `Typebot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `TypebotSetting` ADD CONSTRAINT `TypebotSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Media` ADD CONSTRAINT `Media_messageId_fkey` FOREIGN KEY (`messageId`) REFERENCES `Message`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Media` ADD CONSTRAINT `Media_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiCreds` ADD CONSTRAINT `OpenaiCreds_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiBot` ADD CONSTRAINT `OpenaiBot_openaiCredsId_fkey` FOREIGN KEY (`openaiCredsId`) REFERENCES `OpenaiCreds`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiBot` ADD CONSTRAINT `OpenaiBot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiSession` ADD CONSTRAINT `OpenaiSession_openaiBotId_fkey` FOREIGN KEY (`openaiBotId`) REFERENCES `OpenaiBot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiSession` ADD CONSTRAINT `OpenaiSession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiSetting` ADD CONSTRAINT `OpenaiSetting_openaiCredsId_fkey` FOREIGN KEY (`openaiCredsId`) REFERENCES `OpenaiCreds`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiSetting` ADD CONSTRAINT `OpenaiSetting_openaiIdFallback_fkey` FOREIGN KEY (`openaiIdFallback`) REFERENCES `OpenaiBot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `OpenaiSetting` ADD CONSTRAINT `OpenaiSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Template` ADD CONSTRAINT `Template_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Dify` ADD CONSTRAINT `Dify_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `DifySession` ADD CONSTRAINT `DifySession_difyId_fkey` FOREIGN KEY (`difyId`) REFERENCES `Dify`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `DifySession` ADD CONSTRAINT `DifySession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `DifySetting` ADD CONSTRAINT `DifySetting_difyIdFallback_fkey` FOREIGN KEY (`difyIdFallback`) REFERENCES `Dify`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `DifySetting` ADD CONSTRAINT `DifySetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/20240813153900_add_unique_index_for_remoted_jid_and_instance_in_contacts/migration.sql",
    "content": "/*\nWarnings:\n- You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n- A unique constraint covering the columns `[remoteJid,instanceId]` on the table `Contact` will be added. If there are existing duplicate values, this will fail.\n*/\n-- AlterTable\nALTER TABLE `Chat`\nADD COLUMN `name` VARCHAR(100) NULL,\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySession`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance`\nMODIFY `disconnectionAt` TIMESTAMP NULL,\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Label`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `OpenaiBot`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSession`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session`\nMODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSession`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket`\nMODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\nMODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- CreateIndex\nCREATE UNIQUE INDEX `Contact_remoteJid_instanceId_key` ON `Contact` (`remoteJid`, `instanceId`);"
  },
  {
    "path": "prisma/mysql-migrations/20240814173138_add_ignore_jids_chatwoot/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n\n*/\n-- DropIndex\nDROP INDEX `Label_labelId_key` ON `Label`;\n\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` ADD COLUMN `ignoreJids` JSON NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n"
  },
  {
    "path": "prisma/mysql-migrations/20240814214314_integrations_unification/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the column `difySessionId` on the `Message` table. All the data in the column will be lost.\n  - You are about to drop the column `openaiSessionId` on the `Message` table. All the data in the column will be lost.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the `DifySession` table. If the table is not empty, all the data it contains will be lost.\n  - You are about to drop the `OpenaiSession` table. If the table is not empty, all the data it contains will be lost.\n  - You are about to drop the `TypebotSession` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE `DifySession` DROP FOREIGN KEY `DifySession_difyId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `DifySession` DROP FOREIGN KEY `DifySession_instanceId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `Message` DROP FOREIGN KEY `Message_difySessionId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `Message` DROP FOREIGN KEY `Message_openaiSessionId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `Message` DROP FOREIGN KEY `Message_typebotSessionId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `OpenaiSession` DROP FOREIGN KEY `OpenaiSession_instanceId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `OpenaiSession` DROP FOREIGN KEY `OpenaiSession_openaiBotId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `TypebotSession` DROP FOREIGN KEY `TypebotSession_instanceId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `TypebotSession` DROP FOREIGN KEY `TypebotSession_typebotId_fkey`;\n\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Message` DROP COLUMN `difySessionId`,\n    DROP COLUMN `openaiSessionId`,\n    ADD COLUMN `sessionId` VARCHAR(191) NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- DropTable\nDROP TABLE `DifySession`;\n\n-- DropTable\nDROP TABLE `OpenaiSession`;\n\n-- DropTable\nDROP TABLE `TypebotSession`;\n\n-- CreateTable\nCREATE TABLE `IntegrationSession` (\n    `id` VARCHAR(191) NOT NULL,\n    `sessionId` VARCHAR(255) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `pushName` VARCHAR(191) NULL,\n    `status` ENUM('opened', 'closed', 'paused') NOT NULL,\n    `awaitUser` BOOLEAN NOT NULL DEFAULT false,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n    `parameters` JSON NULL,\n    `openaiBotId` VARCHAR(191) NULL,\n    `difyId` VARCHAR(191) NULL,\n    `typebotId` VARCHAR(191) NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- AddForeignKey\nALTER TABLE `Message` ADD CONSTRAINT `Message_sessionId_fkey` FOREIGN KEY (`sessionId`) REFERENCES `IntegrationSession`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_openaiBotId_fkey` FOREIGN KEY (`openaiBotId`) REFERENCES `OpenaiBot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_difyId_fkey` FOREIGN KEY (`difyId`) REFERENCES `Dify`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `IntegrationSession` ADD CONSTRAINT `IntegrationSession_typebotId_fkey` FOREIGN KEY (`typebotId`) REFERENCES `Typebot`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/20240821203259_add_postgres_migrations/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the column `difyId` on the `IntegrationSession` table. All the data in the column will be lost.\n  - You are about to drop the column `openaiBotId` on the `IntegrationSession` table. All the data in the column will be lost.\n  - You are about to drop the column `typebotId` on the `IntegrationSession` table. All the data in the column will be lost.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n\n*/\n-- DropForeignKey\nALTER TABLE `IntegrationSession` DROP FOREIGN KEY `IntegrationSession_difyId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `IntegrationSession` DROP FOREIGN KEY `IntegrationSession_openaiBotId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `IntegrationSession` DROP FOREIGN KEY `IntegrationSession_typebotId_fkey`;\n\n-- DropIndex\nDROP INDEX `Message_typebotSessionId_fkey` ON `Message`;\n\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` DROP COLUMN `difyId`,\n    DROP COLUMN `openaiBotId`,\n    DROP COLUMN `typebotId`,\n    ADD COLUMN `botId` VARCHAR(191) NULL,\n    ADD COLUMN `context` JSON NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL,\n    MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- CreateTable\nCREATE TABLE `GenericBot` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255) NULL,\n    `apiUrl` VARCHAR(255) NULL,\n    `apiKey` VARCHAR(255) NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `GenericSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `botIdFallback` VARCHAR(100) NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `GenericSetting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `Flowise` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255) NULL,\n    `apiUrl` VARCHAR(255) NULL,\n    `apiKey` VARCHAR(255) NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `FlowiseSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `flowiseIdFallback` VARCHAR(100) NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `FlowiseSetting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- AddForeignKey\nALTER TABLE `GenericBot` ADD CONSTRAINT `GenericBot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `GenericSetting` ADD CONSTRAINT `GenericSetting_botIdFallback_fkey` FOREIGN KEY (`botIdFallback`) REFERENCES `GenericBot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `GenericSetting` ADD CONSTRAINT `GenericSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `Flowise` ADD CONSTRAINT `Flowise_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `FlowiseSetting` ADD CONSTRAINT `FlowiseSetting_flowiseIdFallback_fkey` FOREIGN KEY (`flowiseIdFallback`) REFERENCES `Flowise`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `FlowiseSetting` ADD CONSTRAINT `FlowiseSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/20240824162012_add_type_on_integration_sessions/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `GenericBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `GenericBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `GenericSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `GenericSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n\n*/\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `GenericBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `GenericSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` ADD COLUMN `type` VARCHAR(100) NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n"
  },
  {
    "path": "prisma/mysql-migrations/20240825131301_change_to_evolution_bot/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the `GenericBot` table. If the table is not empty, all the data it contains will be lost.\n  - You are about to drop the `GenericSetting` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE `GenericBot` DROP FOREIGN KEY `GenericBot_instanceId_fkey`;\n\n-- DropForeignKey\nALTER TABLE `GenericSetting` DROP FOREIGN KEY `GenericSetting_botIdFallback_fkey`;\n\n-- DropForeignKey\nALTER TABLE `GenericSetting` DROP FOREIGN KEY `GenericSetting_instanceId_fkey`;\n\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- DropTable\nDROP TABLE `GenericBot`;\n\n-- DropTable\nDROP TABLE `GenericSetting`;\n\n-- CreateTable\nCREATE TABLE `EvolutionBot` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255) NULL,\n    `apiUrl` VARCHAR(255) NULL,\n    `apiKey` VARCHAR(255) NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `EvolutionBotSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER NULL DEFAULT 0,\n    `keywordFinish` VARCHAR(100) NULL,\n    `delayMessage` INTEGER NULL,\n    `unknownMessage` VARCHAR(100) NULL,\n    `listeningFromMe` BOOLEAN NULL DEFAULT false,\n    `stopBotFromMe` BOOLEAN NULL DEFAULT false,\n    `keepOpen` BOOLEAN NULL DEFAULT false,\n    `debounceTime` INTEGER NULL,\n    `ignoreJids` JSON NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `botIdFallback` VARCHAR(100) NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `EvolutionBotSetting_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- AddForeignKey\nALTER TABLE `EvolutionBot` ADD CONSTRAINT `EvolutionBot_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `EvolutionBotSetting` ADD CONSTRAINT `EvolutionBotSetting_botIdFallback_fkey` FOREIGN KEY (`botIdFallback`) REFERENCES `EvolutionBot`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `EvolutionBotSetting` ADD CONSTRAINT `EvolutionBotSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/20241001172800_add_message_status/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n\n*/\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Message` ADD COLUMN `status` INTEGER NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` ADD COLUMN `headers` JSON NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- CreateTable\nCREATE TABLE `IsOnWhatsapp` (\n    `id` VARCHAR(191) NOT NULL,\n    `remoteJid` VARCHAR(100) NOT NULL,\n    `jidOptions` VARCHAR(191) NOT NULL,\n    `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n\n    UNIQUE INDEX `IsOnWhatsapp_remoteJid_key`(`remoteJid`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n"
  },
  {
    "path": "prisma/mysql-migrations/20241108101333_fix_message_status_as_string/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n\n*/\n-- AlterTable\nALTER TABLE `Chat` ADD COLUMN `unreadMessages` INTEGER NOT NULL DEFAULT 0,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBot` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBotSetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Flowise` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `FlowiseSetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `IsOnWhatsapp` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Message` MODIFY `status` VARCHAR(30) NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` ADD COLUMN `splitMessages` BOOLEAN NULL DEFAULT false,\n    ADD COLUMN `timePerChar` INTEGER NULL DEFAULT 50,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- CreateTable\nCREATE TABLE `Pusher` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `appId` VARCHAR(100) NOT NULL,\n    `key` VARCHAR(100) NOT NULL,\n    `secret` VARCHAR(100) NOT NULL,\n    `cluster` VARCHAR(100) NOT NULL,\n    `useTLS` BOOLEAN NOT NULL DEFAULT false,\n    `events` JSON NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Pusher_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateIndex\nCREATE INDEX `Chat_remoteJid_idx` ON `Chat`(`remoteJid`);\n\n-- CreateIndex\nCREATE INDEX `Contact_remoteJid_idx` ON `Contact`(`remoteJid`);\n\n-- CreateIndex\nCREATE INDEX `Setting_instanceId_idx` ON `Setting`(`instanceId`);\n\n-- CreateIndex\nCREATE INDEX `Webhook_instanceId_idx` ON `Webhook`(`instanceId`);\n\n-- AddForeignKey\nALTER TABLE `Pusher` ADD CONSTRAINT `Pusher_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- RenameIndex\nALTER TABLE `Chat` RENAME INDEX `Chat_instanceId_fkey` TO `Chat_instanceId_idx`;\n\n-- RenameIndex\nALTER TABLE `Contact` RENAME INDEX `Contact_instanceId_fkey` TO `Contact_instanceId_idx`;\n\n-- RenameIndex\nALTER TABLE `Message` RENAME INDEX `Message_instanceId_fkey` TO `Message_instanceId_idx`;\n\n-- RenameIndex\nALTER TABLE `MessageUpdate` RENAME INDEX `MessageUpdate_instanceId_fkey` TO `MessageUpdate_instanceId_idx`;\n\n-- RenameIndex\nALTER TABLE `MessageUpdate` RENAME INDEX `MessageUpdate_messageId_fkey` TO `MessageUpdate_messageId_idx`;\n"
  },
  {
    "path": "prisma/mysql-migrations/20250214181954_add_wavoip_token_column/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - A unique constraint covering the columns `[instanceId,remoteJid]` on the table `Chat` will be added. If there are existing duplicate values, this will fail.\n\n*/\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `IsOnWhatsapp` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Pusher` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` ADD COLUMN `wavoipToken` VARCHAR(100) NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- CreateIndex\nCREATE UNIQUE INDEX `Chat_instanceId_remoteJid_key` ON `Chat`(`instanceId`, `remoteJid`);\n"
  },
  {
    "path": "prisma/mysql-migrations/20250225180031_add_nats_integration/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE `Nats` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `events` JSON NOT NULL,\n    `createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateIndex\nCREATE UNIQUE INDEX `Nats_instanceId_key` ON `Nats`(`instanceId`);\n\n-- AddForeignKey\nALTER TABLE `Nats` ADD CONSTRAINT `Nats_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;"
  },
  {
    "path": "prisma/mysql-migrations/20250510035200_add_wavoip_token_to_settings_table/migration.sql",
    "content": "/*\nWarnings:\n\n- A unique constraint covering the columns `[remoteJid,instanceId]` on the table `Chat` will be added. If there are existing duplicate values, this will fail.\n\n*/\n\n-- AlterTable\nSET @column_exists := (\n  SELECT COUNT(*) \n  FROM information_schema.columns \n  WHERE table_schema = DATABASE() \n    AND table_name = 'Setting' \n    AND column_name = 'wavoipToken'\n);\n\nSET @sql := IF(@column_exists = 0, \n  'ALTER TABLE Setting ADD COLUMN wavoipToken VARCHAR(100);', \n  'SELECT \"Column already exists\";'\n);\n\nPREPARE stmt FROM @sql;\nEXECUTE stmt;\nDEALLOCATE PREPARE stmt;\n\nALTER TABLE Chat ADD CONSTRAINT unique_remote_instance UNIQUE (remoteJid, instanceId);\n"
  },
  {
    "path": "prisma/mysql-migrations/20250514232744_add_n8n_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE `N8n` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255),\n    `webhookUrl` VARCHAR(255),\n    `basicAuthUser` VARCHAR(255),\n    `basicAuthPass` VARCHAR(255),\n    `expire` INTEGER DEFAULT 0,\n    `keywordFinish` VARCHAR(100),\n    `delayMessage` INTEGER,\n    `unknownMessage` VARCHAR(100),\n    `listeningFromMe` BOOLEAN DEFAULT false,\n    `stopBotFromMe` BOOLEAN DEFAULT false,\n    `keepOpen` BOOLEAN DEFAULT false,\n    `debounceTime` INTEGER,\n    `ignoreJids` JSON,\n    `splitMessages` BOOLEAN DEFAULT false,\n    `timePerChar` INTEGER DEFAULT 50,\n    `triggerType` ENUM('all', 'keyword', 'none') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `N8nSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER DEFAULT 0,\n    `keywordFinish` VARCHAR(100),\n    `delayMessage` INTEGER,\n    `unknownMessage` VARCHAR(100),\n    `listeningFromMe` BOOLEAN DEFAULT false,\n    `stopBotFromMe` BOOLEAN DEFAULT false,\n    `keepOpen` BOOLEAN DEFAULT false,\n    `debounceTime` INTEGER,\n    `ignoreJids` JSON,\n    `splitMessages` BOOLEAN DEFAULT false,\n    `timePerChar` INTEGER DEFAULT 50,\n    `createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `n8nIdFallback` VARCHAR(100),\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateIndex\nCREATE UNIQUE INDEX `N8nSetting_instanceId_key` ON `N8nSetting`(`instanceId`);\n\n-- AddForeignKey\nALTER TABLE `N8n` ADD CONSTRAINT `N8n_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `N8nSetting` ADD CONSTRAINT `N8nSetting_n8nIdFallback_fkey` FOREIGN KEY (`n8nIdFallback`) REFERENCES `N8n`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `N8nSetting` ADD CONSTRAINT `N8nSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/20250515211815_add_evoai_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE `Evoai` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT true,\n    `description` VARCHAR(255),\n    `agentUrl` VARCHAR(255),\n    `apiKey` VARCHAR(255),\n    `expire` INTEGER DEFAULT 0,\n    `keywordFinish` VARCHAR(100),\n    `delayMessage` INTEGER,\n    `unknownMessage` VARCHAR(100),\n    `listeningFromMe` BOOLEAN DEFAULT false,\n    `stopBotFromMe` BOOLEAN DEFAULT false,\n    `keepOpen` BOOLEAN DEFAULT false,\n    `debounceTime` INTEGER,\n    `ignoreJids` JSON,\n    `splitMessages` BOOLEAN DEFAULT false,\n    `timePerChar` INTEGER DEFAULT 50,\n    `triggerType` ENUM('all', 'keyword', 'none') NULL,\n    `triggerOperator` ENUM('contains', 'equals', 'startsWith', 'endsWith', 'regex') NULL,\n    `triggerValue` VARCHAR(191) NULL,\n    `createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateTable\nCREATE TABLE `EvoaiSetting` (\n    `id` VARCHAR(191) NOT NULL,\n    `expire` INTEGER DEFAULT 0,\n    `keywordFinish` VARCHAR(100),\n    `delayMessage` INTEGER,\n    `unknownMessage` VARCHAR(100),\n    `listeningFromMe` BOOLEAN DEFAULT false,\n    `stopBotFromMe` BOOLEAN DEFAULT false,\n    `keepOpen` BOOLEAN DEFAULT false,\n    `debounceTime` INTEGER,\n    `ignoreJids` JSON,\n    `splitMessages` BOOLEAN DEFAULT false,\n    `timePerChar` INTEGER DEFAULT 50,\n    `createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `evoaiIdFallback` VARCHAR(100),\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- CreateIndex\nCREATE UNIQUE INDEX `EvoaiSetting_instanceId_key` ON `EvoaiSetting`(`instanceId`);\n\n-- AddForeignKey\nALTER TABLE `Evoai` ADD CONSTRAINT `Evoai_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `EvoaiSetting` ADD CONSTRAINT `EvoaiSetting_evoaiIdFallback_fkey` FOREIGN KEY (`evoaiIdFallback`) REFERENCES `Evoai`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE `EvoaiSetting` ADD CONSTRAINT `EvoaiSetting_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/20250516012152_remove_unique_atribute_for_file_name_in_media/migration.sql",
    "content": "-- DropIndex\nALTER TABLE `Media` DROP INDEX `Media_fileName_key`;\n"
  },
  {
    "path": "prisma/mysql-migrations/20250612155048_add_coluns_trypebot_tables/migration.sql",
    "content": "-- AlterTable\nALTER TABLE `Typebot` ADD COLUMN     `splitMessages` BOOLEAN DEFAULT false,\nADD COLUMN     `timePerChar` INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` ADD COLUMN     `splitMessages` BOOLEAN DEFAULT false,\nADD COLUMN     `timePerChar` INTEGER DEFAULT 50;\n"
  },
  {
    "path": "prisma/mysql-migrations/20250613143000_add_lid_column_to_is_onwhatsapp/migration.sql",
    "content": "-- AlterTable\nALTER TABLE `IsOnWhatsapp` ADD COLUMN     `lid` VARCHAR(100);\n"
  },
  {
    "path": "prisma/mysql-migrations/20250918183910_add_kafka_integration/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to alter the column `createdAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chat` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Chatwoot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Contact` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Dify` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `DifySetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Evoai` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Evoai` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvoaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvoaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `EvolutionBotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Flowise` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `FlowiseSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `disconnectionAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Instance` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IntegrationSession` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the column `lid` on the `IsOnWhatsapp` table. All the data in the column will be lost.\n  - You are about to alter the column `createdAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `IsOnWhatsapp` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Label` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Media` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `N8n` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `N8n` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `N8nSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `N8nSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Nats` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Nats` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiBot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiCreds` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `OpenaiSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Proxy` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Pusher` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Rabbitmq` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Session` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Setting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Sqs` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Template` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the column `splitMessages` on the `Typebot` table. All the data in the column will be lost.\n  - You are about to drop the column `timePerChar` on the `Typebot` table. All the data in the column will be lost.\n  - You are about to alter the column `createdAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Typebot` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to drop the column `splitMessages` on the `TypebotSetting` table. All the data in the column will be lost.\n  - You are about to drop the column `timePerChar` on the `TypebotSetting` table. All the data in the column will be lost.\n  - You are about to alter the column `createdAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `TypebotSetting` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Webhook` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `createdAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n  - You are about to alter the column `updatedAt` on the `Websocket` table. The data in that column could be lost. The data in that column will be cast from `Timestamp(0)` to `Timestamp`.\n\n*/\n-- DropIndex\nDROP INDEX `unique_remote_instance` ON `Chat`;\n\n-- AlterTable\nALTER TABLE `Chat` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Chatwoot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Contact` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `Dify` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `DifySetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Evoai` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvoaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `EvolutionBotSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Flowise` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `FlowiseSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Instance` MODIFY `disconnectionAt` TIMESTAMP NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `IntegrationSession` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `IsOnWhatsapp` DROP COLUMN `lid`,\n    MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Label` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Media` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `N8n` MODIFY `triggerType` ENUM('all', 'keyword', 'none', 'advanced') NULL,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `N8nSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Nats` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiBot` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiCreds` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `OpenaiSetting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Proxy` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Pusher` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Rabbitmq` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Session` MODIFY `createdAt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;\n\n-- AlterTable\nALTER TABLE `Setting` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Sqs` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Template` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Typebot` DROP COLUMN `splitMessages`,\n    DROP COLUMN `timePerChar`,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NULL;\n\n-- AlterTable\nALTER TABLE `TypebotSetting` DROP COLUMN `splitMessages`,\n    DROP COLUMN `timePerChar`,\n    MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Webhook` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- AlterTable\nALTER TABLE `Websocket` MODIFY `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    MODIFY `updatedAt` TIMESTAMP NOT NULL;\n\n-- CreateTable\nCREATE TABLE `Kafka` (\n    `id` VARCHAR(191) NOT NULL,\n    `enabled` BOOLEAN NOT NULL DEFAULT false,\n    `events` JSON NOT NULL,\n    `createdAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,\n    `updatedAt` TIMESTAMP NOT NULL,\n    `instanceId` VARCHAR(191) NOT NULL,\n\n    UNIQUE INDEX `Kafka_instanceId_key`(`instanceId`),\n    PRIMARY KEY (`id`)\n) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n\n-- AddForeignKey\nALTER TABLE `Kafka` ADD CONSTRAINT `Kafka_instanceId_fkey` FOREIGN KEY (`instanceId`) REFERENCES `Instance`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/mysql-migrations/migration_lock.toml",
    "content": "# Please do not edit this file manually\n# It should be added in your version-control system (e.g., Git)\nprovider = \"mysql\""
  },
  {
    "path": "prisma/mysql-schema.prisma",
    "content": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"mysql\"\n  url      = env(\"DATABASE_CONNECTION_URI\")\n}\n\nenum InstanceConnectionStatus {\n  open\n  close\n  connecting\n}\n\nenum DeviceMessage {\n  ios\n  android\n  web\n  unknown\n  desktop\n}\n\nenum SessionStatus {\n  opened\n  closed\n  paused\n}\n\nenum TriggerType {\n  all\n  keyword\n  none\n  advanced\n}\n\nenum TriggerOperator {\n  contains\n  equals\n  startsWith\n  endsWith\n  regex\n}\n\nenum OpenaiBotType {\n  assistant\n  chatCompletion\n}\n\nenum DifyBotType {\n  chatBot\n  textGenerator\n  agent\n  workflow\n}\n\nmodel Instance {\n  id                      String                   @id @default(cuid())\n  name                    String                   @unique @db.VarChar(255)\n  connectionStatus        InstanceConnectionStatus @default(open)\n  ownerJid                String?                  @db.VarChar(100)\n  profileName             String?                  @db.VarChar(100)\n  profilePicUrl           String?                  @db.VarChar(500)\n  integration             String?                  @db.VarChar(100)\n  number                  String?                  @db.VarChar(100)\n  businessId              String?                  @db.VarChar(100)\n  token                   String?                  @db.VarChar(255)\n  clientName              String?                  @db.VarChar(100)\n  disconnectionReasonCode Int?                     @db.Int\n  disconnectionObject     Json?                    @db.Json\n  disconnectionAt         DateTime?                @db.Timestamp\n  createdAt               DateTime?                @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt               DateTime?                @updatedAt @db.Timestamp\n  Chat                    Chat[]\n  Contact                 Contact[]\n  Message                 Message[]\n  Webhook                 Webhook?\n  Chatwoot                Chatwoot?\n  Label                   Label[]\n  Proxy                   Proxy?\n  Setting                 Setting?\n  Rabbitmq                Rabbitmq?\n  Nats                    Nats?\n  Sqs                     Sqs?\n  Kafka                   Kafka?\n  Websocket               Websocket?\n  Typebot                 Typebot[]\n  Session                 Session?\n  MessageUpdate           MessageUpdate[]\n  TypebotSetting          TypebotSetting?\n  Media                   Media[]\n  OpenaiCreds             OpenaiCreds[]\n  OpenaiBot               OpenaiBot[]\n  OpenaiSetting           OpenaiSetting?\n  Template                Template[]\n  Dify                    Dify[]\n  DifySetting             DifySetting?\n  IntegrationSession      IntegrationSession[]\n  EvolutionBot            EvolutionBot[]\n  EvolutionBotSetting     EvolutionBotSetting?\n  Flowise                 Flowise[]\n  FlowiseSetting          FlowiseSetting?\n  N8n                     N8n[]\n  N8nSetting              N8nSetting?\n  Evoai                   Evoai[]\n  EvoaiSetting            EvoaiSetting?\n  Pusher                  Pusher?\n}\n\nmodel Session {\n  id        String   @id @default(cuid())\n  sessionId String   @unique\n  creds     String?  @db.Text\n  createdAt DateTime @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  Instance  Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade)\n}\n\nmodel Chat {\n  id             String    @id @default(cuid())\n  remoteJid      String    @db.VarChar(100)\n  name           String?   @db.VarChar(100)\n  labels         Json?     @db.Json\n  createdAt      DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt      DateTime? @updatedAt @db.Timestamp\n  Instance       Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId     String\n  unreadMessages Int       @default(0)\n\n  @@unique([instanceId, remoteJid])\n  @@index([instanceId])\n  @@index([remoteJid])\n}\n\nmodel Contact {\n  id            String    @id @default(cuid())\n  remoteJid     String    @db.VarChar(100)\n  pushName      String?   @db.VarChar(100)\n  profilePicUrl String?   @db.VarChar(500)\n  createdAt     DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt     DateTime? @updatedAt @db.Timestamp\n  Instance      Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId    String\n\n  @@unique([remoteJid, instanceId])\n  @@index([remoteJid])\n  @@index([instanceId])\n}\n\nmodel Message {\n  id                           String          @id @default(cuid())\n  key                          Json            @db.Json\n  pushName                     String?         @db.VarChar(100)\n  participant                  String?         @db.VarChar(100)\n  messageType                  String          @db.VarChar(100)\n  message                      Json            @db.Json\n  contextInfo                  Json?           @db.Json\n  source                       DeviceMessage\n  messageTimestamp             Int             @db.Int\n  chatwootMessageId            Int?            @db.Int\n  chatwootInboxId              Int?            @db.Int\n  chatwootConversationId       Int?            @db.Int\n  chatwootContactInboxSourceId String?         @db.VarChar(100)\n  chatwootIsRead               Boolean?        @default(false)\n  Instance                     Instance        @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId                   String\n  typebotSessionId             String?\n  MessageUpdate                MessageUpdate[]\n  Media                        Media?\n  webhookUrl                   String?         @db.VarChar(500)\n  status                       String?         @db.VarChar(30)\n\n  sessionId String?\n  session   IntegrationSession? @relation(fields: [sessionId], references: [id])\n\n  @@index([instanceId])\n}\n\nmodel MessageUpdate {\n  id          String   @id @default(cuid())\n  keyId       String   @db.VarChar(100)\n  remoteJid   String   @db.VarChar(100)\n  fromMe      Boolean\n  participant String?  @db.VarChar(100)\n  pollUpdates Json?    @db.Json\n  status      String   @db.VarChar(30)\n  Message     Message  @relation(fields: [messageId], references: [id], onDelete: Cascade)\n  messageId   String\n  Instance    Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId  String\n\n  @@index([instanceId])\n  @@index([messageId])\n}\n\nmodel Webhook {\n  id              String    @id @default(cuid())\n  url             String    @db.VarChar(500)\n  headers         Json?     @db.Json\n  enabled         Boolean?  @default(true)\n  events          Json?     @db.Json\n  webhookByEvents Boolean?  @default(false)\n  webhookBase64   Boolean?  @default(false)\n  createdAt       DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n\n  @@index([instanceId])\n}\n\nmodel Chatwoot {\n  id                      String    @id @default(cuid())\n  enabled                 Boolean?  @default(true)\n  accountId               String?   @db.VarChar(100)\n  token                   String?   @db.VarChar(100)\n  url                     String?   @db.VarChar(500)\n  nameInbox               String?   @db.VarChar(100)\n  signMsg                 Boolean?  @default(false)\n  signDelimiter           String?   @db.VarChar(100)\n  number                  String?   @db.VarChar(100)\n  reopenConversation      Boolean?  @default(false)\n  conversationPending     Boolean?  @default(false)\n  mergeBrazilContacts     Boolean?  @default(false)\n  importContacts          Boolean?  @default(false)\n  importMessages          Boolean?  @default(false)\n  daysLimitImportMessages Int?      @db.Int\n  organization            String?   @db.VarChar(100)\n  logo                    String?   @db.VarChar(500)\n  ignoreJids              Json?\n  createdAt               DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt               DateTime  @updatedAt @db.Timestamp\n  Instance                Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId              String    @unique\n}\n\nmodel Label {\n  id           String    @id @default(cuid())\n  labelId      String?   @db.VarChar(100)\n  name         String    @db.VarChar(100)\n  color        String    @db.VarChar(100)\n  predefinedId String?   @db.VarChar(100)\n  createdAt    DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt    DateTime  @updatedAt @db.Timestamp\n  Instance     Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId   String\n}\n\nmodel Proxy {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  host       String    @db.VarChar(100)\n  port       String    @db.VarChar(100)\n  protocol   String    @db.VarChar(100)\n  username   String    @db.VarChar(100)\n  password   String    @db.VarChar(100)\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Setting {\n  id              String    @id @default(cuid())\n  rejectCall      Boolean   @default(false)\n  msgCall         String?   @db.VarChar(100)\n  groupsIgnore    Boolean   @default(false)\n  alwaysOnline    Boolean   @default(false)\n  readMessages    Boolean   @default(false)\n  readStatus      Boolean   @default(false)\n  syncFullHistory Boolean   @default(false)\n  wavoipToken     String?   @db.VarChar(100)\n  createdAt       DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n\n  @@index([instanceId])\n}\n\nmodel Rabbitmq {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  events     Json      @db.Json\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Nats {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  events     Json      @db.Json\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Sqs {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  events     Json      @db.Json\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Kafka {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  events     Json      @db.Json\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Websocket {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  events     Json      @db.Json\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Pusher {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false)\n  appId      String    @db.VarChar(100)\n  key        String    @db.VarChar(100)\n  secret     String    @db.VarChar(100)\n  cluster    String    @db.VarChar(100)\n  useTLS     Boolean   @default(false)\n  events     Json      @db.Json\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Typebot {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true)\n  description     String?          @db.VarChar(255)\n  url             String           @db.VarChar(500)\n  typebot         String           @db.VarChar(100)\n  expire          Int?             @default(0) @db.Int\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Int\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false)\n  stopBotFromMe   Boolean?         @default(false)\n  keepOpen        Boolean?         @default(false)\n  debounceTime    Int?             @db.Int\n  createdAt       DateTime?        @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime?        @updatedAt @db.Timestamp\n  ignoreJids      Json?\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  TypebotSetting  TypebotSetting[]\n}\n\nmodel TypebotSetting {\n  id                String    @id @default(cuid())\n  expire            Int?      @default(0) @db.Int\n  keywordFinish     String?   @db.VarChar(100)\n  delayMessage      Int?      @db.Int\n  unknownMessage    String?   @db.VarChar(100)\n  listeningFromMe   Boolean?  @default(false)\n  stopBotFromMe     Boolean?  @default(false)\n  keepOpen          Boolean?  @default(false)\n  debounceTime      Int?      @db.Int\n  typebotIdFallback String?   @db.VarChar(100)\n  ignoreJids        Json?\n  createdAt         DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt         DateTime  @updatedAt @db.Timestamp\n  Fallback          Typebot?  @relation(fields: [typebotIdFallback], references: [id])\n  Instance          Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String    @unique\n}\n\nmodel IntegrationSession {\n  id         String        @id @default(cuid())\n  sessionId  String        @db.VarChar(255)\n  remoteJid  String        @db.VarChar(100)\n  pushName   String?\n  status     SessionStatus\n  awaitUser  Boolean       @default(false)\n  context    Json?\n  type       String?       @db.VarChar(100)\n  createdAt  DateTime?     @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime      @updatedAt @db.Timestamp\n  Message    Message[]\n  Instance   Instance      @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n  parameters Json?\n\n  botId String?\n}\n\nmodel Media {\n  id         String    @id @default(cuid())\n  fileName   String    @db.VarChar(500)\n  type       String    @db.VarChar(100)\n  mimetype   String    @db.VarChar(100)\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  Message    Message   @relation(fields: [messageId], references: [id], onDelete: Cascade)\n  messageId  String    @unique\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n}\n\nmodel OpenaiCreds {\n  id              String         @id @default(cuid())\n  name            String?        @unique @db.VarChar(255)\n  apiKey          String?        @unique @db.VarChar(255)\n  createdAt       DateTime?      @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime       @updatedAt @db.Timestamp\n  Instance        Instance       @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  OpenaiAssistant OpenaiBot[]\n  OpenaiSetting   OpenaiSetting?\n}\n\nmodel OpenaiBot {\n  id                String           @id @default(cuid())\n  enabled           Boolean          @default(true)\n  description       String?          @db.VarChar(255)\n  botType           OpenaiBotType\n  assistantId       String?          @db.VarChar(255)\n  functionUrl       String?          @db.VarChar(500)\n  model             String?          @db.VarChar(100)\n  systemMessages    Json?            @db.Json\n  assistantMessages Json?            @db.Json\n  userMessages      Json?            @db.Json\n  maxTokens         Int?             @db.Int\n  expire            Int?             @default(0) @db.Int\n  keywordFinish     String?          @db.VarChar(100)\n  delayMessage      Int?             @db.Int\n  unknownMessage    String?          @db.VarChar(100)\n  listeningFromMe   Boolean?         @default(false)\n  stopBotFromMe     Boolean?         @default(false)\n  keepOpen          Boolean?         @default(false)\n  debounceTime      Int?             @db.Int\n  ignoreJids        Json?\n  splitMessages     Boolean?         @default(false)\n  timePerChar       Int?             @default(50) @db.Int\n  triggerType       TriggerType?\n  triggerOperator   TriggerOperator?\n  triggerValue      String?\n  createdAt         DateTime?        @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt         DateTime         @updatedAt @db.Timestamp\n  OpenaiCreds       OpenaiCreds      @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)\n  openaiCredsId     String\n  Instance          Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String\n  OpenaiSetting     OpenaiSetting[]\n}\n\nmodel OpenaiSetting {\n  id               String       @id @default(cuid())\n  expire           Int?         @default(0) @db.Int\n  keywordFinish    String?      @db.VarChar(100)\n  delayMessage     Int?         @db.Int\n  unknownMessage   String?      @db.VarChar(100)\n  listeningFromMe  Boolean?     @default(false)\n  stopBotFromMe    Boolean?     @default(false)\n  keepOpen         Boolean?     @default(false)\n  debounceTime     Int?         @db.Int\n  ignoreJids       Json?\n  splitMessages    Boolean?     @default(false)\n  timePerChar      Int?         @default(50) @db.Int\n  speechToText     Boolean?     @default(false)\n  createdAt        DateTime?    @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt        DateTime     @updatedAt @db.Timestamp\n  OpenaiCreds      OpenaiCreds? @relation(fields: [openaiCredsId], references: [id])\n  openaiCredsId    String       @unique\n  Fallback         OpenaiBot?   @relation(fields: [openaiIdFallback], references: [id])\n  openaiIdFallback String?      @db.VarChar(100)\n  Instance         Instance     @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId       String       @unique\n}\n\nmodel Template {\n  id         String    @id @default(cuid())\n  templateId String    @unique @db.VarChar(255)\n  name       String    @unique @db.VarChar(255)\n  template   Json      @db.Json\n  webhookUrl String?   @db.VarChar(500)\n  createdAt  DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n}\n\nmodel Dify {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true)\n  description     String?          @db.VarChar(255)\n  botType         DifyBotType\n  apiUrl          String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Int\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Int\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false)\n  stopBotFromMe   Boolean?         @default(false)\n  keepOpen        Boolean?         @default(false)\n  debounceTime    Int?             @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false)\n  timePerChar     Int?             @default(50) @db.Int\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  DifySetting     DifySetting[]\n}\n\nmodel DifySetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Int\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Int\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false)\n  stopBotFromMe   Boolean?  @default(false)\n  keepOpen        Boolean?  @default(false)\n  debounceTime    Int?      @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false)\n  timePerChar     Int?      @default(50) @db.Int\n  createdAt       DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        Dify?     @relation(fields: [difyIdFallback], references: [id])\n  difyIdFallback  String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n\nmodel EvolutionBot {\n  id                  String                @id @default(cuid())\n  enabled             Boolean               @default(true)\n  description         String?               @db.VarChar(255)\n  apiUrl              String?               @db.VarChar(255)\n  apiKey              String?               @db.VarChar(255)\n  expire              Int?                  @default(0) @db.Int\n  keywordFinish       String?               @db.VarChar(100)\n  delayMessage        Int?                  @db.Int\n  unknownMessage      String?               @db.VarChar(100)\n  listeningFromMe     Boolean?              @default(false)\n  stopBotFromMe       Boolean?              @default(false)\n  keepOpen            Boolean?              @default(false)\n  debounceTime        Int?                  @db.Int\n  ignoreJids          Json?\n  splitMessages       Boolean?              @default(false)\n  timePerChar         Int?                  @default(50) @db.Int\n  triggerType         TriggerType?\n  triggerOperator     TriggerOperator?\n  triggerValue        String?\n  createdAt           DateTime?             @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt           DateTime              @updatedAt @db.Timestamp\n  Instance            Instance              @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId          String\n  EvolutionBotSetting EvolutionBotSetting[]\n}\n\nmodel EvolutionBotSetting {\n  id              String        @id @default(cuid())\n  expire          Int?          @default(0) @db.Int\n  keywordFinish   String?       @db.VarChar(100)\n  delayMessage    Int?          @db.Int\n  unknownMessage  String?       @db.VarChar(100)\n  listeningFromMe Boolean?      @default(false)\n  stopBotFromMe   Boolean?      @default(false)\n  keepOpen        Boolean?      @default(false)\n  debounceTime    Int?          @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?      @default(false)\n  timePerChar     Int?          @default(50) @db.Int\n  createdAt       DateTime?     @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime      @updatedAt @db.Timestamp\n  Fallback        EvolutionBot? @relation(fields: [botIdFallback], references: [id])\n  botIdFallback   String?       @db.VarChar(100)\n  Instance        Instance      @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String        @unique\n}\n\nmodel Flowise {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true)\n  description     String?          @db.VarChar(255)\n  apiUrl          String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Int\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Int\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false)\n  stopBotFromMe   Boolean?         @default(false)\n  keepOpen        Boolean?         @default(false)\n  debounceTime    Int?             @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false)\n  timePerChar     Int?             @default(50) @db.Int\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  FlowiseSetting  FlowiseSetting[]\n}\n\nmodel FlowiseSetting {\n  id                String    @id @default(cuid())\n  expire            Int?      @default(0) @db.Int\n  keywordFinish     String?   @db.VarChar(100)\n  delayMessage      Int?      @db.Int\n  unknownMessage    String?   @db.VarChar(100)\n  listeningFromMe   Boolean?  @default(false)\n  stopBotFromMe     Boolean?  @default(false)\n  keepOpen          Boolean?  @default(false)\n  debounceTime      Int?      @db.Int\n  ignoreJids        Json?\n  splitMessages     Boolean?  @default(false)\n  timePerChar       Int?      @default(50) @db.Int\n  createdAt         DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt         DateTime  @updatedAt @db.Timestamp\n  Fallback          Flowise?  @relation(fields: [flowiseIdFallback], references: [id])\n  flowiseIdFallback String?   @db.VarChar(100)\n  Instance          Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String    @unique\n}\n\nmodel IsOnWhatsapp {\n  id         String   @id @default(cuid())\n  remoteJid  String   @unique @db.VarChar(100)\n  jidOptions String\n  createdAt  DateTime @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt  DateTime @updatedAt @db.Timestamp\n}\n\nmodel N8n {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.TinyInt()\n  description     String?          @db.VarChar(255)\n  webhookUrl      String?          @db.VarChar(255)\n  basicAuthUser   String?          @db.VarChar(255)\n  basicAuthPass   String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Int\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Int\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false)\n  stopBotFromMe   Boolean?         @default(false)\n  keepOpen        Boolean?         @default(false)\n  debounceTime    Int?             @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false)\n  timePerChar     Int?             @default(50) @db.Int\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  N8nSetting      N8nSetting[]\n}\n\nmodel N8nSetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Int\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Int\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false)\n  stopBotFromMe   Boolean?  @default(false)\n  keepOpen        Boolean?  @default(false)\n  debounceTime    Int?      @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false)\n  timePerChar     Int?      @default(50) @db.Int\n  createdAt       DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        N8n?      @relation(fields: [n8nIdFallback], references: [id])\n  n8nIdFallback   String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n\nmodel Evoai {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.TinyInt()\n  description     String?          @db.VarChar(255)\n  agentUrl        String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Int\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Int\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false)\n  stopBotFromMe   Boolean?         @default(false)\n  keepOpen        Boolean?         @default(false)\n  debounceTime    Int?             @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false)\n  timePerChar     Int?             @default(50) @db.Int\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  EvoaiSetting    EvoaiSetting[]\n}\n\nmodel EvoaiSetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Int\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Int\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false)\n  stopBotFromMe   Boolean?  @default(false)\n  keepOpen        Boolean?  @default(false)\n  debounceTime    Int?      @db.Int\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false)\n  timePerChar     Int?      @default(50) @db.Int\n  createdAt       DateTime? @default(dbgenerated(\"CURRENT_TIMESTAMP\")) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        Evoai?    @relation(fields: [evoaiIdFallback], references: [id])\n  evoaiIdFallback String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240609181238_init/migration.sql",
    "content": "-- CreateEnum\nCREATE TYPE \"InstanceConnectionStatus\" AS ENUM ('open', 'close', 'connecting');\n\n-- CreateEnum\nCREATE TYPE \"DeviceMessage\" AS ENUM ('ios', 'android', 'web', 'unknown', 'desktop');\n\n-- CreateEnum\nCREATE TYPE \"TypebotSessionStatus\" AS ENUM ('open', 'closed', 'paused');\n\n-- CreateEnum\nCREATE TYPE \"TriggerType\" AS ENUM ('all', 'keyword');\n\n-- CreateEnum\nCREATE TYPE \"TriggerOperator\" AS ENUM ('contains', 'equals', 'startsWith', 'endsWith');\n\n-- CreateTable\nCREATE TABLE \"Instance\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" VARCHAR(255) NOT NULL,\n    \"connectionStatus\" \"InstanceConnectionStatus\" NOT NULL DEFAULT 'open',\n    \"ownerJid\" VARCHAR(100),\n    \"profilePicUrl\" VARCHAR(500),\n    \"integration\" VARCHAR(100),\n    \"number\" VARCHAR(100),\n    \"token\" VARCHAR(255),\n    \"clientName\" VARCHAR(100),\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP,\n\n    CONSTRAINT \"Instance_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Session\" (\n    \"id\" TEXT NOT NULL,\n    \"sessionId\" TEXT NOT NULL,\n    \"creds\" TEXT,\n    \"createdAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n\n    CONSTRAINT \"Session_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Chat\" (\n    \"id\" TEXT NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"labels\" JSONB,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Chat_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Contact\" (\n    \"id\" TEXT NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"pushName\" VARCHAR(100),\n    \"profilePicUrl\" VARCHAR(500),\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Contact_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Message\" (\n    \"id\" TEXT NOT NULL,\n    \"key\" JSONB NOT NULL,\n    \"pushName\" VARCHAR(100),\n    \"participant\" VARCHAR(100),\n    \"messageType\" VARCHAR(100) NOT NULL,\n    \"message\" JSONB NOT NULL,\n    \"contextInfo\" JSONB,\n    \"source\" \"DeviceMessage\" NOT NULL,\n    \"messageTimestamp\" INTEGER NOT NULL,\n    \"chatwootMessageId\" INTEGER,\n    \"chatwootInboxId\" INTEGER,\n    \"chatwootConversationId\" INTEGER,\n    \"chatwootContactInboxSourceId\" VARCHAR(100),\n    \"chatwootIsRead\" BOOLEAN,\n    \"instanceId\" TEXT NOT NULL,\n    \"typebotSessionId\" TEXT,\n\n    CONSTRAINT \"Message_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"MessageUpdate\" (\n    \"id\" TEXT NOT NULL,\n    \"keyId\" VARCHAR(100) NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"fromMe\" BOOLEAN NOT NULL,\n    \"participant\" VARCHAR(100),\n    \"pollUpdates\" JSONB,\n    \"status\" VARCHAR(30) NOT NULL,\n    \"messageId\" TEXT NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"MessageUpdate_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Webhook\" (\n    \"id\" TEXT NOT NULL,\n    \"url\" VARCHAR(500) NOT NULL,\n    \"enabled\" BOOLEAN DEFAULT true,\n    \"events\" JSONB,\n    \"webhookByEvents\" BOOLEAN DEFAULT false,\n    \"webhookBase64\" BOOLEAN DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Webhook_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Chatwoot\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN DEFAULT true,\n    \"accountId\" VARCHAR(100),\n    \"token\" VARCHAR(100),\n    \"url\" VARCHAR(500),\n    \"nameInbox\" VARCHAR(100),\n    \"signMsg\" BOOLEAN DEFAULT false,\n    \"signDelimiter\" VARCHAR(100),\n    \"number\" VARCHAR(100),\n    \"reopenConversation\" BOOLEAN DEFAULT false,\n    \"conversationPending\" BOOLEAN DEFAULT false,\n    \"mergeBrazilContacts\" BOOLEAN DEFAULT false,\n    \"importContacts\" BOOLEAN DEFAULT false,\n    \"importMessages\" BOOLEAN DEFAULT false,\n    \"daysLimitImportMessages\" INTEGER,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Chatwoot_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Label\" (\n    \"id\" TEXT NOT NULL,\n    \"labelId\" VARCHAR(100),\n    \"name\" VARCHAR(100) NOT NULL,\n    \"color\" VARCHAR(100) NOT NULL,\n    \"predefinedId\" VARCHAR(100),\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Label_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Proxy\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"host\" VARCHAR(100) NOT NULL,\n    \"port\" VARCHAR(100) NOT NULL,\n    \"protocol\" VARCHAR(100) NOT NULL,\n    \"username\" VARCHAR(100) NOT NULL,\n    \"password\" VARCHAR(100) NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Proxy_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Setting\" (\n    \"id\" TEXT NOT NULL,\n    \"rejectCall\" BOOLEAN NOT NULL DEFAULT false,\n    \"msgCall\" VARCHAR(100),\n    \"groupsIgnore\" BOOLEAN NOT NULL DEFAULT false,\n    \"alwaysOnline\" BOOLEAN NOT NULL DEFAULT false,\n    \"readMessages\" BOOLEAN NOT NULL DEFAULT false,\n    \"readStatus\" BOOLEAN NOT NULL DEFAULT false,\n    \"syncFullHistory\" BOOLEAN NOT NULL DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Setting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Rabbitmq\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"events\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Rabbitmq_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Sqs\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"events\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Sqs_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Websocket\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"events\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Websocket_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"Typebot\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"url\" VARCHAR(500) NOT NULL,\n    \"typebot\" VARCHAR(100) NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Typebot_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"TypebotSession\" (\n    \"id\" TEXT NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"pushName\" VARCHAR(100),\n    \"sessionId\" VARCHAR(100) NOT NULL,\n    \"status\" VARCHAR(100) NOT NULL,\n    \"prefilledVariables\" JSONB,\n    \"awaitUser\" BOOLEAN NOT NULL DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"typebotId\" TEXT NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"TypebotSession_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"TypebotSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"TypebotSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Instance_name_key\" ON \"Instance\"(\"name\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Instance_token_key\" ON \"Instance\"(\"token\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Session_sessionId_key\" ON \"Session\"(\"sessionId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Webhook_instanceId_key\" ON \"Webhook\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Chatwoot_instanceId_key\" ON \"Chatwoot\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Label_labelId_key\" ON \"Label\"(\"labelId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Proxy_instanceId_key\" ON \"Proxy\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Setting_instanceId_key\" ON \"Setting\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Rabbitmq_instanceId_key\" ON \"Rabbitmq\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Sqs_instanceId_key\" ON \"Sqs\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Websocket_instanceId_key\" ON \"Websocket\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"TypebotSetting_instanceId_key\" ON \"TypebotSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Session\" ADD CONSTRAINT \"Session_sessionId_fkey\" FOREIGN KEY (\"sessionId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Chat\" ADD CONSTRAINT \"Chat_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Contact\" ADD CONSTRAINT \"Contact_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Message\" ADD CONSTRAINT \"Message_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Message\" ADD CONSTRAINT \"Message_typebotSessionId_fkey\" FOREIGN KEY (\"typebotSessionId\") REFERENCES \"TypebotSession\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"MessageUpdate\" ADD CONSTRAINT \"MessageUpdate_messageId_fkey\" FOREIGN KEY (\"messageId\") REFERENCES \"Message\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"MessageUpdate\" ADD CONSTRAINT \"MessageUpdate_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Webhook\" ADD CONSTRAINT \"Webhook_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Chatwoot\" ADD CONSTRAINT \"Chatwoot_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Label\" ADD CONSTRAINT \"Label_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Proxy\" ADD CONSTRAINT \"Proxy_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Setting\" ADD CONSTRAINT \"Setting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Rabbitmq\" ADD CONSTRAINT \"Rabbitmq_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Sqs\" ADD CONSTRAINT \"Sqs_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Websocket\" ADD CONSTRAINT \"Websocket_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Typebot\" ADD CONSTRAINT \"Typebot_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"TypebotSession\" ADD CONSTRAINT \"TypebotSession_typebotId_fkey\" FOREIGN KEY (\"typebotId\") REFERENCES \"Typebot\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"TypebotSession\" ADD CONSTRAINT \"TypebotSession_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"TypebotSetting\" ADD CONSTRAINT \"TypebotSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240610144159_create_column_profile_name_instance/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Instance\" ADD COLUMN     \"profileName\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240611125754_create_columns_whitelabel_chatwoot/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Chatwoot\" ADD COLUMN     \"logo\" VARCHAR(500),\nADD COLUMN     \"organization\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240611202817_create_columns_debounce_time_typebot/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Typebot\" ADD COLUMN     \"debounceTime\" INTEGER;\n\n-- AlterTable\nALTER TABLE \"TypebotSetting\" ADD COLUMN     \"debounceTime\" INTEGER;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240712144948_add_business_id_column_to_instances/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Instance\" ADD COLUMN     \"businessId\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240712150256_create_templates_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Template\" (\n    \"id\" TEXT NOT NULL,\n    \"name\" VARCHAR(255) NOT NULL,\n    \"language\" VARCHAR(255) NOT NULL,\n    \"templateId\" VARCHAR(255) NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Template_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Template_templateId_key\" ON \"Template\"(\"templateId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Template_instanceId_key\" ON \"Template\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Template\" ADD CONSTRAINT \"Template_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240712155950_adjusts_in_templates_table/migration.sql",
    "content": "-- DropIndex\nDROP INDEX \"Template_instanceId_key\";\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240712162206_remove_templates_table/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the `Template` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE \"Template\" DROP CONSTRAINT \"Template_instanceId_fkey\";\n\n-- DropTable\nDROP TABLE \"Template\";\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240712223655_column_fallback_typebot/migration.sql",
    "content": "-- AlterEnum\nALTER TYPE \"TriggerOperator\" ADD VALUE 'regex';\n\n-- AlterTable\nALTER TABLE \"TypebotSetting\" ADD COLUMN     \"typebotIdFallback\" VARCHAR(100);\n\n-- AddForeignKey\nALTER TABLE \"TypebotSetting\" ADD CONSTRAINT \"TypebotSetting_typebotIdFallback_fkey\" FOREIGN KEY (\"typebotIdFallback\") REFERENCES \"Typebot\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240712230631_column_ignore_jids_typebot/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Typebot\" ADD COLUMN     \"ignoreJids\" JSONB;\n\n-- AlterTable\nALTER TABLE \"TypebotSetting\" ADD COLUMN     \"ignoreJids\" JSONB;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240713184337_add_media_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Media\" (\n    \"id\" TEXT NOT NULL,\n    \"fileName\" VARCHAR(500) NOT NULL,\n    \"type\" VARCHAR(100) NOT NULL,\n    \"mimetype\" VARCHAR(100) NOT NULL,\n    \"createdAt\" DATE DEFAULT CURRENT_TIMESTAMP,\n    \"messageId\" TEXT NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Media_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Media_fileName_key\" ON \"Media\"(\"fileName\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Media_messageId_key\" ON \"Media\"(\"messageId\");\n\n-- AddForeignKey\nALTER TABLE \"Media\" ADD CONSTRAINT \"Media_messageId_fkey\" FOREIGN KEY (\"messageId\") REFERENCES \"Message\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Media\" ADD CONSTRAINT \"Media_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240718121437_add_openai_tables/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Message\" ADD COLUMN     \"openaiSessionId\" TEXT;\n\n-- CreateTable\nCREATE TABLE \"OpenaiCreds\" (\n    \"id\" TEXT NOT NULL,\n    \"apiKey\" VARCHAR(255) NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"OpenaiCreds_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"OpenaiBot\" (\n    \"id\" TEXT NOT NULL,\n    \"botType\" VARCHAR(100) NOT NULL,\n    \"assistantId\" VARCHAR(255),\n    \"model\" VARCHAR(100),\n    \"systemMessages\" JSONB,\n    \"assistantMessages\" JSONB,\n    \"userMessages\" JSONB,\n    \"maxTokens\" INTEGER,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"openaiCredsId\" TEXT NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"OpenaiBot_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"OpenaiSession\" (\n    \"id\" TEXT NOT NULL,\n    \"sessionId\" VARCHAR(255) NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"status\" \"TypebotSessionStatus\" NOT NULL,\n    \"awaitUser\" BOOLEAN NOT NULL DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"openaiBotId\" TEXT NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"OpenaiSession_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"OpenaiSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"openaiCredsId\" TEXT NOT NULL,\n    \"openaiIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"OpenaiSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"OpenaiCreds_apiKey_key\" ON \"OpenaiCreds\"(\"apiKey\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"OpenaiCreds_instanceId_key\" ON \"OpenaiCreds\"(\"instanceId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"OpenaiBot_assistantId_key\" ON \"OpenaiBot\"(\"assistantId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"OpenaiSetting_instanceId_key\" ON \"OpenaiSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Message\" ADD CONSTRAINT \"Message_openaiSessionId_fkey\" FOREIGN KEY (\"openaiSessionId\") REFERENCES \"OpenaiSession\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiCreds\" ADD CONSTRAINT \"OpenaiCreds_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiBot\" ADD CONSTRAINT \"OpenaiBot_openaiCredsId_fkey\" FOREIGN KEY (\"openaiCredsId\") REFERENCES \"OpenaiCreds\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiBot\" ADD CONSTRAINT \"OpenaiBot_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiSession\" ADD CONSTRAINT \"OpenaiSession_openaiBotId_fkey\" FOREIGN KEY (\"openaiBotId\") REFERENCES \"OpenaiBot\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiSession\" ADD CONSTRAINT \"OpenaiSession_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiSetting\" ADD CONSTRAINT \"OpenaiSetting_openaiCredsId_fkey\" FOREIGN KEY (\"openaiCredsId\") REFERENCES \"OpenaiCreds\"(\"id\") ON DELETE RESTRICT ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiSetting\" ADD CONSTRAINT \"OpenaiSetting_openaiIdFallback_fkey\" FOREIGN KEY (\"openaiIdFallback\") REFERENCES \"OpenaiBot\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"OpenaiSetting\" ADD CONSTRAINT \"OpenaiSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240718123923_adjusts_openai_tables/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"OpenaiBot\" ADD COLUMN     \"enabled\" BOOLEAN NOT NULL DEFAULT true;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240722173259_add_name_column_to_openai_creds/migration.sql",
    "content": "/*\n  Warnings:\n\n  - A unique constraint covering the columns `[name]` on the table `OpenaiCreds` will be added. If there are existing duplicate values, this will fail.\n\n*/\n-- AlterTable\nALTER TABLE \"OpenaiCreds\" ADD COLUMN     \"name\" VARCHAR(255),\nALTER COLUMN \"apiKey\" DROP NOT NULL;\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"OpenaiCreds_name_key\" ON \"OpenaiCreds\"(\"name\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240722173518_add_name_column_to_openai_creds/migration.sql",
    "content": "-- DropIndex\nDROP INDEX \"OpenaiCreds_instanceId_key\";\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240723152648_adjusts_in_column_openai_creds/migration.sql",
    "content": "/*\n  Warnings:\n\n  - A unique constraint covering the columns `[openaiCredsId]` on the table `OpenaiSetting` will be added. If there are existing duplicate values, this will fail.\n\n*/\n-- CreateIndex\nCREATE UNIQUE INDEX \"OpenaiSetting_openaiCredsId_key\" ON \"OpenaiSetting\"(\"openaiCredsId\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240723200254_add_webhookurl_on_message/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Message\" ADD COLUMN     \"webhookUrl\" VARCHAR(500);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240725184147_create_template_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Template\" (\n    \"id\" TEXT NOT NULL,\n    \"templateId\" VARCHAR(255) NOT NULL,\n    \"name\" VARCHAR(255) NOT NULL,\n    \"template\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Template_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Template_templateId_key\" ON \"Template\"(\"templateId\");\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Template_name_key\" ON \"Template\"(\"name\");\n\n-- AddForeignKey\nALTER TABLE \"Template\" ADD CONSTRAINT \"Template_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240725202651_add_webhook_url_template_table/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Template\" ADD COLUMN     \"webhookUrl\" VARCHAR(500);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240725221646_modify_token_instance_table/migration.sql",
    "content": "-- DropIndex\nDROP INDEX \"Instance_token_key\";\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240729115127_modify_trigger_type_openai_typebot_table/migration.sql",
    "content": "-- AlterEnum\nALTER TYPE \"TriggerType\" ADD VALUE 'none';\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240729180347_modify_typebot_session_status_openai_typebot_table/migration.sql",
    "content": "/*\n  Warnings:\n\n  - The values [open] on the enum `TypebotSessionStatus` will be removed. If these variants are still used in the database, this will fail.\n  - Changed the type of `status` on the `TypebotSession` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.\n\n*/\n-- AlterEnum\nBEGIN;\nCREATE TYPE \"TypebotSessionStatus_new\" AS ENUM ('opened', 'closed', 'paused');\nALTER TABLE \"TypebotSession\" ALTER COLUMN \"status\" TYPE \"TypebotSessionStatus_new\" USING (\"status\"::text::\"TypebotSessionStatus_new\");\nALTER TABLE \"OpenaiSession\" ALTER COLUMN \"status\" TYPE \"TypebotSessionStatus_new\" USING (\"status\"::text::\"TypebotSessionStatus_new\");\nALTER TYPE \"TypebotSessionStatus\" RENAME TO \"TypebotSessionStatus_old\";\nALTER TYPE \"TypebotSessionStatus_new\" RENAME TO \"TypebotSessionStatus\";\nDROP TYPE \"TypebotSessionStatus_old\";\nCOMMIT;\n\n-- AlterTable\nALTER TABLE \"TypebotSession\" DROP COLUMN \"status\",\nADD COLUMN     \"status\" \"TypebotSessionStatus\" NOT NULL;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240730152156_create_dify_tables/migration.sql",
    "content": "/*\n  Warnings:\n\n  - Changed the type of `botType` on the `OpenaiBot` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.\n\n*/\n-- CreateEnum\nCREATE TYPE \"OpenaiBotType\" AS ENUM ('assistant', 'chatCompletion');\n\n-- CreateEnum\nCREATE TYPE \"DifyBotType\" AS ENUM ('chatBot', 'textGenerator', 'agent', 'workflow');\n\n-- DropIndex\nDROP INDEX \"OpenaiBot_assistantId_key\";\n\n-- AlterTable\nALTER TABLE \"Message\" ADD COLUMN     \"difySessionId\" TEXT;\n\n-- AlterTable\nALTER TABLE \"OpenaiBot\" DROP COLUMN \"botType\",\nADD COLUMN     \"botType\" \"OpenaiBotType\" NOT NULL;\n\n-- CreateTable\nCREATE TABLE \"Dify\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"botType\" \"DifyBotType\" NOT NULL,\n    \"apiUrl\" VARCHAR(255),\n    \"apiKey\" VARCHAR(255),\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Dify_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"DifySession\" (\n    \"id\" TEXT NOT NULL,\n    \"sessionId\" VARCHAR(255) NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"status\" \"TypebotSessionStatus\" NOT NULL,\n    \"awaitUser\" BOOLEAN NOT NULL DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"difyId\" TEXT NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"DifySession_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"DifySetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"difyIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"DifySetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"DifySetting_instanceId_key\" ON \"DifySetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Message\" ADD CONSTRAINT \"Message_difySessionId_fkey\" FOREIGN KEY (\"difySessionId\") REFERENCES \"DifySession\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"Dify\" ADD CONSTRAINT \"Dify_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"DifySession\" ADD CONSTRAINT \"DifySession_difyId_fkey\" FOREIGN KEY (\"difyId\") REFERENCES \"Dify\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"DifySession\" ADD CONSTRAINT \"DifySession_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"DifySetting\" ADD CONSTRAINT \"DifySetting_difyIdFallback_fkey\" FOREIGN KEY (\"difyIdFallback\") REFERENCES \"Dify\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"DifySetting\" ADD CONSTRAINT \"DifySetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240801193907_add_column_speech_to_text_openai_setting_table/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"OpenaiSetting\" ADD COLUMN     \"speechToText\" BOOLEAN DEFAULT false;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240803163908_add_column_description_on_integrations_table/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Dify\" ADD COLUMN     \"description\" VARCHAR(255);\n\n-- AlterTable\nALTER TABLE \"OpenaiBot\" ADD COLUMN     \"description\" VARCHAR(255);\n\n-- AlterTable\nALTER TABLE \"Typebot\" ADD COLUMN     \"description\" VARCHAR(255);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240808210239_add_column_function_url_openaibot_table/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Instance\" ADD COLUMN     \"disconnectionAt\" TIMESTAMP,\nADD COLUMN     \"disconnectionObject\" JSONB,\nADD COLUMN     \"disconnectionReasonCode\" INTEGER;\n\n-- AlterTable\nALTER TABLE \"OpenaiBot\" ADD COLUMN     \"functionUrl\" VARCHAR(500);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240811021156_add_chat_name_column/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Chat\" ADD COLUMN     \"name\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240811183328_add_unique_index_for_remoted_jid_and_instance_in_contacts/migration.sql",
    "content": "/*\n  Warnings:\n\n  - A unique constraint covering the columns `[remoteJid,instanceId]` on the table `Contact` will be added. If there are existing duplicate values, this will fail.\n\n*/\n-- Remove the duplicates\nDELETE FROM \"Contact\"\nWHERE ctid NOT IN (\n  SELECT min(ctid)\n  FROM \"Contact\"\n  GROUP BY \"remoteJid\", \"instanceId\"\n);\n\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Contact_remoteJid_instanceId_key\" ON \"Contact\"(\"remoteJid\", \"instanceId\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240813003116_make_label_unique_for_instance/migration.sql",
    "content": "/*\n  Warnings:\n\n  - A unique constraint covering the columns `[labelId,instanceId]` on the table `Label` will be added. If there are existing duplicate values, this will fail.\n\n*/\n-- DropIndex\nDROP INDEX \"Label_labelId_key\";\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Label_labelId_instanceId_key\" ON \"Label\"(\"labelId\", \"instanceId\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240814173033_add_ignore_jids_chatwoot/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Chatwoot\" ADD COLUMN     \"ignoreJids\" JSONB;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240814202359_integrations_unification/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the column `difySessionId` on the `Message` table. All the data in the column will be lost.\n  - You are about to drop the column `openaiSessionId` on the `Message` table. All the data in the column will be lost.\n  - You are about to drop the column `typebotSessionId` on the `Message` table. All the data in the column will be lost.\n  - You are about to drop the `DifySession` table. If the table is not empty, all the data it contains will be lost.\n  - You are about to drop the `OpenaiSession` table. If the table is not empty, all the data it contains will be lost.\n  - You are about to drop the `TypebotSession` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- CreateEnum\nCREATE TYPE \"SessionStatus\" AS ENUM ('opened', 'closed', 'paused');\n\n-- DropForeignKey\nALTER TABLE \"DifySession\" DROP CONSTRAINT \"DifySession_difyId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"DifySession\" DROP CONSTRAINT \"DifySession_instanceId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"Message\" DROP CONSTRAINT \"Message_difySessionId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"Message\" DROP CONSTRAINT \"Message_openaiSessionId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"Message\" DROP CONSTRAINT \"Message_typebotSessionId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"OpenaiSession\" DROP CONSTRAINT \"OpenaiSession_instanceId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"OpenaiSession\" DROP CONSTRAINT \"OpenaiSession_openaiBotId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"TypebotSession\" DROP CONSTRAINT \"TypebotSession_instanceId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"TypebotSession\" DROP CONSTRAINT \"TypebotSession_typebotId_fkey\";\n\n-- AlterTable\nALTER TABLE \"Message\" DROP COLUMN \"difySessionId\",\nDROP COLUMN \"openaiSessionId\",\nDROP COLUMN \"typebotSessionId\",\nADD COLUMN     \"sessionId\" TEXT;\n\n-- DropTable\nDROP TABLE \"DifySession\";\n\n-- DropTable\nDROP TABLE \"OpenaiSession\";\n\n-- DropTable\nDROP TABLE \"TypebotSession\";\n\n-- DropEnum\nDROP TYPE \"TypebotSessionStatus\";\n\n-- CreateTable\nCREATE TABLE \"IntegrationSession\" (\n    \"id\" TEXT NOT NULL,\n    \"sessionId\" VARCHAR(255) NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"pushName\" TEXT,\n    \"status\" \"SessionStatus\" NOT NULL,\n    \"awaitUser\" BOOLEAN NOT NULL DEFAULT false,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n    \"parameters\" JSONB,\n    \"openaiBotId\" TEXT,\n    \"difyId\" TEXT,\n    \"typebotId\" TEXT,\n\n    CONSTRAINT \"IntegrationSession_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- AddForeignKey\nALTER TABLE \"Message\" ADD CONSTRAINT \"Message_sessionId_fkey\" FOREIGN KEY (\"sessionId\") REFERENCES \"IntegrationSession\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"IntegrationSession\" ADD CONSTRAINT \"IntegrationSession_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"IntegrationSession\" ADD CONSTRAINT \"IntegrationSession_openaiBotId_fkey\" FOREIGN KEY (\"openaiBotId\") REFERENCES \"OpenaiBot\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"IntegrationSession\" ADD CONSTRAINT \"IntegrationSession_difyId_fkey\" FOREIGN KEY (\"difyId\") REFERENCES \"Dify\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"IntegrationSession\" ADD CONSTRAINT \"IntegrationSession_typebotId_fkey\" FOREIGN KEY (\"typebotId\") REFERENCES \"Typebot\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240817110155_add_trigger_type_advanced/migration.sql",
    "content": "-- AlterEnum\nALTER TYPE \"TriggerType\" ADD VALUE 'advanced';\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240819154941_add_context_to_integration_session/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"IntegrationSession\" ADD COLUMN     \"context\" JSONB;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240821120816_bot_id_integration_session/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the column `difyId` on the `IntegrationSession` table. All the data in the column will be lost.\n  - You are about to drop the column `openaiBotId` on the `IntegrationSession` table. All the data in the column will be lost.\n  - You are about to drop the column `typebotId` on the `IntegrationSession` table. All the data in the column will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE \"IntegrationSession\" DROP CONSTRAINT \"IntegrationSession_difyId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"IntegrationSession\" DROP CONSTRAINT \"IntegrationSession_openaiBotId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"IntegrationSession\" DROP CONSTRAINT \"IntegrationSession_typebotId_fkey\";\n\n-- AlterTable\nALTER TABLE \"IntegrationSession\" DROP COLUMN \"difyId\",\nDROP COLUMN \"openaiBotId\",\nDROP COLUMN \"typebotId\",\nADD COLUMN     \"botId\" TEXT;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240821171327_add_generic_bot_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"GenericBot\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"description\" VARCHAR(255),\n    \"apiUrl\" VARCHAR(255),\n    \"apiKey\" VARCHAR(255),\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"GenericBot_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"GenericSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"botIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"GenericSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"GenericSetting_instanceId_key\" ON \"GenericSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"GenericBot\" ADD CONSTRAINT \"GenericBot_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"GenericSetting\" ADD CONSTRAINT \"GenericSetting_botIdFallback_fkey\" FOREIGN KEY (\"botIdFallback\") REFERENCES \"GenericBot\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"GenericSetting\" ADD CONSTRAINT \"GenericSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240821194524_add_flowise_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Flowise\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"description\" VARCHAR(255),\n    \"apiUrl\" VARCHAR(255),\n    \"apiKey\" VARCHAR(255),\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Flowise_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"FlowiseSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"flowiseIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"FlowiseSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"FlowiseSetting_instanceId_key\" ON \"FlowiseSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Flowise\" ADD CONSTRAINT \"Flowise_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"FlowiseSetting\" ADD CONSTRAINT \"FlowiseSetting_flowiseIdFallback_fkey\" FOREIGN KEY (\"flowiseIdFallback\") REFERENCES \"Flowise\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"FlowiseSetting\" ADD CONSTRAINT \"FlowiseSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240824161333_add_type_on_integration_sessions/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"IntegrationSession\" ADD COLUMN     \"type\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240825130616_change_to_evolution_bot/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the `GenericBot` table. If the table is not empty, all the data it contains will be lost.\n  - You are about to drop the `GenericSetting` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- DropForeignKey\nALTER TABLE \"GenericBot\" DROP CONSTRAINT \"GenericBot_instanceId_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"GenericSetting\" DROP CONSTRAINT \"GenericSetting_botIdFallback_fkey\";\n\n-- DropForeignKey\nALTER TABLE \"GenericSetting\" DROP CONSTRAINT \"GenericSetting_instanceId_fkey\";\n\n-- DropTable\nDROP TABLE \"GenericBot\";\n\n-- DropTable\nDROP TABLE \"GenericSetting\";\n\n-- CreateTable\nCREATE TABLE \"EvolutionBot\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"description\" VARCHAR(255),\n    \"apiUrl\" VARCHAR(255),\n    \"apiKey\" VARCHAR(255),\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"EvolutionBot_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"EvolutionBotSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"botIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"EvolutionBotSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"EvolutionBotSetting_instanceId_key\" ON \"EvolutionBotSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"EvolutionBot\" ADD CONSTRAINT \"EvolutionBot_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"EvolutionBotSetting\" ADD CONSTRAINT \"EvolutionBotSetting_botIdFallback_fkey\" FOREIGN KEY (\"botIdFallback\") REFERENCES \"EvolutionBot\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"EvolutionBotSetting\" ADD CONSTRAINT \"EvolutionBotSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240828140837_add_is_on_whatsapp_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"is_on_whatsapp\" (\n    \"id\" TEXT NOT NULL,\n    \"remote_jid\" VARCHAR(100) NOT NULL,\n    \"name\" TEXT,\n    \"jid_options\" TEXT NOT NULL,\n    \"created_at\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    \"updated_at\" TIMESTAMP NOT NULL,\n\n    CONSTRAINT \"is_on_whatsapp_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"is_on_whatsapp_remote_jid_key\" ON \"is_on_whatsapp\"(\"remote_jid\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240828141556_remove_name_column_from_on_whatsapp_table/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the column `name` on the `is_on_whatsapp` table. All the data in the column will be lost.\n\n*/\n-- AlterTable\nALTER TABLE \"is_on_whatsapp\" DROP COLUMN \"name\";\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240830193533_changed_table_case/migration.sql",
    "content": "/*\n  Warnings:\n\n  - You are about to drop the `is_on_whatsapp` table. If the table is not empty, all the data it contains will be lost.\n\n*/\n-- DropTable\nDROP TABLE \"is_on_whatsapp\";\n\n-- CreateTable\nCREATE TABLE \"IsOnWhatsapp\" (\n    \"id\" TEXT NOT NULL,\n    \"remoteJid\" VARCHAR(100) NOT NULL,\n    \"jidOptions\" TEXT NOT NULL,\n    \"createdAt\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n\n    CONSTRAINT \"IsOnWhatsapp_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"IsOnWhatsapp_remoteJid_key\" ON \"IsOnWhatsapp\"(\"remoteJid\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20240906202019_add_headers_on_webhook_config/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Webhook\" ADD COLUMN     \"headers\" JSONB;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20241001180457_add_message_status/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Message\" ADD COLUMN     \"status\" INTEGER;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20241006130306_alter_status_on_message_table/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Message\"\nALTER COLUMN \"status\"\nSET\n    DATA TYPE VARCHAR(30);\n\nUPDATE \"Message\" SET \"status\" = 'PENDING';"
  },
  {
    "path": "prisma/postgresql-migrations/20241007164026_add_unread_messages_on_chat_table/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Chat\" ADD COLUMN     \"unreadMessages\" INTEGER NOT NULL DEFAULT 0;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20241011085129_create_pusher_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Pusher\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"appId\" VARCHAR(100) NOT NULL,\n    \"key\" VARCHAR(100) NOT NULL,\n    \"secret\" VARCHAR(100) NOT NULL,\n    \"cluster\" VARCHAR(100) NOT NULL,\n    \"useTLS\" BOOLEAN NOT NULL DEFAULT false,\n    \"events\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Pusher_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Pusher_instanceId_key\" ON \"Pusher\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Pusher\" ADD CONSTRAINT \"Pusher_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20241011100803_split_messages_and_time_per_char_integrations/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Dify\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"DifySetting\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"EvolutionBot\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"EvolutionBotSetting\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"Flowise\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"FlowiseSetting\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"OpenaiBot\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"OpenaiSetting\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20241017144950_create_index/migration.sql",
    "content": "-- CreateIndex\nCREATE INDEX \"Chat_instanceId_idx\" ON \"Chat\"(\"instanceId\");\n\n-- CreateIndex\nCREATE INDEX \"Chat_remoteJid_idx\" ON \"Chat\"(\"remoteJid\");\n\n-- CreateIndex\nCREATE INDEX \"Contact_remoteJid_idx\" ON \"Contact\"(\"remoteJid\");\n\n-- CreateIndex\nCREATE INDEX \"Contact_instanceId_idx\" ON \"Contact\"(\"instanceId\");\n\n-- CreateIndex\nCREATE INDEX \"Message_instanceId_idx\" ON \"Message\"(\"instanceId\");\n\n-- CreateIndex\nCREATE INDEX \"MessageUpdate_instanceId_idx\" ON \"MessageUpdate\"(\"instanceId\");\n\n-- CreateIndex\nCREATE INDEX \"MessageUpdate_messageId_idx\" ON \"MessageUpdate\"(\"messageId\");\n\n-- CreateIndex\nCREATE INDEX \"Setting_instanceId_idx\" ON \"Setting\"(\"instanceId\");\n\n-- CreateIndex\nCREATE INDEX \"Webhook_instanceId_idx\" ON \"Webhook\"(\"instanceId\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250116001415_add_wavoip_token_to_settings_table/migration.sql",
    "content": "/*\nWarnings:\n\n- A unique constraint covering the columns `[remoteJid,instanceId]` on the table `Chat` will be added. If there are existing duplicate values, this will fail.\n\n*/\n\n-- AlterTable\nALTER TABLE \"Setting\" ADD COLUMN IF NOT EXISTS \"wavoipToken\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250225180031_add_nats_integration/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Nats\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"events\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Nats_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Nats_instanceId_key\" ON \"Nats\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Nats\" ADD CONSTRAINT \"Nats_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250514232744_add_n8n_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"N8n\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"description\" VARCHAR(255),\n    \"webhookUrl\" VARCHAR(255),\n    \"basicAuthUser\" VARCHAR(255),\n    \"basicAuthPass\" VARCHAR(255),\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"splitMessages\" BOOLEAN DEFAULT false,\n    \"timePerChar\" INTEGER DEFAULT 50,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"N8n_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"N8nSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"splitMessages\" BOOLEAN DEFAULT false,\n    \"timePerChar\" INTEGER DEFAULT 50,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"n8nIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"N8nSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"N8nSetting_instanceId_key\" ON \"N8nSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"N8n\" ADD CONSTRAINT \"N8n_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"N8nSetting\" ADD CONSTRAINT \"N8nSetting_n8nIdFallback_fkey\" FOREIGN KEY (\"n8nIdFallback\") REFERENCES \"N8n\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"N8nSetting\" ADD CONSTRAINT \"N8nSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250515211815_add_evoai_table/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Evoai\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT true,\n    \"description\" VARCHAR(255),\n    \"agentUrl\" VARCHAR(255),\n    \"apiKey\" VARCHAR(255),\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"splitMessages\" BOOLEAN DEFAULT false,\n    \"timePerChar\" INTEGER DEFAULT 50,\n    \"triggerType\" \"TriggerType\",\n    \"triggerOperator\" \"TriggerOperator\",\n    \"triggerValue\" TEXT,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Evoai_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateTable\nCREATE TABLE \"EvoaiSetting\" (\n    \"id\" TEXT NOT NULL,\n    \"expire\" INTEGER DEFAULT 0,\n    \"keywordFinish\" VARCHAR(100),\n    \"delayMessage\" INTEGER,\n    \"unknownMessage\" VARCHAR(100),\n    \"listeningFromMe\" BOOLEAN DEFAULT false,\n    \"stopBotFromMe\" BOOLEAN DEFAULT false,\n    \"keepOpen\" BOOLEAN DEFAULT false,\n    \"debounceTime\" INTEGER,\n    \"ignoreJids\" JSONB,\n    \"splitMessages\" BOOLEAN DEFAULT false,\n    \"timePerChar\" INTEGER DEFAULT 50,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"evoaiIdFallback\" VARCHAR(100),\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"EvoaiSetting_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"EvoaiSetting_instanceId_key\" ON \"EvoaiSetting\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Evoai\" ADD CONSTRAINT \"Evoai_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"EvoaiSetting\" ADD CONSTRAINT \"EvoaiSetting_evoaiIdFallback_fkey\" FOREIGN KEY (\"evoaiIdFallback\") REFERENCES \"Evoai\"(\"id\") ON DELETE SET NULL ON UPDATE CASCADE;\n\n-- AddForeignKey\nALTER TABLE \"EvoaiSetting\" ADD CONSTRAINT \"EvoaiSetting_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250516012152_remove_unique_atribute_for_file_name_in_media/migration.sql",
    "content": "-- DropIndex\nDROP INDEX \"Media_fileName_key\";\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250612155048_add_coluns_trypebot_tables/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"Typebot\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n\n-- AlterTable\nALTER TABLE \"TypebotSetting\" ADD COLUMN     \"splitMessages\" BOOLEAN DEFAULT false,\nADD COLUMN     \"timePerChar\" INTEGER DEFAULT 50;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250613143000_add_lid_column_to_is_onwhatsapp/migration.sql",
    "content": "-- AlterTable\nALTER TABLE \"IsOnWhatsapp\" ADD COLUMN     \"lid\" VARCHAR(100);\n"
  },
  {
    "path": "prisma/postgresql-migrations/20250918182355_add_kafka_integration/migration.sql",
    "content": "-- CreateTable\nCREATE TABLE \"Kafka\" (\n    \"id\" TEXT NOT NULL,\n    \"enabled\" BOOLEAN NOT NULL DEFAULT false,\n    \"events\" JSONB NOT NULL,\n    \"createdAt\" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    \"updatedAt\" TIMESTAMP NOT NULL,\n    \"instanceId\" TEXT NOT NULL,\n\n    CONSTRAINT \"Kafka_pkey\" PRIMARY KEY (\"id\")\n);\n\n-- CreateIndex\nCREATE UNIQUE INDEX \"Kafka_instanceId_key\" ON \"Kafka\"(\"instanceId\");\n\n-- AddForeignKey\nALTER TABLE \"Kafka\" ADD CONSTRAINT \"Kafka_instanceId_fkey\" FOREIGN KEY (\"instanceId\") REFERENCES \"Instance\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE;\n"
  },
  {
    "path": "prisma/postgresql-migrations/20251122003044_add_chat_instance_remotejid_unique/migration.sql",
    "content": "-- 1. Cleanup: Remove duplicate chats, keeping the most recently updated one\nDELETE FROM \"Chat\"\nWHERE id IN (\n  SELECT id FROM (\n    SELECT id,\n           ROW_NUMBER() OVER (\n             PARTITION BY \"instanceId\", \"remoteJid\"\n             ORDER BY \"updatedAt\" DESC\n           ) as row_num\n    FROM \"Chat\"\n  ) t\n  WHERE t.row_num > 1\n);\n\n-- 2. Create the unique index (Constraint)\nCREATE UNIQUE INDEX \"Chat_instanceId_remoteJid_key\" ON \"Chat\"(\"instanceId\", \"remoteJid\");\n"
  },
  {
    "path": "prisma/postgresql-migrations/migration_lock.toml",
    "content": "# Please do not edit this file manually\n# It should be added in your version-control system (e.g., Git)\nprovider = \"postgresql\""
  },
  {
    "path": "prisma/postgresql-schema.prisma",
    "content": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"postgresql\"\n  url      = env(\"DATABASE_CONNECTION_URI\")\n}\n\nenum InstanceConnectionStatus {\n  open\n  close\n  connecting\n}\n\nenum DeviceMessage {\n  ios\n  android\n  web\n  unknown\n  desktop\n}\n\nenum SessionStatus {\n  opened\n  closed\n  paused\n}\n\nenum TriggerType {\n  all\n  keyword\n  none\n  advanced\n}\n\nenum TriggerOperator {\n  contains\n  equals\n  startsWith\n  endsWith\n  regex\n}\n\nenum OpenaiBotType {\n  assistant\n  chatCompletion\n}\n\nenum DifyBotType {\n  chatBot\n  textGenerator\n  agent\n  workflow\n}\n\nmodel Instance {\n  id                      String                   @id @default(cuid())\n  name                    String                   @unique @db.VarChar(255)\n  connectionStatus        InstanceConnectionStatus @default(open)\n  ownerJid                String?                  @db.VarChar(100)\n  profileName             String?                  @db.VarChar(100)\n  profilePicUrl           String?                  @db.VarChar(500)\n  integration             String?                  @db.VarChar(100)\n  number                  String?                  @db.VarChar(100)\n  businessId              String?                  @db.VarChar(100)\n  token                   String?                  @db.VarChar(255)\n  clientName              String?                  @db.VarChar(100)\n  disconnectionReasonCode Int?                     @db.Integer\n  disconnectionObject     Json?                    @db.JsonB\n  disconnectionAt         DateTime?                @db.Timestamp\n  createdAt               DateTime?                @default(now()) @db.Timestamp\n  updatedAt               DateTime?                @updatedAt @db.Timestamp\n  Chat                    Chat[]\n  Contact                 Contact[]\n  Message                 Message[]\n  Webhook                 Webhook?\n  Chatwoot                Chatwoot?\n  Label                   Label[]\n  Proxy                   Proxy?\n  Setting                 Setting?\n  Rabbitmq                Rabbitmq?\n  Nats                    Nats?\n  Sqs                     Sqs?\n  Kafka                   Kafka?\n  Websocket               Websocket?\n  Typebot                 Typebot[]\n  Session                 Session?\n  MessageUpdate           MessageUpdate[]\n  TypebotSetting          TypebotSetting?\n  Media                   Media[]\n  OpenaiCreds             OpenaiCreds[]\n  OpenaiBot               OpenaiBot[]\n  OpenaiSetting           OpenaiSetting?\n  Template                Template[]\n  Dify                    Dify[]\n  DifySetting             DifySetting?\n  IntegrationSession      IntegrationSession[]\n  EvolutionBot            EvolutionBot[]\n  EvolutionBotSetting     EvolutionBotSetting?\n  Flowise                 Flowise[]\n  FlowiseSetting          FlowiseSetting?\n  Pusher                  Pusher?\n  N8n                     N8n[]\n  N8nSetting              N8nSetting[]\n  Evoai                   Evoai[]\n  EvoaiSetting            EvoaiSetting?\n}\n\nmodel Session {\n  id        String   @id @default(cuid())\n  sessionId String   @unique\n  creds     String?  @db.Text\n  createdAt DateTime @default(now()) @db.Timestamp\n  Instance  Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade)\n}\n\nmodel Chat {\n  id             String    @id @default(cuid())\n  remoteJid      String    @db.VarChar(100)\n  name           String?   @db.VarChar(100)\n  labels         Json?     @db.JsonB\n  createdAt      DateTime? @default(now()) @db.Timestamp\n  updatedAt      DateTime? @updatedAt @db.Timestamp\n  Instance       Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId     String\n  unreadMessages Int       @default(0)\n\n  @@unique([instanceId, remoteJid])\n  @@index([instanceId])\n  @@index([remoteJid])\n}\n\nmodel Contact {\n  id            String    @id @default(cuid())\n  remoteJid     String    @db.VarChar(100)\n  pushName      String?   @db.VarChar(100)\n  profilePicUrl String?   @db.VarChar(500)\n  createdAt     DateTime? @default(now()) @db.Timestamp\n  updatedAt     DateTime? @updatedAt @db.Timestamp\n  Instance      Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId    String\n\n  @@unique([remoteJid, instanceId])\n  @@index([remoteJid])\n  @@index([instanceId])\n}\n\nmodel Message {\n  id                           String          @id @default(cuid())\n  key                          Json            @db.JsonB\n  pushName                     String?         @db.VarChar(100)\n  participant                  String?         @db.VarChar(100)\n  messageType                  String          @db.VarChar(100)\n  message                      Json            @db.JsonB\n  contextInfo                  Json?           @db.JsonB\n  source                       DeviceMessage\n  messageTimestamp             Int             @db.Integer\n  chatwootMessageId            Int?            @db.Integer\n  chatwootInboxId              Int?            @db.Integer\n  chatwootConversationId       Int?            @db.Integer\n  chatwootContactInboxSourceId String?         @db.VarChar(100)\n  chatwootIsRead               Boolean?        @db.Boolean\n  Instance                     Instance        @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId                   String\n  MessageUpdate                MessageUpdate[]\n  Media                        Media?\n  webhookUrl                   String?         @db.VarChar(500)\n  status                       String?         @db.VarChar(30)\n\n  sessionId String?\n  session   IntegrationSession? @relation(fields: [sessionId], references: [id])\n\n  @@index([instanceId])\n}\n\nmodel MessageUpdate {\n  id          String   @id @default(cuid())\n  keyId       String   @db.VarChar(100)\n  remoteJid   String   @db.VarChar(100)\n  fromMe      Boolean  @db.Boolean\n  participant String?  @db.VarChar(100)\n  pollUpdates Json?    @db.JsonB\n  status      String   @db.VarChar(30)\n  Message     Message  @relation(fields: [messageId], references: [id], onDelete: Cascade)\n  messageId   String\n  Instance    Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId  String\n\n  @@index([instanceId])\n  @@index([messageId])\n}\n\nmodel Webhook {\n  id              String    @id @default(cuid())\n  url             String    @db.VarChar(500)\n  headers         Json?     @db.JsonB\n  enabled         Boolean?  @default(true) @db.Boolean\n  events          Json?     @db.JsonB\n  webhookByEvents Boolean?  @default(false) @db.Boolean\n  webhookBase64   Boolean?  @default(false) @db.Boolean\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n\n  @@index([instanceId])\n}\n\nmodel Chatwoot {\n  id                      String    @id @default(cuid())\n  enabled                 Boolean?  @default(true) @db.Boolean\n  accountId               String?   @db.VarChar(100)\n  token                   String?   @db.VarChar(100)\n  url                     String?   @db.VarChar(500)\n  nameInbox               String?   @db.VarChar(100)\n  signMsg                 Boolean?  @default(false) @db.Boolean\n  signDelimiter           String?   @db.VarChar(100)\n  number                  String?   @db.VarChar(100)\n  reopenConversation      Boolean?  @default(false) @db.Boolean\n  conversationPending     Boolean?  @default(false) @db.Boolean\n  mergeBrazilContacts     Boolean?  @default(false) @db.Boolean\n  importContacts          Boolean?  @default(false) @db.Boolean\n  importMessages          Boolean?  @default(false) @db.Boolean\n  daysLimitImportMessages Int?      @db.Integer\n  organization            String?   @db.VarChar(100)\n  logo                    String?   @db.VarChar(500)\n  ignoreJids              Json?\n  createdAt               DateTime? @default(now()) @db.Timestamp\n  updatedAt               DateTime  @updatedAt @db.Timestamp\n  Instance                Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId              String    @unique\n}\n\nmodel Label {\n  id           String    @id @default(cuid())\n  labelId      String?   @db.VarChar(100)\n  name         String    @db.VarChar(100)\n  color        String    @db.VarChar(100)\n  predefinedId String?   @db.VarChar(100)\n  createdAt    DateTime? @default(now()) @db.Timestamp\n  updatedAt    DateTime  @updatedAt @db.Timestamp\n  Instance     Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId   String\n\n  @@unique([labelId, instanceId])\n}\n\nmodel Proxy {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  host       String    @db.VarChar(100)\n  port       String    @db.VarChar(100)\n  protocol   String    @db.VarChar(100)\n  username   String    @db.VarChar(100)\n  password   String    @db.VarChar(100)\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Setting {\n  id              String    @id @default(cuid())\n  rejectCall      Boolean   @default(false) @db.Boolean\n  msgCall         String?   @db.VarChar(100)\n  groupsIgnore    Boolean   @default(false) @db.Boolean\n  alwaysOnline    Boolean   @default(false) @db.Boolean\n  readMessages    Boolean   @default(false) @db.Boolean\n  readStatus      Boolean   @default(false) @db.Boolean\n  syncFullHistory Boolean   @default(false) @db.Boolean\n  wavoipToken     String?   @db.VarChar(100)\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n\n  @@index([instanceId])\n}\n\nmodel Rabbitmq {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Nats {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Sqs {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Kafka {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Websocket {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Pusher {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  appId      String    @db.VarChar(100)\n  key        String    @db.VarChar(100)\n  secret     String    @db.VarChar(100)\n  cluster    String    @db.VarChar(100)\n  useTLS     Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Typebot {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  url             String           @db.VarChar(500)\n  typebot         String           @db.VarChar(100)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime?        @updatedAt @db.Timestamp\n  ignoreJids      Json?\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  TypebotSetting  TypebotSetting[]\n}\n\nmodel TypebotSetting {\n  id                String    @id @default(cuid())\n  expire            Int?      @default(0) @db.Integer\n  keywordFinish     String?   @db.VarChar(100)\n  delayMessage      Int?      @db.Integer\n  unknownMessage    String?   @db.VarChar(100)\n  listeningFromMe   Boolean?  @default(false) @db.Boolean\n  stopBotFromMe     Boolean?  @default(false) @db.Boolean\n  keepOpen          Boolean?  @default(false) @db.Boolean\n  debounceTime      Int?      @db.Integer\n  typebotIdFallback String?   @db.VarChar(100)\n  ignoreJids        Json?\n  splitMessages     Boolean?  @default(false) @db.Boolean\n  timePerChar       Int?      @default(50) @db.Integer\n  createdAt         DateTime? @default(now()) @db.Timestamp\n  updatedAt         DateTime  @updatedAt @db.Timestamp\n  Fallback          Typebot?  @relation(fields: [typebotIdFallback], references: [id])\n  Instance          Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String    @unique\n}\n\nmodel Media {\n  id         String    @id @default(cuid())\n  fileName   String    @db.VarChar(500)\n  type       String    @db.VarChar(100)\n  mimetype   String    @db.VarChar(100)\n  createdAt  DateTime? @default(now()) @db.Date\n  Message    Message   @relation(fields: [messageId], references: [id], onDelete: Cascade)\n  messageId  String    @unique\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n}\n\nmodel OpenaiCreds {\n  id              String         @id @default(cuid())\n  name            String?        @unique @db.VarChar(255)\n  apiKey          String?        @unique @db.VarChar(255)\n  createdAt       DateTime?      @default(now()) @db.Timestamp\n  updatedAt       DateTime       @updatedAt @db.Timestamp\n  Instance        Instance       @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  OpenaiAssistant OpenaiBot[]\n  OpenaiSetting   OpenaiSetting?\n}\n\nmodel OpenaiBot {\n  id                String           @id @default(cuid())\n  enabled           Boolean          @default(true) @db.Boolean\n  description       String?          @db.VarChar(255)\n  botType           OpenaiBotType\n  assistantId       String?          @db.VarChar(255)\n  functionUrl       String?          @db.VarChar(500)\n  model             String?          @db.VarChar(100)\n  systemMessages    Json?            @db.JsonB\n  assistantMessages Json?            @db.JsonB\n  userMessages      Json?            @db.JsonB\n  maxTokens         Int?             @db.Integer\n  expire            Int?             @default(0) @db.Integer\n  keywordFinish     String?          @db.VarChar(100)\n  delayMessage      Int?             @db.Integer\n  unknownMessage    String?          @db.VarChar(100)\n  listeningFromMe   Boolean?         @default(false) @db.Boolean\n  stopBotFromMe     Boolean?         @default(false) @db.Boolean\n  keepOpen          Boolean?         @default(false) @db.Boolean\n  debounceTime      Int?             @db.Integer\n  splitMessages     Boolean?         @default(false) @db.Boolean\n  timePerChar       Int?             @default(50) @db.Integer\n  ignoreJids        Json?\n  triggerType       TriggerType?\n  triggerOperator   TriggerOperator?\n  triggerValue      String?\n  createdAt         DateTime?        @default(now()) @db.Timestamp\n  updatedAt         DateTime         @updatedAt @db.Timestamp\n  OpenaiCreds       OpenaiCreds      @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)\n  openaiCredsId     String\n  Instance          Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String\n  OpenaiSetting     OpenaiSetting[]\n}\n\nmodel IntegrationSession {\n  id         String        @id @default(cuid())\n  sessionId  String        @db.VarChar(255)\n  remoteJid  String        @db.VarChar(100)\n  pushName   String?\n  status     SessionStatus\n  awaitUser  Boolean       @default(false) @db.Boolean\n  context    Json?\n  type       String?       @db.VarChar(100)\n  createdAt  DateTime?     @default(now()) @db.Timestamp\n  updatedAt  DateTime      @updatedAt @db.Timestamp\n  Message    Message[]\n  Instance   Instance      @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n  parameters Json?         @db.JsonB\n\n  botId String?\n}\n\nmodel OpenaiSetting {\n  id               String       @id @default(cuid())\n  expire           Int?         @default(0) @db.Integer\n  keywordFinish    String?      @db.VarChar(100)\n  delayMessage     Int?         @db.Integer\n  unknownMessage   String?      @db.VarChar(100)\n  listeningFromMe  Boolean?     @default(false) @db.Boolean\n  stopBotFromMe    Boolean?     @default(false) @db.Boolean\n  keepOpen         Boolean?     @default(false) @db.Boolean\n  debounceTime     Int?         @db.Integer\n  ignoreJids       Json?\n  splitMessages    Boolean?     @default(false) @db.Boolean\n  timePerChar      Int?         @default(50) @db.Integer\n  speechToText     Boolean?     @default(false) @db.Boolean\n  createdAt        DateTime?    @default(now()) @db.Timestamp\n  updatedAt        DateTime     @updatedAt @db.Timestamp\n  OpenaiCreds      OpenaiCreds? @relation(fields: [openaiCredsId], references: [id])\n  openaiCredsId    String       @unique\n  Fallback         OpenaiBot?   @relation(fields: [openaiIdFallback], references: [id])\n  openaiIdFallback String?      @db.VarChar(100)\n  Instance         Instance     @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId       String       @unique\n}\n\nmodel Template {\n  id         String    @id @default(cuid())\n  templateId String    @unique @db.VarChar(255)\n  name       String    @unique @db.VarChar(255)\n  template   Json      @db.JsonB\n  webhookUrl String?   @db.VarChar(500)\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n}\n\nmodel Dify {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  botType         DifyBotType\n  apiUrl          String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  DifySetting     DifySetting[]\n}\n\nmodel DifySetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Integer\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Integer\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false) @db.Boolean\n  stopBotFromMe   Boolean?  @default(false) @db.Boolean\n  keepOpen        Boolean?  @default(false) @db.Boolean\n  debounceTime    Int?      @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false) @db.Boolean\n  timePerChar     Int?      @default(50) @db.Integer\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        Dify?     @relation(fields: [difyIdFallback], references: [id])\n  difyIdFallback  String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n\nmodel EvolutionBot {\n  id                  String                @id @default(cuid())\n  enabled             Boolean               @default(true) @db.Boolean\n  description         String?               @db.VarChar(255)\n  apiUrl              String?               @db.VarChar(255)\n  apiKey              String?               @db.VarChar(255)\n  expire              Int?                  @default(0) @db.Integer\n  keywordFinish       String?               @db.VarChar(100)\n  delayMessage        Int?                  @db.Integer\n  unknownMessage      String?               @db.VarChar(100)\n  listeningFromMe     Boolean?              @default(false) @db.Boolean\n  stopBotFromMe       Boolean?              @default(false) @db.Boolean\n  keepOpen            Boolean?              @default(false) @db.Boolean\n  debounceTime        Int?                  @db.Integer\n  ignoreJids          Json?\n  splitMessages       Boolean?              @default(false) @db.Boolean\n  timePerChar         Int?                  @default(50) @db.Integer\n  triggerType         TriggerType?\n  triggerOperator     TriggerOperator?\n  triggerValue        String?\n  createdAt           DateTime?             @default(now()) @db.Timestamp\n  updatedAt           DateTime              @updatedAt @db.Timestamp\n  Instance            Instance              @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId          String\n  EvolutionBotSetting EvolutionBotSetting[]\n}\n\nmodel EvolutionBotSetting {\n  id              String        @id @default(cuid())\n  expire          Int?          @default(0) @db.Integer\n  keywordFinish   String?       @db.VarChar(100)\n  delayMessage    Int?          @db.Integer\n  unknownMessage  String?       @db.VarChar(100)\n  listeningFromMe Boolean?      @default(false) @db.Boolean\n  stopBotFromMe   Boolean?      @default(false) @db.Boolean\n  keepOpen        Boolean?      @default(false) @db.Boolean\n  debounceTime    Int?          @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?      @default(false) @db.Boolean\n  timePerChar     Int?          @default(50) @db.Integer\n  createdAt       DateTime?     @default(now()) @db.Timestamp\n  updatedAt       DateTime      @updatedAt @db.Timestamp\n  Fallback        EvolutionBot? @relation(fields: [botIdFallback], references: [id])\n  botIdFallback   String?       @db.VarChar(100)\n  Instance        Instance      @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String        @unique\n}\n\nmodel Flowise {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  apiUrl          String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  FlowiseSetting  FlowiseSetting[]\n}\n\nmodel FlowiseSetting {\n  id                String    @id @default(cuid())\n  expire            Int?      @default(0) @db.Integer\n  keywordFinish     String?   @db.VarChar(100)\n  delayMessage      Int?      @db.Integer\n  unknownMessage    String?   @db.VarChar(100)\n  listeningFromMe   Boolean?  @default(false) @db.Boolean\n  stopBotFromMe     Boolean?  @default(false) @db.Boolean\n  keepOpen          Boolean?  @default(false) @db.Boolean\n  debounceTime      Int?      @db.Integer\n  ignoreJids        Json?\n  splitMessages     Boolean?  @default(false) @db.Boolean\n  timePerChar       Int?      @default(50) @db.Integer\n  createdAt         DateTime? @default(now()) @db.Timestamp\n  updatedAt         DateTime  @updatedAt @db.Timestamp\n  Fallback          Flowise?  @relation(fields: [flowiseIdFallback], references: [id])\n  flowiseIdFallback String?   @db.VarChar(100)\n  Instance          Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String    @unique\n}\n\nmodel IsOnWhatsapp {\n  id         String   @id @default(cuid())\n  remoteJid  String   @unique @db.VarChar(100)\n  jidOptions String\n  lid        String?  @db.VarChar(100)\n  createdAt  DateTime @default(now()) @db.Timestamp\n  updatedAt  DateTime @updatedAt @db.Timestamp\n}\n\nmodel N8n {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  webhookUrl      String?          @db.VarChar(255)\n  basicAuthUser   String?          @db.VarChar(255)\n  basicAuthPass   String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  N8nSetting      N8nSetting[]\n}\n\nmodel N8nSetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Integer\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Integer\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false) @db.Boolean\n  stopBotFromMe   Boolean?  @default(false) @db.Boolean\n  keepOpen        Boolean?  @default(false) @db.Boolean\n  debounceTime    Int?      @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false) @db.Boolean\n  timePerChar     Int?      @default(50) @db.Integer\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        N8n?      @relation(fields: [n8nIdFallback], references: [id])\n  n8nIdFallback   String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n\nmodel Evoai {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  agentUrl        String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  EvoaiSetting    EvoaiSetting[]\n}\n\nmodel EvoaiSetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Integer\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Integer\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false) @db.Boolean\n  stopBotFromMe   Boolean?  @default(false) @db.Boolean\n  keepOpen        Boolean?  @default(false) @db.Boolean\n  debounceTime    Int?      @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false) @db.Boolean\n  timePerChar     Int?      @default(50) @db.Integer\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        Evoai?    @relation(fields: [evoaiIdFallback], references: [id])\n  evoaiIdFallback String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n"
  },
  {
    "path": "prisma/psql_bouncer-schema.prisma",
    "content": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider  = \"postgresql\"\n  url       = env(\"DATABASE_BOUNCER_CONNECTION_URI\")\n  directUrl = env(\"DATABASE_CONNECTION_URI\")\n}\n\nenum InstanceConnectionStatus {\n  open\n  close\n  connecting\n}\n\nenum DeviceMessage {\n  ios\n  android\n  web\n  unknown\n  desktop\n}\n\nenum SessionStatus {\n  opened\n  closed\n  paused\n}\n\nenum TriggerType {\n  all\n  keyword\n  none\n  advanced\n}\n\nenum TriggerOperator {\n  contains\n  equals\n  startsWith\n  endsWith\n  regex\n}\n\nenum OpenaiBotType {\n  assistant\n  chatCompletion\n}\n\nenum DifyBotType {\n  chatBot\n  textGenerator\n  agent\n  workflow\n}\n\nmodel Instance {\n  id                      String                   @id @default(cuid())\n  name                    String                   @unique @db.VarChar(255)\n  connectionStatus        InstanceConnectionStatus @default(open)\n  ownerJid                String?                  @db.VarChar(100)\n  profileName             String?                  @db.VarChar(100)\n  profilePicUrl           String?                  @db.VarChar(500)\n  integration             String?                  @db.VarChar(100)\n  number                  String?                  @db.VarChar(100)\n  businessId              String?                  @db.VarChar(100)\n  token                   String?                  @db.VarChar(255)\n  clientName              String?                  @db.VarChar(100)\n  disconnectionReasonCode Int?                     @db.Integer\n  disconnectionObject     Json?                    @db.JsonB\n  disconnectionAt         DateTime?                @db.Timestamp\n  createdAt               DateTime?                @default(now()) @db.Timestamp\n  updatedAt               DateTime?                @updatedAt @db.Timestamp\n  Chat                    Chat[]\n  Contact                 Contact[]\n  Message                 Message[]\n  Webhook                 Webhook?\n  Chatwoot                Chatwoot?\n  Label                   Label[]\n  Proxy                   Proxy?\n  Setting                 Setting?\n  Rabbitmq                Rabbitmq?\n  Nats                    Nats?\n  Sqs                     Sqs?\n  Kafka                   Kafka?\n  Websocket               Websocket?\n  Typebot                 Typebot[]\n  Session                 Session?\n  MessageUpdate           MessageUpdate[]\n  TypebotSetting          TypebotSetting?\n  Media                   Media[]\n  OpenaiCreds             OpenaiCreds[]\n  OpenaiBot               OpenaiBot[]\n  OpenaiSetting           OpenaiSetting?\n  Template                Template[]\n  Dify                    Dify[]\n  DifySetting             DifySetting?\n  IntegrationSession      IntegrationSession[]\n  EvolutionBot            EvolutionBot[]\n  EvolutionBotSetting     EvolutionBotSetting?\n  Flowise                 Flowise[]\n  FlowiseSetting          FlowiseSetting?\n  Pusher                  Pusher?\n  N8n                     N8n[]\n  N8nSetting              N8nSetting[]\n  Evoai                   Evoai[]\n  EvoaiSetting            EvoaiSetting?\n}\n\nmodel Session {\n  id        String   @id @default(cuid())\n  sessionId String   @unique\n  creds     String?  @db.Text\n  createdAt DateTime @default(now()) @db.Timestamp\n  Instance  Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade)\n}\n\nmodel Chat {\n  id             String    @id @default(cuid())\n  remoteJid      String    @db.VarChar(100)\n  name           String?   @db.VarChar(100)\n  labels         Json?     @db.JsonB\n  createdAt      DateTime? @default(now()) @db.Timestamp\n  updatedAt      DateTime? @updatedAt @db.Timestamp\n  Instance       Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId     String\n  unreadMessages Int       @default(0)\n\n  @@index([instanceId])\n  @@index([remoteJid])\n}\n\nmodel Contact {\n  id            String    @id @default(cuid())\n  remoteJid     String    @db.VarChar(100)\n  pushName      String?   @db.VarChar(100)\n  profilePicUrl String?   @db.VarChar(500)\n  createdAt     DateTime? @default(now()) @db.Timestamp\n  updatedAt     DateTime? @updatedAt @db.Timestamp\n  Instance      Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId    String\n\n  @@unique([remoteJid, instanceId])\n  @@index([remoteJid])\n  @@index([instanceId])\n}\n\nmodel Message {\n  id                           String          @id @default(cuid())\n  key                          Json            @db.JsonB\n  pushName                     String?         @db.VarChar(100)\n  participant                  String?         @db.VarChar(100)\n  messageType                  String          @db.VarChar(100)\n  message                      Json            @db.JsonB\n  contextInfo                  Json?           @db.JsonB\n  source                       DeviceMessage\n  messageTimestamp             Int             @db.Integer\n  chatwootMessageId            Int?            @db.Integer\n  chatwootInboxId              Int?            @db.Integer\n  chatwootConversationId       Int?            @db.Integer\n  chatwootContactInboxSourceId String?         @db.VarChar(100)\n  chatwootIsRead               Boolean?        @db.Boolean\n  Instance                     Instance        @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId                   String\n  MessageUpdate                MessageUpdate[]\n  Media                        Media?\n  webhookUrl                   String?         @db.VarChar(500)\n  status                       String?         @db.VarChar(30)\n\n  sessionId String?\n  session   IntegrationSession? @relation(fields: [sessionId], references: [id])\n\n  @@index([instanceId])\n}\n\nmodel MessageUpdate {\n  id          String   @id @default(cuid())\n  keyId       String   @db.VarChar(100)\n  remoteJid   String   @db.VarChar(100)\n  fromMe      Boolean  @db.Boolean\n  participant String?  @db.VarChar(100)\n  pollUpdates Json?    @db.JsonB\n  status      String   @db.VarChar(30)\n  Message     Message  @relation(fields: [messageId], references: [id], onDelete: Cascade)\n  messageId   String\n  Instance    Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId  String\n\n  @@index([instanceId])\n  @@index([messageId])\n}\n\nmodel Webhook {\n  id              String    @id @default(cuid())\n  url             String    @db.VarChar(500)\n  headers         Json?     @db.JsonB\n  enabled         Boolean?  @default(true) @db.Boolean\n  events          Json?     @db.JsonB\n  webhookByEvents Boolean?  @default(false) @db.Boolean\n  webhookBase64   Boolean?  @default(false) @db.Boolean\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n\n  @@index([instanceId])\n}\n\nmodel Chatwoot {\n  id                      String    @id @default(cuid())\n  enabled                 Boolean?  @default(true) @db.Boolean\n  accountId               String?   @db.VarChar(100)\n  token                   String?   @db.VarChar(100)\n  url                     String?   @db.VarChar(500)\n  nameInbox               String?   @db.VarChar(100)\n  signMsg                 Boolean?  @default(false) @db.Boolean\n  signDelimiter           String?   @db.VarChar(100)\n  number                  String?   @db.VarChar(100)\n  reopenConversation      Boolean?  @default(false) @db.Boolean\n  conversationPending     Boolean?  @default(false) @db.Boolean\n  mergeBrazilContacts     Boolean?  @default(false) @db.Boolean\n  importContacts          Boolean?  @default(false) @db.Boolean\n  importMessages          Boolean?  @default(false) @db.Boolean\n  daysLimitImportMessages Int?      @db.Integer\n  organization            String?   @db.VarChar(100)\n  logo                    String?   @db.VarChar(500)\n  ignoreJids              Json?\n  createdAt               DateTime? @default(now()) @db.Timestamp\n  updatedAt               DateTime  @updatedAt @db.Timestamp\n  Instance                Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId              String    @unique\n}\n\nmodel Label {\n  id           String    @id @default(cuid())\n  labelId      String?   @db.VarChar(100)\n  name         String    @db.VarChar(100)\n  color        String    @db.VarChar(100)\n  predefinedId String?   @db.VarChar(100)\n  createdAt    DateTime? @default(now()) @db.Timestamp\n  updatedAt    DateTime  @updatedAt @db.Timestamp\n  Instance     Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId   String\n\n  @@unique([labelId, instanceId])\n}\n\nmodel Proxy {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  host       String    @db.VarChar(100)\n  port       String    @db.VarChar(100)\n  protocol   String    @db.VarChar(100)\n  username   String    @db.VarChar(100)\n  password   String    @db.VarChar(100)\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Setting {\n  id              String    @id @default(cuid())\n  rejectCall      Boolean   @default(false) @db.Boolean\n  msgCall         String?   @db.VarChar(100)\n  groupsIgnore    Boolean   @default(false) @db.Boolean\n  alwaysOnline    Boolean   @default(false) @db.Boolean\n  readMessages    Boolean   @default(false) @db.Boolean\n  readStatus      Boolean   @default(false) @db.Boolean\n  syncFullHistory Boolean   @default(false) @db.Boolean\n  wavoipToken     String?   @db.VarChar(100)\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n\n  @@index([instanceId])\n}\n\nmodel Rabbitmq {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Nats {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Sqs {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Kafka {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Websocket {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Pusher {\n  id         String    @id @default(cuid())\n  enabled    Boolean   @default(false) @db.Boolean\n  appId      String    @db.VarChar(100)\n  key        String    @db.VarChar(100)\n  secret     String    @db.VarChar(100)\n  cluster    String    @db.VarChar(100)\n  useTLS     Boolean   @default(false) @db.Boolean\n  events     Json      @db.JsonB\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String    @unique\n}\n\nmodel Typebot {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  url             String           @db.VarChar(500)\n  typebot         String           @db.VarChar(100)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime?        @updatedAt @db.Timestamp\n  ignoreJids      Json?\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  TypebotSetting  TypebotSetting[]\n}\n\nmodel TypebotSetting {\n  id                String    @id @default(cuid())\n  expire            Int?      @default(0) @db.Integer\n  keywordFinish     String?   @db.VarChar(100)\n  delayMessage      Int?      @db.Integer\n  unknownMessage    String?   @db.VarChar(100)\n  listeningFromMe   Boolean?  @default(false) @db.Boolean\n  stopBotFromMe     Boolean?  @default(false) @db.Boolean\n  keepOpen          Boolean?  @default(false) @db.Boolean\n  debounceTime      Int?      @db.Integer\n  typebotIdFallback String?   @db.VarChar(100)\n  ignoreJids        Json?\n  splitMessages     Boolean?  @default(false) @db.Boolean\n  timePerChar       Int?      @default(50) @db.Integer\n  createdAt         DateTime? @default(now()) @db.Timestamp\n  updatedAt         DateTime  @updatedAt @db.Timestamp\n  Fallback          Typebot?  @relation(fields: [typebotIdFallback], references: [id])\n  Instance          Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String    @unique\n}\n\nmodel Media {\n  id         String    @id @default(cuid())\n  fileName   String    @db.VarChar(500)\n  type       String    @db.VarChar(100)\n  mimetype   String    @db.VarChar(100)\n  createdAt  DateTime? @default(now()) @db.Date\n  Message    Message   @relation(fields: [messageId], references: [id], onDelete: Cascade)\n  messageId  String    @unique\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n}\n\nmodel OpenaiCreds {\n  id              String         @id @default(cuid())\n  name            String?        @unique @db.VarChar(255)\n  apiKey          String?        @unique @db.VarChar(255)\n  createdAt       DateTime?      @default(now()) @db.Timestamp\n  updatedAt       DateTime       @updatedAt @db.Timestamp\n  Instance        Instance       @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  OpenaiAssistant OpenaiBot[]\n  OpenaiSetting   OpenaiSetting?\n}\n\nmodel OpenaiBot {\n  id                String           @id @default(cuid())\n  enabled           Boolean          @default(true) @db.Boolean\n  description       String?          @db.VarChar(255)\n  botType           OpenaiBotType\n  assistantId       String?          @db.VarChar(255)\n  functionUrl       String?          @db.VarChar(500)\n  model             String?          @db.VarChar(100)\n  systemMessages    Json?            @db.JsonB\n  assistantMessages Json?            @db.JsonB\n  userMessages      Json?            @db.JsonB\n  maxTokens         Int?             @db.Integer\n  expire            Int?             @default(0) @db.Integer\n  keywordFinish     String?          @db.VarChar(100)\n  delayMessage      Int?             @db.Integer\n  unknownMessage    String?          @db.VarChar(100)\n  listeningFromMe   Boolean?         @default(false) @db.Boolean\n  stopBotFromMe     Boolean?         @default(false) @db.Boolean\n  keepOpen          Boolean?         @default(false) @db.Boolean\n  debounceTime      Int?             @db.Integer\n  splitMessages     Boolean?         @default(false) @db.Boolean\n  timePerChar       Int?             @default(50) @db.Integer\n  ignoreJids        Json?\n  triggerType       TriggerType?\n  triggerOperator   TriggerOperator?\n  triggerValue      String?\n  createdAt         DateTime?        @default(now()) @db.Timestamp\n  updatedAt         DateTime         @updatedAt @db.Timestamp\n  OpenaiCreds       OpenaiCreds      @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)\n  openaiCredsId     String\n  Instance          Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String\n  OpenaiSetting     OpenaiSetting[]\n}\n\nmodel IntegrationSession {\n  id         String        @id @default(cuid())\n  sessionId  String        @db.VarChar(255)\n  remoteJid  String        @db.VarChar(100)\n  pushName   String?\n  status     SessionStatus\n  awaitUser  Boolean       @default(false) @db.Boolean\n  context    Json?\n  type       String?       @db.VarChar(100)\n  createdAt  DateTime?     @default(now()) @db.Timestamp\n  updatedAt  DateTime      @updatedAt @db.Timestamp\n  Message    Message[]\n  Instance   Instance      @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n  parameters Json?         @db.JsonB\n\n  botId String?\n}\n\nmodel OpenaiSetting {\n  id               String       @id @default(cuid())\n  expire           Int?         @default(0) @db.Integer\n  keywordFinish    String?      @db.VarChar(100)\n  delayMessage     Int?         @db.Integer\n  unknownMessage   String?      @db.VarChar(100)\n  listeningFromMe  Boolean?     @default(false) @db.Boolean\n  stopBotFromMe    Boolean?     @default(false) @db.Boolean\n  keepOpen         Boolean?     @default(false) @db.Boolean\n  debounceTime     Int?         @db.Integer\n  ignoreJids       Json?\n  splitMessages    Boolean?     @default(false) @db.Boolean\n  timePerChar      Int?         @default(50) @db.Integer\n  speechToText     Boolean?     @default(false) @db.Boolean\n  createdAt        DateTime?    @default(now()) @db.Timestamp\n  updatedAt        DateTime     @updatedAt @db.Timestamp\n  OpenaiCreds      OpenaiCreds? @relation(fields: [openaiCredsId], references: [id])\n  openaiCredsId    String       @unique\n  Fallback         OpenaiBot?   @relation(fields: [openaiIdFallback], references: [id])\n  openaiIdFallback String?      @db.VarChar(100)\n  Instance         Instance     @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId       String       @unique\n}\n\nmodel Template {\n  id         String    @id @default(cuid())\n  templateId String    @unique @db.VarChar(255)\n  name       String    @unique @db.VarChar(255)\n  template   Json      @db.JsonB\n  webhookUrl String?   @db.VarChar(500)\n  createdAt  DateTime? @default(now()) @db.Timestamp\n  updatedAt  DateTime  @updatedAt @db.Timestamp\n  Instance   Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId String\n}\n\nmodel Dify {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  botType         DifyBotType\n  apiUrl          String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  DifySetting     DifySetting[]\n}\n\nmodel DifySetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Integer\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Integer\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false) @db.Boolean\n  stopBotFromMe   Boolean?  @default(false) @db.Boolean\n  keepOpen        Boolean?  @default(false) @db.Boolean\n  debounceTime    Int?      @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false) @db.Boolean\n  timePerChar     Int?      @default(50) @db.Integer\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        Dify?     @relation(fields: [difyIdFallback], references: [id])\n  difyIdFallback  String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n\nmodel EvolutionBot {\n  id                  String                @id @default(cuid())\n  enabled             Boolean               @default(true) @db.Boolean\n  description         String?               @db.VarChar(255)\n  apiUrl              String?               @db.VarChar(255)\n  apiKey              String?               @db.VarChar(255)\n  expire              Int?                  @default(0) @db.Integer\n  keywordFinish       String?               @db.VarChar(100)\n  delayMessage        Int?                  @db.Integer\n  unknownMessage      String?               @db.VarChar(100)\n  listeningFromMe     Boolean?              @default(false) @db.Boolean\n  stopBotFromMe       Boolean?              @default(false) @db.Boolean\n  keepOpen            Boolean?              @default(false) @db.Boolean\n  debounceTime        Int?                  @db.Integer\n  ignoreJids          Json?\n  splitMessages       Boolean?              @default(false) @db.Boolean\n  timePerChar         Int?                  @default(50) @db.Integer\n  triggerType         TriggerType?\n  triggerOperator     TriggerOperator?\n  triggerValue        String?\n  createdAt           DateTime?             @default(now()) @db.Timestamp\n  updatedAt           DateTime              @updatedAt @db.Timestamp\n  Instance            Instance              @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId          String\n  EvolutionBotSetting EvolutionBotSetting[]\n}\n\nmodel EvolutionBotSetting {\n  id              String        @id @default(cuid())\n  expire          Int?          @default(0) @db.Integer\n  keywordFinish   String?       @db.VarChar(100)\n  delayMessage    Int?          @db.Integer\n  unknownMessage  String?       @db.VarChar(100)\n  listeningFromMe Boolean?      @default(false) @db.Boolean\n  stopBotFromMe   Boolean?      @default(false) @db.Boolean\n  keepOpen        Boolean?      @default(false) @db.Boolean\n  debounceTime    Int?          @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?      @default(false) @db.Boolean\n  timePerChar     Int?          @default(50) @db.Integer\n  createdAt       DateTime?     @default(now()) @db.Timestamp\n  updatedAt       DateTime      @updatedAt @db.Timestamp\n  Fallback        EvolutionBot? @relation(fields: [botIdFallback], references: [id])\n  botIdFallback   String?       @db.VarChar(100)\n  Instance        Instance      @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String        @unique\n}\n\nmodel Flowise {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  apiUrl          String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  FlowiseSetting  FlowiseSetting[]\n}\n\nmodel FlowiseSetting {\n  id                String    @id @default(cuid())\n  expire            Int?      @default(0) @db.Integer\n  keywordFinish     String?   @db.VarChar(100)\n  delayMessage      Int?      @db.Integer\n  unknownMessage    String?   @db.VarChar(100)\n  listeningFromMe   Boolean?  @default(false) @db.Boolean\n  stopBotFromMe     Boolean?  @default(false) @db.Boolean\n  keepOpen          Boolean?  @default(false) @db.Boolean\n  debounceTime      Int?      @db.Integer\n  ignoreJids        Json?\n  splitMessages     Boolean?  @default(false) @db.Boolean\n  timePerChar       Int?      @default(50) @db.Integer\n  createdAt         DateTime? @default(now()) @db.Timestamp\n  updatedAt         DateTime  @updatedAt @db.Timestamp\n  Fallback          Flowise?  @relation(fields: [flowiseIdFallback], references: [id])\n  flowiseIdFallback String?   @db.VarChar(100)\n  Instance          Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId        String    @unique\n}\n\nmodel IsOnWhatsapp {\n  id         String   @id @default(cuid())\n  remoteJid  String   @unique @db.VarChar(100)\n  jidOptions String\n  lid        String?  @db.VarChar(100)\n  createdAt  DateTime @default(now()) @db.Timestamp\n  updatedAt  DateTime @updatedAt @db.Timestamp\n}\n\nmodel N8n {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  webhookUrl      String?          @db.VarChar(255)\n  basicAuthUser   String?          @db.VarChar(255)\n  basicAuthPass   String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  N8nSetting      N8nSetting[]\n}\n\nmodel N8nSetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Integer\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Integer\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false) @db.Boolean\n  stopBotFromMe   Boolean?  @default(false) @db.Boolean\n  keepOpen        Boolean?  @default(false) @db.Boolean\n  debounceTime    Int?      @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false) @db.Boolean\n  timePerChar     Int?      @default(50) @db.Integer\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        N8n?      @relation(fields: [n8nIdFallback], references: [id])\n  n8nIdFallback   String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n\nmodel Evoai {\n  id              String           @id @default(cuid())\n  enabled         Boolean          @default(true) @db.Boolean\n  description     String?          @db.VarChar(255)\n  agentUrl        String?          @db.VarChar(255)\n  apiKey          String?          @db.VarChar(255)\n  expire          Int?             @default(0) @db.Integer\n  keywordFinish   String?          @db.VarChar(100)\n  delayMessage    Int?             @db.Integer\n  unknownMessage  String?          @db.VarChar(100)\n  listeningFromMe Boolean?         @default(false) @db.Boolean\n  stopBotFromMe   Boolean?         @default(false) @db.Boolean\n  keepOpen        Boolean?         @default(false) @db.Boolean\n  debounceTime    Int?             @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?         @default(false) @db.Boolean\n  timePerChar     Int?             @default(50) @db.Integer\n  triggerType     TriggerType?\n  triggerOperator TriggerOperator?\n  triggerValue    String?\n  createdAt       DateTime?        @default(now()) @db.Timestamp\n  updatedAt       DateTime         @updatedAt @db.Timestamp\n  Instance        Instance         @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String\n  EvoaiSetting    EvoaiSetting[]\n}\n\nmodel EvoaiSetting {\n  id              String    @id @default(cuid())\n  expire          Int?      @default(0) @db.Integer\n  keywordFinish   String?   @db.VarChar(100)\n  delayMessage    Int?      @db.Integer\n  unknownMessage  String?   @db.VarChar(100)\n  listeningFromMe Boolean?  @default(false) @db.Boolean\n  stopBotFromMe   Boolean?  @default(false) @db.Boolean\n  keepOpen        Boolean?  @default(false) @db.Boolean\n  debounceTime    Int?      @db.Integer\n  ignoreJids      Json?\n  splitMessages   Boolean?  @default(false) @db.Boolean\n  timePerChar     Int?      @default(50) @db.Integer\n  createdAt       DateTime? @default(now()) @db.Timestamp\n  updatedAt       DateTime  @updatedAt @db.Timestamp\n  Fallback        Evoai?    @relation(fields: [evoaiIdFallback], references: [id])\n  evoaiIdFallback String?   @db.VarChar(100)\n  Instance        Instance  @relation(fields: [instanceId], references: [id], onDelete: Cascade)\n  instanceId      String    @unique\n}\n"
  },
  {
    "path": "prometheus.yml.example",
    "content": "# Prometheus configuration example for Evolution API\n# Copy this file to prometheus.yml and adjust the settings\n\nglobal:\n  scrape_interval: 15s\n  evaluation_interval: 15s\n\nrule_files:\n  # - \"first_rules.yml\"\n  # - \"second_rules.yml\"\n\nscrape_configs:\n  # Evolution API metrics\n  - job_name: 'evolution-api'\n    static_configs:\n      - targets: ['localhost:8080']  # Adjust to your Evolution API URL\n    \n    # Metrics endpoint path\n    metrics_path: '/metrics'\n    \n    # Scrape interval for this job\n    scrape_interval: 30s\n    \n    # Basic authentication (if METRICS_AUTH_REQUIRED=true)\n    basic_auth:\n      username: 'prometheus'  # Should match METRICS_USER\n      password: 'secure_random_password_here'  # Should match METRICS_PASSWORD\n    \n    # Optional: Add custom labels\n    relabel_configs:\n      - source_labels: [__address__]\n        target_label: __param_target\n      - source_labels: [__param_target]\n        target_label: instance\n      - target_label: __address__\n        replacement: localhost:8080  # Evolution API address\n\n# Alerting configuration (optional)\nalerting:\n  alertmanagers:\n    - static_configs:\n        - targets:\n          # - alertmanager:9093\n\n# Example alert rules for Evolution API\n# Create a file called evolution_alerts.yml with these rules:\n#\n# groups:\n#   - name: evolution-api\n#     rules:\n#       - alert: EvolutionAPIDown\n#         expr: up{job=\"evolution-api\"} == 0\n#         for: 1m\n#         labels:\n#           severity: critical\n#         annotations:\n#           summary: \"Evolution API is down\"\n#           description: \"Evolution API has been down for more than 1 minute.\"\n#       \n#       - alert: EvolutionInstanceDown\n#         expr: evolution_instance_up == 0\n#         for: 2m\n#         labels:\n#           severity: warning\n#         annotations:\n#           summary: \"Evolution instance {{ $labels.instance }} is down\"\n#           description: \"Instance {{ $labels.instance }} has been down for more than 2 minutes.\"\n#       \n#       - alert: HighInstanceCount\n#         expr: evolution_instances_total > 100\n#         for: 5m\n#         labels:\n#           severity: warning\n#         annotations:\n#           summary: \"High number of Evolution instances\"\n#           description: \"Evolution API is managing {{ $value }} instances.\"\n"
  },
  {
    "path": "runWithProvider.js",
    "content": "const dotenv = require('dotenv');\nconst { execSync } = require('child_process');\nconst { existsSync } = require('fs');\n\ndotenv.config();\n\nconst { DATABASE_PROVIDER } = process.env;\nconst databaseProviderDefault = DATABASE_PROVIDER ?? 'postgresql';\n\nif (!DATABASE_PROVIDER) {\n  console.warn(`DATABASE_PROVIDER is not set in the .env file, using default: ${databaseProviderDefault}`);\n}\n\n// Função para determinar qual pasta de migrations usar\n// Função para determinar qual pasta de migrations usar\nfunction getMigrationsFolder(provider) {\n  switch (provider) {\n    case 'psql_bouncer':\n      return 'postgresql-migrations'; // psql_bouncer usa as migrations do postgresql\n    default:\n      return `${provider}-migrations`;\n  }\n}\n\nconst migrationsFolder = getMigrationsFolder(databaseProviderDefault);\n\nlet command = process.argv\n  .slice(2)\n  .join(' ')\n  .replace(/DATABASE_PROVIDER/g, databaseProviderDefault);\n\n// Substituir referências à pasta de migrations pela pasta correta\nconst migrationsPattern = new RegExp(`${databaseProviderDefault}-migrations`, 'g');\ncommand = command.replace(migrationsPattern, migrationsFolder);\n\nif (command.includes('rmdir') && existsSync('prisma\\\\migrations')) {\n  try {\n    execSync('rmdir /S /Q prisma\\\\migrations', { stdio: 'inherit' });\n  } catch (error) {\n    console.error(`Error removing directory: prisma\\\\migrations`);\n    process.exit(1);\n  }\n} else if (command.includes('rmdir')) {\n  console.warn(`Directory 'prisma\\\\migrations' does not exist, skipping removal.`);\n}\n\ntry {\n  execSync(command, { stdio: 'inherit' });\n} catch (error) {\n  console.error(`Error executing command: ${command}`);\n  process.exit(1);\n}"
  },
  {
    "path": "src/@types/express.d.ts",
    "content": "import { Multer } from 'multer';\n\ndeclare global {\n  namespace Express {\n    interface Request {\n      file?: Multer.File;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/abstract/abstract.cache.ts",
    "content": "export interface ICache {\n  get(key: string): Promise<any>;\n\n  hGet(key: string, field: string): Promise<any>;\n\n  set(key: string, value: any, ttl?: number): void;\n\n  hSet(key: string, field: string, value: any): Promise<void>;\n\n  has(key: string): Promise<boolean>;\n\n  keys(appendCriteria?: string): Promise<string[]>;\n\n  delete(key: string | string[]): Promise<number>;\n\n  hDelete(key: string, field: string): Promise<any>;\n\n  deleteAll(appendCriteria?: string): Promise<number>;\n}\n"
  },
  {
    "path": "src/api/abstract/abstract.repository.ts",
    "content": "import { ConfigService, Database } from '@config/env.config';\nimport { ROOT_DIR } from '@config/path.config';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\n\nexport type IInsert = { insertCount: number };\n\nexport interface IRepository {\n  insert(data: any, instanceName: string, saveDb?: boolean): Promise<IInsert>;\n  update(data: any, instanceName: string, saveDb?: boolean): Promise<IInsert>;\n  find(query: any): Promise<any>;\n  delete(query: any, force?: boolean): Promise<any>;\n\n  dbSettings: Database;\n  readonly storePath: string;\n}\n\ntype WriteStore<U> = {\n  path: string;\n  fileName: string;\n  data: U;\n};\n\nexport abstract class Repository implements IRepository {\n  constructor(configService: ConfigService) {\n    this.dbSettings = configService.get<Database>('DATABASE');\n  }\n\n  dbSettings: Database;\n  readonly storePath = join(ROOT_DIR, 'store');\n\n  public writeStore = <T = any>(create: WriteStore<T>) => {\n    if (!existsSync(create.path)) {\n      mkdirSync(create.path, { recursive: true });\n    }\n    try {\n      writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), {\n        encoding: 'utf-8',\n      });\n\n      return { message: 'create - success' };\n    } finally {\n      create.data = undefined;\n    }\n  };\n\n  // eslint-disable-next-line\n    public insert(data: any, instanceName: string, saveDb = false): Promise<IInsert> {\n    throw new Error('Method not implemented.');\n  }\n\n  // eslint-disable-next-line\n    public update(data: any, instanceName: string, saveDb = false): Promise<IInsert> {\n    throw new Error('Method not implemented.');\n  }\n\n  // eslint-disable-next-line\n    public find(query: any): Promise<any> {\n    throw new Error('Method not implemented.');\n  }\n\n  // eslint-disable-next-line\n    delete(query: any, force?: boolean): Promise<any> {\n    throw new Error('Method not implemented.');\n  }\n}\n"
  },
  {
    "path": "src/api/abstract/abstract.router.ts",
    "content": "import 'express-async-errors';\n\nimport { GetParticipant, GroupInvite } from '@api/dto/group.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { Request } from 'express';\nimport { JSONSchema7 } from 'json-schema';\nimport { validate } from 'jsonschema';\n\ntype DataValidate<T> = {\n  request: Request;\n  schema: JSONSchema7;\n  ClassRef: any;\n  execute: (instance: InstanceDto, data: T) => Promise<any>;\n};\n\nconst logger = new Logger('Validate');\n\nexport abstract class RouterBroker {\n  constructor() {}\n  public routerPath(path: string, param = true) {\n    let route = '/' + path;\n    param ? (route += '/:instanceName') : null;\n\n    return route;\n  }\n\n  public async dataValidate<T>(args: DataValidate<T>) {\n    const { request, schema, ClassRef, execute } = args;\n\n    const ref = new ClassRef();\n    const body = request.body;\n    const instance = request.params as unknown as InstanceDto;\n\n    if (request?.query && Object.keys(request.query).length > 0) {\n      Object.assign(instance, request.query);\n    }\n\n    if (request.originalUrl.includes('/instance/create')) {\n      Object.assign(instance, body);\n    }\n\n    Object.assign(ref, body);\n\n    const v = schema ? validate(ref, schema) : { valid: true, errors: [] };\n\n    if (!v.valid) {\n      const message: any[] = v.errors.map(({ stack, schema }) => {\n        let message: string;\n        if (schema['description']) {\n          message = schema['description'];\n        } else {\n          message = stack.replace('instance.', '');\n        }\n        return message;\n      });\n      logger.error(message);\n      throw new BadRequestException(message);\n    }\n\n    return await execute(instance, ref);\n  }\n\n  public async groupNoValidate<T>(args: DataValidate<T>) {\n    const { request, ClassRef, schema, execute } = args;\n\n    const instance = request.params as unknown as InstanceDto;\n\n    const ref = new ClassRef();\n\n    Object.assign(ref, request.body);\n\n    const v = validate(ref, schema);\n\n    if (!v.valid) {\n      const message: any[] = v.errors.map(({ property, stack, schema }) => {\n        let message: string;\n        if (schema['description']) {\n          message = schema['description'];\n        } else {\n          message = stack.replace('instance.', '');\n        }\n        return {\n          property: property.replace('instance.', ''),\n          message,\n        };\n      });\n      logger.error([...message]);\n      throw new BadRequestException(...message);\n    }\n\n    return await execute(instance, ref);\n  }\n\n  public async groupValidate<T>(args: DataValidate<T>) {\n    const { request, ClassRef, schema, execute } = args;\n\n    const instance = request.params as unknown as InstanceDto;\n    const body = request.body;\n\n    let groupJid = body?.groupJid;\n\n    if (!groupJid) {\n      if (request.query?.groupJid) {\n        groupJid = request.query.groupJid;\n      } else {\n        throw new BadRequestException('The group id needs to be informed in the query', 'ex: \"groupJid=120362@g.us\"');\n      }\n    }\n\n    if (!groupJid.endsWith('@g.us')) {\n      groupJid = groupJid + '@g.us';\n    }\n\n    Object.assign(body, {\n      groupJid: groupJid,\n    });\n\n    const ref = new ClassRef();\n\n    Object.assign(ref, body);\n\n    const v = validate(ref, schema);\n\n    if (!v.valid) {\n      const message: any[] = v.errors.map(({ property, stack, schema }) => {\n        let message: string;\n        if (schema['description']) {\n          message = schema['description'];\n        } else {\n          message = stack.replace('instance.', '');\n        }\n        return {\n          property: property.replace('instance.', ''),\n          message,\n        };\n      });\n      logger.error([...message]);\n      throw new BadRequestException(...message);\n    }\n\n    return await execute(instance, ref);\n  }\n\n  public async inviteCodeValidate<T>(args: DataValidate<T>) {\n    const { request, ClassRef, schema, execute } = args;\n\n    const inviteCode = request.query as unknown as GroupInvite;\n\n    if (!inviteCode?.inviteCode) {\n      throw new BadRequestException(\n        'The group invite code id needs to be informed in the query',\n        'ex: \"inviteCode=F1EX5QZxO181L3TMVP31gY\" (Obtained from group join link)',\n      );\n    }\n\n    const instance = request.params as unknown as InstanceDto;\n    const body = request.body;\n\n    const ref = new ClassRef();\n\n    Object.assign(body, inviteCode);\n    Object.assign(ref, body);\n\n    const v = validate(ref, schema);\n\n    if (!v.valid) {\n      const message: any[] = v.errors.map(({ property, stack, schema }) => {\n        let message: string;\n        if (schema['description']) {\n          message = schema['description'];\n        } else {\n          message = stack.replace('instance.', '');\n        }\n        return {\n          property: property.replace('instance.', ''),\n          message,\n        };\n      });\n      logger.error([...message]);\n      throw new BadRequestException(...message);\n    }\n\n    return await execute(instance, ref);\n  }\n\n  public async getParticipantsValidate<T>(args: DataValidate<T>) {\n    const { request, ClassRef, schema, execute } = args;\n\n    const getParticipants = request.query as unknown as GetParticipant;\n\n    if (!getParticipants?.getParticipants) {\n      throw new BadRequestException('The getParticipants needs to be informed in the query');\n    }\n\n    const instance = request.params as unknown as InstanceDto;\n    const body = request.body;\n\n    const ref = new ClassRef();\n\n    Object.assign(body, getParticipants);\n    Object.assign(ref, body);\n\n    const v = validate(ref, schema);\n\n    if (!v.valid) {\n      const message: any[] = v.errors.map(({ property, stack, schema }) => {\n        let message: string;\n        if (schema['description']) {\n          message = schema['description'];\n        } else {\n          message = stack.replace('instance.', '');\n        }\n        return {\n          property: property.replace('instance.', ''),\n          message,\n        };\n      });\n      logger.error([...message]);\n      throw new BadRequestException(...message);\n    }\n\n    return await execute(instance, ref);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/business.controller.ts",
    "content": "import { getCatalogDto, getCollectionsDto } from '@api/dto/business.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\n\nexport class BusinessController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async fetchCatalog({ instanceName }: InstanceDto, data: getCatalogDto) {\n    return await this.waMonitor.waInstances[instanceName].fetchCatalog(instanceName, data);\n  }\n\n  public async fetchCollections({ instanceName }: InstanceDto, data: getCollectionsDto) {\n    return await this.waMonitor.waInstances[instanceName].fetchCollections(instanceName, data);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/call.controller.ts",
    "content": "import { OfferCallDto } from '@api/dto/call.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\n\nexport class CallController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async offerCall({ instanceName }: InstanceDto, data: OfferCallDto) {\n    return await this.waMonitor.waInstances[instanceName].offerCall(data);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/chat.controller.ts",
    "content": "import {\n  ArchiveChatDto,\n  BlockUserDto,\n  DeleteMessage,\n  getBase64FromMediaMessageDto,\n  MarkChatUnreadDto,\n  NumberDto,\n  PrivacySettingDto,\n  ProfileNameDto,\n  ProfilePictureDto,\n  ProfileStatusDto,\n  ReadMessageDto,\n  SendPresenceDto,\n  UpdateMessageDto,\n  WhatsAppNumberDto,\n} from '@api/dto/chat.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { Query } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Contact, Message, MessageUpdate } from '@prisma/client';\n\nexport class ChatController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) {\n    return await this.waMonitor.waInstances[instanceName].whatsappNumber(data);\n  }\n\n  public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) {\n    return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data);\n  }\n\n  public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) {\n    return await this.waMonitor.waInstances[instanceName].archiveChat(data);\n  }\n\n  public async markChatUnread({ instanceName }: InstanceDto, data: MarkChatUnreadDto) {\n    return await this.waMonitor.waInstances[instanceName].markChatUnread(data);\n  }\n\n  public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) {\n    return await this.waMonitor.waInstances[instanceName].deleteMessage(data);\n  }\n\n  public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) {\n    return await this.waMonitor.waInstances[instanceName].profilePicture(data.number);\n  }\n\n  public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) {\n    return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number);\n  }\n\n  public async fetchContacts({ instanceName }: InstanceDto, query: Query<Contact>) {\n    return await this.waMonitor.waInstances[instanceName].fetchContacts(query);\n  }\n\n  public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) {\n    return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data);\n  }\n\n  public async fetchMessages({ instanceName }: InstanceDto, query: Query<Message>) {\n    return await this.waMonitor.waInstances[instanceName].fetchMessages(query);\n  }\n\n  public async fetchStatusMessage({ instanceName }: InstanceDto, query: Query<MessageUpdate>) {\n    return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query);\n  }\n\n  public async fetchChats({ instanceName }: InstanceDto, query: Query<Contact>) {\n    return await this.waMonitor.waInstances[instanceName].fetchChats(query);\n  }\n\n  public async findChatByRemoteJid({ instanceName }: InstanceDto, remoteJid: string) {\n    return await this.waMonitor.waInstances[instanceName].findChatByRemoteJid(remoteJid);\n  }\n\n  public async sendPresence({ instanceName }: InstanceDto, data: SendPresenceDto) {\n    return await this.waMonitor.waInstances[instanceName].sendPresence(data);\n  }\n\n  public async fetchPrivacySettings({ instanceName }: InstanceDto) {\n    return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings();\n  }\n\n  public async updatePrivacySettings({ instanceName }: InstanceDto, data: PrivacySettingDto) {\n    return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data);\n  }\n\n  public async fetchBusinessProfile({ instanceName }: InstanceDto, data: ProfilePictureDto) {\n    return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile(data.number);\n  }\n\n  public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) {\n    return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name);\n  }\n\n  public async updateProfileStatus({ instanceName }: InstanceDto, data: ProfileStatusDto) {\n    return await this.waMonitor.waInstances[instanceName].updateProfileStatus(data.status);\n  }\n\n  public async updateProfilePicture({ instanceName }: InstanceDto, data: ProfilePictureDto) {\n    return await this.waMonitor.waInstances[instanceName].updateProfilePicture(data.picture);\n  }\n\n  public async removeProfilePicture({ instanceName }: InstanceDto) {\n    return await this.waMonitor.waInstances[instanceName].removeProfilePicture();\n  }\n\n  public async updateMessage({ instanceName }: InstanceDto, data: UpdateMessageDto) {\n    return await this.waMonitor.waInstances[instanceName].updateMessage(data);\n  }\n\n  public async blockUser({ instanceName }: InstanceDto, data: BlockUserDto) {\n    return await this.waMonitor.waInstances[instanceName].blockUser(data);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/group.controller.ts",
    "content": "import {\n  AcceptGroupInvite,\n  CreateGroupDto,\n  GetParticipant,\n  GroupDescriptionDto,\n  GroupInvite,\n  GroupJid,\n  GroupPictureDto,\n  GroupSendInvite,\n  GroupSubjectDto,\n  GroupToggleEphemeralDto,\n  GroupUpdateParticipantDto,\n  GroupUpdateSettingDto,\n} from '@api/dto/group.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\n\nexport class GroupController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async createGroup(instance: InstanceDto, create: CreateGroupDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].createGroup(create);\n  }\n\n  public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update);\n  }\n\n  public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update);\n  }\n\n  public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update);\n  }\n\n  public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) {\n    return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid);\n  }\n\n  public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) {\n    return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants);\n  }\n\n  public async inviteCode(instance: InstanceDto, groupJid: GroupJid) {\n    return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid);\n  }\n\n  public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) {\n    return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode);\n  }\n\n  public async sendInvite(instance: InstanceDto, data: GroupSendInvite) {\n    return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data);\n  }\n\n  public async acceptInviteCode(instance: InstanceDto, inviteCode: AcceptGroupInvite) {\n    return await this.waMonitor.waInstances[instance.instanceName].acceptInviteCode(inviteCode);\n  }\n\n  public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) {\n    return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid);\n  }\n\n  public async findParticipants(instance: InstanceDto, groupJid: GroupJid) {\n    return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid);\n  }\n\n  public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update);\n  }\n\n  public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update);\n  }\n\n  public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) {\n    return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update);\n  }\n\n  public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) {\n    return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/instance.controller.ts",
    "content": "import { InstanceDto, SetPresenceDto } from '@api/dto/instance.dto';\nimport { ChatwootService } from '@api/integrations/chatbot/chatwoot/services/chatwoot.service';\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { channelController, eventManager } from '@api/server.module';\nimport { CacheService } from '@api/services/cache.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { SettingsService } from '@api/services/settings.service';\nimport { Events, Integration, wa } from '@api/types/wa.types';\nimport { Auth, Chatwoot, ConfigService, HttpServer, WaBusiness } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException, InternalServerErrorException, UnauthorizedException } from '@exceptions';\nimport { delay } from 'baileys';\nimport { isArray, isURL } from 'class-validator';\nimport EventEmitter2 from 'eventemitter2';\nimport { v4 } from 'uuid';\n\nimport { ProxyController } from './proxy.controller';\n\nexport class InstanceController {\n  constructor(\n    private readonly waMonitor: WAMonitoringService,\n    private readonly configService: ConfigService,\n    private readonly prismaRepository: PrismaRepository,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly chatwootService: ChatwootService,\n    private readonly settingsService: SettingsService,\n    private readonly proxyService: ProxyController,\n    private readonly cache: CacheService,\n    private readonly chatwootCache: CacheService,\n    private readonly baileysCache: CacheService,\n    private readonly providerFiles: ProviderFiles,\n  ) {}\n\n  private readonly logger = new Logger('InstanceController');\n\n  public async createInstance(instanceData: InstanceDto) {\n    try {\n      const instance = channelController.init(instanceData, {\n        configService: this.configService,\n        eventEmitter: this.eventEmitter,\n        prismaRepository: this.prismaRepository,\n        cache: this.cache,\n        chatwootCache: this.chatwootCache,\n        baileysCache: this.baileysCache,\n        providerFiles: this.providerFiles,\n      });\n\n      if (!instance) {\n        throw new BadRequestException('Invalid integration');\n      }\n\n      const instanceId = v4();\n\n      instanceData.instanceId = instanceId;\n\n      let hash: string;\n\n      if (!instanceData.token) hash = v4().toUpperCase();\n      else hash = instanceData.token;\n\n      await this.waMonitor.saveInstance({\n        instanceId,\n        integration: instanceData.integration,\n        instanceName: instanceData.instanceName,\n        ownerJid: instanceData.ownerJid,\n        profileName: instanceData.profileName,\n        profilePicUrl: instanceData.profilePicUrl,\n        hash,\n        number: instanceData.number,\n        businessId: instanceData.businessId,\n        status: instanceData.status,\n      });\n\n      instance.setInstance({\n        instanceName: instanceData.instanceName,\n        instanceId,\n        integration: instanceData.integration,\n        token: hash,\n        number: instanceData.number,\n        businessId: instanceData.businessId,\n      });\n\n      this.waMonitor.waInstances[instance.instanceName] = instance;\n      this.waMonitor.delInstanceTime(instance.instanceName);\n\n      // set events\n      await eventManager.setInstance(instance.instanceName, instanceData);\n\n      instance.sendDataWebhook(Events.INSTANCE_CREATE, {\n        instanceName: instanceData.instanceName,\n        instanceId: instanceId,\n      });\n\n      const instanceDto: InstanceDto = {\n        instanceName: instance.instanceName,\n        instanceId: instance.instanceId,\n        connectionStatus:\n          typeof instance.connectionStatus === 'string'\n            ? instance.connectionStatus\n            : instance.connectionStatus?.state || 'unknown',\n      };\n\n      if (instanceData.proxyHost && instanceData.proxyPort && instanceData.proxyProtocol) {\n        const testProxy = await this.proxyService.testProxy({\n          host: instanceData.proxyHost,\n          port: instanceData.proxyPort,\n          protocol: instanceData.proxyProtocol,\n          username: instanceData.proxyUsername,\n          password: instanceData.proxyPassword,\n        });\n        if (!testProxy) {\n          throw new BadRequestException('Invalid proxy');\n        }\n        await this.proxyService.createProxy(instanceDto, {\n          enabled: true,\n          host: instanceData.proxyHost,\n          port: instanceData.proxyPort,\n          protocol: instanceData.proxyProtocol,\n          username: instanceData.proxyUsername,\n          password: instanceData.proxyPassword,\n        });\n      }\n\n      const settings: wa.LocalSettings = {\n        rejectCall: instanceData.rejectCall === true,\n        msgCall: instanceData.msgCall || '',\n        groupsIgnore: instanceData.groupsIgnore === true,\n        alwaysOnline: instanceData.alwaysOnline === true,\n        readMessages: instanceData.readMessages === true,\n        readStatus: instanceData.readStatus === true,\n        syncFullHistory: instanceData.syncFullHistory === true,\n        wavoipToken: instanceData.wavoipToken || '',\n      };\n\n      await this.settingsService.create(instanceDto, settings);\n\n      let webhookWaBusiness = null,\n        accessTokenWaBusiness = '';\n\n      if (instanceData.integration === Integration.WHATSAPP_BUSINESS) {\n        if (!instanceData.number) {\n          throw new BadRequestException('number is required');\n        }\n        const urlServer = this.configService.get<HttpServer>('SERVER').URL;\n        webhookWaBusiness = `${urlServer}/webhook/meta`;\n        accessTokenWaBusiness = this.configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK;\n      }\n\n      if (!instanceData.chatwootAccountId || !instanceData.chatwootToken || !instanceData.chatwootUrl) {\n        let getQrcode: wa.QrCode;\n\n        if (instanceData.qrcode && instanceData.integration === Integration.WHATSAPP_BAILEYS) {\n          await instance.connectToWhatsapp(instanceData.number);\n          await delay(5000);\n          getQrcode = instance.qrCode;\n        }\n\n        const result = {\n          instance: {\n            instanceName: instance.instanceName,\n            instanceId: instanceId,\n            integration: instanceData.integration,\n            webhookWaBusiness,\n            accessTokenWaBusiness,\n            status:\n              typeof instance.connectionStatus === 'string'\n                ? instance.connectionStatus\n                : instance.connectionStatus?.state || 'unknown',\n          },\n          hash,\n          webhook: {\n            webhookUrl: instanceData?.webhook?.url,\n            webhookHeaders: instanceData?.webhook?.headers,\n            webhookByEvents: instanceData?.webhook?.byEvents,\n            webhookBase64: instanceData?.webhook?.base64,\n          },\n          websocket: {\n            enabled: instanceData?.websocket?.enabled,\n          },\n          rabbitmq: {\n            enabled: instanceData?.rabbitmq?.enabled,\n          },\n          nats: {\n            enabled: instanceData?.nats?.enabled,\n          },\n          sqs: {\n            enabled: instanceData?.sqs?.enabled,\n          },\n          settings,\n          qrcode: getQrcode,\n        };\n\n        return result;\n      }\n\n      if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED)\n        throw new BadRequestException('Chatwoot is not enabled');\n\n      if (!instanceData.chatwootAccountId) {\n        throw new BadRequestException('accountId is required');\n      }\n\n      if (!instanceData.chatwootToken) {\n        throw new BadRequestException('token is required');\n      }\n\n      if (!instanceData.chatwootUrl) {\n        throw new BadRequestException('url is required');\n      }\n\n      if (!isURL(instanceData.chatwootUrl, { require_tld: false })) {\n        throw new BadRequestException('Invalid \"url\" property in chatwoot');\n      }\n\n      if (instanceData.chatwootSignMsg !== true && instanceData.chatwootSignMsg !== false) {\n        throw new BadRequestException('signMsg is required');\n      }\n\n      if (instanceData.chatwootReopenConversation !== true && instanceData.chatwootReopenConversation !== false) {\n        throw new BadRequestException('reopenConversation is required');\n      }\n\n      if (instanceData.chatwootConversationPending !== true && instanceData.chatwootConversationPending !== false) {\n        throw new BadRequestException('conversationPending is required');\n      }\n\n      const urlServer = this.configService.get<HttpServer>('SERVER').URL;\n\n      try {\n        this.chatwootService.create(instanceDto, {\n          enabled: true,\n          accountId: instanceData.chatwootAccountId,\n          token: instanceData.chatwootToken,\n          url: instanceData.chatwootUrl,\n          signMsg: instanceData.chatwootSignMsg || false,\n          nameInbox: instanceData.chatwootNameInbox ?? instance.instanceName.split('-cwId-')[0],\n          number: instanceData.number,\n          reopenConversation: instanceData.chatwootReopenConversation || false,\n          conversationPending: instanceData.chatwootConversationPending || false,\n          importContacts: instanceData.chatwootImportContacts ?? true,\n          mergeBrazilContacts: instanceData.chatwootMergeBrazilContacts ?? false,\n          importMessages: instanceData.chatwootImportMessages ?? true,\n          daysLimitImportMessages: instanceData.chatwootDaysLimitImportMessages ?? 60,\n          organization: instanceData.chatwootOrganization,\n          logo: instanceData.chatwootLogo,\n          autoCreate: instanceData.chatwootAutoCreate !== false,\n        });\n      } catch (error) {\n        this.logger.log(error);\n      }\n\n      return {\n        instance: {\n          instanceName: instance.instanceName,\n          instanceId: instanceId,\n          integration: instanceData.integration,\n          webhookWaBusiness,\n          accessTokenWaBusiness,\n          status:\n            typeof instance.connectionStatus === 'string'\n              ? instance.connectionStatus\n              : instance.connectionStatus?.state || 'unknown',\n        },\n        hash,\n        webhook: {\n          webhookUrl: instanceData?.webhook?.url,\n          webhookHeaders: instanceData?.webhook?.headers,\n          webhookByEvents: instanceData?.webhook?.byEvents,\n          webhookBase64: instanceData?.webhook?.base64,\n        },\n        websocket: {\n          enabled: instanceData?.websocket?.enabled,\n        },\n        rabbitmq: {\n          enabled: instanceData?.rabbitmq?.enabled,\n        },\n        nats: {\n          enabled: instanceData?.nats?.enabled,\n        },\n        sqs: {\n          enabled: instanceData?.sqs?.enabled,\n        },\n        settings,\n        chatwoot: {\n          enabled: true,\n          accountId: instanceData.chatwootAccountId,\n          token: instanceData.chatwootToken,\n          url: instanceData.chatwootUrl,\n          signMsg: instanceData.chatwootSignMsg || false,\n          reopenConversation: instanceData.chatwootReopenConversation || false,\n          conversationPending: instanceData.chatwootConversationPending || false,\n          mergeBrazilContacts: instanceData.chatwootMergeBrazilContacts ?? false,\n          importContacts: instanceData.chatwootImportContacts ?? true,\n          importMessages: instanceData.chatwootImportMessages ?? true,\n          daysLimitImportMessages: instanceData.chatwootDaysLimitImportMessages || 60,\n          number: instanceData.number,\n          nameInbox: instanceData.chatwootNameInbox ?? instance.instanceName,\n          webhookUrl: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,\n        },\n      };\n    } catch (error) {\n      this.waMonitor.deleteInstance(instanceData.instanceName);\n      this.logger.error(isArray(error.message) ? error.message[0] : error.message);\n      throw new BadRequestException(isArray(error.message) ? error.message[0] : error.message);\n    }\n  }\n\n  public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) {\n    try {\n      const instance = this.waMonitor.waInstances[instanceName];\n      const state = instance?.connectionStatus?.state;\n\n      if (!state) {\n        throw new BadRequestException('The \"' + instanceName + '\" instance does not exist');\n      }\n\n      if (state == 'open') {\n        return await this.connectionState({ instanceName });\n      }\n\n      if (state == 'connecting') {\n        return instance.qrCode;\n      }\n\n      if (state == 'close') {\n        await instance.connectToWhatsapp(number);\n\n        await delay(2000);\n        return instance.qrCode;\n      }\n\n      return {\n        instance: {\n          instanceName: instanceName,\n          status: state,\n        },\n        qrcode: instance?.qrCode,\n      };\n    } catch (error) {\n      this.logger.error(error);\n      return { error: true, message: error.toString() };\n    }\n  }\n\n  public async restartInstance({ instanceName }: InstanceDto) {\n    try {\n      const instance = this.waMonitor.waInstances[instanceName];\n      const state = instance?.connectionStatus?.state;\n\n      if (!state) {\n        throw new BadRequestException('The \"' + instanceName + '\" instance does not exist');\n      }\n\n      if (state === 'close') {\n        throw new BadRequestException('The \"' + instanceName + '\" instance is not connected');\n      }\n      this.logger.info(`Restarting instance: ${instanceName}`);\n\n      if (typeof instance.restart === 'function') {\n        await instance.restart();\n        // Wait a bit for the reconnection to be established\n        await new Promise((r) => setTimeout(r, 2000));\n        return {\n          instance: {\n            instanceName: instanceName,\n            status: instance.connectionStatus?.state || 'connecting',\n          },\n        };\n      }\n\n      // Fallback for Baileys (uses different mechanism)\n      if (state === 'open' || state === 'connecting') {\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) instance.clearCacheChatwoot();\n\n        instance.client?.ws?.close();\n        instance.client?.end(new Error('restart'));\n        return await this.connectToWhatsapp({ instanceName });\n      }\n\n      return {\n        instance: {\n          instanceName: instanceName,\n          status: state,\n        },\n      };\n    } catch (error) {\n      this.logger.error(error);\n      return { error: true, message: error.toString() };\n    }\n  }\n\n  public async connectionState({ instanceName }: InstanceDto) {\n    return {\n      instance: {\n        instanceName: instanceName,\n        state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state,\n      },\n    };\n  }\n\n  public async fetchInstances({ instanceName, instanceId, number }: InstanceDto, key: string) {\n    const env = this.configService.get<Auth>('AUTHENTICATION').API_KEY;\n\n    if (env.KEY !== key) {\n      const instancesByKey = await this.prismaRepository.instance.findMany({\n        where: {\n          token: key,\n          name: instanceName || undefined,\n          id: instanceId || undefined,\n        },\n      });\n\n      if (instancesByKey.length > 0) {\n        const names = instancesByKey.map((instance) => instance.name);\n\n        return this.waMonitor.instanceInfo(names);\n      } else {\n        throw new UnauthorizedException();\n      }\n    }\n\n    if (instanceId || number) {\n      return this.waMonitor.instanceInfoById(instanceId, number);\n    }\n\n    const instanceNames = instanceName ? [instanceName] : null;\n\n    return this.waMonitor.instanceInfo(instanceNames);\n  }\n\n  public async setPresence({ instanceName }: InstanceDto, data: SetPresenceDto) {\n    return await this.waMonitor.waInstances[instanceName].setPresence(data);\n  }\n\n  public async logout({ instanceName }: InstanceDto) {\n    const { instance } = await this.connectionState({ instanceName });\n\n    if (instance.state === 'close') {\n      throw new BadRequestException('The \"' + instanceName + '\" instance is not connected');\n    }\n\n    try {\n      await this.waMonitor.waInstances[instanceName]?.logoutInstance();\n\n      return { status: 'SUCCESS', error: false, response: { message: 'Instance logged out' } };\n    } catch (error) {\n      throw new InternalServerErrorException(error.toString());\n    }\n  }\n\n  public async deleteInstance({ instanceName }: InstanceDto) {\n    const { instance } = await this.connectionState({ instanceName });\n    try {\n      const waInstances = this.waMonitor.waInstances[instanceName];\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) waInstances?.clearCacheChatwoot();\n\n      if (instance.state === 'connecting' || instance.state === 'open') {\n        await this.logout({ instanceName });\n      }\n\n      try {\n        waInstances?.sendDataWebhook(Events.INSTANCE_DELETE, {\n          instanceName,\n          instanceId: waInstances.instanceId,\n        });\n      } catch (error) {\n        this.logger.error(error);\n      }\n\n      this.eventEmitter.emit('remove.instance', instanceName, 'inner');\n      return { status: 'SUCCESS', error: false, response: { message: 'Instance deleted' } };\n    } catch (error) {\n      throw new BadRequestException(error.toString());\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/label.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { HandleLabelDto } from '@api/dto/label.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\n\nexport class LabelController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async fetchLabels({ instanceName }: InstanceDto) {\n    return await this.waMonitor.waInstances[instanceName].fetchLabels();\n  }\n\n  public async handleLabel({ instanceName }: InstanceDto, data: HandleLabelDto) {\n    return await this.waMonitor.waInstances[instanceName].handleLabel(data);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/proxy.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ProxyDto } from '@api/dto/proxy.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { ProxyService } from '@api/services/proxy.service';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException, NotFoundException } from '@exceptions';\nimport { makeProxyAgent } from '@utils/makeProxyAgent';\nimport axios from 'axios';\n\nconst logger = new Logger('ProxyController');\n\nexport class ProxyController {\n  constructor(\n    private readonly proxyService: ProxyService,\n    private readonly waMonitor: WAMonitoringService,\n  ) {}\n\n  public async createProxy(instance: InstanceDto, data: ProxyDto) {\n    if (!this.waMonitor.waInstances[instance.instanceName]) {\n      throw new NotFoundException(`The \"${instance.instanceName}\" instance does not exist`);\n    }\n\n    if (!data?.enabled) {\n      data.host = '';\n      data.port = '';\n      data.protocol = '';\n      data.username = '';\n      data.password = '';\n    }\n\n    if (data.host) {\n      const testProxy = await this.testProxy(data);\n      if (!testProxy) {\n        throw new BadRequestException('Invalid proxy');\n      }\n    }\n\n    return this.proxyService.create(instance, data);\n  }\n\n  public async findProxy(instance: InstanceDto) {\n    if (!this.waMonitor.waInstances[instance.instanceName]) {\n      throw new NotFoundException(`The \"${instance.instanceName}\" instance does not exist`);\n    }\n\n    return this.proxyService.find(instance);\n  }\n\n  public async testProxy(proxy: ProxyDto) {\n    try {\n      const serverIp = await axios.get('https://icanhazip.com/');\n      const response = await axios.get('https://icanhazip.com/', {\n        httpsAgent: makeProxyAgent(proxy),\n      });\n\n      const result = response?.data !== serverIp?.data;\n      if (result) {\n        logger.info('testProxy: proxy connection successful');\n      } else {\n        logger.warn(\"testProxy: proxy connection doesn't change the origin IP\");\n      }\n\n      return result;\n    } catch (error) {\n      if (axios.isAxiosError(error)) {\n        logger.error('testProxy error: axios error: ' + error.message);\n      } else {\n        logger.error('testProxy error: unexpected error: ' + error);\n      }\n\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/sendMessage.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport {\n  SendAudioDto,\n  SendButtonsDto,\n  SendContactDto,\n  SendListDto,\n  SendLocationDto,\n  SendMediaDto,\n  SendPollDto,\n  SendPtvDto,\n  SendReactionDto,\n  SendStatusDto,\n  SendStickerDto,\n  SendTemplateDto,\n  SendTextDto,\n} from '@api/dto/sendMessage.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { BadRequestException } from '@exceptions';\nimport { isBase64, isURL } from 'class-validator';\nimport emojiRegex from 'emoji-regex';\n\nconst regex = emojiRegex();\n\nfunction isEmoji(str: string) {\n  if (str === '') return true;\n\n  const match = str.match(regex);\n  return match?.length === 1 && match[0] === str;\n}\n\nexport class SendMessageController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async sendTemplate({ instanceName }: InstanceDto, data: SendTemplateDto) {\n    return await this.waMonitor.waInstances[instanceName].templateMessage(data);\n  }\n\n  public async sendText({ instanceName }: InstanceDto, data: SendTextDto) {\n    return await this.waMonitor.waInstances[instanceName].textMessage(data);\n  }\n\n  public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto, file?: any) {\n    if (isBase64(data?.media) && !data?.fileName && data?.mediatype === 'document') {\n      throw new BadRequestException('For base64 the file name must be informed.');\n    }\n\n    if (file || isURL(data?.media) || isBase64(data?.media)) {\n      return await this.waMonitor.waInstances[instanceName].mediaMessage(data, file);\n    }\n    throw new BadRequestException('Owned media must be a url or base64');\n  }\n\n  public async sendPtv({ instanceName }: InstanceDto, data: SendPtvDto, file?: any) {\n    if (file || isURL(data?.video) || isBase64(data?.video)) {\n      return await this.waMonitor.waInstances[instanceName].ptvMessage(data, file);\n    }\n    throw new BadRequestException('Owned media must be a url or base64');\n  }\n\n  public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto, file?: any) {\n    if (file || isURL(data.sticker) || isBase64(data.sticker)) {\n      return await this.waMonitor.waInstances[instanceName].mediaSticker(data, file);\n    }\n    throw new BadRequestException('Owned media must be a url or base64');\n  }\n\n  public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto, file?: any) {\n    if (file?.buffer || isURL(data.audio) || isBase64(data.audio)) {\n      // Si file existe y tiene buffer, o si es una URL o Base64, continúa\n      return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data, file);\n    } else {\n      console.error('El archivo no tiene buffer o el audio no es una URL o Base64 válida');\n      throw new BadRequestException('Owned media must be a url, base64, or valid file with buffer');\n    }\n  }\n\n  public async sendButtons({ instanceName }: InstanceDto, data: SendButtonsDto) {\n    return await this.waMonitor.waInstances[instanceName].buttonMessage(data);\n  }\n\n  public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) {\n    return await this.waMonitor.waInstances[instanceName].locationMessage(data);\n  }\n\n  public async sendList({ instanceName }: InstanceDto, data: SendListDto) {\n    return await this.waMonitor.waInstances[instanceName].listMessage(data);\n  }\n\n  public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) {\n    return await this.waMonitor.waInstances[instanceName].contactMessage(data);\n  }\n\n  public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) {\n    if (!isEmoji(data.reaction)) {\n      throw new BadRequestException('Reaction must be a single emoji or empty string');\n    }\n    return await this.waMonitor.waInstances[instanceName].reactionMessage(data);\n  }\n\n  public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) {\n    return await this.waMonitor.waInstances[instanceName].pollMessage(data);\n  }\n\n  public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto, file?: any) {\n    return await this.waMonitor.waInstances[instanceName].statusMessage(data, file);\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/settings.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { SettingsDto } from '@api/dto/settings.dto';\nimport { SettingsService } from '@api/services/settings.service';\n\nexport class SettingsController {\n  constructor(private readonly settingsService: SettingsService) {}\n\n  public async createSettings(instance: InstanceDto, data: SettingsDto) {\n    return this.settingsService.create(instance, data);\n  }\n\n  public async findSettings(instance: InstanceDto) {\n    const settings = this.settingsService.find(instance);\n    return settings;\n  }\n}\n"
  },
  {
    "path": "src/api/controllers/template.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { TemplateDto } from '@api/dto/template.dto';\nimport { TemplateService } from '@api/services/template.service';\n\nexport class TemplateController {\n  constructor(private readonly templateService: TemplateService) {}\n\n  public async createTemplate(instance: InstanceDto, data: TemplateDto) {\n    return this.templateService.create(instance, data);\n  }\n\n  public async findTemplate(instance: InstanceDto) {\n    return this.templateService.find(instance);\n  }\n\n  public async editTemplate(\n    instance: InstanceDto,\n    data: { templateId: string; category?: string; components?: any; allowCategoryChange?: boolean; ttl?: number },\n  ) {\n    return this.templateService.edit(instance, data);\n  }\n\n  public async deleteTemplate(instance: InstanceDto, data: { name: string; hsmId?: string }) {\n    return this.templateService.delete(instance, data);\n  }\n}\n"
  },
  {
    "path": "src/api/dto/business.dto.ts",
    "content": "export class NumberDto {\n  number: string;\n}\n\nexport class getCatalogDto {\n  number?: string;\n  limit?: number;\n  cursor?: string;\n}\n\nexport class getCollectionsDto {\n  number?: string;\n  limit?: number;\n}\n"
  },
  {
    "path": "src/api/dto/call.dto.ts",
    "content": "export class Metadata {\n  number: string;\n}\n\nexport class OfferCallDto extends Metadata {\n  isVideo?: boolean;\n  callDuration?: number;\n}\n"
  },
  {
    "path": "src/api/dto/chat.dto.ts",
    "content": "import {\n  proto,\n  WAPresence,\n  WAPrivacyGroupAddValue,\n  WAPrivacyOnlineValue,\n  WAPrivacyValue,\n  WAReadReceiptsValue,\n} from 'baileys';\n\nexport class OnWhatsAppDto {\n  constructor(\n    public readonly jid: string,\n    public readonly exists: boolean,\n    public readonly number: string,\n    public readonly name?: string,\n    public readonly lid?: string,\n  ) {}\n}\n\nexport class getBase64FromMediaMessageDto {\n  message: proto.WebMessageInfo;\n  convertToMp4?: boolean;\n}\n\nexport class WhatsAppNumberDto {\n  numbers: string[];\n}\n\nexport class NumberDto {\n  number: string;\n}\n\nexport class NumberBusiness {\n  wid?: string;\n  jid?: string;\n  exists?: boolean;\n  isBusiness: boolean;\n  name?: string;\n  message?: string;\n  description?: string;\n  email?: string;\n  websites?: string[];\n  website?: string[];\n  address?: string;\n  about?: string;\n  vertical?: string;\n  profilehandle?: string;\n}\n\nexport class ProfileNameDto {\n  name: string;\n}\n\nexport class ProfileStatusDto {\n  status: string;\n}\n\nexport class ProfilePictureDto {\n  number?: string;\n  // url or base64\n  picture?: string;\n}\n\nclass Key {\n  id: string;\n  fromMe: boolean;\n  remoteJid: string;\n}\nexport class ReadMessageDto {\n  readMessages: Key[];\n}\n\nexport class LastMessage {\n  key: Key;\n  messageTimestamp?: number;\n}\n\nexport class ArchiveChatDto {\n  lastMessage?: LastMessage;\n  chat?: string;\n  archive: boolean;\n}\n\nexport class MarkChatUnreadDto {\n  lastMessage?: LastMessage;\n  chat?: string;\n}\n\nexport class PrivacySettingDto {\n  readreceipts: WAReadReceiptsValue;\n  profile: WAPrivacyValue;\n  status: WAPrivacyValue;\n  online: WAPrivacyOnlineValue;\n  last: WAPrivacyValue;\n  groupadd: WAPrivacyGroupAddValue;\n}\n\nexport class DeleteMessage {\n  id: string;\n  fromMe: boolean;\n  remoteJid: string;\n  participant?: string;\n}\nexport class Options {\n  delay?: number;\n  presence?: WAPresence;\n}\nclass OptionsMessage {\n  options: Options;\n}\nexport class Metadata extends OptionsMessage {\n  number: string;\n}\n\nexport class SendPresenceDto extends Metadata {\n  presence: WAPresence;\n  delay: number;\n}\n\nexport class UpdateMessageDto extends Metadata {\n  number: string;\n  key: proto.IMessageKey;\n  text: string;\n}\n\nexport class BlockUserDto {\n  number: string;\n  status: 'block' | 'unblock';\n}\n"
  },
  {
    "path": "src/api/dto/chatbot.dto.ts",
    "content": "export class Session {\n  remoteJid?: string;\n  sessionId?: string;\n  status?: string;\n  createdAt?: number;\n  updateAt?: number;\n}\n\nexport class IgnoreJidDto {\n  remoteJid?: string;\n  action?: string;\n}\n"
  },
  {
    "path": "src/api/dto/group.dto.ts",
    "content": "export class CreateGroupDto {\n  subject: string;\n  participants: string[];\n  description?: string;\n  promoteParticipants?: boolean;\n}\n\nexport class GroupPictureDto {\n  groupJid: string;\n  image: string;\n}\n\nexport class GroupSubjectDto {\n  groupJid: string;\n  subject: string;\n}\n\nexport class GroupDescriptionDto {\n  groupJid: string;\n  description: string;\n}\n\nexport class GroupJid {\n  groupJid: string;\n}\n\nexport class GetParticipant {\n  getParticipants: string;\n}\n\nexport class GroupInvite {\n  inviteCode: string;\n}\n\nexport class AcceptGroupInvite {\n  inviteCode: string;\n}\n\nexport class GroupSendInvite {\n  groupJid: string;\n  description: string;\n  numbers: string[];\n}\n\nexport class GroupUpdateParticipantDto extends GroupJid {\n  action: 'add' | 'remove' | 'promote' | 'demote';\n  participants: string[];\n}\n\nexport class GroupUpdateSettingDto extends GroupJid {\n  action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked';\n}\n\nexport class GroupToggleEphemeralDto extends GroupJid {\n  expiration: 0 | 86400 | 604800 | 7776000;\n}\n"
  },
  {
    "path": "src/api/dto/instance.dto.ts",
    "content": "import { IntegrationDto } from '@api/integrations/integration.dto';\nimport { JsonValue } from '@prisma/client/runtime/library';\nimport { WAPresence } from 'baileys';\n\nexport class InstanceDto extends IntegrationDto {\n  instanceName: string;\n  instanceId?: string;\n  qrcode?: boolean;\n  businessId?: string;\n  number?: string;\n  integration?: string;\n  token?: string;\n  status?: string;\n  ownerJid?: string;\n  connectionStatus?: string;\n  profileName?: string;\n  profilePicUrl?: string;\n  // settings\n  rejectCall?: boolean;\n  msgCall?: string;\n  groupsIgnore?: boolean;\n  alwaysOnline?: boolean;\n  readMessages?: boolean;\n  readStatus?: boolean;\n  syncFullHistory?: boolean;\n  wavoipToken?: string;\n  // proxy\n  proxyHost?: string;\n  proxyPort?: string;\n  proxyProtocol?: string;\n  proxyUsername?: string;\n  proxyPassword?: string;\n  webhook?: {\n    enabled?: boolean;\n    events?: string[];\n    headers?: JsonValue;\n    url?: string;\n    byEvents?: boolean;\n    base64?: boolean;\n  };\n  chatwootAccountId?: string;\n  chatwootConversationPending?: boolean;\n  chatwootAutoCreate?: boolean;\n  chatwootDaysLimitImportMessages?: number;\n  chatwootImportContacts?: boolean;\n  chatwootImportMessages?: boolean;\n  chatwootLogo?: string;\n  chatwootMergeBrazilContacts?: boolean;\n  chatwootNameInbox?: string;\n  chatwootOrganization?: string;\n  chatwootReopenConversation?: boolean;\n  chatwootSignMsg?: boolean;\n  chatwootToken?: string;\n  chatwootUrl?: string;\n}\n\nexport class SetPresenceDto {\n  presence: WAPresence;\n}\n"
  },
  {
    "path": "src/api/dto/label.dto.ts",
    "content": "export class LabelDto {\n  id?: string;\n  name: string;\n  color: string;\n  predefinedId?: string;\n}\n\nexport class HandleLabelDto {\n  number: string;\n  labelId: string;\n  action: 'add' | 'remove';\n}\n"
  },
  {
    "path": "src/api/dto/proxy.dto.ts",
    "content": "export class ProxyDto {\n  enabled?: boolean;\n  host: string;\n  port: string;\n  protocol: string;\n  username?: string;\n  password?: string;\n}\n"
  },
  {
    "path": "src/api/dto/sendMessage.dto.ts",
    "content": "import { proto, WAPresence } from 'baileys';\n\nexport class Quoted {\n  key: proto.IMessageKey;\n  message: proto.IMessage;\n}\n\nexport class Options {\n  delay?: number;\n  presence?: WAPresence;\n  quoted?: Quoted;\n  linkPreview?: boolean;\n  encoding?: boolean;\n  mentionsEveryOne?: boolean;\n  mentioned?: string[];\n  webhookUrl?: string;\n}\n\nexport class MediaMessage {\n  mediatype: MediaType;\n  mimetype?: string;\n  caption?: string;\n  // for document\n  fileName?: string;\n  // url or base64\n  media: string;\n}\n\nexport class StatusMessage {\n  type: string;\n  content: string;\n  statusJidList?: string[];\n  allContacts?: boolean;\n  caption?: string;\n  backgroundColor?: string;\n  font?: number;\n}\n\nexport class Metadata {\n  number: string;\n  delay?: number;\n  quoted?: Quoted;\n  linkPreview?: boolean;\n  mentionsEveryOne?: boolean;\n  mentioned?: string[];\n  encoding?: boolean;\n  notConvertSticker?: boolean;\n}\n\nexport class SendTextDto extends Metadata {\n  text: string;\n}\nexport class SendPresence extends Metadata {\n  text: string;\n}\n\nexport class SendStatusDto extends Metadata {\n  type: string;\n  content: string;\n  statusJidList?: string[];\n  allContacts?: boolean;\n  caption?: string;\n  backgroundColor?: string;\n  font?: number;\n}\n\nexport class SendPollDto extends Metadata {\n  name: string;\n  selectableCount: number;\n  values: string[];\n  messageSecret?: Uint8Array;\n}\n\nexport type MediaType = 'image' | 'document' | 'video' | 'audio' | 'ptv';\n\nexport class SendMediaDto extends Metadata {\n  mediatype: MediaType;\n  mimetype?: string;\n  caption?: string;\n  // for document\n  fileName?: string;\n  // url or base64\n  media: string;\n}\n\nexport class SendPtvDto extends Metadata {\n  video: string;\n}\n\nexport class SendStickerDto extends Metadata {\n  sticker: string;\n}\n\nexport class SendAudioDto extends Metadata {\n  audio: string;\n}\n\nexport type TypeButton = 'reply' | 'copy' | 'url' | 'call' | 'pix';\n\nexport type KeyType = 'phone' | 'email' | 'cpf' | 'cnpj' | 'random';\n\nexport class Button {\n  type: TypeButton;\n  displayText?: string;\n  id?: string;\n  url?: string;\n  copyCode?: string;\n  phoneNumber?: string;\n  currency?: string;\n  name?: string;\n  keyType?: KeyType;\n  key?: string;\n}\n\nexport class SendButtonsDto extends Metadata {\n  thumbnailUrl?: string;\n  title: string;\n  description?: string;\n  footer?: string;\n  buttons: Button[];\n}\n\nexport class SendLocationDto extends Metadata {\n  latitude: number;\n  longitude: number;\n  name?: string;\n  address?: string;\n}\n\nclass Row {\n  title: string;\n  description: string;\n  rowId: string;\n}\nclass Section {\n  title: string;\n  rows: Row[];\n}\nexport class SendListDto extends Metadata {\n  title: string;\n  description?: string;\n  footerText?: string;\n  buttonText: string;\n  sections: Section[];\n}\n\nexport class ContactMessage {\n  fullName: string;\n  wuid: string;\n  phoneNumber: string;\n  organization?: string;\n  email?: string;\n  url?: string;\n}\n\nexport class SendTemplateDto extends Metadata {\n  name: string;\n  language: string;\n  components: any;\n  webhookUrl?: string;\n}\nexport class SendContactDto extends Metadata {\n  contact: ContactMessage[];\n}\n\nexport class SendReactionDto {\n  key: proto.IMessageKey;\n  reaction: string;\n}\n"
  },
  {
    "path": "src/api/dto/settings.dto.ts",
    "content": "export class SettingsDto {\n  rejectCall?: boolean;\n  msgCall?: string;\n  groupsIgnore?: boolean;\n  alwaysOnline?: boolean;\n  readMessages?: boolean;\n  readStatus?: boolean;\n  syncFullHistory?: boolean;\n  wavoipToken?: string;\n}\n"
  },
  {
    "path": "src/api/dto/template.dto.ts",
    "content": "export class TemplateDto {\n  name: string;\n  category: string;\n  allowCategoryChange: boolean;\n  language: string;\n  components: any;\n  webhookUrl?: string;\n}\n\nexport class TemplateEditDto {\n  templateId: string;\n  category?: 'AUTHENTICATION' | 'MARKETING' | 'UTILITY';\n  allowCategoryChange?: boolean;\n  ttl?: number;\n  components?: any;\n}\n\nexport class TemplateDeleteDto {\n  name: string;\n  hsmId?: string;\n}\n"
  },
  {
    "path": "src/api/guards/auth.guard.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { prismaRepository } from '@api/server.module';\nimport { Auth, configService, Database } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { ForbiddenException, UnauthorizedException } from '@exceptions';\nimport { NextFunction, Request, Response } from 'express';\n\nconst logger = new Logger('GUARD');\n\nasync function apikey(req: Request, _: Response, next: NextFunction) {\n  const env = configService.get<Auth>('AUTHENTICATION').API_KEY;\n  const key = req.get('apikey');\n  const db = configService.get<Database>('DATABASE');\n\n  if (!key) {\n    throw new UnauthorizedException();\n  }\n\n  if (env.KEY === key) {\n    return next();\n  }\n\n  if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) {\n    throw new ForbiddenException('Missing global api key', 'The global api key must be set');\n  }\n  const param = req.params as unknown as InstanceDto;\n\n  try {\n    if (param?.instanceName) {\n      const instance = await prismaRepository.instance.findUnique({\n        where: { name: param.instanceName },\n      });\n      if (instance.token === key) {\n        return next();\n      }\n    } else {\n      if (req.originalUrl.includes('/instance/fetchInstances') && db.SAVE_DATA.INSTANCE) {\n        const instanceByKey = await prismaRepository.instance.findFirst({\n          where: { token: key },\n        });\n        if (instanceByKey) {\n          return next();\n        }\n      }\n    }\n  } catch (error) {\n    logger.error(error);\n  }\n\n  throw new UnauthorizedException();\n}\n\nexport const authGuard = { apikey };\n"
  },
  {
    "path": "src/api/guards/instance.guard.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { cache, prismaRepository, waMonitor } from '@api/server.module';\nimport { CacheConf, configService } from '@config/env.config';\nimport { BadRequestException, ForbiddenException, InternalServerErrorException, NotFoundException } from '@exceptions';\nimport { NextFunction, Request, Response } from 'express';\n\nasync function getInstance(instanceName: string) {\n  try {\n    const cacheConf = configService.get<CacheConf>('CACHE');\n\n    const exists = !!waMonitor.waInstances[instanceName];\n\n    if (cacheConf.REDIS.ENABLED && cacheConf.REDIS.SAVE_INSTANCES) {\n      const keyExists = await cache.has(instanceName);\n\n      return exists || keyExists;\n    }\n\n    return exists || (await prismaRepository.instance.findMany({ where: { name: instanceName } })).length > 0;\n  } catch (error) {\n    throw new InternalServerErrorException(error?.toString());\n  }\n}\n\nexport async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) {\n  if (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) {\n    return next();\n  }\n\n  const param = req.params as unknown as InstanceDto;\n  if (!param?.instanceName) {\n    throw new BadRequestException('\"instanceName\" not provided.');\n  }\n\n  if (!(await getInstance(param.instanceName))) {\n    throw new NotFoundException(`The \"${param.instanceName}\" instance does not exist`);\n  }\n\n  next();\n}\n\nexport async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) {\n  if (req.originalUrl.includes('/instance/create')) {\n    const instance = req.body as InstanceDto;\n    if (await getInstance(instance.instanceName)) {\n      throw new ForbiddenException(`This name \"${instance.instanceName}\" is already in use.`);\n    }\n\n    if (waMonitor.waInstances[instance.instanceName]) {\n      delete waMonitor.waInstances[instance.instanceName];\n    }\n  }\n\n  next();\n}\n"
  },
  {
    "path": "src/api/guards/telemetry.guard.ts",
    "content": "import { sendTelemetry } from '@utils/sendTelemetry';\nimport { NextFunction, Request, Response } from 'express';\n\nclass Telemetry {\n  public collectTelemetry(req: Request, res: Response, next: NextFunction): void {\n    sendTelemetry(req.path);\n\n    next();\n  }\n}\n\nexport default Telemetry;\n"
  },
  {
    "path": "src/api/integrations/channel/channel.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { CacheService } from '@api/services/cache.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService } from '@config/env.config';\nimport { BadRequestException } from '@exceptions';\nimport EventEmitter2 from 'eventemitter2';\n\nimport { EvolutionStartupService } from './evolution/evolution.channel.service';\nimport { BusinessStartupService } from './meta/whatsapp.business.service';\nimport { BaileysStartupService } from './whatsapp/whatsapp.baileys.service';\n\ntype ChannelDataType = {\n  configService: ConfigService;\n  eventEmitter: EventEmitter2;\n  prismaRepository: PrismaRepository;\n  cache: CacheService;\n  chatwootCache: CacheService;\n  baileysCache: CacheService;\n  providerFiles: ProviderFiles;\n};\n\nexport interface ChannelControllerInterface {\n  receiveWebhook(data: any): Promise<any>;\n}\n\nexport class ChannelController {\n  public prismaRepository: PrismaRepository;\n  public waMonitor: WAMonitoringService;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    this.prisma = prismaRepository;\n    this.monitor = waMonitor;\n  }\n\n  public set prisma(prisma: PrismaRepository) {\n    this.prismaRepository = prisma;\n  }\n\n  public get prisma() {\n    return this.prismaRepository;\n  }\n\n  public set monitor(waMonitor: WAMonitoringService) {\n    this.waMonitor = waMonitor;\n  }\n\n  public get monitor() {\n    return this.waMonitor;\n  }\n\n  public init(instanceData: InstanceDto, data: ChannelDataType) {\n    if (!instanceData.token && instanceData.integration === Integration.WHATSAPP_BUSINESS) {\n      throw new BadRequestException('token is required');\n    }\n\n    if (instanceData.integration === Integration.WHATSAPP_BUSINESS) {\n      return new BusinessStartupService(\n        data.configService,\n        data.eventEmitter,\n        data.prismaRepository,\n        data.cache,\n        data.chatwootCache,\n        data.baileysCache,\n        data.providerFiles,\n      );\n    }\n\n    if (instanceData.integration === Integration.EVOLUTION) {\n      return new EvolutionStartupService(\n        data.configService,\n        data.eventEmitter,\n        data.prismaRepository,\n        data.cache,\n        data.chatwootCache,\n      );\n    }\n\n    if (instanceData.integration === Integration.WHATSAPP_BAILEYS) {\n      return new BaileysStartupService(\n        data.configService,\n        data.eventEmitter,\n        data.prismaRepository,\n        data.cache,\n        data.chatwootCache,\n        data.baileysCache,\n        data.providerFiles,\n      );\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/channel.router.ts",
    "content": "import { Router } from 'express';\n\nimport { EvolutionRouter } from './evolution/evolution.router';\nimport { MetaRouter } from './meta/meta.router';\nimport { BaileysRouter } from './whatsapp/baileys.router';\n\nexport class ChannelRouter {\n  public readonly router: Router;\n\n  constructor(configService: any, ...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/', new EvolutionRouter(configService).router);\n    this.router.use('/', new MetaRouter(configService).router);\n    this.router.use('/baileys', new BaileysRouter(...guards).router);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/evolution/evolution.channel.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport {\n  MediaMessage,\n  Options,\n  SendAudioDto,\n  SendButtonsDto,\n  SendMediaDto,\n  SendTextDto,\n} from '@api/dto/sendMessage.dto';\nimport * as s3Service from '@api/integrations/storage/s3/libs/minio.server';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { chatbotController } from '@api/server.module';\nimport { CacheService } from '@api/services/cache.service';\nimport { ChannelStartupService } from '@api/services/channel.service';\nimport { Events, wa } from '@api/types/wa.types';\nimport { AudioConverter, Chatwoot, ConfigService, Openai, S3 } from '@config/env.config';\nimport { BadRequestException, InternalServerErrorException } from '@exceptions';\nimport { createJid } from '@utils/createJid';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { isBase64, isURL } from 'class-validator';\nimport EventEmitter2 from 'eventemitter2';\nimport FormData from 'form-data';\nimport mimeTypes from 'mime-types';\nimport { join } from 'path';\nimport { v4 } from 'uuid';\n\nexport class EvolutionStartupService extends ChannelStartupService {\n  constructor(\n    public readonly configService: ConfigService,\n    public readonly eventEmitter: EventEmitter2,\n    public readonly prismaRepository: PrismaRepository,\n    public readonly cache: CacheService,\n    public readonly chatwootCache: CacheService,\n  ) {\n    super(configService, eventEmitter, prismaRepository, chatwootCache);\n\n    this.client = null;\n  }\n\n  public client: any;\n\n  public stateConnection: wa.StateConnection = { state: 'open' };\n\n  public phoneNumber: string;\n  public mobile: boolean;\n\n  public get connectionStatus() {\n    return this.stateConnection;\n  }\n\n  public async closeClient() {\n    this.stateConnection = { state: 'close' };\n  }\n\n  public get qrCode(): wa.QrCode {\n    return {\n      pairingCode: this.instance.qrcode?.pairingCode,\n      code: this.instance.qrcode?.code,\n      base64: this.instance.qrcode?.base64,\n      count: this.instance.qrcode?.count,\n    };\n  }\n\n  public async logoutInstance() {\n    await this.closeClient();\n  }\n\n  public setInstance(instance: InstanceDto) {\n    this.logger.setInstance(instance.instanceId);\n\n    this.instance.name = instance.instanceName;\n    this.instance.id = instance.instanceId;\n    this.instance.integration = instance.integration;\n    this.instance.number = instance.number;\n    this.instance.token = instance.token;\n    this.instance.businessId = instance.businessId;\n\n    if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n      this.chatwootService.eventWhatsapp(\n        Events.STATUS_INSTANCE,\n        {\n          instanceName: this.instance.name,\n          instanceId: this.instance.id,\n          integration: instance.integration,\n        },\n        {\n          instance: this.instance.name,\n          status: 'created',\n        },\n      );\n    }\n  }\n\n  public async profilePicture(number: string) {\n    const jid = createJid(number);\n\n    return {\n      wuid: jid,\n      profilePictureUrl: null,\n    };\n  }\n\n  public async getProfileName() {\n    return null;\n  }\n\n  public async profilePictureUrl() {\n    return null;\n  }\n\n  public async getProfileStatus() {\n    return null;\n  }\n\n  public async connectToWhatsapp(data?: any): Promise<any> {\n    if (!data) {\n      this.loadChatwoot();\n      return;\n    }\n\n    try {\n      this.eventHandler(data);\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString());\n    }\n  }\n\n  protected async eventHandler(received: any) {\n    try {\n      let messageRaw: any;\n\n      if (received.message) {\n        const key = {\n          id: received.key.id || v4(),\n          remoteJid: received.key.remoteJid,\n          fromMe: received.key.fromMe,\n          profilePicUrl: received.profilePicUrl,\n        };\n        messageRaw = {\n          key,\n          pushName: received.pushName,\n          message: received.message,\n          messageType: received.messageType,\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n\n        const isAudio = received?.message?.audioMessage;\n\n        if (this.configService.get<Openai>('OPENAI').ENABLED && isAudio) {\n          const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({\n            where: {\n              instanceId: this.instanceId,\n            },\n            include: {\n              OpenaiCreds: true,\n            },\n          });\n\n          if (\n            openAiDefaultSettings &&\n            openAiDefaultSettings.openaiCredsId &&\n            openAiDefaultSettings.speechToText &&\n            received?.message?.audioMessage\n          ) {\n            messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(received, this)}`;\n          }\n        }\n\n        this.logger.log(messageRaw);\n\n        sendTelemetry(`received.message.${messageRaw.messageType ?? 'unknown'}`);\n\n        this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw);\n\n        await chatbotController.emit({\n          instance: { instanceName: this.instance.name, instanceId: this.instanceId },\n          remoteJid: messageRaw.key.remoteJid,\n          msg: messageRaw,\n          pushName: messageRaw.pushName,\n        });\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n          const chatwootSentMessage = await this.chatwootService.eventWhatsapp(\n            Events.MESSAGES_UPSERT,\n            { instanceName: this.instance.name, instanceId: this.instanceId },\n            messageRaw,\n          );\n\n          if (chatwootSentMessage?.id) {\n            messageRaw.chatwootMessageId = chatwootSentMessage.id;\n            messageRaw.chatwootInboxId = chatwootSentMessage.id;\n            messageRaw.chatwootConversationId = chatwootSentMessage.id;\n          }\n        }\n\n        await this.prismaRepository.message.create({\n          data: messageRaw,\n        });\n\n        await this.updateContact({\n          remoteJid: messageRaw.key.remoteJid,\n          pushName: messageRaw.pushName,\n          profilePicUrl: received.profilePicUrl,\n        });\n      }\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  private async updateContact(data: { remoteJid: string; pushName?: string; profilePicUrl?: string }) {\n    const contactRaw: any = {\n      remoteJid: data.remoteJid,\n      pushName: data?.pushName,\n      instanceId: this.instanceId,\n      profilePicUrl: data?.profilePicUrl,\n    };\n\n    const existingContact = await this.prismaRepository.contact.findFirst({\n      where: {\n        remoteJid: data.remoteJid,\n        instanceId: this.instanceId,\n      },\n    });\n\n    if (existingContact) {\n      await this.prismaRepository.contact.updateMany({\n        where: {\n          remoteJid: data.remoteJid,\n          instanceId: this.instanceId,\n        },\n        data: contactRaw,\n      });\n    } else {\n      await this.prismaRepository.contact.create({\n        data: contactRaw,\n      });\n    }\n\n    this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);\n\n    if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n      await this.chatwootService.eventWhatsapp(\n        Events.CONTACTS_UPDATE,\n        {\n          instanceName: this.instance.name,\n          instanceId: this.instanceId,\n          integration: this.instance.integration,\n        },\n        contactRaw,\n      );\n    }\n\n    const chat = await this.prismaRepository.chat.findFirst({\n      where: { instanceId: this.instanceId, remoteJid: data.remoteJid },\n    });\n\n    if (chat) {\n      const chatRaw: any = {\n        remoteJid: data.remoteJid,\n        instanceId: this.instanceId,\n      };\n\n      this.sendDataWebhook(Events.CHATS_UPDATE, chatRaw);\n\n      await this.prismaRepository.chat.updateMany({\n        where: { remoteJid: chat.remoteJid },\n        data: chatRaw,\n      });\n    }\n\n    const chatRaw: any = {\n      remoteJid: data.remoteJid,\n      instanceId: this.instanceId,\n    };\n\n    this.sendDataWebhook(Events.CHATS_UPSERT, chatRaw);\n\n    await this.prismaRepository.chat.create({\n      data: chatRaw,\n    });\n  }\n\n  protected async sendMessageWithTyping(\n    number: string,\n    message: any,\n    options?: Options,\n    file?: any,\n    isIntegration = false,\n  ) {\n    try {\n      let quoted: any;\n      let webhookUrl: any;\n\n      if (options?.quoted) {\n        const m = options?.quoted;\n\n        const msg = m?.key;\n\n        if (!msg) {\n          throw 'Message not found';\n        }\n\n        quoted = msg;\n      }\n\n      if (options.delay) {\n        await new Promise((resolve) => setTimeout(resolve, options.delay));\n      }\n\n      if (options?.webhookUrl) {\n        webhookUrl = options.webhookUrl;\n      }\n\n      let audioFile;\n\n      const messageId = v4();\n\n      let messageRaw: any;\n\n      if (message?.mediaType === 'image') {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            base64: isBase64(message.media) ? message.media : null,\n            mediaUrl: isURL(message.media) ? message.media : null,\n            quoted,\n          },\n          messageType: 'imageMessage',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n      } else if (message?.mediaType === 'video') {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            base64: isBase64(message.media) ? message.media : null,\n            mediaUrl: isURL(message.media) ? message.media : null,\n            quoted,\n          },\n          messageType: 'videoMessage',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n      } else if (message?.mediaType === 'audio') {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            base64: isBase64(message.media) ? message.media : null,\n            mediaUrl: isURL(message.media) ? message.media : null,\n            quoted,\n          },\n          messageType: 'audioMessage',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n\n        const buffer = Buffer.from(message.media, 'base64');\n        audioFile = {\n          buffer,\n          mimetype: 'audio/mp4',\n          originalname: `${messageId}.mp4`,\n        };\n      } else if (message?.mediaType === 'document') {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            base64: isBase64(message.media) ? message.media : null,\n            mediaUrl: isURL(message.media) ? message.media : null,\n            quoted,\n          },\n          messageType: 'documentMessage',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n      } else if (message.buttonMessage) {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            ...message.buttonMessage,\n            buttons: message.buttonMessage.buttons,\n            footer: message.buttonMessage.footer,\n            body: message.buttonMessage.body,\n            quoted,\n          },\n          messageType: 'buttonMessage',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n      } else if (message.listMessage) {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            ...message.listMessage,\n            quoted,\n          },\n          messageType: 'listMessage',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n      } else {\n        messageRaw = {\n          key: { fromMe: true, id: messageId, remoteJid: number },\n          message: {\n            ...message,\n            quoted,\n          },\n          messageType: 'conversation',\n          messageTimestamp: Math.round(new Date().getTime() / 1000),\n          webhookUrl,\n          source: 'unknown',\n          instanceId: this.instanceId,\n        };\n      }\n\n      if (messageRaw.message.contextInfo) {\n        messageRaw.contextInfo = {\n          ...messageRaw.message.contextInfo,\n        };\n      }\n\n      if (messageRaw.contextInfo?.stanzaId) {\n        const key: any = {\n          id: messageRaw.contextInfo.stanzaId,\n        };\n\n        const findMessage = await this.prismaRepository.message.findFirst({\n          where: {\n            instanceId: this.instanceId,\n            key,\n          },\n        });\n\n        if (findMessage) {\n          messageRaw.contextInfo.quotedMessage = findMessage.message;\n        }\n      }\n\n      const { base64 } = messageRaw.message;\n      delete messageRaw.message.base64;\n\n      if (base64 || file || audioFile) {\n        if (this.configService.get<S3>('S3').ENABLE) {\n          try {\n            // Verificação adicional para garantir que há conteúdo de mídia real\n            const hasRealMedia = this.hasValidMediaContent(messageRaw);\n\n            if (!hasRealMedia) {\n              this.logger.warn('Message detected as media but contains no valid media content');\n            } else {\n              const fileBuffer = audioFile?.buffer || file?.buffer;\n              const buffer = base64 ? Buffer.from(base64, 'base64') : fileBuffer;\n\n              let mediaType: string;\n              let mimetype = audioFile?.mimetype || file.mimetype;\n\n              if (messageRaw.messageType === 'documentMessage') {\n                mediaType = 'document';\n                mimetype = !mimetype ? 'application/pdf' : mimetype;\n              } else if (messageRaw.messageType === 'imageMessage') {\n                mediaType = 'image';\n                mimetype = !mimetype ? 'image/png' : mimetype;\n              } else if (messageRaw.messageType === 'audioMessage') {\n                mediaType = 'audio';\n                mimetype = !mimetype ? 'audio/mp4' : mimetype;\n              } else if (messageRaw.messageType === 'videoMessage') {\n                mediaType = 'video';\n                mimetype = !mimetype ? 'video/mp4' : mimetype;\n              }\n\n              const fileName = `${messageRaw.key.id}.${mimetype.split('/')[1]}`;\n\n              const size = buffer.byteLength;\n\n              const fullName = join(`${this.instance.id}`, messageRaw.key.remoteJid, mediaType, fileName);\n\n              await s3Service.uploadFile(fullName, buffer, size, {\n                'Content-Type': mimetype,\n              });\n\n              const mediaUrl = await s3Service.getObjectUrl(fullName);\n\n              messageRaw.message.mediaUrl = mediaUrl;\n            }\n          } catch (error) {\n            this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);\n          }\n        }\n      }\n\n      this.logger.log(messageRaw);\n\n      this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw);\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && !isIntegration) {\n        this.chatwootService.eventWhatsapp(\n          Events.SEND_MESSAGE,\n          { instanceName: this.instance.name, instanceId: this.instanceId },\n          messageRaw,\n        );\n      }\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && isIntegration)\n        await chatbotController.emit({\n          instance: { instanceName: this.instance.name, instanceId: this.instanceId },\n          remoteJid: messageRaw.key.remoteJid,\n          msg: messageRaw,\n          pushName: messageRaw.pushName,\n        });\n\n      await this.prismaRepository.message.create({\n        data: messageRaw,\n      });\n\n      return messageRaw;\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  public async textMessage(data: SendTextDto, isIntegration = false) {\n    const res = await this.sendMessageWithTyping(\n      data.number,\n      {\n        conversation: data.text,\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      null,\n      isIntegration,\n    );\n    return res;\n  }\n\n  protected async prepareMediaMessage(mediaMessage: MediaMessage) {\n    try {\n      if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) {\n        const regex = new RegExp(/.*\\/(.+?)\\./);\n        const arrayMatch = regex.exec(mediaMessage.media);\n        mediaMessage.fileName = arrayMatch[1];\n      }\n\n      if (mediaMessage.mediatype === 'image' && !mediaMessage.fileName) {\n        mediaMessage.fileName = 'image.png';\n      }\n\n      if (mediaMessage.mediatype === 'video' && !mediaMessage.fileName) {\n        mediaMessage.fileName = 'video.mp4';\n      }\n\n      let mimetype: string | false;\n\n      const prepareMedia: any = {\n        caption: mediaMessage?.caption,\n        fileName: mediaMessage.fileName,\n        mediaType: mediaMessage.mediatype,\n        media: mediaMessage.media,\n        gifPlayback: false,\n      };\n\n      if (isURL(mediaMessage.media)) {\n        mimetype = mimeTypes.lookup(mediaMessage.media);\n      } else {\n        mimetype = mimeTypes.lookup(mediaMessage.fileName);\n      }\n\n      prepareMedia.mimetype = mimetype;\n\n      return prepareMedia;\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString() || error);\n    }\n  }\n\n  public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {\n    const mediaData: SendMediaDto = { ...data };\n\n    if (file) mediaData.media = file.buffer.toString('base64');\n\n    const message = await this.prepareMediaMessage(mediaData);\n\n    const mediaSent = await this.sendMessageWithTyping(\n      data.number,\n      { ...message },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      file,\n      isIntegration,\n    );\n\n    return mediaSent;\n  }\n\n  public async processAudio(audio: string, number: string, file: any) {\n    number = number.replace(/\\D/g, '');\n    const hash = `${number}-${new Date().getTime()}`;\n\n    const audioConverterConfig = this.configService.get<AudioConverter>('AUDIO_CONVERTER');\n    if (audioConverterConfig.API_URL) {\n      try {\n        this.logger.verbose('Using audio converter API');\n        const formData = new FormData();\n\n        if (file) {\n          formData.append('file', file.buffer, {\n            filename: file.originalname,\n            contentType: file.mimetype,\n          });\n        } else if (isURL(audio)) {\n          formData.append('url', audio);\n        } else {\n          formData.append('base64', audio);\n        }\n\n        formData.append('format', 'mp4');\n\n        const response = await axios.post(audioConverterConfig.API_URL, formData, {\n          headers: {\n            ...formData.getHeaders(),\n            apikey: audioConverterConfig.API_KEY,\n          },\n        });\n\n        if (!response?.data?.audio) {\n          throw new InternalServerErrorException('Failed to convert audio');\n        }\n\n        const prepareMedia: any = {\n          fileName: `${hash}.mp4`,\n          mediaType: 'audio',\n          media: response?.data?.audio,\n          mimetype: 'audio/mpeg',\n        };\n\n        return prepareMedia;\n      } catch (error) {\n        this.logger.error(error?.response?.data || error);\n        throw new InternalServerErrorException(error?.response?.data?.message || error?.toString() || error);\n      }\n    } else {\n      let mimetype: string;\n\n      const prepareMedia: any = {\n        fileName: `${hash}.mp3`,\n        mediaType: 'audio',\n        media: audio,\n        mimetype: 'audio/mpeg',\n      };\n\n      if (isURL(audio)) {\n        mimetype = mimeTypes.lookup(audio).toString();\n      } else {\n        mimetype = mimeTypes.lookup(prepareMedia.fileName).toString();\n      }\n\n      prepareMedia.mimetype = mimetype;\n\n      return prepareMedia;\n    }\n  }\n\n  public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {\n    const mediaData: SendAudioDto = { ...data };\n\n    if (file?.buffer) {\n      mediaData.audio = file.buffer.toString('base64');\n    } else {\n      console.error('El archivo o buffer no est� definido correctamente.');\n      throw new Error('File or buffer is undefined.');\n    }\n\n    const message = await this.processAudio(mediaData.audio, data.number, file);\n\n    const audioSent = await this.sendMessageWithTyping(\n      data.number,\n      { ...message },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      file,\n      isIntegration,\n    );\n\n    return audioSent;\n  }\n\n  public async buttonMessage(data: SendButtonsDto, isIntegration = false) {\n    return await this.sendMessageWithTyping(\n      data.number,\n      {\n        buttonMessage: {\n          title: data.title,\n          description: data.description,\n          footer: data.footer,\n          buttons: data.buttons,\n        },\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      null,\n      isIntegration,\n    );\n  }\n  public async locationMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async listMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async templateMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async contactMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async reactionMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async getBase64FromMediaMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async deleteMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async mediaSticker() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async pollMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async statusMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async reloadConnection() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async whatsappNumber() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async markMessageAsRead() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async archiveChat() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async markChatUnread() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async fetchProfile() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async offerCall() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async sendPresence() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async setPresence() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async fetchPrivacySettings() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updatePrivacySettings() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async fetchBusinessProfile() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateProfileName() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateProfileStatus() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateProfilePicture() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async removeProfilePicture() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async blockUser() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateMessage() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async createGroup() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateGroupPicture() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateGroupSubject() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateGroupDescription() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async findGroup() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async fetchAllGroups() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async inviteCode() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async inviteInfo() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async sendInvite() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async acceptInviteCode() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async revokeInviteCode() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async findParticipants() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateGParticipant() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async updateGSetting() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async toggleEphemeral() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async leaveGroup() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async fetchLabels() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async handleLabel() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async receiveMobileCode() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n  public async fakeCall() {\n    throw new BadRequestException('Method not available on Evolution Channel');\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/evolution/evolution.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Logger } from '@config/logger.config';\n\nimport { ChannelController, ChannelControllerInterface } from '../channel.controller';\n\nexport class EvolutionController extends ChannelController implements ChannelControllerInterface {\n  private readonly logger = new Logger('EvolutionController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n  }\n\n  integrationEnabled: boolean;\n\n  public async receiveWebhook(data: any) {\n    const numberId = data.numberId;\n\n    if (!numberId) {\n      this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');\n      return;\n    }\n\n    const instance = await this.prismaRepository.instance.findFirst({\n      where: { number: numberId },\n    });\n\n    if (!instance) {\n      this.logger.error('WebhookService -> receiveWebhook -> instance not found');\n      return;\n    }\n\n    await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);\n\n    return {\n      status: 'success',\n    };\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/evolution/evolution.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { evolutionController } from '@api/server.module';\nimport { ConfigService } from '@config/env.config';\nimport { Router } from 'express';\n\nexport class EvolutionRouter extends RouterBroker {\n  constructor(readonly configService: ConfigService) {\n    super();\n    this.router.post(this.routerPath('webhook/evolution', false), async (req, res) => {\n      const { body } = req;\n      const response = await evolutionController.receiveWebhook(body);\n\n      return res.status(200).json(response);\n    });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/channel/meta/meta.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Logger } from '@config/logger.config';\nimport axios from 'axios';\n\nimport { ChannelController, ChannelControllerInterface } from '../channel.controller';\n\nexport class MetaController extends ChannelController implements ChannelControllerInterface {\n  private readonly logger = new Logger('MetaController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n  }\n\n  integrationEnabled: boolean;\n\n  public async receiveWebhook(data: any) {\n    if (data.object === 'whatsapp_business_account') {\n      if (data.entry[0]?.changes[0]?.field === 'message_template_status_update') {\n        const template = await this.prismaRepository.template.findFirst({\n          where: { templateId: `${data.entry[0].changes[0].value.message_template_id}` },\n        });\n\n        if (!template) {\n          console.log('template not found');\n          return;\n        }\n\n        const { webhookUrl } = template;\n\n        await axios.post(webhookUrl, data.entry[0].changes[0].value, {\n          headers: {\n            'Content-Type': 'application/json',\n          },\n        });\n        return;\n      }\n\n      data.entry?.forEach(async (entry: any) => {\n        const numberId = entry.changes[0].value.metadata.phone_number_id;\n\n        if (!numberId) {\n          this.logger.error('WebhookService -> receiveWebhookMeta -> numberId not found');\n          return {\n            status: 'success',\n          };\n        }\n\n        const instance = await this.prismaRepository.instance.findFirst({\n          where: { number: numberId },\n        });\n\n        if (!instance) {\n          this.logger.error('WebhookService -> receiveWebhookMeta -> instance not found');\n          return {\n            status: 'success',\n          };\n        }\n\n        await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);\n\n        return {\n          status: 'success',\n        };\n      });\n    }\n\n    return {\n      status: 'success',\n    };\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/meta/meta.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { metaController } from '@api/server.module';\nimport { ConfigService, WaBusiness } from '@config/env.config';\nimport { Router } from 'express';\n\nexport class MetaRouter extends RouterBroker {\n  constructor(readonly configService: ConfigService) {\n    super();\n    this.router\n      .get(this.routerPath('webhook/meta', false), async (req, res) => {\n        if (req.query['hub.verify_token'] === configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK)\n          res.send(req.query['hub.challenge']);\n        else res.send('Error, wrong validation token');\n      })\n      .post(this.routerPath('webhook/meta', false), async (req, res) => {\n        const { body } = req;\n        const response = await metaController.receiveWebhook(body);\n\n        return res.status(200).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/channel/meta/whatsapp.business.service.ts",
    "content": "import { NumberBusiness } from '@api/dto/chat.dto';\nimport {\n  ContactMessage,\n  MediaMessage,\n  Options,\n  SendAudioDto,\n  SendButtonsDto,\n  SendContactDto,\n  SendListDto,\n  SendLocationDto,\n  SendMediaDto,\n  SendReactionDto,\n  SendTemplateDto,\n  SendTextDto,\n} from '@api/dto/sendMessage.dto';\nimport * as s3Service from '@api/integrations/storage/s3/libs/minio.server';\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { chatbotController } from '@api/server.module';\nimport { CacheService } from '@api/services/cache.service';\nimport { ChannelStartupService } from '@api/services/channel.service';\nimport { Events, wa } from '@api/types/wa.types';\nimport { AudioConverter, Chatwoot, ConfigService, Database, Openai, S3, WaBusiness } from '@config/env.config';\nimport { BadRequestException, InternalServerErrorException } from '@exceptions';\nimport { createJid } from '@utils/createJid';\nimport { status } from '@utils/renderStatus';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { arrayUnique, isURL } from 'class-validator';\nimport EventEmitter2 from 'eventemitter2';\nimport FormData from 'form-data';\nimport mimeTypes from 'mime-types';\nimport { join } from 'path';\n\nexport class BusinessStartupService extends ChannelStartupService {\n  constructor(\n    public readonly configService: ConfigService,\n    public readonly eventEmitter: EventEmitter2,\n    public readonly prismaRepository: PrismaRepository,\n    public readonly cache: CacheService,\n    public readonly chatwootCache: CacheService,\n    public readonly baileysCache: CacheService,\n    private readonly providerFiles: ProviderFiles,\n  ) {\n    super(configService, eventEmitter, prismaRepository, chatwootCache);\n  }\n\n  public stateConnection: wa.StateConnection = { state: 'open' };\n\n  public phoneNumber: string;\n  public mobile: boolean;\n\n  public get connectionStatus() {\n    return this.stateConnection;\n  }\n\n  public async closeClient() {\n    this.stateConnection = { state: 'close' };\n  }\n\n  public get qrCode(): wa.QrCode {\n    return {\n      pairingCode: this.instance.qrcode?.pairingCode,\n      code: this.instance.qrcode?.code,\n      base64: this.instance.qrcode?.base64,\n      count: this.instance.qrcode?.count,\n    };\n  }\n\n  public async logoutInstance() {\n    await this.closeClient();\n  }\n\n  private isMediaMessage(message: any) {\n    return message.document || message.image || message.audio || message.video;\n  }\n\n  private async post(message: any, params: string) {\n    try {\n      let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;\n      const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;\n      urlServer = `${urlServer}/${version}/${this.number}/${params}`;\n      const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };\n      const result = await axios.post(urlServer, message, { headers });\n      return result.data;\n    } catch (e) {\n      return e.response?.data?.error;\n    }\n  }\n\n  public async profilePicture(number: string) {\n    const jid = createJid(number);\n\n    return {\n      wuid: jid,\n      profilePictureUrl: null,\n    };\n  }\n\n  public async getProfileName() {\n    return null;\n  }\n\n  public async profilePictureUrl() {\n    return null;\n  }\n\n  public async getProfileStatus() {\n    return null;\n  }\n\n  public async setWhatsappBusinessProfile(data: NumberBusiness): Promise<any> {\n    const content = {\n      messaging_product: 'whatsapp',\n      about: data.about,\n      address: data.address,\n      description: data.description,\n      vertical: data.vertical,\n      email: data.email,\n      websites: data.websites,\n      profile_picture_handle: data.profilehandle,\n    };\n    return await this.post(content, 'whatsapp_business_profile');\n  }\n\n  public async connectToWhatsapp(data?: any): Promise<any> {\n    if (!data) return;\n\n    const content = data.entry[0].changes[0].value;\n\n    try {\n      this.loadChatwoot();\n\n      this.eventHandler(content);\n\n      this.phoneNumber = createJid(content.messages ? content.messages[0].from : content.statuses[0]?.recipient_id);\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString());\n    }\n  }\n\n  private async downloadMediaMessage(message: any) {\n    try {\n      const id = message[message.type].id;\n      let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;\n      const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;\n      urlServer = `${urlServer}/${version}/${id}`;\n      const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };\n\n      // Primeiro, obtenha a URL do arquivo\n      let result = await axios.get(urlServer, { headers });\n\n      // Depois, baixe o arquivo usando a URL retornada\n      result = await axios.get(result.data.url, {\n        headers: { Authorization: `Bearer ${this.token}` }, // Use apenas o token de autorização para download\n        responseType: 'arraybuffer',\n      });\n\n      return result.data;\n    } catch (e) {\n      this.logger.error(`Error downloading media: ${e}`);\n      throw e;\n    }\n  }\n\n  private messageMediaJson(received: any) {\n    const message = received.messages[0];\n    let content: any = message.type + 'Message';\n    content = { [content]: message[message.type] };\n    if (message.context) {\n      content = { ...content, contextInfo: { stanzaId: message.context.id } };\n    }\n    return content;\n  }\n\n  private messageAudioJson(received: any) {\n    const message = received.messages[0];\n    let content: any = {\n      audioMessage: {\n        ...message.audio,\n        ptt: message.audio.voice || false, // Define se é mensagem de voz\n      },\n    };\n    if (message.context) {\n      content = { ...content, contextInfo: { stanzaId: message.context.id } };\n    }\n    return content;\n  }\n\n  private messageInteractiveJson(received: any) {\n    const message = received.messages[0];\n    let content: any = { conversation: message.interactive[message.interactive.type].title };\n    message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;\n    return content;\n  }\n\n  private messageButtonJson(received: any) {\n    const message = received.messages[0];\n    let content: any = { conversation: received.messages[0].button?.text };\n    message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;\n    return content;\n  }\n\n  private messageReactionJson(received: any) {\n    const message = received.messages[0];\n    let content: any = {\n      reactionMessage: {\n        key: {\n          id: message.reaction.message_id,\n        },\n        text: message.reaction.emoji,\n      },\n    };\n    message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;\n    return content;\n  }\n\n  private messageTextJson(received: any) {\n    // Verificar que received y received.messages existen\n    if (!received || !received.messages || received.messages.length === 0) {\n      this.logger.error('Error: received object or messages array is undefined or empty');\n      return null;\n    }\n\n    const message = received.messages[0];\n    let content: any;\n\n    // Verificar si es un mensaje de tipo sticker, location u otro tipo que no tiene text\n    if (!message.text) {\n      // Si no hay texto, manejamos diferente según el tipo de mensaje\n      if (message.type === 'sticker') {\n        content = { stickerMessage: {} };\n      } else if (message.type === 'location') {\n        content = {\n          locationMessage: {\n            degreesLatitude: message.location?.latitude,\n            degreesLongitude: message.location?.longitude,\n            name: message.location?.name,\n            address: message.location?.address,\n          },\n        };\n      } else {\n        // Para otros tipos de mensajes sin texto, creamos un contenido genérico\n        this.logger.log(`Mensaje de tipo ${message.type} sin campo text`);\n        content = { [message.type + 'Message']: message[message.type] || {} };\n      }\n\n      // Añadir contexto si existe\n      if (message.context) {\n        content = { ...content, contextInfo: { stanzaId: message.context.id } };\n      }\n\n      return content;\n    }\n\n    // Si el mensaje tiene texto, procesamos normalmente\n    if (!received.metadata || !received.metadata.phone_number_id) {\n      this.logger.error('Error: metadata or phone_number_id is undefined');\n      return null;\n    }\n\n    if (message.from === received.metadata.phone_number_id) {\n      content = {\n        extendedTextMessage: { text: message.text.body },\n      };\n      if (message.context) {\n        content = { ...content, contextInfo: { stanzaId: message.context.id } };\n      }\n    } else {\n      content = { conversation: message.text.body };\n      if (message.context) {\n        content = { ...content, contextInfo: { stanzaId: message.context.id } };\n      }\n    }\n\n    return content;\n  }\n\n  private messageLocationJson(received: any) {\n    const message = received.messages[0];\n    let content: any = {\n      locationMessage: {\n        degreesLatitude: message.location.latitude,\n        degreesLongitude: message.location.longitude,\n        name: message.location?.name,\n        address: message.location?.address,\n      },\n    };\n    message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;\n    return content;\n  }\n\n  private messageContactsJson(received: any) {\n    const message = received.messages[0];\n    let content: any = {};\n\n    const vcard = (contact: any) => {\n      let result =\n        'BEGIN:VCARD\\n' +\n        'VERSION:3.0\\n' +\n        `N:${contact.name.formatted_name}\\n` +\n        `FN:${contact.name.formatted_name}\\n`;\n\n      if (contact.org) {\n        result += `ORG:${contact.org.company};\\n`;\n      }\n\n      if (contact.emails) {\n        result += `EMAIL:${contact.emails[0].email}\\n`;\n      }\n\n      if (contact.urls) {\n        result += `URL:${contact.urls[0].url}\\n`;\n      }\n\n      if (!contact.phones[0]?.wa_id) {\n        contact.phones[0].wa_id = createJid(contact.phones[0].phone);\n      }\n\n      result +=\n        `item1.TEL;waid=${contact.phones[0]?.wa_id}:${contact.phones[0].phone}\\n` +\n        'item1.X-ABLabel:Celular\\n' +\n        'END:VCARD';\n\n      return result;\n    };\n\n    if (message.contacts.length === 1) {\n      content.contactMessage = {\n        displayName: message.contacts[0].name.formatted_name,\n        vcard: vcard(message.contacts[0]),\n      };\n    } else {\n      content.contactsArrayMessage = {\n        displayName: `${message.length} contacts`,\n        contacts: message.map((contact) => {\n          return {\n            displayName: contact.name.formatted_name,\n            vcard: vcard(contact),\n          };\n        }),\n      };\n    }\n    message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;\n    return content;\n  }\n\n  private renderMessageType(type: string) {\n    let messageType: string;\n\n    switch (type) {\n      case 'text':\n        messageType = 'conversation';\n        break;\n      case 'image':\n        messageType = 'imageMessage';\n        break;\n      case 'video':\n        messageType = 'videoMessage';\n        break;\n      case 'audio':\n        messageType = 'audioMessage';\n        break;\n      case 'document':\n        messageType = 'documentMessage';\n        break;\n      case 'template':\n        messageType = 'conversation';\n        break;\n      case 'location':\n        messageType = 'locationMessage';\n        break;\n      case 'sticker':\n        messageType = 'stickerMessage';\n        break;\n      default:\n        messageType = 'conversation';\n        break;\n    }\n\n    return messageType;\n  }\n\n  protected async messageHandle(received: any, database: Database, settings: any) {\n    try {\n      let messageRaw: any;\n      let pushName: any;\n\n      if (received.contacts) pushName = received.contacts[0].profile.name;\n\n      if (received.messages) {\n        const message = received.messages[0]; // Añadir esta línea para definir message\n\n        const key = {\n          id: message.id,\n          remoteJid: this.phoneNumber,\n          fromMe: message.from === received.metadata.phone_number_id,\n        };\n\n        if (message.type === 'sticker') {\n          this.logger.log('Procesando mensaje de tipo sticker');\n          messageRaw = {\n            key,\n            pushName,\n            message: {\n              stickerMessage: message.sticker || {},\n            },\n            messageType: 'stickerMessage',\n            messageTimestamp: parseInt(message.timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n        } else if (this.isMediaMessage(message)) {\n          const messageContent =\n            message.type === 'audio' ? this.messageAudioJson(received) : this.messageMediaJson(received);\n\n          messageRaw = {\n            key,\n            pushName,\n            message: messageContent,\n            contextInfo: messageContent?.contextInfo,\n            messageType: this.renderMessageType(received.messages[0].type),\n            messageTimestamp: parseInt(received.messages[0].timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n\n          if (this.configService.get<S3>('S3').ENABLE) {\n            try {\n              const message: any = received;\n\n              // Verificação adicional para garantir que há conteúdo de mídia real\n              const hasRealMedia = this.hasValidMediaContent(messageRaw);\n\n              if (!hasRealMedia) {\n                this.logger.warn('Message detected as media but contains no valid media content');\n              } else {\n                const id = message.messages[0][message.messages[0].type].id;\n                let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;\n                const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;\n                urlServer = `${urlServer}/${version}/${id}`;\n                const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };\n                const result = await axios.get(urlServer, { headers });\n\n                const buffer = await axios.get(result.data.url, {\n                  headers: { Authorization: `Bearer ${this.token}` }, // Use apenas o token de autorização para download\n                  responseType: 'arraybuffer',\n                });\n\n                let mediaType;\n\n                if (message.messages[0].document) {\n                  mediaType = 'document';\n                } else if (message.messages[0].image) {\n                  mediaType = 'image';\n                } else if (message.messages[0].audio) {\n                  mediaType = 'audio';\n                } else {\n                  mediaType = 'video';\n                }\n\n                if (mediaType == 'video' && !this.configService.get<S3>('S3').SAVE_VIDEO) {\n                  this.logger?.info?.('Video upload attempted but is disabled by configuration.');\n                  return {\n                    success: false,\n                    message:\n                      'Video upload is currently disabled. Please contact support if you need this feature enabled.',\n                  };\n                }\n\n                const mimetype = result.data?.mime_type || result.headers['content-type'];\n\n                const contentDisposition = result.headers['content-disposition'];\n                let fileName = `${message.messages[0].id}.${mimetype.split('/')[1]}`;\n                if (contentDisposition) {\n                  const match = contentDisposition.match(/filename=\"(.+?)\"/);\n                  if (match) {\n                    fileName = match[1];\n                  }\n                }\n\n                // Para áudio, garantir extensão correta baseada no mimetype\n                if (mediaType === 'audio') {\n                  if (mimetype.includes('ogg')) {\n                    fileName = `${message.messages[0].id}.ogg`;\n                  } else if (mimetype.includes('mp3')) {\n                    fileName = `${message.messages[0].id}.mp3`;\n                  } else if (mimetype.includes('m4a')) {\n                    fileName = `${message.messages[0].id}.m4a`;\n                  }\n                }\n\n                const size = result.headers['content-length'] || buffer.data.byteLength;\n\n                const fullName = join(`${this.instance.id}`, key.remoteJid, mediaType, fileName);\n\n                await s3Service.uploadFile(fullName, buffer.data, size, {\n                  'Content-Type': mimetype,\n                });\n\n                const createdMessage = await this.prismaRepository.message.create({\n                  data: messageRaw,\n                });\n\n                await this.prismaRepository.media.create({\n                  data: {\n                    messageId: createdMessage.id,\n                    instanceId: this.instanceId,\n                    type: mediaType,\n                    fileName: fullName,\n                    mimetype,\n                  },\n                });\n\n                const mediaUrl = await s3Service.getObjectUrl(fullName);\n\n                messageRaw.message.mediaUrl = mediaUrl;\n                if (this.localWebhook.enabled && this.localWebhook.webhookBase64) {\n                  messageRaw.message.base64 = buffer.data.toString('base64');\n                }\n\n                // Processar OpenAI speech-to-text para áudio após o mediaUrl estar disponível\n                if (this.configService.get<Openai>('OPENAI').ENABLED && mediaType === 'audio') {\n                  const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({\n                    where: {\n                      instanceId: this.instanceId,\n                    },\n                    include: {\n                      OpenaiCreds: true,\n                    },\n                  });\n\n                  if (\n                    openAiDefaultSettings &&\n                    openAiDefaultSettings.openaiCredsId &&\n                    openAiDefaultSettings.speechToText\n                  ) {\n                    try {\n                      messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(\n                        openAiDefaultSettings.OpenaiCreds,\n                        {\n                          message: {\n                            mediaUrl: messageRaw.message.mediaUrl,\n                            ...messageRaw,\n                          },\n                        },\n                      )}`;\n                    } catch (speechError) {\n                      this.logger.error(`Error processing speech-to-text: ${speechError}`);\n                    }\n                  }\n                }\n              }\n            } catch (error) {\n              this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);\n            }\n          } else {\n            if (this.localWebhook.enabled && this.localWebhook.webhookBase64) {\n              const buffer = await this.downloadMediaMessage(received?.messages[0]);\n              messageRaw.message.base64 = buffer.toString('base64');\n            }\n\n            // Processar OpenAI speech-to-text para áudio mesmo sem S3\n            if (this.configService.get<Openai>('OPENAI').ENABLED && message.type === 'audio') {\n              let openAiBase64 = messageRaw.message.base64;\n              if (!openAiBase64) {\n                const buffer = await this.downloadMediaMessage(received?.messages[0]);\n                openAiBase64 = buffer.toString('base64');\n              }\n\n              const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({\n                where: {\n                  instanceId: this.instanceId,\n                },\n                include: {\n                  OpenaiCreds: true,\n                },\n              });\n\n              if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {\n                try {\n                  messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(\n                    openAiDefaultSettings.OpenaiCreds,\n                    {\n                      message: {\n                        base64: openAiBase64,\n                        ...messageRaw,\n                      },\n                    },\n                  )}`;\n                } catch (speechError) {\n                  this.logger.error(`Error processing speech-to-text: ${speechError}`);\n                }\n              }\n            }\n          }\n        } else if (received?.messages[0].interactive) {\n          messageRaw = {\n            key,\n            pushName,\n            message: {\n              ...this.messageInteractiveJson(received),\n            },\n            contextInfo: this.messageInteractiveJson(received)?.contextInfo,\n            messageType: 'interactiveMessage',\n            messageTimestamp: parseInt(received.messages[0].timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n        } else if (received?.messages[0].button) {\n          messageRaw = {\n            key,\n            pushName,\n            message: {\n              ...this.messageButtonJson(received),\n            },\n            contextInfo: this.messageButtonJson(received)?.contextInfo,\n            messageType: 'buttonMessage',\n            messageTimestamp: parseInt(received.messages[0].timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n        } else if (received?.messages[0].reaction) {\n          messageRaw = {\n            key,\n            pushName,\n            message: {\n              ...this.messageReactionJson(received),\n            },\n            contextInfo: this.messageReactionJson(received)?.contextInfo,\n            messageType: 'reactionMessage',\n            messageTimestamp: parseInt(received.messages[0].timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n        } else if (received?.messages[0].contacts) {\n          messageRaw = {\n            key,\n            pushName,\n            message: {\n              ...this.messageContactsJson(received),\n            },\n            contextInfo: this.messageContactsJson(received)?.contextInfo,\n            messageType: 'contactMessage',\n            messageTimestamp: parseInt(received.messages[0].timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n        } else {\n          messageRaw = {\n            key,\n            pushName,\n            message: this.messageTextJson(received),\n            contextInfo: this.messageTextJson(received)?.contextInfo,\n            messageType: this.renderMessageType(received.messages[0].type),\n            messageTimestamp: parseInt(received.messages[0].timestamp) as number,\n            source: 'unknown',\n            instanceId: this.instanceId,\n          };\n        }\n\n        if (this.localSettings.readMessages) {\n          // await this.client.readMessages([received.key]);\n        }\n\n        this.logger.log(messageRaw);\n\n        sendTelemetry(`received.message.${messageRaw.messageType ?? 'unknown'}`);\n\n        this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw);\n\n        await chatbotController.emit({\n          instance: { instanceName: this.instance.name, instanceId: this.instanceId },\n          remoteJid: messageRaw.key.remoteJid,\n          msg: messageRaw,\n          pushName: messageRaw.pushName,\n        });\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n          const chatwootSentMessage = await this.chatwootService.eventWhatsapp(\n            Events.MESSAGES_UPSERT,\n            { instanceName: this.instance.name, instanceId: this.instanceId },\n            messageRaw,\n          );\n\n          if (chatwootSentMessage?.id) {\n            messageRaw.chatwootMessageId = chatwootSentMessage.id;\n            messageRaw.chatwootInboxId = chatwootSentMessage.id;\n            messageRaw.chatwootConversationId = chatwootSentMessage.id;\n          }\n        }\n\n        if (!this.isMediaMessage(message) && message.type !== 'sticker') {\n          await this.prismaRepository.message.create({\n            data: messageRaw,\n          });\n        }\n\n        const contact = await this.prismaRepository.contact.findFirst({\n          where: { instanceId: this.instanceId, remoteJid: key.remoteJid },\n        });\n\n        const contactRaw: any = {\n          remoteJid: received.contacts[0].profile.phone,\n          pushName,\n          // profilePicUrl: '',\n          instanceId: this.instanceId,\n        };\n\n        if (contactRaw.remoteJid === 'status@broadcast') {\n          return;\n        }\n\n        if (contact) {\n          const contactRaw: any = {\n            remoteJid: received.contacts[0].profile.phone,\n            pushName,\n            // profilePicUrl: '',\n            instanceId: this.instanceId,\n          };\n\n          this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw);\n\n          if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n            await this.chatwootService.eventWhatsapp(\n              Events.CONTACTS_UPDATE,\n              { instanceName: this.instance.name, instanceId: this.instanceId },\n              contactRaw,\n            );\n          }\n\n          await this.prismaRepository.contact.updateMany({\n            where: { remoteJid: contact.remoteJid },\n            data: contactRaw,\n          });\n          return;\n        }\n\n        this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);\n\n        this.prismaRepository.contact.create({\n          data: contactRaw,\n        });\n      }\n      if (received.statuses) {\n        for await (const item of received.statuses) {\n          const key = {\n            id: item.id,\n            remoteJid: this.phoneNumber,\n            fromMe: this.phoneNumber === received.metadata.phone_number_id,\n          };\n          if (settings?.groups_ignore && key.remoteJid.includes('@g.us')) {\n            return;\n          }\n          if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\\d+)/)) {\n            const findMessage = await this.prismaRepository.message.findFirst({\n              where: {\n                instanceId: this.instanceId,\n                key: {\n                  path: ['id'],\n                  equals: key.id,\n                },\n              },\n            });\n\n            if (!findMessage) {\n              return;\n            }\n\n            if (item.message === null && item.status === undefined) {\n              this.sendDataWebhook(Events.MESSAGES_DELETE, key);\n\n              const message: any = {\n                messageId: findMessage.id,\n                keyId: key.id,\n                remoteJid: key.remoteJid,\n                fromMe: key.fromMe,\n                participant: key?.remoteJid,\n                status: 'DELETED',\n                instanceId: this.instanceId,\n              };\n\n              await this.prismaRepository.messageUpdate.create({\n                data: message,\n              });\n\n              if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n                this.chatwootService.eventWhatsapp(\n                  Events.MESSAGES_DELETE,\n                  { instanceName: this.instance.name, instanceId: this.instanceId },\n                  { key: key },\n                );\n              }\n\n              return;\n            }\n\n            const message: any = {\n              messageId: findMessage.id,\n              keyId: key.id,\n              remoteJid: key.remoteJid,\n              fromMe: key.fromMe,\n              participant: key?.remoteJid,\n              status: item.status.toUpperCase(),\n              instanceId: this.instanceId,\n            };\n\n            this.sendDataWebhook(Events.MESSAGES_UPDATE, message);\n\n            await this.prismaRepository.messageUpdate.create({\n              data: message,\n            });\n\n            if (findMessage.webhookUrl) {\n              await axios.post(findMessage.webhookUrl, message);\n            }\n          }\n        }\n      }\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  private convertMessageToRaw(message: any, content: any) {\n    let convertMessage: any;\n\n    if (message?.conversation) {\n      if (content?.context?.message_id) {\n        convertMessage = {\n          ...message,\n          contextInfo: { stanzaId: content.context.message_id },\n        };\n        return convertMessage;\n      }\n      convertMessage = message;\n      return convertMessage;\n    }\n\n    if (message?.mediaType === 'image') {\n      if (content?.context?.message_id) {\n        convertMessage = {\n          imageMessage: message,\n          contextInfo: { stanzaId: content.context.message_id },\n        };\n        return convertMessage;\n      }\n      return {\n        imageMessage: message,\n      };\n    }\n\n    if (message?.mediaType === 'video') {\n      if (content?.context?.message_id) {\n        convertMessage = {\n          videoMessage: message,\n          contextInfo: { stanzaId: content.context.message_id },\n        };\n        return convertMessage;\n      }\n      return {\n        videoMessage: message,\n      };\n    }\n\n    if (message?.mediaType === 'audio') {\n      if (content?.context?.message_id) {\n        convertMessage = {\n          audioMessage: message,\n          contextInfo: { stanzaId: content.context.message_id },\n        };\n        return convertMessage;\n      }\n      return {\n        audioMessage: message,\n      };\n    }\n\n    if (message?.mediaType === 'document') {\n      if (content?.context?.message_id) {\n        convertMessage = {\n          documentMessage: message,\n          contextInfo: { stanzaId: content.context.message_id },\n        };\n        return convertMessage;\n      }\n      return {\n        documentMessage: message,\n      };\n    }\n\n    return message;\n  }\n\n  protected async eventHandler(content: any) {\n    try {\n      // Registro para depuración\n      this.logger.log('Contenido recibido en eventHandler:');\n      this.logger.log(JSON.stringify(content, null, 2));\n\n      const database = this.configService.get<Database>('DATABASE');\n      const settings = await this.findSettings();\n\n      // Si hay mensajes, verificar primero el tipo\n      if (content.messages && content.messages.length > 0) {\n        const message = content.messages[0];\n        this.logger.log(`Tipo de mensaje recibido: ${message.type}`);\n\n        // Verificamos el tipo de mensaje antes de procesarlo\n        if (\n          message.type === 'text' ||\n          message.type === 'image' ||\n          message.type === 'video' ||\n          message.type === 'audio' ||\n          message.type === 'document' ||\n          message.type === 'sticker' ||\n          message.type === 'location' ||\n          message.type === 'contacts' ||\n          message.type === 'interactive' ||\n          message.type === 'button' ||\n          message.type === 'reaction'\n        ) {\n          // Procesar el mensaje normalmente\n          this.messageHandle(content, database, settings);\n        } else {\n          this.logger.warn(`Tipo de mensaje no reconocido: ${message.type}`);\n        }\n      } else if (content.statuses) {\n        // Procesar actualizaciones de estado\n        this.messageHandle(content, database, settings);\n      } else {\n        this.logger.warn('No se encontraron mensajes ni estados en el contenido recibido');\n      }\n    } catch (error) {\n      this.logger.error('Error en eventHandler:');\n      this.logger.error(error);\n    }\n  }\n\n  protected async sendMessageWithTyping(number: string, message: any, options?: Options, isIntegration = false) {\n    try {\n      let quoted: any;\n      let webhookUrl: any;\n      if (options?.quoted) {\n        const m = options?.quoted;\n\n        const msg = m?.key;\n\n        if (!msg) {\n          throw 'Message not found';\n        }\n\n        quoted = msg;\n      }\n      if (options?.webhookUrl) {\n        webhookUrl = options.webhookUrl;\n      }\n\n      let content: any;\n      const messageSent = await (async () => {\n        if (message['reactionMessage']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            type: 'reaction',\n            to: number.replace(/\\D/g, ''),\n            reaction: {\n              message_id: message['reactionMessage']['key']['id'],\n              emoji: message['reactionMessage']['text'],\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          return await this.post(content, 'messages');\n        }\n        if (message['locationMessage']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            type: 'location',\n            to: number.replace(/\\D/g, ''),\n            location: {\n              longitude: message['locationMessage']['degreesLongitude'],\n              latitude: message['locationMessage']['degreesLatitude'],\n              name: message['locationMessage']['name'],\n              address: message['locationMessage']['address'],\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          return await this.post(content, 'messages');\n        }\n        if (message['contacts']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            type: 'contacts',\n            to: number.replace(/\\D/g, ''),\n            contacts: message['contacts'],\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          message = message['message'];\n          return await this.post(content, 'messages');\n        }\n        if (message['conversation']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            type: 'text',\n            to: number.replace(/\\D/g, ''),\n            text: {\n              body: message['conversation'],\n              preview_url: Boolean(options?.linkPreview),\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          return await this.post(content, 'messages');\n        }\n        if (message['media']) {\n          const isImage = message['mimetype']?.startsWith('image/');\n\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            type: message['mediaType'],\n            to: number.replace(/\\D/g, ''),\n            [message['mediaType']]: {\n              [message['type']]: message['id'],\n              ...(message['mediaType'] !== 'audio' &&\n                message['mediaType'] !== 'video' &&\n                message['fileName'] &&\n                !isImage && { filename: message['fileName'] }),\n              ...(message['mediaType'] !== 'audio' && message['caption'] && { caption: message['caption'] }),\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          return await this.post(content, 'messages');\n        }\n        if (message['audio']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            type: 'audio',\n            to: number.replace(/\\D/g, ''),\n            audio: {\n              [message['type']]: message['id'],\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          return await this.post(content, 'messages');\n        }\n        if (message['buttons']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            to: number.replace(/\\D/g, ''),\n            type: 'interactive',\n            interactive: {\n              type: 'button',\n              body: {\n                text: message['text'] || 'Select',\n              },\n              action: {\n                buttons: message['buttons'],\n              },\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          let formattedText = '';\n          for (const item of message['buttons']) {\n            formattedText += `▶️ ${item.reply?.title}\\n`;\n          }\n          message = { conversation: `${message['text'] || 'Select'}\\n` + formattedText };\n          return await this.post(content, 'messages');\n        }\n        if (message['listMessage']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            to: number.replace(/\\D/g, ''),\n            type: 'interactive',\n            interactive: {\n              type: 'list',\n              header: {\n                type: 'text',\n                text: message['listMessage']['title'],\n              },\n              body: {\n                text: message['listMessage']['description'],\n              },\n              footer: {\n                text: message['listMessage']['footerText'],\n              },\n              action: {\n                button: message['listMessage']['buttonText'],\n                sections: message['listMessage']['sections'],\n              },\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          let formattedText = '';\n          for (const section of message['listMessage']['sections']) {\n            formattedText += `${section?.title}\\n`;\n            for (const row of section.rows) {\n              formattedText += `${row?.title}\\n`;\n            }\n          }\n          message = { conversation: `${message['listMessage']['title']}\\n` + formattedText };\n          return await this.post(content, 'messages');\n        }\n        if (message['template']) {\n          content = {\n            messaging_product: 'whatsapp',\n            recipient_type: 'individual',\n            to: number.replace(/\\D/g, ''),\n            type: 'template',\n            template: {\n              name: message['template']['name'],\n              language: {\n                code: message['template']['language'] || 'en_US',\n              },\n              components: message['template']['components'],\n            },\n          };\n          quoted ? (content.context = { message_id: quoted.id }) : content;\n          message = { conversation: `▶️${message['template']['name']}◀️` };\n          return await this.post(content, 'messages');\n        }\n      })();\n\n      if (messageSent?.error_data || messageSent.message) {\n        this.logger.error(messageSent);\n        return messageSent;\n      }\n\n      const messageRaw: any = {\n        key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: createJid(number) },\n        message: this.convertMessageToRaw(message, content),\n        messageType: this.renderMessageType(content.type),\n        messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000),\n        instanceId: this.instanceId,\n        webhookUrl,\n        status: status[1],\n        source: 'unknown',\n      };\n\n      this.logger.log(messageRaw);\n\n      this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw);\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && !isIntegration) {\n        this.chatwootService.eventWhatsapp(\n          Events.SEND_MESSAGE,\n          { instanceName: this.instance.name, instanceId: this.instanceId },\n          messageRaw,\n        );\n      }\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && isIntegration)\n        await chatbotController.emit({\n          instance: { instanceName: this.instance.name, instanceId: this.instanceId },\n          remoteJid: messageRaw.key.remoteJid,\n          msg: messageRaw,\n          pushName: messageRaw.pushName,\n        });\n\n      await this.prismaRepository.message.create({\n        data: messageRaw,\n      });\n\n      return messageRaw;\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  // Send Message Controller\n  public async textMessage(data: SendTextDto, isIntegration = false) {\n    const res = await this.sendMessageWithTyping(\n      data.number,\n      {\n        conversation: data.text,\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      isIntegration,\n    );\n    return res;\n  }\n\n  private async getIdMedia(mediaMessage: any, isFile = false) {\n    try {\n      const formData = new FormData();\n\n      if (isFile === false) {\n        if (isURL(mediaMessage.media)) {\n          const response = await axios.get(mediaMessage.media, { responseType: 'arraybuffer' });\n          const buffer = Buffer.from(response.data, 'base64');\n          formData.append('file', buffer, {\n            filename: mediaMessage.fileName || 'media',\n            contentType: mediaMessage.mimetype,\n          });\n        } else {\n          const buffer = Buffer.from(mediaMessage.media, 'base64');\n          formData.append('file', buffer, {\n            filename: mediaMessage.fileName || 'media',\n            contentType: mediaMessage.mimetype,\n          });\n        }\n      } else {\n        formData.append('file', mediaMessage.media.buffer, {\n          filename: mediaMessage.media.originalname,\n          contentType: mediaMessage.media.mimetype,\n        });\n      }\n\n      const mimetype = mediaMessage.mimetype || mediaMessage.media.mimetype;\n\n      formData.append('typeFile', mimetype);\n      formData.append('messaging_product', 'whatsapp');\n\n      const token = this.token;\n\n      const headers = { Authorization: `Bearer ${token}` };\n      const url = `${this.configService.get<WaBusiness>('WA_BUSINESS').URL}/${\n        this.configService.get<WaBusiness>('WA_BUSINESS').VERSION\n      }/${this.number}/media`;\n\n      const res = await axios.post(url, formData, { headers });\n      return res.data.id;\n    } catch (error) {\n      this.logger.error(error.response.data);\n      throw new InternalServerErrorException(error?.toString() || error);\n    }\n  }\n\n  protected async prepareMediaMessage(mediaMessage: MediaMessage) {\n    try {\n      if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) {\n        const regex = new RegExp(/.*\\/(.+?)\\./);\n        const arrayMatch = regex.exec(mediaMessage.media);\n        mediaMessage.fileName = arrayMatch[1];\n      }\n\n      if (mediaMessage.mediatype === 'image' && !mediaMessage.fileName) {\n        mediaMessage.fileName = 'image.png';\n      }\n\n      if (mediaMessage.mediatype === 'video' && !mediaMessage.fileName) {\n        mediaMessage.fileName = 'video.mp4';\n      }\n\n      let mimetype: string | false;\n\n      const prepareMedia: any = {\n        caption: mediaMessage?.caption,\n        fileName: mediaMessage.fileName,\n        mediaType: mediaMessage.mediatype,\n        media: mediaMessage.media,\n        gifPlayback: false,\n      };\n\n      if (isURL(mediaMessage.media)) {\n        mimetype = mimeTypes.lookup(mediaMessage.media);\n        prepareMedia.id = mediaMessage.media;\n        prepareMedia.type = 'link';\n      } else {\n        mimetype = mimeTypes.lookup(mediaMessage.fileName);\n        const id = await this.getIdMedia(prepareMedia);\n        prepareMedia.id = id;\n        prepareMedia.type = 'id';\n      }\n\n      prepareMedia.mimetype = mimetype;\n\n      return prepareMedia;\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString() || error);\n    }\n  }\n\n  public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {\n    const mediaData: SendMediaDto = { ...data };\n\n    if (file) mediaData.media = file.buffer.toString('base64');\n\n    const message = await this.prepareMediaMessage(mediaData);\n\n    const mediaSent = await this.sendMessageWithTyping(\n      data.number,\n      { ...message },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      isIntegration,\n    );\n\n    return mediaSent;\n  }\n\n  public async processAudio(audio: string, number: string, file: any) {\n    number = number.replace(/\\D/g, '');\n    const hash = `${number}-${new Date().getTime()}`;\n\n    const audioConverterConfig = this.configService.get<AudioConverter>('AUDIO_CONVERTER');\n    if (audioConverterConfig.API_URL) {\n      this.logger.verbose('Using audio converter API');\n      const formData = new FormData();\n\n      if (file) {\n        formData.append('file', file.buffer, {\n          filename: file.originalname,\n          contentType: file.mimetype,\n        });\n      } else if (isURL(audio)) {\n        formData.append('url', audio);\n      } else {\n        formData.append('base64', audio);\n      }\n\n      formData.append('format', 'mp3');\n\n      const response = await axios.post(audioConverterConfig.API_URL, formData, {\n        headers: {\n          ...formData.getHeaders(),\n          apikey: audioConverterConfig.API_KEY,\n        },\n      });\n\n      const audioConverter = response?.data?.audio || response?.data?.url;\n\n      if (!audioConverter) {\n        throw new InternalServerErrorException('Failed to convert audio');\n      }\n\n      const prepareMedia: any = {\n        fileName: `${hash}.mp3`,\n        mediaType: 'audio',\n        media: audioConverter,\n        mimetype: 'audio/mpeg',\n      };\n\n      const id = await this.getIdMedia(prepareMedia);\n      prepareMedia.id = id;\n      prepareMedia.type = 'id';\n\n      this.logger.verbose('Audio converted');\n      return prepareMedia;\n    } else {\n      let mimetype: string | false;\n\n      const prepareMedia: any = {\n        fileName: `${hash}.mp3`,\n        mediaType: 'audio',\n        media: audio,\n      };\n\n      if (isURL(audio)) {\n        mimetype = mimeTypes.lookup(audio);\n        prepareMedia.id = audio;\n        prepareMedia.type = 'link';\n      } else if (audio && !file) {\n        mimetype = mimeTypes.lookup(prepareMedia.fileName);\n        const id = await this.getIdMedia(prepareMedia);\n        prepareMedia.id = id;\n        prepareMedia.type = 'id';\n      } else if (file) {\n        prepareMedia.media = file;\n        const id = await this.getIdMedia(prepareMedia, true);\n        prepareMedia.id = id;\n        prepareMedia.type = 'id';\n        mimetype = file.mimetype;\n      }\n\n      prepareMedia.mimetype = mimetype;\n\n      return prepareMedia;\n    }\n  }\n\n  public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {\n    const message = await this.processAudio(data.audio, data.number, file);\n\n    const audioSent = await this.sendMessageWithTyping(\n      data.number,\n      { ...message },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      isIntegration,\n    );\n\n    return audioSent;\n  }\n\n  public async buttonMessage(data: SendButtonsDto) {\n    const embeddedMedia: any = {};\n\n    const btnItems = {\n      text: data.buttons.map((btn) => btn.displayText),\n      ids: data.buttons.map((btn) => btn.id),\n    };\n\n    if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) {\n      throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.');\n    }\n\n    return await this.sendMessageWithTyping(\n      data.number,\n      {\n        text: !embeddedMedia?.mediaKey ? data.title : undefined,\n        buttons: data.buttons.map((button) => {\n          return {\n            type: 'reply',\n            reply: {\n              title: button.displayText,\n              id: button.id,\n            },\n          };\n        }),\n        [embeddedMedia?.mediaKey]: embeddedMedia?.message,\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n  }\n\n  public async locationMessage(data: SendLocationDto) {\n    return await this.sendMessageWithTyping(\n      data.number,\n      {\n        locationMessage: {\n          degreesLatitude: data.latitude,\n          degreesLongitude: data.longitude,\n          name: data?.name,\n          address: data?.address,\n        },\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n  }\n\n  public async listMessage(data: SendListDto) {\n    const sectionsItems = {\n      title: data.sections.map((list) => list.title),\n    };\n\n    if (!arrayUnique(sectionsItems.title)) {\n      throw new BadRequestException('Section tiles cannot be repeated');\n    }\n\n    const sendData: any = {\n      listMessage: {\n        title: data.title,\n        description: data.description,\n        footerText: data?.footerText,\n        buttonText: data?.buttonText,\n        sections: data.sections.map((section) => {\n          return {\n            title: section.title,\n            rows: section.rows.map((row) => {\n              return {\n                title: row.title,\n                description: row.description.substring(0, 72),\n                id: row.rowId,\n              };\n            }),\n          };\n        }),\n      },\n    };\n\n    return await this.sendMessageWithTyping(data.number, sendData, {\n      delay: data?.delay,\n      presence: 'composing',\n      quoted: data?.quoted,\n      linkPreview: data?.linkPreview,\n      mentionsEveryOne: data?.mentionsEveryOne,\n      mentioned: data?.mentioned,\n    });\n  }\n\n  public async templateMessage(data: SendTemplateDto, isIntegration = false) {\n    const res = await this.sendMessageWithTyping(\n      data.number,\n      {\n        template: {\n          name: data.name,\n          language: data.language,\n          components: data.components,\n        },\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n        webhookUrl: data?.webhookUrl,\n      },\n      isIntegration,\n    );\n    return res;\n  }\n\n  public async contactMessage(data: SendContactDto) {\n    const message: any = {};\n\n    const vcard = (contact: ContactMessage) => {\n      let result = 'BEGIN:VCARD\\n' + 'VERSION:3.0\\n' + `N:${contact.fullName}\\n` + `FN:${contact.fullName}\\n`;\n\n      if (contact.organization) {\n        result += `ORG:${contact.organization};\\n`;\n      }\n\n      if (contact.email) {\n        result += `EMAIL:${contact.email}\\n`;\n      }\n\n      if (contact.url) {\n        result += `URL:${contact.url}\\n`;\n      }\n\n      if (!contact.wuid) {\n        contact.wuid = createJid(contact.phoneNumber);\n      }\n\n      result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\\n` + 'item1.X-ABLabel:Celular\\n' + 'END:VCARD';\n\n      return result;\n    };\n\n    if (data.contact.length === 1) {\n      message.contact = {\n        displayName: data.contact[0].fullName,\n        vcard: vcard(data.contact[0]),\n      };\n    } else {\n      message.contactsArrayMessage = {\n        displayName: `${data.contact.length} contacts`,\n        contacts: data.contact.map((contact) => {\n          return {\n            displayName: contact.fullName,\n            vcard: vcard(contact),\n          };\n        }),\n      };\n    }\n    return await this.sendMessageWithTyping(\n      data.number,\n      {\n        contacts: data.contact.map((contact) => {\n          return {\n            name: { formatted_name: contact.fullName, first_name: contact.fullName },\n            phones: [{ phone: contact.phoneNumber }],\n            urls: [{ url: contact.url }],\n            emails: [{ email: contact.email }],\n            org: { company: contact.organization },\n          };\n        }),\n        message,\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n  }\n\n  public async reactionMessage(data: SendReactionDto) {\n    return await this.sendMessageWithTyping(data.key.remoteJid, {\n      reactionMessage: {\n        key: data.key,\n        text: data.reaction,\n      },\n    });\n  }\n\n  public async getBase64FromMediaMessage(data: any) {\n    try {\n      const msg = data.message;\n      const messageType = msg.messageType.includes('Message') ? msg.messageType : msg.messageType + 'Message';\n      const mediaMessage = msg.message[messageType];\n\n      if (!msg.message?.base64) {\n        const buffer = await this.downloadMediaMessage({ type: messageType, ...msg.message });\n        msg.message.base64 = buffer.toString('base64');\n      }\n\n      return {\n        mediaType: msg.messageType,\n        fileName: mediaMessage?.fileName || mediaMessage?.filename,\n        caption: mediaMessage?.caption,\n        size: {\n          fileLength: mediaMessage?.fileLength,\n          height: mediaMessage?.fileLength,\n          width: mediaMessage?.width,\n        },\n        mimetype: mediaMessage?.mime_type,\n        base64: msg.message.base64,\n      };\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  public async deleteMessage() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n\n  // methods not available on WhatsApp Business API\n  public async mediaSticker() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async pollMessage() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async statusMessage() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async reloadConnection() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async whatsappNumber() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async markMessageAsRead() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async archiveChat() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async markChatUnread() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async fetchProfile() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async offerCall() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async sendPresence() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async setPresence() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async fetchPrivacySettings() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updatePrivacySettings() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async fetchBusinessProfile() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateProfileName() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateProfileStatus() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateProfilePicture() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async removeProfilePicture() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async blockUser() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateMessage() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async createGroup() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateGroupPicture() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateGroupSubject() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateGroupDescription() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async findGroup() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async fetchAllGroups() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async inviteCode() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async inviteInfo() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async sendInvite() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async acceptInviteCode() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async revokeInviteCode() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async findParticipants() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateGParticipant() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async updateGSetting() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async toggleEphemeral() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async leaveGroup() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async fetchLabels() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async handleLabel() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async receiveMobileCode() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n  public async fakeCall() {\n    throw new BadRequestException('Method not available on WhatsApp Business API');\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/whatsapp/baileys.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { WAMonitoringService } from '@api/services/monitor.service';\n\nexport class BaileysController {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  public async onWhatsapp({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysOnWhatsapp(body?.jid);\n  }\n\n  public async profilePictureUrl({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysProfilePictureUrl(body?.jid, body?.type, body?.timeoutMs);\n  }\n\n  public async assertSessions({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysAssertSessions(body?.jids, body?.force);\n  }\n\n  public async createParticipantNodes({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysCreateParticipantNodes(body?.jids, body?.message, body?.extraAttrs);\n  }\n\n  public async getUSyncDevices({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysGetUSyncDevices(body?.jids, body?.useCache, body?.ignoreZeroDevices);\n  }\n\n  public async generateMessageTag({ instanceName }: InstanceDto) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysGenerateMessageTag();\n  }\n\n  public async sendNode({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysSendNode(body?.stanza);\n  }\n\n  public async signalRepositoryDecryptMessage({ instanceName }: InstanceDto, body: any) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysSignalRepositoryDecryptMessage(body?.jid, body?.type, body?.ciphertext);\n  }\n\n  public async getAuthState({ instanceName }: InstanceDto) {\n    const instance = this.waMonitor.waInstances[instanceName];\n\n    return instance.baileysGetAuthState();\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/whatsapp/baileys.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { baileysController } from '@api/server.module';\nimport { instanceSchema } from '@validate/instance.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class BaileysRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('onWhatsapp'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.onWhatsapp(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('profilePictureUrl'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.profilePictureUrl(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('assertSessions'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.assertSessions(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('createParticipantNodes'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.createParticipantNodes(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('getUSyncDevices'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.getUSyncDevices(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('generateMessageTag'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.generateMessageTag(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('sendNode'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.sendNode(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('signalRepositoryDecryptMessage'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.signalRepositoryDecryptMessage(instance, req.body),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('getAuthState'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => baileysController.getAuthState(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/channel/whatsapp/baileysMessage.processor.ts",
    "content": "import { Logger } from '@config/logger.config';\nimport { BaileysEventMap, MessageUpsertType, WAMessage } from 'baileys';\nimport { catchError, concatMap, delay, EMPTY, from, retryWhen, Subject, Subscription, take, tap } from 'rxjs';\n\ntype MessageUpsertPayload = BaileysEventMap['messages.upsert'];\ntype MountProps = {\n  onMessageReceive: (payload: MessageUpsertPayload, settings: any) => Promise<void>;\n};\n\nexport class BaileysMessageProcessor {\n  private processorLogs = new Logger('BaileysMessageProcessor');\n  private subscription?: Subscription;\n\n  protected messageSubject = new Subject<{\n    messages: WAMessage[];\n    type: MessageUpsertType;\n    requestId?: string;\n    settings: any;\n  }>();\n\n  mount({ onMessageReceive }: MountProps) {\n    // Se já existe subscription, fazer cleanup primeiro\n    if (this.subscription && !this.subscription.closed) {\n      this.subscription.unsubscribe();\n    }\n\n    // Se o Subject foi completado, recriar\n    if (this.messageSubject.closed) {\n      this.processorLogs.warn('MessageSubject was closed, recreating...');\n      this.messageSubject = new Subject<{\n        messages: WAMessage[];\n        type: MessageUpsertType;\n        requestId?: string;\n        settings: any;\n      }>();\n    }\n\n    this.subscription = this.messageSubject\n      .pipe(\n        tap(({ messages }) => {\n          this.processorLogs.log(`Processing batch of ${messages.length} messages`);\n        }),\n        concatMap(({ messages, type, requestId, settings }) =>\n          from(onMessageReceive({ messages, type, requestId }, settings)).pipe(\n            retryWhen((errors) =>\n              errors.pipe(\n                tap((error) => this.processorLogs.warn(`Retrying message batch due to error: ${error.message}`)),\n                delay(1000), // 1 segundo de delay\n                take(3), // Máximo 3 tentativas\n              ),\n            ),\n          ),\n        ),\n        catchError((error) => {\n          this.processorLogs.error(`Error processing message batch: ${error}`);\n          return EMPTY;\n        }),\n      )\n      .subscribe({\n        error: (error) => {\n          this.processorLogs.error(`Message stream error: ${error}`);\n        },\n      });\n  }\n\n  processMessage(payload: MessageUpsertPayload, settings: any) {\n    const { messages, type, requestId } = payload;\n    this.messageSubject.next({ messages, type, requestId, settings });\n  }\n\n  onDestroy() {\n    this.subscription?.unsubscribe();\n    this.messageSubject.complete();\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/channel/whatsapp/voiceCalls/transport.type.ts",
    "content": "import { BinaryNode, Contact, JidWithDevice, proto, WAConnectionState } from 'baileys';\n\nexport interface ServerToClientEvents {\n  withAck: (d: string, callback: (e: number) => void) => void;\n  onWhatsApp: onWhatsAppType;\n  profilePictureUrl: ProfilePictureUrlType;\n  assertSessions: AssertSessionsType;\n  createParticipantNodes: CreateParticipantNodesType;\n  getUSyncDevices: GetUSyncDevicesType;\n  generateMessageTag: GenerateMessageTagType;\n  sendNode: SendNodeType;\n  'signalRepository:decryptMessage': SignalRepositoryDecryptMessageType;\n}\n\nexport interface ClientToServerEvents {\n  init: (\n    me: Contact | undefined,\n    account: proto.IADVSignedDeviceIdentity | undefined,\n    status: WAConnectionState,\n  ) => void;\n  'CB:call': (packet: any) => void;\n  'CB:ack,class:call': (packet: any) => void;\n  'connection.update:status': (\n    me: Contact | undefined,\n    account: proto.IADVSignedDeviceIdentity | undefined,\n    status: WAConnectionState,\n  ) => void;\n  'connection.update:qr': (qr: string) => void;\n}\n\nexport type onWhatsAppType = (jid: string, callback: onWhatsAppCallback) => void;\nexport type onWhatsAppCallback = (\n  response: {\n    exists: boolean;\n    jid: string;\n  }[],\n) => void;\n\nexport type ProfilePictureUrlType = (\n  jid: string,\n  type: 'image' | 'preview',\n  timeoutMs: number | undefined,\n  callback: ProfilePictureUrlCallback,\n) => void;\nexport type ProfilePictureUrlCallback = (response: string | undefined) => void;\n\nexport type AssertSessionsType = (jids: string[], force: boolean, callback: AssertSessionsCallback) => void;\nexport type AssertSessionsCallback = (response: boolean) => void;\n\nexport type CreateParticipantNodesType = (\n  jids: string[],\n  message: any,\n  extraAttrs: any,\n  callback: CreateParticipantNodesCallback,\n) => void;\nexport type CreateParticipantNodesCallback = (nodes: any, shouldIncludeDeviceIdentity: boolean) => void;\n\nexport type GetUSyncDevicesType = (\n  jids: string[],\n  useCache: boolean,\n  ignoreZeroDevices: boolean,\n  callback: GetUSyncDevicesTypeCallback,\n) => void;\nexport type GetUSyncDevicesTypeCallback = (jids: JidWithDevice[]) => void;\n\nexport type GenerateMessageTagType = (callback: GenerateMessageTagTypeCallback) => void;\nexport type GenerateMessageTagTypeCallback = (response: string) => void;\n\nexport type SendNodeType = (stanza: BinaryNode, callback: SendNodeTypeCallback) => void;\nexport type SendNodeTypeCallback = (response: boolean) => void;\n\nexport type SignalRepositoryDecryptMessageType = (\n  jid: string,\n  type: 'pkmsg' | 'msg',\n  ciphertext: Buffer,\n  callback: SignalRepositoryDecryptMessageCallback,\n) => void;\nexport type SignalRepositoryDecryptMessageCallback = (response: any) => void;\n"
  },
  {
    "path": "src/api/integrations/channel/whatsapp/voiceCalls/useVoiceCallsBaileys.ts",
    "content": "import { ConnectionState, WAConnectionState, WASocket } from 'baileys';\nimport { io, Socket } from 'socket.io-client';\n\nimport { ClientToServerEvents, ServerToClientEvents } from './transport.type';\n\nlet baileys_connection_state: WAConnectionState = 'close';\n\nexport const useVoiceCallsBaileys = async (\n  wavoip_token: string,\n  baileys_sock: WASocket,\n  status?: WAConnectionState,\n  logger?: boolean,\n) => {\n  baileys_connection_state = status ?? 'close';\n\n  const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io('https://devices.wavoip.com/baileys', {\n    transports: ['websocket'],\n    path: `/${wavoip_token}/websocket`,\n  });\n\n  socket.on('connect', () => {\n    if (logger) console.log('[*] - Wavoip connected', socket.id);\n\n    socket.emit(\n      'init',\n      baileys_sock.authState.creds.me,\n      baileys_sock.authState.creds.account,\n      baileys_connection_state,\n    );\n  });\n\n  socket.on('disconnect', () => {\n    if (logger) console.log('[*] - Wavoip disconnect');\n  });\n\n  socket.on('connect_error', (error) => {\n    if (socket.active) {\n      if (logger)\n        console.log(\n          '[*] - Wavoip connection error temporary failure, the socket will automatically try to reconnect',\n          error,\n        );\n    } else {\n      if (logger) console.log('[*] - Wavoip connection error', error.message);\n    }\n  });\n\n  socket.on('onWhatsApp', async (jid, callback) => {\n    try {\n      const response: any = await baileys_sock.onWhatsApp(jid);\n\n      callback(response);\n\n      if (logger) console.log('[*] Success on call onWhatsApp function', response, jid);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call onWhatsApp function', error);\n    }\n  });\n\n  socket.on('profilePictureUrl', async (jid, type, timeoutMs, callback) => {\n    try {\n      const response = await baileys_sock.profilePictureUrl(jid, type, timeoutMs);\n\n      callback(response);\n\n      if (logger) console.log('[*] Success on call profilePictureUrl function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call profilePictureUrl function', error);\n    }\n  });\n\n  socket.on('assertSessions', async (jids, force, callback) => {\n    try {\n      const response = await baileys_sock.assertSessions(jids);\n\n      callback(response);\n\n      if (logger) console.log('[*] Success on call assertSessions function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call assertSessions function', error);\n    }\n  });\n\n  socket.on('createParticipantNodes', async (jids, message, extraAttrs, callback) => {\n    try {\n      const response = await baileys_sock.createParticipantNodes(jids, message, extraAttrs);\n\n      callback(response, true);\n\n      if (logger) console.log('[*] Success on call createParticipantNodes function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call createParticipantNodes function', error);\n    }\n  });\n\n  socket.on('getUSyncDevices', async (jids, useCache, ignoreZeroDevices, callback) => {\n    try {\n      const response = await baileys_sock.getUSyncDevices(jids, useCache, ignoreZeroDevices);\n\n      callback(response);\n\n      if (logger) console.log('[*] Success on call getUSyncDevices function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call getUSyncDevices function', error);\n    }\n  });\n\n  socket.on('generateMessageTag', async (callback) => {\n    try {\n      const response = await baileys_sock.generateMessageTag();\n\n      callback(response);\n\n      if (logger) console.log('[*] Success on call generateMessageTag function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call generateMessageTag function', error);\n    }\n  });\n\n  socket.on('sendNode', async (stanza, callback) => {\n    try {\n      console.log('sendNode', JSON.stringify(stanza));\n      const response = await baileys_sock.sendNode(stanza);\n\n      callback(true);\n\n      if (logger) console.log('[*] Success on call sendNode function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call sendNode function', error);\n    }\n  });\n\n  socket.on('signalRepository:decryptMessage', async (jid, type, ciphertext, callback) => {\n    try {\n      const response = await baileys_sock.signalRepository.decryptMessage({\n        jid: jid,\n        type: type,\n        ciphertext: ciphertext,\n      });\n\n      callback(response);\n\n      if (logger) console.log('[*] Success on call signalRepository:decryptMessage function', response);\n    } catch (error) {\n      if (logger) console.error('[*] Error on call signalRepository:decryptMessage function', error);\n    }\n  });\n\n  // we only use this connection data to inform the webphone that the device is connected and creeds account to generate e2e whatsapp key for make call packets\n  baileys_sock.ev.on('connection.update', (update: Partial<ConnectionState>) => {\n    const { connection } = update;\n\n    if (connection) {\n      baileys_connection_state = connection;\n      socket\n        .timeout(1000)\n        .emit(\n          'connection.update:status',\n          baileys_sock.authState.creds.me,\n          baileys_sock.authState.creds.account,\n          connection,\n        );\n    }\n\n    if (update.qr) {\n      socket.timeout(1000).emit('connection.update:qr', update.qr);\n    }\n  });\n\n  baileys_sock.ws.on('CB:call', (packet) => {\n    if (logger) console.log('[*] Signling received');\n    socket.volatile.timeout(1000).emit('CB:call', packet);\n  });\n\n  baileys_sock.ws.on('CB:ack,class:call', (packet) => {\n    if (logger) console.log('[*] Signling ack received');\n    socket.volatile.timeout(1000).emit('CB:ack,class:call', packet);\n  });\n\n  return socket;\n};\n"
  },
  {
    "path": "src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts",
    "content": "import { getCollectionsDto } from '@api/dto/business.dto';\nimport { OfferCallDto } from '@api/dto/call.dto';\nimport {\n  ArchiveChatDto,\n  BlockUserDto,\n  DeleteMessage,\n  getBase64FromMediaMessageDto,\n  LastMessage,\n  MarkChatUnreadDto,\n  NumberBusiness,\n  OnWhatsAppDto,\n  PrivacySettingDto,\n  ReadMessageDto,\n  SendPresenceDto,\n  UpdateMessageDto,\n  WhatsAppNumberDto,\n} from '@api/dto/chat.dto';\nimport {\n  AcceptGroupInvite,\n  CreateGroupDto,\n  GetParticipant,\n  GroupDescriptionDto,\n  GroupInvite,\n  GroupJid,\n  GroupPictureDto,\n  GroupSendInvite,\n  GroupSubjectDto,\n  GroupToggleEphemeralDto,\n  GroupUpdateParticipantDto,\n  GroupUpdateSettingDto,\n} from '@api/dto/group.dto';\nimport { InstanceDto, SetPresenceDto } from '@api/dto/instance.dto';\nimport { HandleLabelDto, LabelDto } from '@api/dto/label.dto';\nimport {\n  Button,\n  ContactMessage,\n  KeyType,\n  MediaMessage,\n  Options,\n  SendAudioDto,\n  SendButtonsDto,\n  SendContactDto,\n  SendListDto,\n  SendLocationDto,\n  SendMediaDto,\n  SendPollDto,\n  SendPtvDto,\n  SendReactionDto,\n  SendStatusDto,\n  SendStickerDto,\n  SendTextDto,\n  StatusMessage,\n  TypeButton,\n} from '@api/dto/sendMessage.dto';\nimport { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';\nimport * as s3Service from '@api/integrations/storage/s3/libs/minio.server';\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { PrismaRepository, Query } from '@api/repository/repository.service';\nimport { chatbotController, waMonitor } from '@api/server.module';\nimport { CacheService } from '@api/services/cache.service';\nimport { ChannelStartupService } from '@api/services/channel.service';\nimport { Events, MessageSubtype, TypeMediaMessage, wa } from '@api/types/wa.types';\nimport { CacheEngine } from '@cache/cacheengine';\nimport {\n  AudioConverter,\n  CacheConf,\n  Chatwoot,\n  ConfigService,\n  configService,\n  ConfigSessionPhone,\n  Database,\n  Log,\n  Openai,\n  ProviderSession,\n  QrCode,\n  S3,\n} from '@config/env.config';\nimport { BadRequestException, InternalServerErrorException, NotFoundException } from '@exceptions';\nimport ffmpegPath from '@ffmpeg-installer/ffmpeg';\nimport { Boom } from '@hapi/boom';\nimport { createId as cuid } from '@paralleldrive/cuid2';\nimport { Instance, Message } from '@prisma/client';\nimport { createJid } from '@utils/createJid';\nimport { fetchLatestWaWebVersion } from '@utils/fetchLatestWaWebVersion';\nimport { makeProxyAgent, makeProxyAgentUndici } from '@utils/makeProxyAgent';\nimport { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache';\nimport { status } from '@utils/renderStatus';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport useMultiFileAuthStatePrisma from '@utils/use-multi-file-auth-state-prisma';\nimport { AuthStateProvider } from '@utils/use-multi-file-auth-state-provider-files';\nimport { useMultiFileAuthStateRedisDb } from '@utils/use-multi-file-auth-state-redis-db';\nimport axios from 'axios';\nimport makeWASocket, {\n  AnyMessageContent,\n  BufferedEventData,\n  BufferJSON,\n  CacheStore,\n  CatalogCollection,\n  Chat,\n  ConnectionState,\n  Contact,\n  decryptPollVote,\n  delay,\n  DisconnectReason,\n  downloadContentFromMessage,\n  downloadMediaMessage,\n  generateWAMessageFromContent,\n  getAggregateVotesInPollMessage,\n  GetCatalogOptions,\n  getContentType,\n  getDevice,\n  GroupMetadata,\n  isJidBroadcast,\n  isJidGroup,\n  isJidNewsletter,\n  isPnUser,\n  jidNormalizedUser,\n  makeCacheableSignalKeyStore,\n  MessageUpsertType,\n  MessageUserReceiptUpdate,\n  MiscMessageGenerationOptions,\n  ParticipantAction,\n  prepareWAMessageMedia,\n  Product,\n  proto,\n  UserFacingSocketConfig,\n  WABrowserDescription,\n  WAMediaUpload,\n  WAMessage,\n  WAMessageKey,\n  WAPresence,\n  WASocket,\n} from 'baileys';\nimport { Label } from 'baileys/lib/Types/Label';\nimport { LabelAssociation } from 'baileys/lib/Types/LabelAssociation';\nimport { spawn } from 'child_process';\nimport { isArray, isBase64, isURL } from 'class-validator';\nimport { createHash } from 'crypto';\nimport EventEmitter2 from 'eventemitter2';\nimport ffmpeg from 'fluent-ffmpeg';\nimport FormData from 'form-data';\nimport Long from 'long';\nimport mimeTypes from 'mime-types';\nimport NodeCache from 'node-cache';\nimport cron from 'node-cron';\nimport { release } from 'os';\nimport { join } from 'path';\nimport P from 'pino';\nimport qrcode, { QRCodeToDataURLOptions } from 'qrcode';\nimport qrcodeTerminal from 'qrcode-terminal';\nimport sharp from 'sharp';\nimport { PassThrough, Readable } from 'stream';\nimport { v4 } from 'uuid';\n\nimport { BaileysMessageProcessor } from './baileysMessage.processor';\nimport { useVoiceCallsBaileys } from './voiceCalls/useVoiceCallsBaileys';\n\nexport interface ExtendedIMessageKey extends proto.IMessageKey {\n  remoteJidAlt?: string;\n  participantAlt?: string;\n  server_id?: string;\n  isViewOnce?: boolean;\n}\n\nconst groupMetadataCache = new CacheService(new CacheEngine(configService, 'groups').getEngine());\n\n// Adicione a função getVideoDuration no início do arquivo\nasync function getVideoDuration(input: Buffer | string | Readable): Promise<number> {\n  const MediaInfoFactory = (await import('mediainfo.js')).default;\n  const mediainfo = await MediaInfoFactory({ format: 'JSON' });\n\n  let fileSize: number;\n  let readChunk: (size: number, offset: number) => Promise<Buffer>;\n\n  if (Buffer.isBuffer(input)) {\n    fileSize = input.length;\n    readChunk = async (size: number, offset: number): Promise<Buffer> => {\n      return input.slice(offset, offset + size);\n    };\n  } else if (typeof input === 'string') {\n    const fs = await import('fs');\n    const stat = await fs.promises.stat(input);\n    fileSize = stat.size;\n    const fd = await fs.promises.open(input, 'r');\n\n    readChunk = async (size: number, offset: number): Promise<Buffer> => {\n      const buffer = Buffer.alloc(size);\n      await fd.read(buffer, 0, size, offset);\n      return buffer;\n    };\n\n    try {\n      const result = await mediainfo.analyzeData(() => fileSize, readChunk);\n      const jsonResult = JSON.parse(result);\n\n      const generalTrack = jsonResult.media.track.find((t: any) => t['@type'] === 'General');\n      const duration = generalTrack.Duration;\n\n      return Math.round(parseFloat(duration));\n    } finally {\n      await fd.close();\n    }\n  } else if (input instanceof Readable) {\n    const chunks: Buffer[] = [];\n    for await (const chunk of input) {\n      chunks.push(chunk);\n    }\n    const data = Buffer.concat(chunks);\n    fileSize = data.length;\n\n    readChunk = async (size: number, offset: number): Promise<Buffer> => {\n      return data.slice(offset, offset + size);\n    };\n  } else {\n    throw new Error('Tipo de entrada não suportado');\n  }\n\n  const result = await mediainfo.analyzeData(() => fileSize, readChunk);\n  const jsonResult = JSON.parse(result);\n\n  const generalTrack = jsonResult.media.track.find((t: any) => t['@type'] === 'General');\n  const duration = generalTrack.Duration;\n\n  return Math.round(parseFloat(duration));\n}\n\nexport class BaileysStartupService extends ChannelStartupService {\n  private messageProcessor = new BaileysMessageProcessor();\n\n  constructor(\n    public readonly configService: ConfigService,\n    public readonly eventEmitter: EventEmitter2,\n    public readonly prismaRepository: PrismaRepository,\n    public readonly cache: CacheService,\n    public readonly chatwootCache: CacheService,\n    public readonly baileysCache: CacheService,\n    private readonly providerFiles: ProviderFiles,\n  ) {\n    super(configService, eventEmitter, prismaRepository, chatwootCache);\n    this.instance.qrcode = { count: 0 };\n    this.messageProcessor.mount({\n      onMessageReceive: this.messageHandle['messages.upsert'].bind(this), // Bind the method to the current context\n    });\n\n    this.authStateProvider = new AuthStateProvider(this.providerFiles);\n  }\n\n  private authStateProvider: AuthStateProvider;\n  private readonly msgRetryCounterCache: CacheStore = new NodeCache();\n  private readonly userDevicesCache: CacheStore = new NodeCache({ stdTTL: 300000, useClones: false });\n  private endSession = false;\n  private logBaileys = this.configService.get<Log>('LOG').BAILEYS;\n  private eventProcessingQueue: Promise<void> = Promise.resolve();\n\n  // Cache TTL constants (in seconds)\n  private readonly MESSAGE_CACHE_TTL_SECONDS = 5 * 60; // 5 minutes - avoid duplicate message processing\n  private readonly UPDATE_CACHE_TTL_SECONDS = 30 * 60; // 30 minutes - avoid duplicate status updates\n\n  public stateConnection: wa.StateConnection = { state: 'close' };\n\n  public phoneNumber: string;\n\n  public get connectionStatus() {\n    return this.stateConnection;\n  }\n\n  public async logoutInstance() {\n    this.messageProcessor.onDestroy();\n    await this.client?.logout('Log out instance: ' + this.instanceName);\n\n    this.client?.ws?.close();\n\n    const db = this.configService.get<Database>('DATABASE');\n    const cache = this.configService.get<CacheConf>('CACHE');\n    const provider = this.configService.get<ProviderSession>('PROVIDER');\n\n    if (provider?.ENABLED) {\n      const authState = await this.authStateProvider.authStateProvider(this.instance.id);\n\n      await authState.removeCreds();\n    }\n\n    if (cache?.REDIS.ENABLED && cache?.REDIS.SAVE_INSTANCES) {\n      const authState = await useMultiFileAuthStateRedisDb(this.instance.id, this.cache);\n\n      await authState.removeCreds();\n    }\n\n    if (db.SAVE_DATA.INSTANCE) {\n      const authState = await useMultiFileAuthStatePrisma(this.instance.id, this.cache);\n\n      await authState.removeCreds();\n    }\n\n    const sessionExists = await this.prismaRepository.session.findFirst({ where: { sessionId: this.instanceId } });\n    if (sessionExists) {\n      await this.prismaRepository.session.delete({ where: { sessionId: this.instanceId } });\n    }\n  }\n\n  public async getProfileName() {\n    let profileName = this.client.user?.name ?? this.client.user?.verifiedName;\n    if (!profileName) {\n      const data = await this.prismaRepository.session.findUnique({ where: { sessionId: this.instanceId } });\n\n      if (data) {\n        const creds = JSON.parse(JSON.stringify(data.creds), BufferJSON.reviver);\n        profileName = creds.me?.name || creds.me?.verifiedName;\n      }\n    }\n\n    return profileName;\n  }\n\n  public async getProfileStatus() {\n    const status = await this.client.fetchStatus(this.instance.wuid);\n\n    return status[0]?.status;\n  }\n\n  public get profilePictureUrl() {\n    return this.instance.profilePictureUrl;\n  }\n\n  public get qrCode(): wa.QrCode {\n    return {\n      pairingCode: this.instance.qrcode?.pairingCode,\n      code: this.instance.qrcode?.code,\n      base64: this.instance.qrcode?.base64,\n      count: this.instance.qrcode?.count,\n    };\n  }\n\n  private async connectionUpdate({ qr, connection, lastDisconnect }: Partial<ConnectionState>) {\n    if (qr) {\n      if (this.instance.qrcode.count === this.configService.get<QrCode>('QRCODE').LIMIT) {\n        this.sendDataWebhook(Events.QRCODE_UPDATED, {\n          message: 'QR code limit reached, please login again',\n          statusCode: DisconnectReason.badSession,\n        });\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n          this.chatwootService.eventWhatsapp(\n            Events.QRCODE_UPDATED,\n            { instanceName: this.instance.name, instanceId: this.instanceId },\n            { message: 'QR code limit reached, please login again', statusCode: DisconnectReason.badSession },\n          );\n        }\n\n        this.sendDataWebhook(Events.CONNECTION_UPDATE, {\n          instance: this.instance.name,\n          state: 'refused',\n          statusReason: DisconnectReason.connectionClosed,\n          wuid: this.instance.wuid,\n          profileName: await this.getProfileName(),\n          profilePictureUrl: this.instance.profilePictureUrl,\n        });\n\n        this.endSession = true;\n\n        return this.eventEmitter.emit('no.connection', this.instance.name);\n      }\n\n      this.instance.qrcode.count++;\n\n      const color = this.configService.get<QrCode>('QRCODE').COLOR;\n\n      const optsQrcode: QRCodeToDataURLOptions = {\n        margin: 3,\n        scale: 4,\n        errorCorrectionLevel: 'H',\n        color: { light: '#ffffff', dark: color },\n      };\n\n      if (this.phoneNumber) {\n        await delay(1000);\n        this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber);\n      } else {\n        this.instance.qrcode.pairingCode = null;\n      }\n\n      qrcode.toDataURL(qr, optsQrcode, (error, base64) => {\n        if (error) {\n          this.logger.error('Qrcode generate failed:' + error.toString());\n          return;\n        }\n\n        this.instance.qrcode.base64 = base64;\n        this.instance.qrcode.code = qr;\n\n        this.sendDataWebhook(Events.QRCODE_UPDATED, {\n          qrcode: { instance: this.instance.name, pairingCode: this.instance.qrcode.pairingCode, code: qr, base64 },\n        });\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n          this.chatwootService.eventWhatsapp(\n            Events.QRCODE_UPDATED,\n            { instanceName: this.instance.name, instanceId: this.instanceId },\n            {\n              qrcode: { instance: this.instance.name, pairingCode: this.instance.qrcode.pairingCode, code: qr, base64 },\n            },\n          );\n        }\n      });\n\n      qrcodeTerminal.generate(qr, { small: true }, (qrcode) =>\n        this.logger.log(\n          `\\n{ instance: ${this.instance.name} pairingCode: ${this.instance.qrcode.pairingCode}, qrcodeCount: ${this.instance.qrcode.count} }\\n` +\n            qrcode,\n        ),\n      );\n\n      await this.prismaRepository.instance.update({\n        where: { id: this.instanceId },\n        data: { connectionStatus: 'connecting' },\n      });\n    }\n\n    if (connection) {\n      this.stateConnection = {\n        state: connection,\n        statusReason: (lastDisconnect?.error as Boom)?.output?.statusCode ?? 200,\n      };\n    }\n\n    if (connection === 'close') {\n      const statusCode = (lastDisconnect?.error as Boom)?.output?.statusCode;\n      const codesToNotReconnect = [DisconnectReason.loggedOut, DisconnectReason.forbidden, 402, 406];\n      const shouldReconnect = !codesToNotReconnect.includes(statusCode);\n      if (shouldReconnect) {\n        await this.connectToWhatsapp(this.phoneNumber);\n      } else {\n        this.sendDataWebhook(Events.STATUS_INSTANCE, {\n          instance: this.instance.name,\n          status: 'closed',\n          disconnectionAt: new Date(),\n          disconnectionReasonCode: statusCode,\n          disconnectionObject: JSON.stringify(lastDisconnect),\n        });\n\n        await this.prismaRepository.instance.update({\n          where: { id: this.instanceId },\n          data: {\n            connectionStatus: 'close',\n            disconnectionAt: new Date(),\n            disconnectionReasonCode: statusCode,\n            disconnectionObject: JSON.stringify(lastDisconnect),\n          },\n        });\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n          this.chatwootService.eventWhatsapp(\n            Events.STATUS_INSTANCE,\n            { instanceName: this.instance.name, instanceId: this.instanceId },\n            { instance: this.instance.name, status: 'closed' },\n          );\n        }\n\n        this.eventEmitter.emit('logout.instance', this.instance.name, 'inner');\n        this.client?.ws?.close();\n        this.client.end(new Error('Close connection'));\n\n        this.sendDataWebhook(Events.CONNECTION_UPDATE, { instance: this.instance.name, ...this.stateConnection });\n      }\n    }\n\n    if (connection === 'open') {\n      this.instance.wuid = this.client.user.id.replace(/:\\d+/, '');\n      try {\n        const profilePic = await this.profilePicture(this.instance.wuid);\n        this.instance.profilePictureUrl = profilePic.profilePictureUrl;\n      } catch {\n        this.instance.profilePictureUrl = null;\n      }\n      const formattedWuid = this.instance.wuid.split('@')[0].padEnd(30, ' ');\n      const formattedName = this.instance.name;\n      this.logger.info(\n        `\n        ┌──────────────────────────────┐\n        │    CONNECTED TO WHATSAPP     │\n        └──────────────────────────────┘`.replace(/^ +/gm, '  '),\n      );\n      this.logger.info(\n        `\n        wuid: ${formattedWuid}\n        name: ${formattedName}\n      `,\n      );\n\n      await this.prismaRepository.instance.update({\n        where: { id: this.instanceId },\n        data: {\n          ownerJid: this.instance.wuid,\n          profileName: (await this.getProfileName()) as string,\n          profilePicUrl: this.instance.profilePictureUrl,\n          connectionStatus: 'open',\n        },\n      });\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n        this.chatwootService.eventWhatsapp(\n          Events.CONNECTION_UPDATE,\n          { instanceName: this.instance.name, instanceId: this.instanceId },\n          { instance: this.instance.name, status: 'open' },\n        );\n        this.syncChatwootLostMessages();\n      }\n\n      this.sendDataWebhook(Events.CONNECTION_UPDATE, {\n        instance: this.instance.name,\n        wuid: this.instance.wuid,\n        profileName: await this.getProfileName(),\n        profilePictureUrl: this.instance.profilePictureUrl,\n        ...this.stateConnection,\n      });\n    }\n\n    if (connection === 'connecting') {\n      this.sendDataWebhook(Events.CONNECTION_UPDATE, { instance: this.instance.name, ...this.stateConnection });\n    }\n  }\n\n  private async getMessage(key: proto.IMessageKey, full = false) {\n    try {\n      // Use raw SQL to avoid JSON path issues\n      const webMessageInfo = (await this.prismaRepository.$queryRaw`\n        SELECT * FROM \"Message\"\n        WHERE \"instanceId\" = ${this.instanceId}\n        AND \"key\"->>'id' = ${key.id}\n      `) as proto.IWebMessageInfo[];\n\n      if (full) {\n        return webMessageInfo[0];\n      }\n      if (webMessageInfo[0].message?.pollCreationMessage) {\n        const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret;\n\n        if (typeof messageSecretBase64 === 'string') {\n          const messageSecret = Buffer.from(messageSecretBase64, 'base64');\n\n          const msg = {\n            messageContextInfo: { messageSecret },\n            pollCreationMessage: webMessageInfo[0].message?.pollCreationMessage,\n          };\n\n          return msg;\n        }\n      }\n\n      return webMessageInfo[0].message;\n    } catch {\n      return { conversation: '' };\n    }\n  }\n\n  private async defineAuthState() {\n    const db = this.configService.get<Database>('DATABASE');\n    const cache = this.configService.get<CacheConf>('CACHE');\n\n    const provider = this.configService.get<ProviderSession>('PROVIDER');\n\n    if (provider?.ENABLED) {\n      return await this.authStateProvider.authStateProvider(this.instance.id);\n    }\n\n    if (cache?.REDIS.ENABLED && cache?.REDIS.SAVE_INSTANCES) {\n      this.logger.info('Redis enabled');\n      return await useMultiFileAuthStateRedisDb(this.instance.id, this.cache);\n    }\n\n    if (db.SAVE_DATA.INSTANCE) {\n      return await useMultiFileAuthStatePrisma(this.instance.id, this.cache);\n    }\n  }\n\n  private async createClient(number?: string): Promise<WASocket> {\n    this.instance.authState = await this.defineAuthState();\n\n    const session = this.configService.get<ConfigSessionPhone>('CONFIG_SESSION_PHONE');\n\n    let browserOptions = {};\n\n    if (number || this.phoneNumber) {\n      this.phoneNumber = number;\n\n      this.logger.info(`Phone number: ${number}`);\n    } else {\n      const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()];\n      browserOptions = { browser };\n\n      this.logger.info(`Browser: ${browser}`);\n    }\n\n    const baileysVersion = await fetchLatestWaWebVersion({});\n    const version = baileysVersion.version;\n    const log = `Baileys version: ${version.join('.')}`;\n\n    this.logger.info(log);\n\n    this.logger.info(`Group Ignore: ${this.localSettings.groupsIgnore}`);\n\n    let options;\n\n    if (this.localProxy?.enabled) {\n      this.logger.info('Proxy enabled: ' + this.localProxy?.host);\n\n      if (this.localProxy?.host?.includes('proxyscrape')) {\n        try {\n          const response = await axios.get(this.localProxy?.host);\n          const text = response.data;\n          const proxyUrls = text.split('\\r\\n');\n          const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length));\n          const proxyUrl = 'http://' + proxyUrls[rand];\n          options = { agent: makeProxyAgent(proxyUrl), fetchAgent: makeProxyAgentUndici(proxyUrl) };\n        } catch {\n          this.localProxy.enabled = false;\n        }\n      } else {\n        options = {\n          agent: makeProxyAgent({\n            host: this.localProxy.host,\n            port: this.localProxy.port,\n            protocol: this.localProxy.protocol,\n            username: this.localProxy.username,\n            password: this.localProxy.password,\n          }),\n          fetchAgent: makeProxyAgentUndici({\n            host: this.localProxy.host,\n            port: this.localProxy.port,\n            protocol: this.localProxy.protocol,\n            username: this.localProxy.username,\n            password: this.localProxy.password,\n          }),\n        };\n      }\n    }\n\n    const socketConfig: UserFacingSocketConfig = {\n      ...options,\n      version,\n      logger: P({ level: this.logBaileys }),\n      printQRInTerminal: false,\n      auth: {\n        creds: this.instance.authState.state.creds,\n        keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any),\n      },\n      msgRetryCounterCache: this.msgRetryCounterCache,\n      generateHighQualityLinkPreview: true,\n      getMessage: async (key) => (await this.getMessage(key)) as Promise<proto.IMessage>,\n      ...browserOptions,\n      markOnlineOnConnect: this.localSettings.alwaysOnline,\n      retryRequestDelayMs: 350,\n      maxMsgRetryCount: 4,\n      fireInitQueries: true,\n      connectTimeoutMs: 30_000,\n      keepAliveIntervalMs: 30_000,\n      qrTimeout: 45_000,\n      emitOwnEvents: false,\n      shouldIgnoreJid: (jid) => {\n        if (this.localSettings.syncFullHistory && isJidGroup(jid)) {\n          return false;\n        }\n\n        const isGroupJid = this.localSettings.groupsIgnore && isJidGroup(jid);\n        const isBroadcast = !this.localSettings.readStatus && isJidBroadcast(jid);\n        const isNewsletter = isJidNewsletter(jid);\n\n        return isGroupJid || isBroadcast || isNewsletter;\n      },\n      syncFullHistory: this.localSettings.syncFullHistory,\n      shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => {\n        return this.historySyncNotification(msg);\n      },\n      cachedGroupMetadata: this.getGroupMetadataCache,\n      userDevicesCache: this.userDevicesCache,\n      transactionOpts: { maxCommitRetries: 10, delayBetweenTriesMs: 3000 },\n      patchMessageBeforeSending(message) {\n        if (\n          message.deviceSentMessage?.message?.listMessage?.listType === proto.Message.ListMessage.ListType.PRODUCT_LIST\n        ) {\n          message = JSON.parse(JSON.stringify(message));\n\n          message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;\n        }\n\n        if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) {\n          message = JSON.parse(JSON.stringify(message));\n\n          message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;\n        }\n\n        return message;\n      },\n    };\n\n    this.endSession = false;\n\n    this.client = makeWASocket(socketConfig);\n\n    if (this.localSettings.wavoipToken && this.localSettings.wavoipToken.length > 0) {\n      useVoiceCallsBaileys(this.localSettings.wavoipToken, this.client, this.connectionStatus.state as any, true);\n    }\n\n    this.eventHandler();\n\n    this.client.ws.on('CB:call', (packet) => {\n      console.log('CB:call', packet);\n      const payload = { event: 'CB:call', packet: packet };\n      this.sendDataWebhook(Events.CALL, payload, true, ['websocket']);\n    });\n\n    this.client.ws.on('CB:ack,class:call', (packet) => {\n      console.log('CB:ack,class:call', packet);\n      const payload = { event: 'CB:ack,class:call', packet: packet };\n      this.sendDataWebhook(Events.CALL, payload, true, ['websocket']);\n    });\n\n    this.phoneNumber = number;\n\n    return this.client;\n  }\n\n  public async connectToWhatsapp(number?: string): Promise<WASocket> {\n    try {\n      this.loadChatwoot();\n      this.loadSettings();\n      this.loadWebhook();\n      this.loadProxy();\n\n      // Remontar o messageProcessor para garantir que está funcionando após reconexão\n      this.messageProcessor.mount({\n        onMessageReceive: this.messageHandle['messages.upsert'].bind(this),\n      });\n\n      return await this.createClient(number);\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString());\n    }\n  }\n\n  public async reloadConnection(): Promise<WASocket> {\n    try {\n      return await this.createClient(this.phoneNumber);\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString());\n    }\n  }\n\n  private readonly chatHandle = {\n    'chats.upsert': async (chats: Chat[]) => {\n      const existingChatIds = await this.prismaRepository.chat.findMany({\n        where: { instanceId: this.instanceId },\n        select: { remoteJid: true },\n      });\n\n      const existingChatIdSet = new Set(existingChatIds.map((chat) => chat.remoteJid));\n\n      const chatsToInsert = chats\n        .filter((chat) => !existingChatIdSet?.has(chat.id))\n        .map((chat) => ({\n          remoteJid: chat.id,\n          instanceId: this.instanceId,\n          name: chat.name,\n          unreadMessages: chat.unreadCount !== undefined ? chat.unreadCount : 0,\n        }));\n\n      this.sendDataWebhook(Events.CHATS_UPSERT, chatsToInsert);\n\n      if (chatsToInsert.length > 0) {\n        if (this.configService.get<Database>('DATABASE').SAVE_DATA.CHATS)\n          await this.prismaRepository.chat.createMany({ data: chatsToInsert, skipDuplicates: true });\n      }\n    },\n\n    'chats.update': async (\n      chats: Partial<\n        proto.IConversation & { lastMessageRecvTimestamp?: number } & {\n          conditional: (bufferedData: BufferedEventData) => boolean;\n        }\n      >[],\n    ) => {\n      const chatsRaw = chats.map((chat) => {\n        return { remoteJid: chat.id, instanceId: this.instanceId };\n      });\n\n      this.sendDataWebhook(Events.CHATS_UPDATE, chatsRaw);\n\n      for (const chat of chats) {\n        await this.prismaRepository.chat.updateMany({\n          where: { instanceId: this.instanceId, remoteJid: chat.id, name: chat.name },\n          data: { remoteJid: chat.id },\n        });\n      }\n    },\n\n    'chats.delete': async (chats: string[]) => {\n      chats.forEach(\n        async (chat) =>\n          await this.prismaRepository.chat.deleteMany({ where: { instanceId: this.instanceId, remoteJid: chat } }),\n      );\n\n      this.sendDataWebhook(Events.CHATS_DELETE, [...chats]);\n    },\n  };\n\n  private readonly contactHandle = {\n    'contacts.upsert': async (contacts: Contact[]) => {\n      try {\n        const contactsRaw: any = contacts.map((contact) => ({\n          remoteJid: contact.id,\n          pushName: contact?.name || contact?.verifiedName || contact.id.split('@')[0],\n          profilePicUrl: null,\n          instanceId: this.instanceId,\n        }));\n\n        if (contactsRaw.length > 0) {\n          this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw);\n\n          if (this.configService.get<Database>('DATABASE').SAVE_DATA.CONTACTS)\n            await this.prismaRepository.contact.createMany({ data: contactsRaw, skipDuplicates: true });\n\n          const usersContacts = contactsRaw.filter((c) => c.remoteJid.includes('@s.whatsapp'));\n          if (usersContacts) {\n            await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.remoteJid })));\n          }\n        }\n\n        if (\n          this.configService.get<Chatwoot>('CHATWOOT').ENABLED &&\n          this.localChatwoot?.enabled &&\n          this.localChatwoot.importContacts &&\n          contactsRaw.length\n        ) {\n          this.chatwootService.addHistoryContacts(\n            { instanceName: this.instance.name, instanceId: this.instance.id },\n            contactsRaw,\n          );\n          chatwootImport.importHistoryContacts(\n            { instanceName: this.instance.name, instanceId: this.instance.id },\n            this.localChatwoot,\n          );\n        }\n\n        const updatedContacts = await Promise.all(\n          contacts.map(async (contact) => ({\n            remoteJid: contact.id,\n            pushName: contact?.name || contact?.verifiedName || contact.id.split('@')[0],\n            profilePicUrl: (await this.profilePicture(contact.id)).profilePictureUrl,\n            instanceId: this.instanceId,\n          })),\n        );\n\n        if (updatedContacts.length > 0) {\n          const usersContacts = updatedContacts.filter((c) => c.remoteJid.includes('@s.whatsapp'));\n          if (usersContacts) {\n            await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.remoteJid })));\n          }\n\n          this.sendDataWebhook(Events.CONTACTS_UPDATE, updatedContacts);\n          await Promise.all(\n            updatedContacts.map(async (contact) => {\n              if (this.configService.get<Database>('DATABASE').SAVE_DATA.CONTACTS) {\n                await this.prismaRepository.contact.updateMany({\n                  where: { remoteJid: contact.remoteJid, instanceId: this.instanceId },\n                  data: { profilePicUrl: contact.profilePicUrl },\n                });\n              }\n\n              if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n                const instance = { instanceName: this.instance.name, instanceId: this.instance.id };\n\n                const findParticipant = await this.chatwootService.findContact(\n                  instance,\n                  contact.remoteJid.split('@')[0],\n                );\n\n                if (!findParticipant) {\n                  return;\n                }\n\n                this.chatwootService.updateContact(instance, findParticipant.id, {\n                  name: contact.pushName,\n                  avatar_url: contact.profilePicUrl,\n                });\n              }\n            }),\n          );\n        }\n      } catch (error) {\n        console.error(error);\n        this.logger.error(`Error: ${error.message}`);\n      }\n    },\n\n    'contacts.update': async (contacts: Partial<Contact>[]) => {\n      const contactsRaw: { remoteJid: string; pushName?: string; profilePicUrl?: string; instanceId: string }[] = [];\n      for await (const contact of contacts) {\n        this.logger.debug(`Updating contact: ${JSON.stringify(contact, null, 2)}`);\n        contactsRaw.push({\n          remoteJid: contact.id,\n          pushName: contact?.name ?? contact?.verifiedName,\n          profilePicUrl: (await this.profilePicture(contact.id)).profilePictureUrl,\n          instanceId: this.instanceId,\n        });\n      }\n\n      this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw);\n\n      if (this.configService.get<Database>('DATABASE').SAVE_DATA.CONTACTS) {\n        const updateTransactions = contactsRaw.map((contact) =>\n          this.prismaRepository.contact.upsert({\n            where: { remoteJid_instanceId: { remoteJid: contact.remoteJid, instanceId: contact.instanceId } },\n            create: contact,\n            update: contact,\n          }),\n        );\n        await this.prismaRepository.$transaction(updateTransactions);\n      }\n\n      //const usersContacts = contactsRaw.filter((c) => c.remoteJid.includes('@s.whatsapp'));\n    },\n  };\n\n  private readonly messageHandle = {\n    'messaging-history.set': async ({\n      messages,\n      chats,\n      contacts,\n      isLatest,\n      progress,\n      syncType,\n    }: {\n      chats: Chat[];\n      contacts: Contact[];\n      messages: WAMessage[];\n      isLatest?: boolean;\n      progress?: number;\n      syncType?: proto.HistorySync.HistorySyncType;\n    }) => {\n      try {\n        if (syncType === proto.HistorySync.HistorySyncType.ON_DEMAND) {\n          console.log('received on-demand history sync, messages=', messages);\n        }\n        console.log(\n          `recv ${chats.length} chats, ${contacts.length} contacts, ${messages.length} msgs (is latest: ${isLatest}, progress: ${progress}%), type: ${syncType}`,\n        );\n\n        const instance: InstanceDto = { instanceName: this.instance.name };\n\n        let timestampLimitToImport = null;\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n          const daysLimitToImport = this.localChatwoot?.enabled ? this.localChatwoot.daysLimitImportMessages : 1000;\n\n          const date = new Date();\n          timestampLimitToImport = new Date(date.setDate(date.getDate() - daysLimitToImport)).getTime() / 1000;\n\n          const maxBatchTimestamp = Math.max(...messages.map((message) => message.messageTimestamp as number));\n\n          const processBatch = maxBatchTimestamp >= timestampLimitToImport;\n\n          if (!processBatch) {\n            return;\n          }\n        }\n\n        const contactsMap = new Map();\n\n        for (const contact of contacts) {\n          if (contact.id && (contact.notify || contact.name)) {\n            contactsMap.set(contact.id, { name: contact.name ?? contact.notify, jid: contact.id });\n          }\n        }\n\n        const chatsRaw: { remoteJid: string; instanceId: string; name?: string }[] = [];\n        const chatsRepository = new Set(\n          (await this.prismaRepository.chat.findMany({ where: { instanceId: this.instanceId } })).map(\n            (chat) => chat.remoteJid,\n          ),\n        );\n\n        for (const chat of chats) {\n          if (chatsRepository?.has(chat.id)) {\n            continue;\n          }\n\n          chatsRaw.push({ remoteJid: chat.id, instanceId: this.instanceId, name: chat.name });\n        }\n\n        this.sendDataWebhook(Events.CHATS_SET, chatsRaw);\n\n        if (this.configService.get<Database>('DATABASE').SAVE_DATA.HISTORIC) {\n          await this.prismaRepository.chat.createMany({ data: chatsRaw, skipDuplicates: true });\n        }\n\n        const messagesRaw: any[] = [];\n\n        const messagesRepository: Set<string> = new Set(\n          chatwootImport.getRepositoryMessagesCache(instance) ??\n            (\n              await this.prismaRepository.message.findMany({\n                select: { key: true },\n                where: { instanceId: this.instanceId },\n              })\n            ).map((message) => {\n              const key = message.key as { id: string };\n\n              return key.id;\n            }),\n        );\n\n        if (chatwootImport.getRepositoryMessagesCache(instance) === null) {\n          chatwootImport.setRepositoryMessagesCache(instance, messagesRepository);\n        }\n\n        for (const m of messages) {\n          if (!m.message || !m.key || !m.messageTimestamp) {\n            continue;\n          }\n\n          if (Long.isLong(m?.messageTimestamp)) {\n            m.messageTimestamp = m.messageTimestamp?.toNumber();\n          }\n\n          if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n            if (m.messageTimestamp <= timestampLimitToImport) {\n              continue;\n            }\n          }\n\n          if (messagesRepository?.has(m.key.id)) {\n            continue;\n          }\n\n          if (!m.pushName && !m.key.fromMe) {\n            const participantJid = m.participant || m.key.participant || m.key.remoteJid;\n            if (participantJid && contactsMap.has(participantJid)) {\n              m.pushName = contactsMap.get(participantJid).name;\n            } else if (participantJid) {\n              m.pushName = participantJid.split('@')[0];\n            }\n          }\n\n          messagesRaw.push(this.prepareMessage(m));\n        }\n\n        this.sendDataWebhook(Events.MESSAGES_SET, [...messagesRaw], true, undefined, {\n          isLatest,\n          progress,\n        });\n\n        if (this.configService.get<Database>('DATABASE').SAVE_DATA.HISTORIC) {\n          await this.prismaRepository.message.createMany({ data: messagesRaw, skipDuplicates: true });\n        }\n\n        if (\n          this.configService.get<Chatwoot>('CHATWOOT').ENABLED &&\n          this.localChatwoot?.enabled &&\n          this.localChatwoot.importMessages &&\n          messagesRaw.length > 0\n        ) {\n          this.chatwootService.addHistoryMessages(\n            instance,\n            messagesRaw.filter((msg) => !chatwootImport.isIgnorePhoneNumber(msg.key?.remoteJid)),\n          );\n        }\n\n        await this.contactHandle['contacts.upsert'](\n          contacts.filter((c) => !!c.notify || !!c.name).map((c) => ({ id: c.id, name: c.name ?? c.notify })),\n        );\n\n        contacts = undefined;\n        messages = undefined;\n        chats = undefined;\n      } catch (error) {\n        this.logger.error(error);\n      }\n    },\n\n    'messages.upsert': async (\n      { messages, type, requestId }: { messages: WAMessage[]; type: MessageUpsertType; requestId?: string },\n      settings: any,\n    ) => {\n      try {\n        for (const received of messages) {\n          if (\n            received?.messageStubParameters?.some?.((param) =>\n              [\n                'No matching sessions found for message',\n                'Bad MAC',\n                'failed to decrypt message',\n                'SessionError',\n                'Invalid PreKey ID',\n                'No session record',\n                'No session found to decrypt message',\n                'Message absent from node',\n              ].some((err) => param?.includes?.(err)),\n            )\n          ) {\n            this.logger.warn(`Message ignored with messageStubParameters: ${JSON.stringify(received, null, 2)}`);\n            continue;\n          }\n          if (received.message?.conversation || received.message?.extendedTextMessage?.text) {\n            const text = received.message?.conversation || received.message?.extendedTextMessage?.text;\n\n            if (text == 'requestPlaceholder' && !requestId) {\n              const messageId = await this.client.requestPlaceholderResend(received.key);\n\n              console.log('requested placeholder resync, id=', messageId);\n            } else if (requestId) {\n              console.log('Message received from phone, id=', requestId, received);\n            }\n\n            if (text == 'onDemandHistSync') {\n              const messageId = await this.client.fetchMessageHistory(50, received.key, received.messageTimestamp!);\n              console.log('requested on-demand sync, id=', messageId);\n            }\n          }\n\n          const editedMessage =\n            received?.message?.protocolMessage || received?.message?.editedMessage?.message?.protocolMessage;\n\n          if (editedMessage) {\n            if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled)\n              this.chatwootService.eventWhatsapp(\n                'messages.edit',\n                { instanceName: this.instance.name, instanceId: this.instance.id },\n                editedMessage,\n              );\n\n            await this.sendDataWebhook(Events.MESSAGES_EDITED, editedMessage);\n\n            if (received.key?.id && editedMessage.key?.id) {\n              await this.baileysCache.set(`protocol_${received.key.id}`, editedMessage.key.id, 60 * 60 * 24);\n            }\n\n            const oldMessage = await this.getMessage(editedMessage.key, true);\n            if ((oldMessage as any)?.id) {\n              const editedMessageTimestamp = Long.isLong(received?.messageTimestamp)\n                ? Math.floor(received?.messageTimestamp.toNumber())\n                : Math.floor(received?.messageTimestamp as number);\n\n              await this.prismaRepository.message.update({\n                where: { id: (oldMessage as any).id },\n                data: {\n                  message: editedMessage.editedMessage as any,\n                  messageTimestamp: editedMessageTimestamp,\n                  status: 'EDITED',\n                },\n              });\n              await this.prismaRepository.messageUpdate.create({\n                data: {\n                  fromMe: editedMessage.key.fromMe,\n                  keyId: editedMessage.key.id,\n                  remoteJid: editedMessage.key.remoteJid,\n                  status: 'EDITED',\n                  instanceId: this.instanceId,\n                  messageId: (oldMessage as any).id,\n                },\n              });\n            }\n          }\n\n          if ((type !== 'notify' && type !== 'append') || editedMessage || !received?.message) {\n            continue;\n          }\n\n          if (Long.isLong(received.messageTimestamp)) {\n            received.messageTimestamp = received.messageTimestamp?.toNumber();\n          }\n\n          if (settings?.groupsIgnore && received.key.remoteJid.includes('@g.us')) {\n            continue;\n          }\n\n          const existingChat = await this.prismaRepository.chat.findFirst({\n            where: { instanceId: this.instanceId, remoteJid: received.key.remoteJid },\n            select: { id: true, name: true },\n          });\n\n          if (\n            existingChat &&\n            received.pushName &&\n            existingChat.name !== received.pushName &&\n            received.pushName.trim().length > 0 &&\n            !received.key.fromMe &&\n            !received.key.remoteJid.includes('@g.us')\n          ) {\n            this.sendDataWebhook(Events.CHATS_UPSERT, [{ ...existingChat, name: received.pushName }]);\n            if (this.configService.get<Database>('DATABASE').SAVE_DATA.CHATS) {\n              try {\n                await this.prismaRepository.chat.update({\n                  where: { id: existingChat.id },\n                  data: { name: received.pushName },\n                });\n              } catch {\n                console.log(`Chat insert record ignored: ${received.key.remoteJid} - ${this.instanceId}`);\n              }\n            }\n          }\n\n          const messageRaw = this.prepareMessage(received);\n\n          if (messageRaw.messageType === 'pollUpdateMessage') {\n            const pollCreationKey = messageRaw.message.pollUpdateMessage.pollCreationMessageKey;\n            const pollMessage = (await this.getMessage(pollCreationKey, true)) as proto.IWebMessageInfo;\n            const pollMessageSecret = (await this.getMessage(pollCreationKey)) as any;\n\n            if (pollMessage) {\n              const pollOptions =\n                (pollMessage.message as any).pollCreationMessage?.options ||\n                (pollMessage.message as any).pollCreationMessageV3?.options ||\n                [];\n              const pollVote = messageRaw.message.pollUpdateMessage.vote;\n\n              const voterJid = received.key.fromMe\n                ? this.instance.wuid\n                : received.key.participant || received.key.remoteJid;\n\n              let pollEncKey = pollMessageSecret?.messageContextInfo?.messageSecret;\n\n              let successfulVoterJid = voterJid;\n\n              if (typeof pollEncKey === 'string') {\n                pollEncKey = Buffer.from(pollEncKey, 'base64');\n              } else if (pollEncKey?.type === 'Buffer' && Array.isArray(pollEncKey.data)) {\n                pollEncKey = Buffer.from(pollEncKey.data);\n              }\n\n              if (Buffer.isBuffer(pollEncKey) && pollEncKey.length === 44) {\n                pollEncKey = Buffer.from(pollEncKey.toString('utf8'), 'base64');\n              }\n\n              if (pollVote.encPayload && pollEncKey) {\n                const creatorCandidates = [\n                  this.instance.wuid,\n                  this.client.user?.lid,\n                  pollMessage.key.participant,\n                  (pollMessage.key as any).participantAlt,\n                  pollMessage.key.remoteJid,\n                ];\n\n                const key = received.key as any;\n                const voterCandidates = [\n                  this.instance.wuid,\n                  this.client.user?.lid,\n                  key.participant,\n                  key.participantAlt,\n                  key.remoteJidAlt,\n                  key.remoteJid,\n                ];\n\n                const uniqueCreators = [\n                  ...new Set(creatorCandidates.filter(Boolean).map((id) => jidNormalizedUser(id))),\n                ];\n                const uniqueVoters = [...new Set(voterCandidates.filter(Boolean).map((id) => jidNormalizedUser(id)))];\n\n                let decryptedVote;\n\n                for (const creator of uniqueCreators) {\n                  for (const voter of uniqueVoters) {\n                    try {\n                      decryptedVote = decryptPollVote(pollVote, {\n                        pollCreatorJid: creator,\n                        pollMsgId: pollMessage.key.id,\n                        pollEncKey,\n                        voterJid: voter,\n                      } as any);\n                      if (decryptedVote) {\n                        successfulVoterJid = voter;\n                        break;\n                      }\n                    } catch {\n                      // Continue trying\n                    }\n                  }\n                  if (decryptedVote) break;\n                }\n\n                if (decryptedVote) {\n                  Object.assign(pollVote, decryptedVote);\n                }\n              }\n\n              const selectedOptions = pollVote?.selectedOptions || [];\n\n              const selectedOptionNames = pollOptions\n                .filter((option) => {\n                  const hash = createHash('sha256').update(option.optionName).digest();\n                  return selectedOptions.some((selected) => Buffer.compare(selected, hash) === 0);\n                })\n                .map((option) => option.optionName);\n\n              messageRaw.message.pollUpdateMessage.vote.selectedOptions = selectedOptionNames;\n\n              const pollUpdates = pollOptions.map((option) => ({\n                name: option.optionName,\n                voters: selectedOptionNames.includes(option.optionName) ? [successfulVoterJid] : [],\n              }));\n\n              messageRaw.pollUpdates = pollUpdates;\n            }\n          }\n\n          const isMedia =\n            received?.message?.imageMessage ||\n            received?.message?.videoMessage ||\n            received?.message?.stickerMessage ||\n            received?.message?.documentMessage ||\n            received?.message?.documentWithCaptionMessage ||\n            received?.message?.ptvMessage ||\n            received?.message?.audioMessage;\n\n          const isVideo = received?.message?.videoMessage;\n\n          if (this.localSettings.readMessages && received.key.id !== 'status@broadcast') {\n            await this.client.readMessages([received.key]);\n          }\n\n          if (this.localSettings.readStatus && received.key.id === 'status@broadcast') {\n            await this.client.readMessages([received.key]);\n          }\n\n          if (\n            this.configService.get<Chatwoot>('CHATWOOT').ENABLED &&\n            this.localChatwoot?.enabled &&\n            !received.key.id.includes('@broadcast')\n          ) {\n            const chatwootSentMessage = await this.chatwootService.eventWhatsapp(\n              Events.MESSAGES_UPSERT,\n              { instanceName: this.instance.name, instanceId: this.instanceId },\n              messageRaw,\n            );\n\n            if (chatwootSentMessage?.id) {\n              messageRaw.chatwootMessageId = chatwootSentMessage.id;\n              messageRaw.chatwootInboxId = chatwootSentMessage.inbox_id;\n              messageRaw.chatwootConversationId = chatwootSentMessage.conversation_id;\n            }\n          }\n\n          if (this.configService.get<Openai>('OPENAI').ENABLED && received?.message?.audioMessage) {\n            const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({\n              where: { instanceId: this.instanceId },\n              include: { OpenaiCreds: true },\n            });\n\n            if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {\n              messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(received, this)}`;\n            }\n          }\n\n          if (this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE) {\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n            const { pollUpdates, ...messageData } = messageRaw;\n            const msg = await this.prismaRepository.message.create({ data: messageData });\n\n            const { remoteJid } = received.key;\n            const timestamp = msg.messageTimestamp;\n            const fromMe = received.key.fromMe.toString();\n            const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;\n\n            const cachedTimestamp = await this.baileysCache.get(messageKey);\n\n            if (!cachedTimestamp) {\n              if (!received.key.fromMe) {\n                if (msg.status === status[3]) {\n                  this.logger.log(`Update not read messages ${remoteJid}`);\n                  await this.updateChatUnreadMessages(remoteJid);\n                } else if (msg.status === status[4]) {\n                  this.logger.log(`Update readed messages ${remoteJid} - ${timestamp}`);\n                  await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);\n                }\n              } else {\n                // is send message by me\n                this.logger.log(`Update readed messages ${remoteJid} - ${timestamp}`);\n                await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);\n              }\n\n              await this.baileysCache.set(messageKey, true, this.MESSAGE_CACHE_TTL_SECONDS);\n            } else {\n              this.logger.info(`Update readed messages duplicated ignored [avoid deadlock]: ${messageKey}`);\n            }\n\n            if (isMedia) {\n              if (this.configService.get<S3>('S3').ENABLE) {\n                try {\n                  if (isVideo && !this.configService.get<S3>('S3').SAVE_VIDEO) {\n                    this.logger.warn('Video upload is disabled. Skipping video upload.');\n                    // Skip video upload by returning early from this block\n                    return;\n                  }\n\n                  const message: any = received;\n\n                  // Verificação adicional para garantir que há conteúdo de mídia real\n                  const hasRealMedia = this.hasValidMediaContent(message);\n\n                  if (!hasRealMedia) {\n                    this.logger.warn('Message detected as media but contains no valid media content');\n                  } else {\n                    const media = await this.getBase64FromMediaMessage({ message }, true);\n\n                    if (!media) {\n                      this.logger.verbose('No valid media to upload (messageContextInfo only), skipping MinIO');\n                      return;\n                    }\n\n                    const { buffer, mediaType, fileName, size } = media;\n                    const mimetype = mimeTypes.lookup(fileName).toString();\n                    const fullName = join(\n                      `${this.instance.id}`,\n                      received.key.remoteJid,\n                      mediaType,\n                      `${Date.now()}_${fileName}`,\n                    );\n                    await s3Service.uploadFile(fullName, buffer, size.fileLength?.low, { 'Content-Type': mimetype });\n\n                    await this.prismaRepository.media.create({\n                      data: {\n                        messageId: msg.id,\n                        instanceId: this.instanceId,\n                        type: mediaType,\n                        fileName: fullName,\n                        mimetype,\n                      },\n                    });\n\n                    const mediaUrl = await s3Service.getObjectUrl(fullName);\n\n                    messageRaw.message.mediaUrl = mediaUrl;\n\n                    await this.prismaRepository.message.update({ where: { id: msg.id }, data: messageRaw });\n                  }\n                } catch (error) {\n                  this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);\n                }\n              }\n            }\n          }\n\n          if (this.localWebhook.enabled) {\n            if (isMedia && this.localWebhook.webhookBase64) {\n              try {\n                const buffer = await downloadMediaMessage(\n                  { key: received.key, message: received?.message },\n                  'buffer',\n                  {},\n                  { logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },\n                );\n\n                if (buffer) {\n                  messageRaw.message.base64 = buffer.toString('base64');\n                } else {\n                  // retry to download media\n                  const buffer = await downloadMediaMessage(\n                    { key: received.key, message: received?.message },\n                    'buffer',\n                    {},\n                    { logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },\n                  );\n\n                  if (buffer) {\n                    messageRaw.message.base64 = buffer.toString('base64');\n                  }\n                }\n              } catch (error) {\n                this.logger.error(['Error converting media to base64', error?.message]);\n              }\n            }\n          }\n\n          this.logger.verbose(messageRaw);\n\n          sendTelemetry(`received.message.${messageRaw.messageType ?? 'unknown'}`);\n          if (messageRaw.key.remoteJid?.includes('@lid') && messageRaw.key.remoteJidAlt) {\n            messageRaw.key.remoteJid = messageRaw.key.remoteJidAlt;\n          }\n          console.log(messageRaw);\n\n          this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw);\n\n          await chatbotController.emit({\n            instance: { instanceName: this.instance.name, instanceId: this.instanceId },\n            remoteJid: messageRaw.key.remoteJid,\n            msg: messageRaw,\n            pushName: messageRaw.pushName,\n          });\n\n          const contact = await this.prismaRepository.contact.findFirst({\n            where: { remoteJid: received.key.remoteJid, instanceId: this.instanceId },\n          });\n\n          const contactRaw: {\n            remoteJid: string;\n            pushName: string;\n            profilePicUrl?: string;\n            instanceId: string;\n          } = {\n            remoteJid: received.key.remoteJid,\n            pushName: received.key.fromMe ? '' : received.key.fromMe == null ? '' : received.pushName,\n            profilePicUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl,\n            instanceId: this.instanceId,\n          };\n\n          if (contactRaw.remoteJid === 'status@broadcast') {\n            continue;\n          }\n\n          if (contactRaw.remoteJid.includes('@s.whatsapp') || contactRaw.remoteJid.includes('@lid')) {\n            await saveOnWhatsappCache([\n              {\n                remoteJid:\n                  messageRaw.key.addressingMode === 'lid' ? messageRaw.key.remoteJidAlt : messageRaw.key.remoteJid,\n                remoteJidAlt: messageRaw.key.remoteJidAlt,\n                lid: messageRaw.key.addressingMode === 'lid' ? 'lid' : null,\n              },\n            ]);\n          }\n\n          if (contact) {\n            this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw);\n\n            if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n              await this.chatwootService.eventWhatsapp(\n                Events.CONTACTS_UPDATE,\n                { instanceName: this.instance.name, instanceId: this.instanceId },\n                contactRaw,\n              );\n            }\n\n            if (this.configService.get<Database>('DATABASE').SAVE_DATA.CONTACTS)\n              await this.prismaRepository.contact.upsert({\n                where: { remoteJid_instanceId: { remoteJid: contactRaw.remoteJid, instanceId: contactRaw.instanceId } },\n                create: contactRaw,\n                update: contactRaw,\n              });\n\n            continue;\n          }\n\n          this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);\n\n          if (this.configService.get<Database>('DATABASE').SAVE_DATA.CONTACTS)\n            await this.prismaRepository.contact.upsert({\n              where: { remoteJid_instanceId: { remoteJid: contactRaw.remoteJid, instanceId: contactRaw.instanceId } },\n              update: contactRaw,\n              create: contactRaw,\n            });\n        }\n      } catch (error) {\n        this.logger.error(error);\n      }\n    },\n\n    'messages.update': async (args: { update: Partial<WAMessage>; key: WAMessageKey }[], settings: any) => {\n      this.logger.verbose(`Update messages ${JSON.stringify(args, undefined, 2)}`);\n\n      const readChatToUpdate: Record<string, true> = {}; // {remoteJid: true}\n\n      for await (const { key, update } of args) {\n        if (settings?.groupsIgnore && key.remoteJid?.includes('@g.us')) {\n          continue;\n        }\n\n        const updateKey = `${this.instance.id}_${key.id}_${update.status}`;\n\n        const cached = await this.baileysCache.get(updateKey);\n\n        const secondsSinceEpoch = Math.floor(Date.now() / 1000);\n        console.log('CACHE:', { cached, updateKey, messageTimestamp: update.messageTimestamp, secondsSinceEpoch });\n\n        if (\n          (update.messageTimestamp && update.messageTimestamp === cached) ||\n          (!update.messageTimestamp && secondsSinceEpoch === cached)\n        ) {\n          this.logger.info(`Update Message duplicated ignored [avoid deadlock]: ${updateKey}`);\n          continue;\n        }\n\n        if (update.messageTimestamp) {\n          await this.baileysCache.set(updateKey, update.messageTimestamp, 30 * 60);\n        } else {\n          await this.baileysCache.set(updateKey, secondsSinceEpoch, 30 * 60);\n        }\n\n        if (status[update.status] === 'READ' && key.fromMe) {\n          if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n            this.chatwootService.eventWhatsapp(\n              'messages.read',\n              { instanceName: this.instance.name, instanceId: this.instanceId },\n              { key: key },\n            );\n          }\n        }\n\n        if (key.remoteJid !== 'status@broadcast' && key.id !== undefined) {\n          let pollUpdates: any;\n\n          if (update.pollUpdates) {\n            const pollCreation = await this.getMessage(key);\n\n            if (pollCreation) {\n              pollUpdates = getAggregateVotesInPollMessage({\n                message: pollCreation as proto.IMessage,\n                pollUpdates: update.pollUpdates,\n              });\n            }\n          }\n\n          const message: any = {\n            keyId: key.id,\n            remoteJid: key?.remoteJid,\n            fromMe: key.fromMe,\n            participant: key?.participant,\n            status: status[update.status] ?? 'SERVER_ACK',\n            pollUpdates,\n            instanceId: this.instanceId,\n          };\n\n          if (update.message) {\n            message.message = update.message;\n          }\n\n          let findMessage: any;\n          const configDatabaseData = this.configService.get<Database>('DATABASE').SAVE_DATA;\n          if (configDatabaseData.HISTORIC || configDatabaseData.NEW_MESSAGE) {\n            // Use raw SQL to avoid JSON path issues\n            const protocolMapKey = `protocol_${key.id}`;\n            const originalMessageId = (await this.baileysCache.get(protocolMapKey)) as string;\n\n            if (originalMessageId) {\n              message.keyId = originalMessageId;\n            }\n\n            const searchId = originalMessageId || key.id;\n\n            const messages = (await this.prismaRepository.$queryRaw`\n              SELECT * FROM \"Message\"\n              WHERE \"instanceId\" = ${this.instanceId}\n              AND \"key\"->>'id' = ${searchId}\n              LIMIT 1\n            `) as any[];\n            findMessage = messages[0] || null;\n\n            if (!findMessage?.id) {\n              this.logger.warn(`Original message not found for update. Skipping. Key: ${JSON.stringify(key)}`);\n              continue;\n            }\n            message.messageId = findMessage.id;\n          }\n\n          if (update.message === null && update.status === undefined) {\n            this.sendDataWebhook(Events.MESSAGES_DELETE, { ...key, status: 'DELETED' });\n\n            if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE)\n              await this.prismaRepository.messageUpdate.create({ data: message });\n\n            if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n              this.chatwootService.eventWhatsapp(\n                Events.MESSAGES_DELETE,\n                { instanceName: this.instance.name, instanceId: this.instanceId },\n                { key: key },\n              );\n            }\n\n            continue;\n          }\n\n          if (findMessage && update.status !== undefined && status[update.status] !== findMessage.status) {\n            if (!key.fromMe && key.remoteJid) {\n              readChatToUpdate[key.remoteJid] = true;\n\n              const { remoteJid } = key;\n              const timestamp = findMessage.messageTimestamp;\n              const fromMe = key.fromMe.toString();\n              const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;\n\n              const cachedTimestamp = await this.baileysCache.get(messageKey);\n\n              if (!cachedTimestamp) {\n                if (status[update.status] === status[4]) {\n                  this.logger.log(`Update as read in message.update ${remoteJid} - ${timestamp}`);\n                  await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);\n                  await this.baileysCache.set(messageKey, true, this.MESSAGE_CACHE_TTL_SECONDS);\n                }\n\n                await this.prismaRepository.message.update({\n                  where: { id: findMessage.id },\n                  data: { status: status[update.status] },\n                });\n              } else {\n                this.logger.info(\n                  `Update readed messages duplicated ignored in message.update [avoid deadlock]: ${messageKey}`,\n                );\n              }\n            }\n          }\n\n          this.sendDataWebhook(Events.MESSAGES_UPDATE, message);\n\n          if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE) {\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n            const { message: _msg, ...messageData } = message;\n            await this.prismaRepository.messageUpdate.create({ data: messageData });\n          }\n\n          const existingChat = await this.prismaRepository.chat.findFirst({\n            where: { instanceId: this.instanceId, remoteJid: message.remoteJid },\n          });\n\n          if (existingChat) {\n            const chatToInsert = { remoteJid: message.remoteJid, instanceId: this.instanceId, unreadMessages: 0 };\n\n            this.sendDataWebhook(Events.CHATS_UPSERT, [chatToInsert]);\n            if (this.configService.get<Database>('DATABASE').SAVE_DATA.CHATS) {\n              try {\n                await this.prismaRepository.chat.update({ where: { id: existingChat.id }, data: chatToInsert });\n              } catch {\n                console.log(`Chat insert record ignored: ${chatToInsert.remoteJid} - ${chatToInsert.instanceId}`);\n              }\n            }\n          }\n        }\n      }\n\n      await Promise.all(Object.keys(readChatToUpdate).map((remoteJid) => this.updateChatUnreadMessages(remoteJid)));\n    },\n  };\n\n  private readonly groupHandler = {\n    'groups.upsert': (groupMetadata: GroupMetadata[]) => {\n      this.sendDataWebhook(Events.GROUPS_UPSERT, groupMetadata);\n    },\n\n    'groups.update': (groupMetadataUpdate: Partial<GroupMetadata>[]) => {\n      this.sendDataWebhook(Events.GROUPS_UPDATE, groupMetadataUpdate);\n\n      groupMetadataUpdate.forEach((group) => {\n        if (isJidGroup(group.id)) {\n          this.updateGroupMetadataCache(group.id);\n        }\n      });\n    },\n\n    'group-participants.update': async (participantsUpdate: {\n      id: string;\n      participants: string[];\n      action: ParticipantAction;\n    }) => {\n      // ENHANCEMENT: Adds participantsData field while maintaining backward compatibility\n      // MAINTAINS: participants: string[] (original JID strings)\n      // ADDS: participantsData: { jid: string, phoneNumber: string, name?: string, imgUrl?: string }[]\n      // This enables LID to phoneNumber conversion without breaking existing webhook consumers\n\n      // Helper to normalize participantId as phone number\n      const normalizePhoneNumber = (id: string | null | undefined): string => {\n        // Remove @lid, @s.whatsapp.net suffixes and extract just the number part\n        return String(id || '').split('@')[0];\n      };\n\n      try {\n        // Usa o mesmo método que o endpoint /group/participants\n        const groupParticipants = await this.findParticipants({ groupJid: participantsUpdate.id });\n\n        // Validação para garantir que temos dados válidos\n        if (!groupParticipants?.participants || !Array.isArray(groupParticipants.participants)) {\n          throw new Error('Invalid participant data received from findParticipants');\n        }\n\n        // Filtra apenas os participantes que estão no evento\n        const resolvedParticipants = participantsUpdate.participants.map((participantId) => {\n          const participantData = groupParticipants.participants.find((p) => p.id === participantId);\n\n          let phoneNumber: string;\n          if (participantData?.phoneNumber) {\n            phoneNumber = participantData.phoneNumber;\n          } else {\n            phoneNumber = normalizePhoneNumber(participantId);\n          }\n\n          return {\n            jid: participantId,\n            phoneNumber,\n            name: participantData?.name,\n            imgUrl: participantData?.imgUrl,\n          };\n        });\n\n        // Mantém formato original + adiciona dados resolvidos\n        const enhancedParticipantsUpdate = {\n          ...participantsUpdate,\n          participants: participantsUpdate.participants, // Mantém array original de strings\n          // Adiciona dados resolvidos em campo separado\n          participantsData: resolvedParticipants,\n        };\n\n        this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, enhancedParticipantsUpdate);\n      } catch (error) {\n        this.logger.error(\n          `Failed to resolve participant data for GROUP_PARTICIPANTS_UPDATE webhook: ${error.message} | Group: ${participantsUpdate.id} | Participants: ${participantsUpdate.participants.length}`,\n        );\n        // Fallback - envia sem conversão\n        this.sendDataWebhook(Events.GROUP_PARTICIPANTS_UPDATE, participantsUpdate);\n      }\n\n      this.updateGroupMetadataCache(participantsUpdate.id);\n    },\n  };\n\n  private readonly labelHandle = {\n    [Events.LABELS_EDIT]: async (label: Label) => {\n      this.sendDataWebhook(Events.LABELS_EDIT, { ...label, instance: this.instance.name });\n\n      const labelsRepository = await this.prismaRepository.label.findMany({ where: { instanceId: this.instanceId } });\n\n      const savedLabel = labelsRepository.find((l) => l.labelId === label.id);\n      if (label.deleted && savedLabel) {\n        await this.prismaRepository.label.delete({\n          where: { labelId_instanceId: { instanceId: this.instanceId, labelId: label.id } },\n        });\n        this.sendDataWebhook(Events.LABELS_EDIT, { ...label, instance: this.instance.name });\n        return;\n      }\n\n      const labelName = label.name.replace(/[^\\x20-\\x7E]/g, '');\n      if (!savedLabel || savedLabel.color !== `${label.color}` || savedLabel.name !== labelName) {\n        if (this.configService.get<Database>('DATABASE').SAVE_DATA.LABELS) {\n          const labelData = {\n            color: `${label.color}`,\n            name: labelName,\n            labelId: label.id,\n            predefinedId: label.predefinedId,\n            instanceId: this.instanceId,\n          };\n          await this.prismaRepository.label.upsert({\n            where: { labelId_instanceId: { instanceId: labelData.instanceId, labelId: labelData.labelId } },\n            update: labelData,\n            create: labelData,\n          });\n        }\n      }\n    },\n\n    [Events.LABELS_ASSOCIATION]: async (\n      data: { association: LabelAssociation; type: 'remove' | 'add' },\n      database: Database,\n    ) => {\n      this.logger.info(\n        `labels association - ${data?.association?.chatId} (${data.type}-${data?.association?.type}): ${data?.association?.labelId}`,\n      );\n      if (database.SAVE_DATA.CHATS) {\n        const instanceId = this.instanceId;\n        const chatId = data.association.chatId;\n        const labelId = data.association.labelId;\n\n        if (data.type === 'add') {\n          await this.addLabel(labelId, instanceId, chatId);\n        } else if (data.type === 'remove') {\n          await this.removeLabel(labelId, instanceId, chatId);\n        }\n      }\n\n      this.sendDataWebhook(Events.LABELS_ASSOCIATION, {\n        instance: this.instance.name,\n        type: data.type,\n        chatId: data.association.chatId,\n        labelId: data.association.labelId,\n      });\n    },\n  };\n\n  private eventHandler() {\n    this.client.ev.process(async (events) => {\n      this.eventProcessingQueue = this.eventProcessingQueue.then(async () => {\n        try {\n          if (!this.endSession) {\n            const database = this.configService.get<Database>('DATABASE');\n            const settings = await this.findSettings();\n\n            if (events.call) {\n              const call = events.call[0];\n\n              if (settings?.rejectCall && call.status == 'offer') {\n                this.client.rejectCall(call.id, call.from);\n              }\n\n              if (settings?.msgCall?.trim().length > 0 && call.status == 'offer') {\n                if (call.from.endsWith('@lid')) {\n                  call.from = await this.client.signalRepository.lidMapping.getPNForLID(call.from as string);\n                }\n                const msg = await this.client.sendMessage(call.from, { text: settings.msgCall });\n\n                this.client.ev.emit('messages.upsert', { messages: [msg], type: 'notify' });\n              }\n\n              this.sendDataWebhook(Events.CALL, call);\n            }\n\n            if (events['connection.update']) {\n              this.connectionUpdate(events['connection.update']);\n            }\n\n            if (events['creds.update']) {\n              this.instance.authState.saveCreds();\n            }\n\n            if (events['messaging-history.set']) {\n              const payload = events['messaging-history.set'];\n              await this.messageHandle['messaging-history.set'](payload);\n            }\n\n            if (events['messages.upsert']) {\n              const payload = events['messages.upsert'];\n\n              // this.messageProcessor.processMessage(payload, settings);\n              await this.messageHandle['messages.upsert'](payload, settings);\n            }\n\n            if (events['messages.update']) {\n              const payload = events['messages.update'];\n              await this.messageHandle['messages.update'](payload, settings);\n            }\n\n            if (events['message-receipt.update']) {\n              const payload = events['message-receipt.update'] as MessageUserReceiptUpdate[];\n              const remotesJidMap: Record<string, number> = {};\n\n              for (const event of payload) {\n                if (typeof event.key.remoteJid === 'string' && typeof event.receipt.readTimestamp === 'number') {\n                  remotesJidMap[event.key.remoteJid] = event.receipt.readTimestamp;\n                }\n              }\n\n              await Promise.all(\n                Object.keys(remotesJidMap).map(async (remoteJid) =>\n                  this.updateMessagesReadedByTimestamp(remoteJid, remotesJidMap[remoteJid]),\n                ),\n              );\n            }\n\n            if (events['presence.update']) {\n              const payload = events['presence.update'];\n\n              if (settings?.groupsIgnore && payload.id.includes('@g.us')) {\n                return;\n              }\n\n              this.sendDataWebhook(Events.PRESENCE_UPDATE, payload);\n            }\n\n            if (!settings?.groupsIgnore) {\n              if (events['groups.upsert']) {\n                const payload = events['groups.upsert'];\n                this.groupHandler['groups.upsert'](payload);\n              }\n\n              if (events['groups.update']) {\n                const payload = events['groups.update'];\n                this.groupHandler['groups.update'](payload);\n              }\n\n              if (events['group-participants.update']) {\n                const payload = events['group-participants.update'] as any;\n                this.groupHandler['group-participants.update'](payload);\n              }\n            }\n\n            if (events['chats.upsert']) {\n              const payload = events['chats.upsert'];\n              this.chatHandle['chats.upsert'](payload);\n            }\n\n            if (events['chats.update']) {\n              const payload = events['chats.update'];\n              this.chatHandle['chats.update'](payload);\n            }\n\n            if (events['chats.delete']) {\n              const payload = events['chats.delete'];\n              this.chatHandle['chats.delete'](payload);\n            }\n\n            if (events['contacts.upsert']) {\n              const payload = events['contacts.upsert'];\n              this.contactHandle['contacts.upsert'](payload);\n            }\n\n            if (events['contacts.update']) {\n              const payload = events['contacts.update'];\n              this.contactHandle['contacts.update'](payload);\n            }\n\n            if (events[Events.LABELS_ASSOCIATION]) {\n              const payload = events[Events.LABELS_ASSOCIATION];\n              this.labelHandle[Events.LABELS_ASSOCIATION](payload, database);\n              return;\n            }\n\n            if (events[Events.LABELS_EDIT]) {\n              const payload = events[Events.LABELS_EDIT];\n              this.labelHandle[Events.LABELS_EDIT](payload);\n              return;\n            }\n          }\n        } catch (error) {\n          this.logger.error(error);\n        }\n      });\n    });\n  }\n\n  private historySyncNotification(msg: proto.Message.IHistorySyncNotification) {\n    const instance: InstanceDto = { instanceName: this.instance.name };\n\n    if (\n      this.configService.get<Chatwoot>('CHATWOOT').ENABLED &&\n      this.localChatwoot?.enabled &&\n      this.localChatwoot.importMessages &&\n      this.isSyncNotificationFromUsedSyncType(msg)\n    ) {\n      if (msg.chunkOrder === 1) {\n        this.chatwootService.startImportHistoryMessages(instance);\n      }\n\n      if (msg.progress === 100) {\n        setTimeout(() => {\n          this.chatwootService.importHistoryMessages(instance);\n        }, 10000);\n      }\n    }\n\n    return true;\n  }\n\n  private isSyncNotificationFromUsedSyncType(msg: proto.Message.IHistorySyncNotification) {\n    return (\n      (this.localSettings.syncFullHistory && msg?.syncType === 2) ||\n      (!this.localSettings.syncFullHistory && msg?.syncType === 3)\n    );\n  }\n\n  public async profilePicture(number: string) {\n    const jid = createJid(number);\n\n    try {\n      const profilePictureUrl = await this.client.profilePictureUrl(jid, 'image');\n\n      return { wuid: jid, profilePictureUrl };\n    } catch {\n      return { wuid: jid, profilePictureUrl: null };\n    }\n  }\n\n  public async getStatus(number: string) {\n    const jid = createJid(number);\n\n    try {\n      return { wuid: jid, status: (await this.client.fetchStatus(jid))[0]?.status };\n    } catch {\n      return { wuid: jid, status: null };\n    }\n  }\n\n  public async fetchProfile(instanceName: string, number?: string) {\n    const jid = number ? createJid(number) : this.client?.user?.id;\n\n    const onWhatsapp = (await this.whatsappNumber({ numbers: [jid] }))?.shift();\n\n    if (!onWhatsapp.exists) {\n      throw new BadRequestException(onWhatsapp);\n    }\n\n    try {\n      if (number) {\n        const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift();\n        const picture = await this.profilePicture(info?.jid);\n        const status = await this.getStatus(info?.jid);\n        const business = await this.fetchBusinessProfile(info?.jid);\n\n        return {\n          wuid: info?.jid || jid,\n          name: info?.name,\n          numberExists: info?.exists,\n          picture: picture?.profilePictureUrl,\n          status: status?.status,\n          isBusiness: business.isBusiness,\n          email: business?.email,\n          description: business?.description,\n          website: business?.website?.shift(),\n        };\n      } else {\n        const instanceNames = instanceName ? [instanceName] : null;\n        const info: Instance = await waMonitor.instanceInfo(instanceNames);\n        const business = await this.fetchBusinessProfile(jid);\n\n        return {\n          wuid: jid,\n          name: info?.profileName,\n          numberExists: true,\n          picture: info?.profilePicUrl,\n          status: info?.connectionStatus,\n          isBusiness: business.isBusiness,\n          email: business?.email,\n          description: business?.description,\n          website: business?.website?.shift(),\n        };\n      }\n    } catch {\n      return { wuid: jid, name: null, picture: null, status: null, os: null, isBusiness: false };\n    }\n  }\n\n  public async offerCall({ number, isVideo, callDuration }: OfferCallDto) {\n    const jid = createJid(number);\n\n    try {\n      // const call = await this.client.offerCall(jid, isVideo);\n      // setTimeout(() => this.client.terminateCall(call.id, call.to), callDuration * 1000);\n\n      // return call;\n      return { id: '123', jid, isVideo, callDuration };\n    } catch (error) {\n      return error;\n    }\n  }\n\n  private async sendMessage(\n    sender: string,\n    message: any,\n    mentions: any,\n    linkPreview: any,\n    quoted: any,\n    messageId?: string,\n    ephemeralExpiration?: number,\n    contextInfo?: any,\n    // participants?: GroupParticipant[],\n  ) {\n    sender = sender.toLowerCase();\n\n    const option: any = { quoted };\n\n    if (isJidGroup(sender)) {\n      option.useCachedGroupMetadata = true;\n      // if (participants)\n      //   option.cachedGroupMetadata = async () => {\n      //     return { participants: participants as GroupParticipant[] };\n      //   };\n    }\n\n    if (ephemeralExpiration) option.ephemeralExpiration = ephemeralExpiration;\n\n    // NOTE: NÃO DEVEMOS GERAR O messageId AQUI, SOMENTE SE VIER INFORMADO POR PARAMETRO. A GERAÇÃO ANTERIOR IMPEDE O WZAP DE IDENTIFICAR A SOURCE.\n    if (messageId) option.messageId = messageId;\n\n    if (message['viewOnceMessage']) {\n      const m = generateWAMessageFromContent(sender, message, {\n        timestamp: new Date(),\n        userJid: this.instance.wuid,\n        messageId,\n        quoted,\n      });\n      const id = await this.client.relayMessage(sender, message, { messageId });\n      m.key = { id: id, remoteJid: sender, participant: isPnUser(sender) ? sender : undefined, fromMe: true };\n      for (const [key, value] of Object.entries(m)) {\n        if (!value || (isArray(value) && value.length) === 0) {\n          delete m[key];\n        }\n      }\n      return m;\n    }\n\n    if (\n      !message['audio'] &&\n      !message['poll'] &&\n      !message['sticker'] &&\n      !message['conversation'] &&\n      sender !== 'status@broadcast'\n    ) {\n      if (message['reactionMessage']) {\n        return await this.client.sendMessage(\n          sender,\n          {\n            react: { text: message['reactionMessage']['text'], key: message['reactionMessage']['key'] },\n          } as unknown as AnyMessageContent,\n          option as unknown as MiscMessageGenerationOptions,\n        );\n      }\n    }\n\n    if (contextInfo) {\n      message['contextInfo'] = contextInfo;\n    }\n\n    if (message['conversation']) {\n      return await this.client.sendMessage(\n        sender,\n        {\n          text: message['conversation'],\n          mentions,\n          linkPreview: linkPreview,\n          contextInfo: message['contextInfo'],\n        } as unknown as AnyMessageContent,\n        option as unknown as MiscMessageGenerationOptions,\n      );\n    }\n\n    if (!message['audio'] && !message['poll'] && !message['sticker'] && sender != 'status@broadcast') {\n      return await this.client.sendMessage(\n        sender,\n        {\n          forward: { key: { remoteJid: this.instance.wuid, fromMe: true }, message },\n          mentions,\n          contextInfo: message['contextInfo'],\n        },\n        option as unknown as MiscMessageGenerationOptions,\n      );\n    }\n\n    if (sender === 'status@broadcast') {\n      let jidList;\n      if (message['status'].option.allContacts) {\n        const contacts = await this.prismaRepository.contact.findMany({\n          where: { instanceId: this.instanceId, remoteJid: { not: { endsWith: '@g.us' } } },\n        });\n\n        jidList = contacts.map((contact) => contact.remoteJid);\n      } else {\n        jidList = message['status'].option.statusJidList;\n      }\n\n      const batchSize = 10;\n\n      const batches = Array.from({ length: Math.ceil(jidList.length / batchSize) }, (_, i) =>\n        jidList.slice(i * batchSize, i * batchSize + batchSize),\n      );\n\n      let msgId: string | null = null;\n\n      let firstMessage: WAMessage;\n\n      const firstBatch = batches.shift();\n\n      if (firstBatch) {\n        firstMessage = await this.client.sendMessage(\n          sender,\n          message['status'].content as unknown as AnyMessageContent,\n          {\n            backgroundColor: message['status'].option.backgroundColor,\n            font: message['status'].option.font,\n            statusJidList: firstBatch,\n          } as unknown as MiscMessageGenerationOptions,\n        );\n\n        msgId = firstMessage.key.id;\n      }\n\n      if (batches.length === 0) return firstMessage;\n\n      await Promise.allSettled(\n        batches.map(async (batch) => {\n          const messageSent = await this.client.sendMessage(\n            sender,\n            message['status'].content as unknown as AnyMessageContent,\n            {\n              backgroundColor: message['status'].option.backgroundColor,\n              font: message['status'].option.font,\n              statusJidList: batch,\n              messageId: msgId,\n            } as unknown as MiscMessageGenerationOptions,\n          );\n\n          return messageSent;\n        }),\n      );\n\n      return firstMessage;\n    }\n\n    return await this.client.sendMessage(\n      sender,\n      message as unknown as AnyMessageContent,\n      option as unknown as MiscMessageGenerationOptions,\n    );\n  }\n\n  private async sendMessageWithTyping<T = proto.IMessage>(\n    number: string,\n    message: T,\n    options?: Options,\n    isIntegration = false,\n  ) {\n    const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift();\n\n    if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) {\n      throw new BadRequestException(isWA);\n    }\n\n    const sender = isWA.jid.toLowerCase();\n\n    this.logger.verbose(`Sending message to ${sender}`);\n\n    try {\n      if (options?.delay) {\n        this.logger.verbose(`Typing for ${options.delay}ms to ${sender}`);\n        if (options.delay > 20000) {\n          let remainingDelay = options.delay;\n          while (remainingDelay > 20000) {\n            await this.client.presenceSubscribe(sender);\n\n            await this.client.sendPresenceUpdate((options.presence as WAPresence) ?? 'composing', sender);\n\n            await delay(20000);\n\n            await this.client.sendPresenceUpdate('paused', sender);\n\n            remainingDelay -= 20000;\n          }\n          if (remainingDelay > 0) {\n            await this.client.presenceSubscribe(sender);\n\n            await this.client.sendPresenceUpdate((options.presence as WAPresence) ?? 'composing', sender);\n\n            await delay(remainingDelay);\n\n            await this.client.sendPresenceUpdate('paused', sender);\n          }\n        } else {\n          await this.client.presenceSubscribe(sender);\n\n          await this.client.sendPresenceUpdate((options.presence as WAPresence) ?? 'composing', sender);\n\n          await delay(options.delay);\n\n          await this.client.sendPresenceUpdate('paused', sender);\n        }\n      }\n\n      const linkPreview = options?.linkPreview != false ? undefined : false;\n\n      let quoted: WAMessage;\n\n      if (options?.quoted) {\n        const m = options?.quoted;\n\n        const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as WAMessage);\n\n        if (msg) {\n          quoted = msg;\n        }\n      }\n\n      let messageSent: WAMessage;\n\n      let mentions: string[];\n      let contextInfo: any;\n\n      if (isJidGroup(sender)) {\n        let group;\n        try {\n          const cache = this.configService.get<CacheConf>('CACHE');\n          if (!cache.REDIS.ENABLED && !cache.LOCAL.ENABLED) group = await this.findGroup({ groupJid: sender }, 'inner');\n          else group = await this.getGroupMetadataCache(sender);\n          // group = await this.findGroup({ groupJid: sender }, 'inner');\n        } catch {\n          throw new NotFoundException('Group not found');\n        }\n\n        if (!group) {\n          throw new NotFoundException('Group not found');\n        }\n\n        if (options?.mentionsEveryOne) {\n          mentions = group.participants.map((participant) => participant.id);\n        } else if (options?.mentioned?.length) {\n          mentions = options.mentioned.map((mention) => {\n            const jid = createJid(mention);\n            if (isJidGroup(jid)) {\n              return null;\n            }\n            return jid;\n          });\n        }\n\n        messageSent = await this.sendMessage(\n          sender,\n          message,\n          mentions,\n          linkPreview,\n          quoted,\n          null,\n          group?.ephemeralDuration,\n          // group?.participants,\n        );\n      } else {\n        contextInfo = {\n          mentionedJid: [],\n          groupMentions: [],\n          //expiration: 7776000,\n          ephemeralSettingTimestamp: {\n            low: Math.floor(Date.now() / 1000) - 172800,\n            high: 0,\n            unsigned: false,\n          },\n          disappearingMode: { initiator: 0 },\n        };\n        messageSent = await this.sendMessage(\n          sender,\n          message,\n          mentions,\n          linkPreview,\n          quoted,\n          null,\n          undefined,\n          contextInfo,\n        );\n      }\n\n      if (Long.isLong(messageSent?.messageTimestamp)) {\n        messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber();\n      }\n\n      const messageRaw = this.prepareMessage(messageSent);\n\n      const isMedia =\n        messageSent?.message?.imageMessage ||\n        messageSent?.message?.videoMessage ||\n        messageSent?.message?.stickerMessage ||\n        messageSent?.message?.ptvMessage ||\n        messageSent?.message?.documentMessage ||\n        messageSent?.message?.documentWithCaptionMessage ||\n        messageSent?.message?.ptvMessage ||\n        messageSent?.message?.audioMessage;\n\n      const isVideo = messageSent?.message?.videoMessage;\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && !isIntegration) {\n        this.chatwootService.eventWhatsapp(\n          Events.SEND_MESSAGE,\n          { instanceName: this.instance.name, instanceId: this.instanceId },\n          messageRaw,\n        );\n      }\n\n      if (this.configService.get<Openai>('OPENAI').ENABLED && messageRaw?.message?.audioMessage) {\n        const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({\n          where: { instanceId: this.instanceId },\n          include: { OpenaiCreds: true },\n        });\n\n        if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {\n          messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(messageRaw, this)}`;\n        }\n      }\n\n      if (this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE) {\n        const msg = await this.prismaRepository.message.create({ data: messageRaw });\n\n        if (isMedia && this.configService.get<S3>('S3').ENABLE) {\n          try {\n            if (isVideo && !this.configService.get<S3>('S3').SAVE_VIDEO) {\n              throw new Error('Video upload is disabled.');\n            }\n\n            const message: any = messageRaw;\n\n            // Verificação adicional para garantir que há conteúdo de mídia real\n            const hasRealMedia = this.hasValidMediaContent(message);\n\n            if (!hasRealMedia) {\n              this.logger.warn('Message detected as media but contains no valid media content');\n            } else {\n              const media = await this.getBase64FromMediaMessage({ message }, true);\n\n              if (!media) {\n                this.logger.verbose('No valid media to upload (messageContextInfo only), skipping MinIO');\n                return;\n              }\n\n              const { buffer, mediaType, fileName, size } = media;\n\n              const mimetype = mimeTypes.lookup(fileName).toString();\n\n              const fullName = join(\n                `${this.instance.id}`,\n                messageRaw.key.remoteJid,\n                `${messageRaw.key.id}`,\n                mediaType,\n                fileName,\n              );\n\n              await s3Service.uploadFile(fullName, buffer, size.fileLength?.low, { 'Content-Type': mimetype });\n\n              await this.prismaRepository.media.create({\n                data: { messageId: msg.id, instanceId: this.instanceId, type: mediaType, fileName: fullName, mimetype },\n              });\n\n              const mediaUrl = await s3Service.getObjectUrl(fullName);\n\n              messageRaw.message.mediaUrl = mediaUrl;\n\n              await this.prismaRepository.message.update({ where: { id: msg.id }, data: messageRaw });\n            }\n          } catch (error) {\n            this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);\n          }\n        }\n      }\n\n      if (this.localWebhook.enabled) {\n        if (isMedia && this.localWebhook.webhookBase64) {\n          try {\n            const buffer = await downloadMediaMessage(\n              { key: messageRaw.key, message: messageRaw?.message },\n              'buffer',\n              {},\n              { logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },\n            );\n\n            if (buffer) {\n              messageRaw.message.base64 = buffer.toString('base64');\n            } else {\n              // retry to download media\n              const buffer = await downloadMediaMessage(\n                { key: messageRaw.key, message: messageRaw?.message },\n                'buffer',\n                {},\n                { logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },\n              );\n\n              if (buffer) {\n                messageRaw.message.base64 = buffer.toString('base64');\n              }\n            }\n          } catch (error) {\n            this.logger.error(['Error converting media to base64', error?.message]);\n          }\n        }\n      }\n\n      this.logger.verbose(messageSent);\n\n      this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw);\n\n      if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && isIntegration) {\n        await chatbotController.emit({\n          instance: { instanceName: this.instance.name, instanceId: this.instanceId },\n          remoteJid: messageRaw.key.remoteJid,\n          msg: messageRaw,\n          pushName: messageRaw.pushName,\n          isIntegration,\n        });\n      }\n\n      return messageRaw;\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  // Instance Controller\n  public async sendPresence(data: SendPresenceDto) {\n    try {\n      const { number } = data;\n\n      const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift();\n\n      if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) {\n        throw new BadRequestException(isWA);\n      }\n\n      const sender = isWA.jid;\n\n      if (data?.delay && data?.delay > 20000) {\n        let remainingDelay = data?.delay;\n        while (remainingDelay > 20000) {\n          await this.client.presenceSubscribe(sender);\n\n          await this.client.sendPresenceUpdate((data?.presence as WAPresence) ?? 'composing', sender);\n\n          await delay(20000);\n\n          await this.client.sendPresenceUpdate('paused', sender);\n\n          remainingDelay -= 20000;\n        }\n        if (remainingDelay > 0) {\n          await this.client.presenceSubscribe(sender);\n\n          await this.client.sendPresenceUpdate((data?.presence as WAPresence) ?? 'composing', sender);\n\n          await delay(remainingDelay);\n\n          await this.client.sendPresenceUpdate('paused', sender);\n        }\n      } else {\n        await this.client.presenceSubscribe(sender);\n\n        await this.client.sendPresenceUpdate((data?.presence as WAPresence) ?? 'composing', sender);\n\n        await delay(data?.delay);\n\n        await this.client.sendPresenceUpdate('paused', sender);\n      }\n\n      return { presence: data.presence };\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  // Presence Controller\n  public async setPresence(data: SetPresenceDto) {\n    try {\n      await this.client.sendPresenceUpdate(data.presence);\n\n      return { presence: data.presence };\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  // Send Message Controller\n  public async textMessage(data: SendTextDto, isIntegration = false) {\n    const text = data.text;\n\n    if (!text || text.trim().length === 0) {\n      throw new BadRequestException('Text is required');\n    }\n\n    return await this.sendMessageWithTyping(\n      data.number,\n      { conversation: data.text },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      isIntegration,\n    );\n  }\n\n  public async pollMessage(data: SendPollDto) {\n    return await this.sendMessageWithTyping(\n      data.number,\n      { poll: { name: data.name, selectableCount: data.selectableCount, values: data.values } },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        linkPreview: data?.linkPreview,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n  }\n\n  private async formatStatusMessage(status: StatusMessage) {\n    if (!status.type) {\n      throw new BadRequestException('Type is required');\n    }\n\n    if (!status.content) {\n      throw new BadRequestException('Content is required');\n    }\n\n    if (status.allContacts) {\n      const contacts = await this.prismaRepository.contact.findMany({ where: { instanceId: this.instanceId } });\n\n      if (!contacts.length) {\n        throw new BadRequestException('Contacts not found');\n      }\n\n      status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.remoteJid);\n    }\n\n    if (!status.statusJidList?.length && !status.allContacts) {\n      throw new BadRequestException('StatusJidList is required');\n    }\n\n    if (status.type === 'text') {\n      if (!status.backgroundColor) {\n        throw new BadRequestException('Background color is required');\n      }\n\n      if (!status.font) {\n        throw new BadRequestException('Font is required');\n      }\n\n      return {\n        content: { text: status.content },\n        option: { backgroundColor: status.backgroundColor, font: status.font, statusJidList: status.statusJidList },\n      };\n    }\n    if (status.type === 'image') {\n      return {\n        content: { image: { url: status.content }, caption: status.caption },\n        option: { statusJidList: status.statusJidList },\n      };\n    }\n\n    if (status.type === 'video') {\n      return {\n        content: { video: { url: status.content }, caption: status.caption },\n        option: { statusJidList: status.statusJidList },\n      };\n    }\n\n    if (status.type === 'audio') {\n      const convert = await this.processAudioMp4(status.content);\n      if (Buffer.isBuffer(convert)) {\n        const result = {\n          content: { audio: convert, ptt: true, mimetype: 'audio/ogg; codecs=opus' },\n          option: { statusJidList: status.statusJidList },\n        };\n\n        return result;\n      } else {\n        throw new InternalServerErrorException(convert);\n      }\n    }\n\n    throw new BadRequestException('Type not found');\n  }\n\n  public async statusMessage(data: SendStatusDto, file?: any) {\n    const mediaData: SendStatusDto = { ...data };\n\n    if (file) mediaData.content = file.buffer.toString('base64');\n\n    const status = await this.formatStatusMessage(mediaData);\n\n    const statusSent = await this.sendMessageWithTyping('status@broadcast', { status });\n\n    return statusSent;\n  }\n\n  private async prepareMediaMessage(mediaMessage: MediaMessage) {\n    try {\n      const type = mediaMessage.mediatype === 'ptv' ? 'video' : mediaMessage.mediatype;\n\n      let mediaInput: any;\n      if (mediaMessage.mediatype === 'image') {\n        let imageBuffer: Buffer;\n        if (isURL(mediaMessage.media)) {\n          let config: any = { responseType: 'arraybuffer' };\n\n          if (this.localProxy?.enabled) {\n            config = {\n              ...config,\n              httpsAgent: makeProxyAgent({\n                host: this.localProxy.host,\n                port: this.localProxy.port,\n                protocol: this.localProxy.protocol,\n                username: this.localProxy.username,\n                password: this.localProxy.password,\n              }),\n            };\n          }\n\n          const response = await axios.get(mediaMessage.media, config);\n          imageBuffer = Buffer.from(response.data, 'binary');\n        } else {\n          imageBuffer = Buffer.from(mediaMessage.media, 'base64');\n        }\n\n        mediaInput = await sharp(imageBuffer).jpeg().toBuffer();\n        mediaMessage.fileName ??= 'image.jpg';\n        mediaMessage.mimetype = 'image/jpeg';\n      } else {\n        mediaInput = isURL(mediaMessage.media)\n          ? { url: mediaMessage.media }\n          : Buffer.from(mediaMessage.media, 'base64');\n      }\n\n      const prepareMedia = await prepareWAMessageMedia(\n        {\n          [type]: mediaInput,\n        } as any,\n        { upload: this.client.waUploadToServer },\n      );\n\n      const mediaType = mediaMessage.mediatype + 'Message';\n\n      if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) {\n        const regex = new RegExp(/.*\\/(.+?)\\./);\n        const arrayMatch = regex.exec(mediaMessage.media);\n        mediaMessage.fileName = arrayMatch[1];\n      }\n\n      if (mediaMessage.mediatype === 'image' && !mediaMessage.fileName) {\n        mediaMessage.fileName = 'image.jpg';\n      }\n\n      if (mediaMessage.mediatype === 'video' && !mediaMessage.fileName) {\n        mediaMessage.fileName = 'video.mp4';\n      }\n\n      let mimetype: string | false;\n\n      if (mediaMessage.mimetype) {\n        mimetype = mediaMessage.mimetype;\n      } else {\n        mimetype = mimeTypes.lookup(mediaMessage.fileName);\n\n        if (!mimetype && isURL(mediaMessage.media)) {\n          let config: any = { responseType: 'arraybuffer' };\n\n          if (this.localProxy?.enabled) {\n            config = {\n              ...config,\n              httpsAgent: makeProxyAgent({\n                host: this.localProxy.host,\n                port: this.localProxy.port,\n                protocol: this.localProxy.protocol,\n                username: this.localProxy.username,\n                password: this.localProxy.password,\n              }),\n            };\n          }\n\n          const response = await axios.get(mediaMessage.media, config);\n\n          mimetype = response.headers['content-type'];\n        }\n      }\n\n      if (mediaMessage.mediatype === 'ptv') {\n        prepareMedia[mediaType] = prepareMedia[type + 'Message'];\n        mimetype = 'video/mp4';\n\n        if (!prepareMedia[mediaType]) {\n          throw new Error('Failed to prepare video message');\n        }\n\n        try {\n          let mediaInput;\n          if (isURL(mediaMessage.media)) {\n            mediaInput = mediaMessage.media;\n          } else {\n            const mediaBuffer = Buffer.from(mediaMessage.media, 'base64');\n            if (!mediaBuffer || mediaBuffer.length === 0) {\n              throw new Error('Invalid media buffer');\n            }\n            mediaInput = mediaBuffer;\n          }\n\n          const duration = await getVideoDuration(mediaInput);\n          if (!duration || duration <= 0) {\n            throw new Error('Invalid media duration');\n          }\n\n          this.logger.verbose(`Video duration: ${duration} seconds`);\n          prepareMedia[mediaType].seconds = duration;\n        } catch (error) {\n          this.logger.error('Error getting video duration:');\n          this.logger.error(error);\n          throw new Error(`Failed to get video duration: ${error.message}`);\n        }\n      }\n\n      if (mediaMessage?.fileName) {\n        mimetype = mimeTypes.lookup(mediaMessage.fileName).toString();\n        if (mimetype === 'application/mp4') {\n          mimetype = 'video/mp4';\n        }\n      }\n\n      prepareMedia[mediaType].caption = mediaMessage?.caption;\n      prepareMedia[mediaType].mimetype = mimetype;\n      prepareMedia[mediaType].fileName = mediaMessage.fileName;\n\n      if (mediaMessage.mediatype === 'video') {\n        prepareMedia[mediaType].gifPlayback = false;\n      }\n\n      return generateWAMessageFromContent(\n        '',\n        { [mediaType]: { ...prepareMedia[mediaType] } },\n        { userJid: this.instance.wuid },\n      );\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException(error?.toString() || error);\n    }\n  }\n\n  private async convertToWebP(image: string): Promise<Buffer> {\n    try {\n      let imageBuffer: Buffer;\n\n      if (isBase64(image)) {\n        const base64Data = image.replace(/^data:image\\/(jpeg|png|gif);base64,/, '');\n        imageBuffer = Buffer.from(base64Data, 'base64');\n      } else {\n        const timestamp = new Date().getTime();\n        const parsedURL = new URL(image);\n        parsedURL.searchParams.set('timestamp', timestamp.toString());\n        const url = parsedURL.toString();\n\n        let config: any = { responseType: 'arraybuffer' };\n\n        if (this.localProxy?.enabled) {\n          config = {\n            ...config,\n            httpsAgent: makeProxyAgent({\n              host: this.localProxy.host,\n              port: this.localProxy.port,\n              protocol: this.localProxy.protocol,\n              username: this.localProxy.username,\n              password: this.localProxy.password,\n            }),\n          };\n        }\n\n        const response = await axios.get(url, config);\n        imageBuffer = Buffer.from(response.data, 'binary');\n      }\n\n      const isAnimated = this.isAnimated(image, imageBuffer);\n\n      if (isAnimated) {\n        return await sharp(imageBuffer, { animated: true }).webp({ quality: 80 }).toBuffer();\n      } else {\n        return await sharp(imageBuffer).webp().toBuffer();\n      }\n    } catch (error) {\n      console.error('Erro ao converter a imagem para WebP:', error);\n      throw error;\n    }\n  }\n\n  private isAnimatedWebp(buffer: Buffer): boolean {\n    if (buffer.length < 12) return false;\n\n    return buffer.indexOf(Buffer.from('ANIM')) !== -1;\n  }\n\n  private isAnimated(image: string, buffer: Buffer): boolean {\n    const lowerCaseImage = image.toLowerCase();\n\n    if (lowerCaseImage.includes('.gif')) return true;\n\n    if (lowerCaseImage.includes('.webp')) return this.isAnimatedWebp(buffer);\n\n    return false;\n  }\n\n  public async mediaSticker(data: SendStickerDto, file?: any) {\n    const mediaData: SendStickerDto = { ...data };\n\n    if (file) mediaData.sticker = file.buffer.toString('base64');\n\n    const convert = data?.notConvertSticker\n      ? Buffer.from(data.sticker, 'base64')\n      : await this.convertToWebP(data.sticker);\n    const gifPlayback = data.sticker.includes('.gif');\n    const result = await this.sendMessageWithTyping(\n      data.number,\n      { sticker: convert, gifPlayback },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n\n    return result;\n  }\n\n  public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {\n    const mediaData: SendMediaDto = { ...data };\n\n    if (file) mediaData.media = file.buffer.toString('base64');\n\n    const generate = await this.prepareMediaMessage(mediaData);\n\n    const mediaSent = await this.sendMessageWithTyping(\n      data.number,\n      { ...generate.message },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      isIntegration,\n    );\n\n    return mediaSent;\n  }\n\n  public async ptvMessage(data: SendPtvDto, file?: any, isIntegration = false) {\n    const mediaData: SendMediaDto = {\n      number: data.number,\n      media: data.video,\n      mediatype: 'ptv',\n      delay: data?.delay,\n      quoted: data?.quoted,\n      mentionsEveryOne: data?.mentionsEveryOne,\n      mentioned: data?.mentioned,\n    };\n\n    if (file) mediaData.media = file.buffer.toString('base64');\n\n    const generate = await this.prepareMediaMessage(mediaData);\n\n    const mediaSent = await this.sendMessageWithTyping(\n      data.number,\n      { ...generate.message },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n      isIntegration,\n    );\n\n    return mediaSent;\n  }\n\n  public async processAudioMp4(audio: string) {\n    let inputStream: PassThrough;\n\n    if (isURL(audio)) {\n      const response = await axios.get(audio, { responseType: 'stream' });\n      inputStream = response.data;\n    } else {\n      const audioBuffer = Buffer.from(audio, 'base64');\n      inputStream = new PassThrough();\n      inputStream.end(audioBuffer);\n    }\n\n    return new Promise<Buffer>((resolve, reject) => {\n      const ffmpegProcess = spawn(ffmpegPath.path, [\n        '-i',\n        'pipe:0',\n        '-vn',\n        '-ab',\n        '128k',\n        '-ar',\n        '44100',\n        '-f',\n        'mp4',\n        '-movflags',\n        'frag_keyframe+empty_moov',\n        'pipe:1',\n      ]);\n\n      const outputChunks: Buffer[] = [];\n      let stderrData = '';\n\n      ffmpegProcess.stdout.on('data', (chunk) => {\n        outputChunks.push(chunk);\n      });\n\n      ffmpegProcess.stderr.on('data', (data) => {\n        stderrData += data.toString();\n        this.logger.verbose(`ffmpeg stderr: ${data}`);\n      });\n\n      ffmpegProcess.on('error', (error) => {\n        console.error('Error in ffmpeg process', error);\n        reject(error);\n      });\n\n      ffmpegProcess.on('close', (code) => {\n        if (code === 0) {\n          this.logger.verbose('Audio converted to mp4');\n          const outputBuffer = Buffer.concat(outputChunks);\n          resolve(outputBuffer);\n        } else {\n          this.logger.error(`ffmpeg exited with code ${code}`);\n          this.logger.error(`ffmpeg stderr: ${stderrData}`);\n          reject(new Error(`ffmpeg exited with code ${code}: ${stderrData}`));\n        }\n      });\n\n      inputStream.pipe(ffmpegProcess.stdin);\n\n      inputStream.on('error', (err) => {\n        console.error('Error in inputStream', err);\n        ffmpegProcess.stdin.end();\n        reject(err);\n      });\n    });\n  }\n\n  public async processAudio(audio: string): Promise<Buffer> {\n    const audioConverterConfig = this.configService.get<AudioConverter>('AUDIO_CONVERTER');\n    if (audioConverterConfig.API_URL) {\n      this.logger.verbose('Using audio converter API');\n      const formData = new FormData();\n\n      if (isURL(audio)) {\n        formData.append('url', audio);\n      } else {\n        formData.append('base64', audio);\n      }\n\n      const { data } = await axios.post(audioConverterConfig.API_URL, formData, {\n        headers: { ...formData.getHeaders(), apikey: audioConverterConfig.API_KEY },\n      });\n\n      if (!data.audio) {\n        throw new InternalServerErrorException('Failed to convert audio');\n      }\n\n      this.logger.verbose('Audio converted');\n      return Buffer.from(data.audio, 'base64');\n    } else {\n      let inputAudioStream: PassThrough;\n\n      if (isURL(audio)) {\n        const timestamp = new Date().getTime();\n        const parsedURL = new URL(audio);\n        parsedURL.searchParams.set('timestamp', timestamp.toString());\n        const url = parsedURL.toString();\n\n        const config: any = { responseType: 'stream' };\n\n        const response = await axios.get(url, config);\n        inputAudioStream = response.data.pipe(new PassThrough());\n      } else {\n        const audioBuffer = Buffer.from(audio, 'base64');\n        inputAudioStream = new PassThrough();\n        inputAudioStream.end(audioBuffer);\n      }\n\n      const isLpcm = isURL(audio) && /\\.lpcm($|\\?)/i.test(audio);\n\n      return new Promise((resolve, reject) => {\n        const outputAudioStream = new PassThrough();\n        const chunks: Buffer[] = [];\n\n        outputAudioStream.on('data', (chunk) => chunks.push(chunk));\n        outputAudioStream.on('end', () => {\n          const outputBuffer = Buffer.concat(chunks);\n          resolve(outputBuffer);\n        });\n\n        outputAudioStream.on('error', (error) => {\n          console.log('error', error);\n          reject(error);\n        });\n\n        ffmpeg.setFfmpegPath(ffmpegPath.path);\n\n        let command = ffmpeg(inputAudioStream);\n\n        if (isLpcm) {\n          this.logger.verbose('Detected LPCM input – applying raw PCM settings');\n          command = command.inputFormat('s16le').inputOptions(['-ar', '24000', '-ac', '1']);\n        }\n\n        command\n          .outputFormat('ogg')\n          .noVideo()\n          .audioCodec('libopus')\n          .addOutputOptions('-avoid_negative_ts make_zero')\n          .audioBitrate('128k')\n          .audioFrequency(48000)\n          .audioChannels(1)\n          .outputOptions([\n            '-write_xing',\n            '0',\n            '-compression_level',\n            '10',\n            '-application',\n            'voip',\n            '-fflags',\n            '+bitexact',\n            '-flags',\n            '+bitexact',\n            '-id3v2_version',\n            '0',\n            '-map_metadata',\n            '-1',\n            '-map_chapters',\n            '-1',\n            '-write_bext',\n            '0',\n          ])\n          .pipe(outputAudioStream, { end: true })\n          .on('error', function (error) {\n            console.log('error', error);\n            reject(error);\n          });\n      });\n    }\n  }\n\n  public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {\n    const mediaData: SendAudioDto = { ...data };\n\n    if (file?.buffer) {\n      mediaData.audio = file.buffer.toString('base64');\n    } else if (!isURL(data.audio) && !isBase64(data.audio)) {\n      console.error('Invalid file or audio source');\n      throw new BadRequestException('File buffer, URL, or base64 audio is required');\n    }\n\n    if (!data?.encoding && data?.encoding !== false) {\n      data.encoding = true;\n    }\n\n    if (data?.encoding) {\n      const convert = await this.processAudio(mediaData.audio);\n\n      if (Buffer.isBuffer(convert)) {\n        const result = this.sendMessageWithTyping<AnyMessageContent>(\n          data.number,\n          { audio: convert, ptt: true, mimetype: 'audio/ogg; codecs=opus' },\n          { presence: 'recording', delay: data?.delay },\n          isIntegration,\n        );\n\n        return result;\n      } else {\n        throw new InternalServerErrorException('Failed to convert audio');\n      }\n    }\n\n    return await this.sendMessageWithTyping<AnyMessageContent>(\n      data.number,\n      {\n        audio: isURL(data.audio) ? { url: data.audio } : Buffer.from(data.audio, 'base64'),\n        ptt: true,\n        mimetype: 'audio/ogg; codecs=opus',\n      },\n      { presence: 'recording', delay: data?.delay },\n      isIntegration,\n    );\n  }\n\n  private generateRandomId(length = 11) {\n    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n    let result = '';\n    for (let i = 0; i < length; i++) {\n      result += characters.charAt(Math.floor(Math.random() * characters.length));\n    }\n    return result;\n  }\n\n  private toJSONString(button: Button): string {\n    const toString = (obj: any) => JSON.stringify(obj);\n\n    const json = {\n      call: () => toString({ display_text: button.displayText, phone_number: button.phoneNumber }),\n      reply: () => toString({ display_text: button.displayText, id: button.id }),\n      copy: () => toString({ display_text: button.displayText, copy_code: button.copyCode }),\n      url: () => toString({ display_text: button.displayText, url: button.url, merchant_url: button.url }),\n      pix: () =>\n        toString({\n          currency: button.currency,\n          total_amount: { value: 0, offset: 100 },\n          reference_id: this.generateRandomId(),\n          type: 'physical-goods',\n          order: {\n            status: 'pending',\n            subtotal: { value: 0, offset: 100 },\n            order_type: 'ORDER',\n            items: [\n              { name: '', amount: { value: 0, offset: 100 }, quantity: 0, sale_amount: { value: 0, offset: 100 } },\n            ],\n          },\n          payment_settings: [\n            {\n              type: 'pix_static_code',\n              pix_static_code: {\n                merchant_name: button.name,\n                key: button.key,\n                key_type: this.mapKeyType.get(button.keyType),\n              },\n            },\n          ],\n          share_payment_status: false,\n        }),\n    };\n\n    return json[button.type]?.() || '';\n  }\n\n  private readonly mapType = new Map<TypeButton, string>([\n    ['reply', 'quick_reply'],\n    ['copy', 'cta_copy'],\n    ['url', 'cta_url'],\n    ['call', 'cta_call'],\n    ['pix', 'payment_info'],\n  ]);\n\n  private readonly mapKeyType = new Map<KeyType, string>([\n    ['phone', 'PHONE'],\n    ['email', 'EMAIL'],\n    ['cpf', 'CPF'],\n    ['cnpj', 'CNPJ'],\n    ['random', 'EVP'],\n  ]);\n\n  public async buttonMessage(data: SendButtonsDto) {\n    if (data.buttons.length === 0) {\n      throw new BadRequestException('At least one button is required');\n    }\n\n    const hasReplyButtons = data.buttons.some((btn) => btn.type === 'reply');\n\n    const hasPixButton = data.buttons.some((btn) => btn.type === 'pix');\n\n    const hasOtherButtons = data.buttons.some((btn) => btn.type !== 'reply' && btn.type !== 'pix');\n\n    if (hasReplyButtons) {\n      if (data.buttons.length > 3) {\n        throw new BadRequestException('Maximum of 3 reply buttons allowed');\n      }\n      if (hasOtherButtons) {\n        throw new BadRequestException('Reply buttons cannot be mixed with other button types');\n      }\n    }\n\n    if (hasPixButton) {\n      if (data.buttons.length > 1) {\n        throw new BadRequestException('Only one PIX button is allowed');\n      }\n      if (hasOtherButtons) {\n        throw new BadRequestException('PIX button cannot be mixed with other button types');\n      }\n\n      const message: proto.IMessage = {\n        viewOnceMessage: {\n          message: {\n            interactiveMessage: {\n              nativeFlowMessage: {\n                buttons: [{ name: this.mapType.get('pix'), buttonParamsJson: this.toJSONString(data.buttons[0]) }],\n                messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),\n              },\n            },\n          },\n        },\n      };\n\n      return await this.sendMessageWithTyping(data.number, message, {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      });\n    }\n\n    const generate = await (async () => {\n      if (data?.thumbnailUrl) {\n        return await this.prepareMediaMessage({ mediatype: 'image', media: data.thumbnailUrl });\n      }\n    })();\n\n    const buttons = data.buttons.map((value) => {\n      return { name: this.mapType.get(value.type), buttonParamsJson: this.toJSONString(value) };\n    });\n\n    const message: proto.IMessage = {\n      viewOnceMessage: {\n        message: {\n          interactiveMessage: {\n            body: {\n              text: (() => {\n                let t = '*' + data.title + '*';\n                if (data?.description) {\n                  t += '\\n\\n';\n                  t += data.description;\n                  t += '\\n';\n                }\n                return t;\n              })(),\n            },\n            footer: { text: data?.footer },\n            header: (() => {\n              if (generate?.message?.imageMessage) {\n                return {\n                  hasMediaAttachment: !!generate.message.imageMessage,\n                  imageMessage: generate.message.imageMessage,\n                };\n              }\n            })(),\n            nativeFlowMessage: {\n              buttons: buttons,\n              messageParamsJson: JSON.stringify({ from: 'api', templateId: v4() }),\n            },\n          },\n        },\n      },\n    };\n\n    return await this.sendMessageWithTyping(data.number, message, {\n      delay: data?.delay,\n      presence: 'composing',\n      quoted: data?.quoted,\n      mentionsEveryOne: data?.mentionsEveryOne,\n      mentioned: data?.mentioned,\n    });\n  }\n\n  public async locationMessage(data: SendLocationDto) {\n    return await this.sendMessageWithTyping(\n      data.number,\n      {\n        locationMessage: {\n          degreesLatitude: data.latitude,\n          degreesLongitude: data.longitude,\n          name: data?.name,\n          address: data?.address,\n        },\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n  }\n\n  public async listMessage(data: SendListDto) {\n    return await this.sendMessageWithTyping(\n      data.number,\n      {\n        listMessage: {\n          title: data.title,\n          description: data.description,\n          buttonText: data?.buttonText,\n          footerText: data?.footerText,\n          sections: data.sections,\n          listType: 2,\n        },\n      },\n      {\n        delay: data?.delay,\n        presence: 'composing',\n        quoted: data?.quoted,\n        mentionsEveryOne: data?.mentionsEveryOne,\n        mentioned: data?.mentioned,\n      },\n    );\n  }\n\n  public async contactMessage(data: SendContactDto) {\n    const message: proto.IMessage = {};\n\n    const vcard = (contact: ContactMessage) => {\n      let result = 'BEGIN:VCARD\\n' + 'VERSION:3.0\\n' + `N:${contact.fullName}\\n` + `FN:${contact.fullName}\\n`;\n\n      if (contact.organization) {\n        result += `ORG:${contact.organization};\\n`;\n      }\n\n      if (contact.email) {\n        result += `EMAIL:${contact.email}\\n`;\n      }\n\n      if (contact.url) {\n        result += `URL:${contact.url}\\n`;\n      }\n\n      if (!contact.wuid) {\n        contact.wuid = createJid(contact.phoneNumber);\n      }\n\n      result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\\n` + 'item1.X-ABLabel:Celular\\n' + 'END:VCARD';\n\n      return result;\n    };\n\n    if (data.contact.length === 1) {\n      message.contactMessage = { displayName: data.contact[0].fullName, vcard: vcard(data.contact[0]) };\n    } else {\n      message.contactsArrayMessage = {\n        displayName: `${data.contact.length} contacts`,\n        contacts: data.contact.map((contact) => {\n          return { displayName: contact.fullName, vcard: vcard(contact) };\n        }),\n      };\n    }\n\n    return await this.sendMessageWithTyping(data.number, { ...message }, {});\n  }\n\n  public async reactionMessage(data: SendReactionDto) {\n    return await this.sendMessageWithTyping(data.key.remoteJid, {\n      reactionMessage: { key: data.key, text: data.reaction },\n    });\n  }\n\n  // Chat Controller\n  public async whatsappNumber(data: WhatsAppNumberDto) {\n    const jids: {\n      groups: { number: string; jid: string }[];\n      broadcast: { number: string; jid: string }[];\n      users: { number: string; jid: string; name?: string }[];\n    } = { groups: [], broadcast: [], users: [] };\n\n    data.numbers.forEach((number) => {\n      const jid = createJid(number);\n\n      if (isJidGroup(jid)) {\n        jids.groups.push({ number, jid });\n      } else if (jid === 'status@broadcast') {\n        jids.broadcast.push({ number, jid });\n      } else {\n        jids.users.push({ number, jid });\n      }\n    });\n\n    const onWhatsapp: OnWhatsAppDto[] = [];\n\n    // BROADCAST\n    onWhatsapp.push(...jids.broadcast.map(({ jid, number }) => new OnWhatsAppDto(jid, false, number)));\n\n    // GROUPS\n    const groups = await Promise.all(\n      jids.groups.map(async ({ jid, number }) => {\n        const group = await this.findGroup({ groupJid: jid }, 'inner');\n\n        if (!group) {\n          return new OnWhatsAppDto(jid, false, number);\n        }\n\n        return new OnWhatsAppDto(group.id, true, number, group?.subject);\n      }),\n    );\n    onWhatsapp.push(...groups);\n\n    // USERS\n    const contacts: any[] = await this.prismaRepository.contact.findMany({\n      where: { instanceId: this.instanceId, remoteJid: { in: jids.users.map(({ jid }) => jid) } },\n    });\n\n    // Unified cache verification for all numbers (normal and LID)\n    const numbersToVerify = jids.users.map(({ jid }) => jid.replace('+', ''));\n\n    // Get all numbers from cache\n    const cachedNumbers = await getOnWhatsappCache(numbersToVerify);\n\n    // Separate numbers that are and are not in cache\n    const cachedJids = new Set(cachedNumbers.flatMap((cached) => cached.jidOptions));\n    const numbersNotInCache = numbersToVerify.filter((jid) => !cachedJids.has(jid));\n\n    // Only call Baileys for normal numbers (@s.whatsapp.net) that are not in cache\n    let verify: { jid: string; exists: boolean }[] = [];\n    const normalNumbersNotInCache = numbersNotInCache.filter((jid) => !jid.includes('@lid'));\n\n    if (normalNumbersNotInCache.length > 0) {\n      this.logger.verbose(`Checking ${normalNumbersNotInCache.length} numbers via Baileys (not found in cache)`);\n      verify = await this.client.onWhatsApp(...normalNumbersNotInCache);\n    }\n\n    const verifiedUsers = await Promise.all(\n      jids.users.map(async (user) => {\n        // Try to get from cache first (works for all: normal and LID)\n        const cached = cachedNumbers.find((cached) => cached.jidOptions.includes(user.jid.replace('+', '')));\n\n        if (cached) {\n          this.logger.verbose(`Number ${user.number} found in cache`);\n          return new OnWhatsAppDto(\n            cached.remoteJid,\n            true,\n            user.number,\n            contacts.find((c) => c.remoteJid === cached.remoteJid)?.pushName,\n            cached.lid || (cached.remoteJid.includes('@lid') ? 'lid' : undefined),\n          );\n        }\n\n        // If it's a LID number and not in cache, consider it valid\n        if (user.jid.includes('@lid')) {\n          return new OnWhatsAppDto(\n            user.jid,\n            true,\n            user.number,\n            contacts.find((c) => c.remoteJid === user.jid)?.pushName,\n            'lid',\n          );\n        }\n\n        // If not in cache and is a normal number, use Baileys verification\n        let numberVerified: (typeof verify)[0] | null = null;\n\n        // Brazilian numbers\n        if (user.number.startsWith('55')) {\n          const numberWithDigit =\n            user.number.slice(4, 5) === '9' && user.number.length === 13\n              ? user.number\n              : `${user.number.slice(0, 4)}9${user.number.slice(4)}`;\n          const numberWithoutDigit =\n            user.number.length === 12 ? user.number : user.number.slice(0, 4) + user.number.slice(5);\n\n          numberVerified = verify.find(\n            (v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,\n          );\n        }\n\n        // Mexican/Argentina numbers\n        // Ref: https://faq.whatsapp.com/1294841057948784\n        if (!numberVerified && (user.number.startsWith('52') || user.number.startsWith('54'))) {\n          let prefix = '';\n          if (user.number.startsWith('52')) {\n            prefix = '1';\n          }\n          if (user.number.startsWith('54')) {\n            prefix = '9';\n          }\n\n          const numberWithDigit =\n            user.number.slice(2, 3) === prefix && user.number.length === 13\n              ? user.number\n              : `${user.number.slice(0, 2)}${prefix}${user.number.slice(2)}`;\n          const numberWithoutDigit =\n            user.number.length === 12 ? user.number : user.number.slice(0, 2) + user.number.slice(3);\n\n          numberVerified = verify.find(\n            (v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,\n          );\n        }\n\n        if (!numberVerified) {\n          numberVerified = verify.find((v) => v.jid === user.jid);\n        }\n\n        const numberJid = numberVerified?.jid || user.jid;\n\n        return new OnWhatsAppDto(\n          numberJid,\n          !!numberVerified?.exists,\n          user.number,\n          contacts.find((c) => c.remoteJid === numberJid)?.pushName,\n          undefined,\n        );\n      }),\n    );\n\n    // Combine results\n    onWhatsapp.push(...verifiedUsers);\n\n    // TODO: Salvar no cache apenas números que NÃO estavam no cache\n    const numbersToCache = onWhatsapp.filter((user) => {\n      if (!user.exists) return false;\n      // Verifica se estava no cache usando jidOptions\n      const cached = cachedNumbers?.find((cached) => cached.jidOptions.includes(user.jid.replace('+', '')));\n      return !cached;\n    });\n\n    if (numbersToCache.length > 0) {\n      this.logger.verbose(`Salvando ${numbersToCache.length} números no cache`);\n      await saveOnWhatsappCache(\n        numbersToCache.map((user) => ({\n          remoteJid: user.jid,\n          lid: user.lid === 'lid' ? 'lid' : undefined,\n        })),\n      );\n    }\n\n    return onWhatsapp;\n  }\n\n  public async markMessageAsRead(data: ReadMessageDto) {\n    try {\n      const keys: proto.IMessageKey[] = [];\n      data.readMessages.forEach((read) => {\n        if (isJidGroup(read.remoteJid) || isPnUser(read.remoteJid)) {\n          keys.push({ remoteJid: read.remoteJid, fromMe: read.fromMe, id: read.id });\n        }\n      });\n      await this.client.readMessages(keys);\n      return { message: 'Read messages', read: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Read messages fail', error.toString());\n    }\n  }\n\n  public async getLastMessage(number: string) {\n    const where: any = { key: { remoteJid: number }, instanceId: this.instance.id };\n\n    const messages = await this.prismaRepository.message.findMany({\n      where,\n      orderBy: { messageTimestamp: 'desc' },\n      take: 1,\n    });\n\n    if (messages.length === 0) {\n      throw new NotFoundException('Messages not found');\n    }\n\n    let lastMessage = messages.pop();\n\n    for (const message of messages) {\n      if (message.messageTimestamp >= lastMessage.messageTimestamp) {\n        lastMessage = message;\n      }\n    }\n\n    return lastMessage as unknown as LastMessage;\n  }\n\n  public async archiveChat(data: ArchiveChatDto) {\n    try {\n      let last_message = data.lastMessage;\n      let number = data.chat;\n\n      if (!last_message && number) {\n        last_message = await this.getLastMessage(number);\n      } else {\n        last_message = data.lastMessage;\n        last_message.messageTimestamp = last_message?.messageTimestamp ?? Date.now();\n        number = last_message?.key?.remoteJid;\n      }\n\n      if (!last_message || Object.keys(last_message).length === 0) {\n        throw new NotFoundException('Last message not found');\n      }\n\n      await this.client.chatModify({ archive: data.archive, lastMessages: [last_message] }, createJid(number));\n\n      return { chatId: number, archived: true };\n    } catch (error) {\n      throw new InternalServerErrorException({\n        archived: false,\n        message: ['An error occurred while archiving the chat. Open a calling.', error.toString()],\n      });\n    }\n  }\n\n  public async markChatUnread(data: MarkChatUnreadDto) {\n    try {\n      let last_message = data.lastMessage;\n      let number = data.chat;\n\n      if (!last_message && number) {\n        last_message = await this.getLastMessage(number);\n      } else {\n        last_message = data.lastMessage;\n        last_message.messageTimestamp = last_message?.messageTimestamp ?? Date.now();\n        number = last_message?.key?.remoteJid;\n      }\n\n      if (!last_message || Object.keys(last_message).length === 0) {\n        throw new NotFoundException('Last message not found');\n      }\n\n      await this.client.chatModify({ markRead: false, lastMessages: [last_message] }, createJid(number));\n\n      return { chatId: number, markedChatUnread: true };\n    } catch (error) {\n      throw new InternalServerErrorException({\n        markedChatUnread: false,\n        message: ['An error occurred while marked unread the chat. Open a calling.', error.toString()],\n      });\n    }\n  }\n\n  public async deleteMessage(del: DeleteMessage) {\n    try {\n      const response = await this.client.sendMessage(del.remoteJid, { delete: del });\n      if (response) {\n        const messageId = response.message?.protocolMessage?.key?.id;\n        if (messageId) {\n          const isLogicalDeleted = configService.get<Database>('DATABASE').DELETE_DATA.LOGICAL_MESSAGE_DELETE;\n          let message = await this.prismaRepository.message.findFirst({\n            where: { key: { path: ['id'], equals: messageId } },\n          });\n          if (isLogicalDeleted) {\n            if (!message) return response;\n            const existingKey = typeof message?.key === 'object' && message.key !== null ? message.key : {};\n            message = await this.prismaRepository.message.update({\n              where: { id: message.id },\n              data: { key: { ...existingKey, deleted: true }, status: 'DELETED' },\n            });\n            if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE) {\n              const messageUpdate: any = {\n                messageId: message.id,\n                keyId: messageId,\n                remoteJid: response.key.remoteJid,\n                fromMe: response.key.fromMe,\n                participant: response.key?.participant,\n                status: 'DELETED',\n                instanceId: this.instanceId,\n              };\n              await this.prismaRepository.messageUpdate.create({ data: messageUpdate });\n            }\n          } else {\n            if (!message) return response;\n            await this.prismaRepository.message.deleteMany({ where: { id: message.id } });\n          }\n          this.sendDataWebhook(Events.MESSAGES_DELETE, {\n            id: message.id,\n            instanceId: message.instanceId,\n            key: message.key,\n            messageType: message.messageType,\n            status: 'DELETED',\n            source: message.source,\n            messageTimestamp: message.messageTimestamp,\n            pushName: message.pushName,\n            participant: message.participant,\n            message: message.message,\n          });\n        }\n      }\n\n      return response;\n    } catch (error) {\n      throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString());\n    }\n  }\n\n  public async mapMediaType(mediaType) {\n    const map = {\n      imageMessage: 'image',\n      videoMessage: 'video',\n      documentMessage: 'document',\n      stickerMessage: 'sticker',\n      audioMessage: 'audio',\n      ptvMessage: 'video',\n    };\n    return map[mediaType] || null;\n  }\n\n  public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto, getBuffer = false) {\n    try {\n      const m = data?.message;\n      const convertToMp4 = data?.convertToMp4 ?? false;\n\n      const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo);\n\n      if (!msg) {\n        throw 'Message not found';\n      }\n\n      for (const subtype of MessageSubtype) {\n        if (msg.message[subtype]) {\n          msg.message = msg.message[subtype].message;\n        }\n      }\n\n      if ('messageContextInfo' in msg.message && Object.keys(msg.message).length === 1) {\n        this.logger.verbose('Message contains only messageContextInfo, skipping media processing');\n        return null;\n      }\n\n      let mediaMessage: any;\n      let mediaType: string;\n\n      if (msg.message?.templateMessage) {\n        const template =\n          msg.message.templateMessage.hydratedTemplate || msg.message.templateMessage.hydratedFourRowTemplate;\n\n        for (const type of TypeMediaMessage) {\n          if (template[type]) {\n            mediaMessage = template[type];\n            mediaType = type;\n            msg.message = { [type]: { ...template[type], url: template[type].staticUrl } };\n            break;\n          }\n        }\n\n        if (!mediaMessage) {\n          throw 'Template message does not contain a supported media type';\n        }\n      } else {\n        for (const type of TypeMediaMessage) {\n          mediaMessage = msg.message[type];\n          if (mediaMessage) {\n            mediaType = type;\n            break;\n          }\n        }\n\n        if (!mediaMessage) {\n          throw 'The message is not of the media type';\n        }\n      }\n\n      if (typeof mediaMessage['mediaKey'] === 'object') {\n        msg.message[mediaType].mediaKey = Uint8Array.from(Object.values(mediaMessage['mediaKey']));\n      }\n\n      let buffer: Buffer;\n\n      try {\n        buffer = await downloadMediaMessage(\n          { key: msg?.key, message: msg?.message },\n          'buffer',\n          {},\n          { logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },\n        );\n      } catch {\n        this.logger.error('Download Media failed, trying to retry in 5 seconds...');\n        await new Promise((resolve) => setTimeout(resolve, 5000));\n        const mediaType = Object.keys(msg.message).find((key) => key.endsWith('Message'));\n        if (!mediaType) throw new Error('Could not determine mediaType for fallback');\n\n        try {\n          const media = await downloadContentFromMessage(\n            {\n              mediaKey: msg.message?.[mediaType]?.mediaKey,\n              directPath: msg.message?.[mediaType]?.directPath,\n              url: `https://mmg.whatsapp.net${msg?.message?.[mediaType]?.directPath}`,\n            },\n            await this.mapMediaType(mediaType),\n            {},\n          );\n          const chunks = [];\n          for await (const chunk of media) {\n            chunks.push(chunk);\n          }\n          buffer = Buffer.concat(chunks);\n          this.logger.info('Download Media with downloadContentFromMessage was successful!');\n        } catch (fallbackErr) {\n          this.logger.error('Download Media with downloadContentFromMessage also failed!');\n          throw fallbackErr;\n        }\n      }\n      const typeMessage = getContentType(msg.message);\n\n      const ext = mimeTypes.extension(mediaMessage?.['mimetype']);\n      const fileName = mediaMessage?.['fileName'] || `${msg.key.id}.${ext}` || `${v4()}.${ext}`;\n\n      if (convertToMp4 && typeMessage === 'audioMessage') {\n        try {\n          const convert = await this.processAudioMp4(buffer.toString('base64'));\n\n          if (Buffer.isBuffer(convert)) {\n            const result = {\n              mediaType,\n              fileName,\n              caption: mediaMessage['caption'],\n              size: {\n                fileLength: mediaMessage['fileLength'],\n                height: mediaMessage['height'],\n                width: mediaMessage['width'],\n              },\n              mimetype: 'audio/mp4',\n              base64: convert.toString('base64'),\n              buffer: getBuffer ? convert : null,\n            };\n\n            return result;\n          }\n        } catch (error) {\n          this.logger.error('Error converting audio to mp4:');\n          this.logger.error(error);\n          throw new BadRequestException('Failed to convert audio to MP4');\n        }\n      }\n\n      return {\n        mediaType,\n        fileName,\n        caption: mediaMessage['caption'],\n        size: { fileLength: mediaMessage['fileLength'], height: mediaMessage['height'], width: mediaMessage['width'] },\n        mimetype: mediaMessage['mimetype'],\n        base64: buffer.toString('base64'),\n        buffer: getBuffer ? buffer : null,\n      };\n    } catch (error) {\n      this.logger.error('Error processing media message:');\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  public async fetchPrivacySettings() {\n    const privacy = await this.client.fetchPrivacySettings();\n\n    return {\n      readreceipts: privacy.readreceipts,\n      profile: privacy.profile,\n      status: privacy.status,\n      online: privacy.online,\n      last: privacy.last,\n      groupadd: privacy.groupadd,\n    };\n  }\n\n  public async updatePrivacySettings(settings: PrivacySettingDto) {\n    try {\n      await this.client.updateReadReceiptsPrivacy(settings.readreceipts);\n      await this.client.updateProfilePicturePrivacy(settings.profile);\n      await this.client.updateStatusPrivacy(settings.status);\n      await this.client.updateOnlinePrivacy(settings.online);\n      await this.client.updateLastSeenPrivacy(settings.last);\n      await this.client.updateGroupsAddPrivacy(settings.groupadd);\n\n      this.reloadConnection();\n\n      return {\n        update: 'success',\n        data: {\n          readreceipts: settings.readreceipts,\n          profile: settings.profile,\n          status: settings.status,\n          online: settings.online,\n          last: settings.last,\n          groupadd: settings.groupadd,\n        },\n      };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating privacy settings', error.toString());\n    }\n  }\n\n  public async fetchBusinessProfile(number: string): Promise<NumberBusiness> {\n    try {\n      const jid = number ? createJid(number) : this.instance.wuid;\n\n      const profile = await this.client.getBusinessProfile(jid);\n\n      if (!profile) {\n        const info = await this.whatsappNumber({ numbers: [jid] });\n\n        return { isBusiness: false, message: 'Not is business profile', ...info?.shift() };\n      }\n\n      return { isBusiness: true, ...profile };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating profile name', error.toString());\n    }\n  }\n\n  public async updateProfileName(name: string) {\n    try {\n      await this.client.updateProfileName(name);\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating profile name', error.toString());\n    }\n  }\n\n  public async updateProfileStatus(status: string) {\n    try {\n      await this.client.updateProfileStatus(status);\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating profile status', error.toString());\n    }\n  }\n\n  public async updateProfilePicture(picture: string) {\n    try {\n      let pic: WAMediaUpload;\n      if (isURL(picture)) {\n        const timestamp = new Date().getTime();\n        const parsedURL = new URL(picture);\n        parsedURL.searchParams.set('timestamp', timestamp.toString());\n        const url = parsedURL.toString();\n\n        let config: any = { responseType: 'arraybuffer' };\n\n        if (this.localProxy?.enabled) {\n          config = {\n            ...config,\n            httpsAgent: makeProxyAgent({\n              host: this.localProxy.host,\n              port: this.localProxy.port,\n              protocol: this.localProxy.protocol,\n              username: this.localProxy.username,\n              password: this.localProxy.password,\n            }),\n          };\n        }\n\n        pic = (await axios.get(url, config)).data;\n      } else if (isBase64(picture)) {\n        pic = Buffer.from(picture, 'base64');\n      } else {\n        throw new BadRequestException('\"profilePicture\" must be a url or a base64');\n      }\n\n      await this.client.updateProfilePicture(this.instance.wuid, pic);\n\n      this.reloadConnection();\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating profile picture', error.toString());\n    }\n  }\n\n  public async removeProfilePicture() {\n    try {\n      await this.client.removeProfilePicture(this.instance.wuid);\n\n      this.reloadConnection();\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error removing profile picture', error.toString());\n    }\n  }\n\n  public async blockUser(data: BlockUserDto) {\n    try {\n      const { number } = data;\n\n      const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift();\n\n      if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) {\n        throw new BadRequestException(isWA);\n      }\n\n      const sender = isWA.jid;\n\n      await this.client.updateBlockStatus(sender, data.status);\n\n      return { block: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error blocking user', error.toString());\n    }\n  }\n\n  private async formatUpdateMessage(data: UpdateMessageDto) {\n    try {\n      if (!this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE) {\n        return data;\n      }\n\n      const msg: any = await this.getMessage(data.key, true);\n\n      if (msg?.messageType === 'conversation' || msg?.messageType === 'extendedTextMessage') {\n        return { text: data.text };\n      }\n\n      if (msg?.messageType === 'imageMessage') {\n        return { image: msg?.message?.imageMessage, caption: data.text };\n      }\n\n      if (msg?.messageType === 'videoMessage') {\n        return { video: msg?.message?.videoMessage, caption: data.text };\n      }\n\n      return null;\n    } catch (error) {\n      this.logger.error(error);\n      throw new BadRequestException(error.toString());\n    }\n  }\n\n  public async updateMessage(data: UpdateMessageDto) {\n    const jid = createJid(data.number);\n\n    const options = await this.formatUpdateMessage(data);\n\n    if (!options) {\n      this.logger.error('Message not compatible');\n      throw new BadRequestException('Message not compatible');\n    }\n\n    try {\n      const oldMessage: any = await this.getMessage(data.key, true);\n      if (this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE) {\n        if (!oldMessage) throw new NotFoundException('Message not found');\n        if (oldMessage?.key?.remoteJid !== jid) {\n          throw new BadRequestException('RemoteJid does not match');\n        }\n        if (oldMessage?.messageTimestamp > Date.now() + 900000) {\n          // 15 minutes in milliseconds\n          throw new BadRequestException('Message is older than 15 minutes');\n        }\n      }\n\n      const messageSent = await this.client.sendMessage(jid, { ...(options as any), edit: data.key });\n      if (messageSent) {\n        const editedMessage =\n          messageSent?.message?.protocolMessage || messageSent?.message?.editedMessage?.message?.protocolMessage;\n\n        if (editedMessage) {\n          this.sendDataWebhook(Events.SEND_MESSAGE_UPDATE, editedMessage);\n          if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled)\n            this.chatwootService.eventWhatsapp(\n              'send.message.update',\n              { instanceName: this.instance.name, instanceId: this.instance.id },\n              editedMessage,\n            );\n\n          const messageId = messageSent.message?.protocolMessage?.key?.id;\n          if (messageId && this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE) {\n            let message = await this.prismaRepository.message.findFirst({\n              where: { key: { path: ['id'], equals: messageId } },\n            });\n            if (!message) throw new NotFoundException('Message not found');\n\n            if (!(message.key.valueOf() as any).fromMe) {\n              new BadRequestException('You cannot edit others messages');\n            }\n            if ((message.key.valueOf() as any)?.deleted) {\n              new BadRequestException('You cannot edit deleted messages');\n            }\n\n            if (oldMessage.messageType === 'conversation' || oldMessage.messageType === 'extendedTextMessage') {\n              oldMessage.message.conversation = data.text;\n            } else {\n              oldMessage.message[oldMessage.messageType].caption = data.text;\n            }\n            message = await this.prismaRepository.message.update({\n              where: { id: message.id },\n              data: {\n                message: oldMessage.message,\n                status: 'EDITED',\n                messageTimestamp: Math.floor(Date.now() / 1000), // Convert to int32 by dividing by 1000 to get seconds\n              },\n            });\n\n            if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE) {\n              const messageUpdate: any = {\n                messageId: message.id,\n                keyId: messageId,\n                remoteJid: messageSent.key.remoteJid,\n                fromMe: messageSent.key.fromMe,\n                participant: messageSent.key?.participant,\n                status: 'EDITED',\n                instanceId: this.instanceId,\n              };\n              await this.prismaRepository.messageUpdate.create({ data: messageUpdate });\n            }\n          }\n        }\n      }\n\n      return messageSent;\n    } catch (error) {\n      this.logger.error(error);\n      throw error;\n    }\n  }\n\n  public async fetchLabels(): Promise<LabelDto[]> {\n    const labels = await this.prismaRepository.label.findMany({ where: { instanceId: this.instanceId } });\n\n    return labels.map((label) => ({\n      color: label.color,\n      name: label.name,\n      id: label.labelId,\n      predefinedId: label.predefinedId,\n    }));\n  }\n\n  public async handleLabel(data: HandleLabelDto) {\n    const whatsappContact = await this.whatsappNumber({ numbers: [data.number] });\n    if (whatsappContact.length === 0) {\n      throw new NotFoundException('Number not found');\n    }\n    const contact = whatsappContact[0];\n    if (!contact.exists) {\n      throw new NotFoundException('Number is not on WhatsApp');\n    }\n\n    try {\n      if (data.action === 'add') {\n        await this.client.addChatLabel(contact.jid, data.labelId);\n        await this.addLabel(data.labelId, this.instanceId, contact.jid);\n\n        return { numberJid: contact.jid, labelId: data.labelId, add: true };\n      }\n      if (data.action === 'remove') {\n        await this.client.removeChatLabel(contact.jid, data.labelId);\n        await this.removeLabel(data.labelId, this.instanceId, contact.jid);\n\n        return { numberJid: contact.jid, labelId: data.labelId, remove: true };\n      }\n    } catch (error) {\n      throw new BadRequestException(`Unable to ${data.action} label to chat`, error.toString());\n    }\n  }\n\n  // Group\n  private async updateGroupMetadataCache(groupJid: string) {\n    try {\n      const meta = await this.client.groupMetadata(groupJid);\n\n      const cacheConf = this.configService.get<CacheConf>('CACHE');\n\n      if ((cacheConf?.REDIS?.ENABLED && cacheConf?.REDIS?.URI !== '') || cacheConf?.LOCAL?.ENABLED) {\n        this.logger.verbose(`Updating cache for group: ${groupJid}`);\n        await groupMetadataCache.set(groupJid, { timestamp: Date.now(), data: meta });\n      }\n\n      return meta;\n    } catch (error) {\n      this.logger.error(error);\n      return null;\n    }\n  }\n\n  private getGroupMetadataCache = async (groupJid: string) => {\n    if (!isJidGroup(groupJid)) return null;\n\n    const cacheConf = this.configService.get<CacheConf>('CACHE');\n\n    if ((cacheConf?.REDIS?.ENABLED && cacheConf?.REDIS?.URI !== '') || cacheConf?.LOCAL?.ENABLED) {\n      if (await groupMetadataCache?.has(groupJid)) {\n        console.log(`Cache request for group: ${groupJid}`);\n        const meta = await groupMetadataCache.get(groupJid);\n\n        if (Date.now() - meta.timestamp > 3600000) {\n          await this.updateGroupMetadataCache(groupJid);\n        }\n\n        return meta.data;\n      }\n\n      console.log(`Cache request for group: ${groupJid} - not found`);\n      return await this.updateGroupMetadataCache(groupJid);\n    }\n\n    return await this.findGroup({ groupJid }, 'inner');\n  };\n\n  public async createGroup(create: CreateGroupDto) {\n    try {\n      const participants = (await this.whatsappNumber({ numbers: create.participants }))\n        .filter((participant) => participant.exists)\n        .map((participant) => participant.jid);\n      const { id } = await this.client.groupCreate(create.subject, participants);\n\n      if (create?.description) {\n        await this.client.groupUpdateDescription(id, create.description);\n      }\n\n      if (create?.promoteParticipants) {\n        await this.updateGParticipant({ groupJid: id, action: 'promote', participants: participants });\n      }\n\n      const group = await this.client.groupMetadata(id);\n\n      return group;\n    } catch (error) {\n      this.logger.error(error);\n      throw new InternalServerErrorException('Error creating group', error.toString());\n    }\n  }\n\n  public async updateGroupPicture(picture: GroupPictureDto) {\n    try {\n      let pic: WAMediaUpload;\n      if (isURL(picture.image)) {\n        const timestamp = new Date().getTime();\n        const parsedURL = new URL(picture.image);\n        parsedURL.searchParams.set('timestamp', timestamp.toString());\n        const url = parsedURL.toString();\n\n        let config: any = { responseType: 'arraybuffer' };\n\n        if (this.localProxy?.enabled) {\n          config = {\n            ...config,\n            httpsAgent: makeProxyAgent({\n              host: this.localProxy.host,\n              port: this.localProxy.port,\n              protocol: this.localProxy.protocol,\n              username: this.localProxy.username,\n              password: this.localProxy.password,\n            }),\n          };\n        }\n\n        pic = (await axios.get(url, config)).data;\n      } else if (isBase64(picture.image)) {\n        pic = Buffer.from(picture.image, 'base64');\n      } else {\n        throw new BadRequestException('\"profilePicture\" must be a url or a base64');\n      }\n      await this.client.updateProfilePicture(picture.groupJid, pic);\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error update group picture', error.toString());\n    }\n  }\n\n  public async updateGroupSubject(data: GroupSubjectDto) {\n    try {\n      await this.client.groupUpdateSubject(data.groupJid, data.subject);\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating group subject', error.toString());\n    }\n  }\n\n  public async updateGroupDescription(data: GroupDescriptionDto) {\n    try {\n      await this.client.groupUpdateDescription(data.groupJid, data.description);\n\n      return { update: 'success' };\n    } catch (error) {\n      throw new InternalServerErrorException('Error updating group description', error.toString());\n    }\n  }\n\n  public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') {\n    try {\n      const group = await this.client.groupMetadata(id.groupJid);\n\n      if (!group) {\n        this.logger.error('Group not found');\n        return null;\n      }\n\n      const picture = await this.profilePicture(group.id);\n\n      return {\n        id: group.id,\n        subject: group.subject,\n        subjectOwner: group.subjectOwner,\n        subjectTime: group.subjectTime,\n        pictureUrl: picture.profilePictureUrl,\n        size: group.participants.length,\n        creation: group.creation,\n        owner: group.owner,\n        desc: group.desc,\n        descId: group.descId,\n        restrict: group.restrict,\n        announce: group.announce,\n        participants: group.participants,\n        isCommunity: group.isCommunity,\n        isCommunityAnnounce: group.isCommunityAnnounce,\n        linkedParent: group.linkedParent,\n      };\n    } catch (error) {\n      if (reply === 'inner') {\n        return;\n      }\n      throw new NotFoundException('Error fetching group', error.toString());\n    }\n  }\n\n  public async fetchAllGroups(getParticipants: GetParticipant) {\n    const fetch = Object.values(await this?.client?.groupFetchAllParticipating());\n\n    let groups = [];\n    for (const group of fetch) {\n      const picture = await this.profilePicture(group.id);\n\n      const result = {\n        id: group.id,\n        subject: group.subject,\n        subjectOwner: group.subjectOwner,\n        subjectTime: group.subjectTime,\n        pictureUrl: picture?.profilePictureUrl,\n        size: group.participants.length,\n        creation: group.creation,\n        owner: group.owner,\n        desc: group.desc,\n        descId: group.descId,\n        restrict: group.restrict,\n        announce: group.announce,\n        isCommunity: group.isCommunity,\n        isCommunityAnnounce: group.isCommunityAnnounce,\n        linkedParent: group.linkedParent,\n      };\n\n      if (getParticipants.getParticipants == 'true') {\n        result['participants'] = group.participants;\n      }\n\n      groups = [...groups, result];\n    }\n\n    return groups;\n  }\n\n  public async inviteCode(id: GroupJid) {\n    try {\n      const code = await this.client.groupInviteCode(id.groupJid);\n      return { inviteUrl: `https://chat.whatsapp.com/${code}`, inviteCode: code };\n    } catch (error) {\n      throw new NotFoundException('No invite code', error.toString());\n    }\n  }\n\n  public async inviteInfo(id: GroupInvite) {\n    try {\n      return await this.client.groupGetInviteInfo(id.inviteCode);\n    } catch {\n      throw new NotFoundException('No invite info', id.inviteCode);\n    }\n  }\n\n  public async sendInvite(id: GroupSendInvite) {\n    try {\n      const inviteCode = await this.inviteCode({ groupJid: id.groupJid });\n\n      const inviteUrl = inviteCode.inviteUrl;\n\n      const numbers = id.numbers.map((number) => createJid(number));\n      const description = id.description ?? '';\n\n      const msg = `${description}\\n\\n${inviteUrl}`;\n\n      const message = { conversation: msg };\n\n      for await (const number of numbers) {\n        await this.sendMessageWithTyping(number, message);\n      }\n\n      return { send: true, inviteUrl };\n    } catch {\n      throw new NotFoundException('No send invite');\n    }\n  }\n\n  public async acceptInviteCode(id: AcceptGroupInvite) {\n    try {\n      const groupJid = await this.client.groupAcceptInvite(id.inviteCode);\n      return { accepted: true, groupJid: groupJid };\n    } catch (error) {\n      throw new NotFoundException('Accept invite error', error.toString());\n    }\n  }\n\n  public async revokeInviteCode(id: GroupJid) {\n    try {\n      const inviteCode = await this.client.groupRevokeInvite(id.groupJid);\n      return { revoked: true, inviteCode };\n    } catch (error) {\n      throw new NotFoundException('Revoke error', error.toString());\n    }\n  }\n\n  public async findParticipants(id: GroupJid) {\n    try {\n      const participants = (await this.client.groupMetadata(id.groupJid)).participants;\n      const contacts = await this.prismaRepository.contact.findMany({\n        where: { instanceId: this.instanceId, remoteJid: { in: participants.map((p) => p.id) } },\n      });\n      const parsedParticipants = participants.map((participant) => {\n        const contact = contacts.find((c) => c.remoteJid === participant.id);\n        return {\n          ...participant,\n          name: participant.name ?? contact?.pushName,\n          imgUrl: participant.imgUrl ?? contact?.profilePicUrl,\n        };\n      });\n\n      const usersContacts = parsedParticipants.filter((c) => c.id.includes('@s.whatsapp'));\n      if (usersContacts) {\n        await saveOnWhatsappCache(usersContacts.map((c) => ({ remoteJid: c.id })));\n      }\n\n      return { participants: parsedParticipants };\n    } catch (error) {\n      console.error(error);\n      throw new NotFoundException('No participants', error.toString());\n    }\n  }\n\n  public async updateGParticipant(update: GroupUpdateParticipantDto) {\n    try {\n      const participants = update.participants.map((p) => createJid(p));\n      const updateParticipants = await this.client.groupParticipantsUpdate(\n        update.groupJid,\n        participants,\n        update.action,\n      );\n      return { updateParticipants: updateParticipants };\n    } catch (error) {\n      throw new BadRequestException('Error updating participants', error.toString());\n    }\n  }\n\n  public async updateGSetting(update: GroupUpdateSettingDto) {\n    try {\n      const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action);\n      return { updateSetting: updateSetting };\n    } catch (error) {\n      throw new BadRequestException('Error updating setting', error.toString());\n    }\n  }\n\n  public async toggleEphemeral(update: GroupToggleEphemeralDto) {\n    try {\n      await this.client.groupToggleEphemeral(update.groupJid, update.expiration);\n      return { success: true };\n    } catch (error) {\n      throw new BadRequestException('Error updating setting', error.toString());\n    }\n  }\n\n  public async leaveGroup(id: GroupJid) {\n    try {\n      await this.client.groupLeave(id.groupJid);\n      return { groupJid: id.groupJid, leave: true };\n    } catch (error) {\n      throw new BadRequestException('Unable to leave the group', error.toString());\n    }\n  }\n\n  public async templateMessage() {\n    throw new Error('Method not available in the Baileys service');\n  }\n\n  private deserializeMessageBuffers(obj: any): any {\n    if (obj === null || obj === undefined) {\n      return obj;\n    }\n\n    if (typeof obj === 'object' && !Array.isArray(obj) && !Buffer.isBuffer(obj)) {\n      const keys = Object.keys(obj);\n      const isIndexedObject = keys.every((key) => !isNaN(Number(key)));\n\n      if (isIndexedObject && keys.length > 0) {\n        const values = keys.sort((a, b) => Number(a) - Number(b)).map((key) => obj[key]);\n        return new Uint8Array(values);\n      }\n    }\n\n    // Is Buffer?, converter to Uint8Array\n    if (Buffer.isBuffer(obj)) {\n      return new Uint8Array(obj);\n    }\n\n    // Process arrays recursively\n    if (Array.isArray(obj)) {\n      return obj.map((item) => this.deserializeMessageBuffers(item));\n    }\n\n    // Process objects recursively\n    if (typeof obj === 'object') {\n      const converted: any = {};\n      for (const key in obj) {\n        if (Object.prototype.hasOwnProperty.call(obj, key)) {\n          converted[key] = this.deserializeMessageBuffers(obj[key]);\n        }\n      }\n      return converted;\n    }\n\n    return obj;\n  }\n\n  private prepareMessage(message: proto.IWebMessageInfo): any {\n    const contentType = getContentType(message.message);\n    const contentMsg = message?.message[contentType] as any;\n\n    const messageRaw = {\n      key: message.key, // Save key exactly as it comes from Baileys\n      pushName:\n        message.pushName ||\n        (message.key.fromMe\n          ? 'Você'\n          : message?.participant || (message.key?.participant ? message.key.participant.split('@')[0] : null)),\n      status: status[message.status],\n      message: this.deserializeMessageBuffers({ ...message.message }),\n      contextInfo: this.deserializeMessageBuffers(contentMsg?.contextInfo),\n      messageType: contentType || 'unknown',\n      messageTimestamp: Long.isLong(message.messageTimestamp)\n        ? message.messageTimestamp.toNumber()\n        : (message.messageTimestamp as number),\n      instanceId: this.instanceId,\n      source: getDevice(message.key.id),\n    };\n\n    if (!messageRaw.status && message.key.fromMe === false) {\n      messageRaw.status = status[3]; // DELIVERED MESSAGE\n    }\n\n    if (messageRaw.message.extendedTextMessage) {\n      messageRaw.messageType = 'conversation';\n      messageRaw.message.conversation = messageRaw.message.extendedTextMessage.text;\n      delete messageRaw.message.extendedTextMessage;\n    }\n\n    if (messageRaw.message.documentWithCaptionMessage) {\n      messageRaw.messageType = 'documentMessage';\n      messageRaw.message.documentMessage = messageRaw.message.documentWithCaptionMessage.message.documentMessage;\n      delete messageRaw.message.documentWithCaptionMessage;\n    }\n\n    const quotedMessage = messageRaw?.contextInfo?.quotedMessage;\n    if (quotedMessage) {\n      if (quotedMessage.extendedTextMessage) {\n        quotedMessage.conversation = quotedMessage.extendedTextMessage.text;\n        delete quotedMessage.extendedTextMessage;\n      }\n\n      if (quotedMessage.documentWithCaptionMessage) {\n        quotedMessage.documentMessage = quotedMessage.documentWithCaptionMessage.message.documentMessage;\n        delete quotedMessage.documentWithCaptionMessage;\n      }\n    }\n\n    return messageRaw;\n  }\n\n  private async syncChatwootLostMessages() {\n    if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n      const chatwootConfig = await this.findChatwoot();\n      const prepare = (message: any) => this.prepareMessage(message);\n      this.chatwootService.syncLostMessages({ instanceName: this.instance.name }, chatwootConfig, prepare);\n\n      // Generate ID for this cron task and store in cache\n      const cronId = cuid();\n      const cronKey = `chatwoot:syncLostMessages`;\n      await this.chatwootService.getCache()?.hSet(cronKey, this.instance.name, cronId);\n\n      const task = cron.schedule('0,30 * * * *', async () => {\n        // Check ID before executing (only if cache is available)\n        const cache = this.chatwootService.getCache();\n        if (cache) {\n          const storedId = await cache.hGet(cronKey, this.instance.name);\n          if (storedId && storedId !== cronId) {\n            this.logger.info(`Stopping syncChatwootLostMessages cron - ID mismatch: ${cronId} vs ${storedId}`);\n            task.stop();\n            return;\n          }\n        }\n        this.chatwootService.syncLostMessages({ instanceName: this.instance.name }, chatwootConfig, prepare);\n      });\n      task.start();\n    }\n  }\n\n  private async updateMessagesReadedByTimestamp(remoteJid: string, timestamp?: number): Promise<number> {\n    if (timestamp === undefined || timestamp === null) return 0;\n\n    // Use raw SQL to avoid JSON path issues\n    const result = await this.prismaRepository.$executeRaw`\n      UPDATE \"Message\"\n      SET \"status\" = ${status[4]}\n      WHERE \"instanceId\" = ${this.instanceId}\n      AND \"key\"->>'remoteJid' = ${remoteJid}\n      AND (\"key\"->>'fromMe')::boolean = false\n      AND \"messageTimestamp\" <= ${timestamp}\n      AND (\"status\" IS NULL OR \"status\" = ${status[3]})\n    `;\n\n    if (result) {\n      if (result > 0) {\n        this.updateChatUnreadMessages(remoteJid);\n      }\n\n      return result;\n    }\n\n    return 0;\n  }\n\n  private async updateChatUnreadMessages(remoteJid: string): Promise<number> {\n    const [chat, unreadMessages] = await Promise.all([\n      this.prismaRepository.chat.findFirst({ where: { remoteJid } }),\n      // Use raw SQL to avoid JSON path issues\n      this.prismaRepository.$queryRaw`\n        SELECT COUNT(*)::int as count FROM \"Message\"\n        WHERE \"instanceId\" = ${this.instanceId}\n        AND \"key\"->>'remoteJid' = ${remoteJid}\n        AND (\"key\"->>'fromMe')::boolean = false\n        AND \"status\" = ${status[3]}\n      `.then((result: any[]) => result[0]?.count || 0),\n    ]);\n\n    if (chat && chat.unreadMessages !== unreadMessages) {\n      await this.prismaRepository.chat.update({ where: { id: chat.id }, data: { unreadMessages } });\n    }\n\n    return unreadMessages;\n  }\n\n  private async addLabel(labelId: string, instanceId: string, chatId: string) {\n    const id = cuid();\n\n    await this.prismaRepository.$executeRawUnsafe(\n      `INSERT INTO \"Chat\" (\"id\", \"instanceId\", \"remoteJid\", \"labels\", \"createdAt\", \"updatedAt\")\n       VALUES ($4, $2, $3, to_jsonb(ARRAY[$1]::text[]), NOW(), NOW()) ON CONFLICT (\"instanceId\", \"remoteJid\")\n     DO\n      UPDATE\n          SET \"labels\" = (\n          SELECT to_jsonb(array_agg(DISTINCT elem))\n          FROM (\n          SELECT jsonb_array_elements_text(\"Chat\".\"labels\") AS elem\n          UNION\n          SELECT $1::text AS elem\n          ) sub\n          ),\n          \"updatedAt\" = NOW();`,\n      labelId,\n      instanceId,\n      chatId,\n      id,\n    );\n  }\n\n  private async removeLabel(labelId: string, instanceId: string, chatId: string) {\n    const id = cuid();\n\n    await this.prismaRepository.$executeRawUnsafe(\n      `INSERT INTO \"Chat\" (\"id\", \"instanceId\", \"remoteJid\", \"labels\", \"createdAt\", \"updatedAt\")\n       VALUES ($4, $2, $3, '[]'::jsonb, NOW(), NOW()) ON CONFLICT (\"instanceId\", \"remoteJid\")\n     DO\n      UPDATE\n          SET \"labels\" = COALESCE (\n          (\n          SELECT jsonb_agg(elem)\n          FROM jsonb_array_elements_text(\"Chat\".\"labels\") AS elem\n          WHERE elem <> $1\n          ),\n          '[]'::jsonb\n          ),\n          \"updatedAt\" = NOW();`,\n      labelId,\n      instanceId,\n      chatId,\n      id,\n    );\n  }\n\n  public async baileysOnWhatsapp(jid: string) {\n    const response = await this.client.onWhatsApp(jid);\n\n    return response;\n  }\n\n  public async baileysProfilePictureUrl(jid: string, type: 'image' | 'preview', timeoutMs: number) {\n    const response = await this.client.profilePictureUrl(jid, type, timeoutMs);\n\n    return response;\n  }\n\n  public async baileysAssertSessions(jids: string[]) {\n    const response = await this.client.assertSessions(jids);\n\n    return response;\n  }\n\n  public async baileysCreateParticipantNodes(jids: string[], message: proto.IMessage, extraAttrs: any) {\n    const response = await this.client.createParticipantNodes(jids, message, extraAttrs);\n\n    const convertedResponse = {\n      ...response,\n      nodes: response.nodes.map((node: any) => ({\n        ...node,\n        content: node.content?.map((c: any) => ({\n          ...c,\n          content: c.content instanceof Uint8Array ? Buffer.from(c.content).toString('base64') : c.content,\n        })),\n      })),\n    };\n\n    return convertedResponse;\n  }\n\n  public async baileysSendNode(stanza: any) {\n    console.log('stanza', JSON.stringify(stanza));\n    const response = await this.client.sendNode(stanza);\n\n    return response;\n  }\n\n  public async baileysGetUSyncDevices(jids: string[], useCache: boolean, ignoreZeroDevices: boolean) {\n    const response = await this.client.getUSyncDevices(jids, useCache, ignoreZeroDevices);\n\n    return response;\n  }\n\n  public async baileysGenerateMessageTag() {\n    const response = await this.client.generateMessageTag();\n\n    return response;\n  }\n\n  public async baileysSignalRepositoryDecryptMessage(jid: string, type: 'pkmsg' | 'msg', ciphertext: string) {\n    try {\n      const ciphertextBuffer = Buffer.from(ciphertext, 'base64');\n\n      const response = await this.client.signalRepository.decryptMessage({ jid, type, ciphertext: ciphertextBuffer });\n\n      return response instanceof Uint8Array ? Buffer.from(response).toString('base64') : response;\n    } catch (error) {\n      this.logger.error('Error decrypting message:');\n      this.logger.error(error);\n      throw error;\n    }\n  }\n\n  public async baileysGetAuthState() {\n    const response = { me: this.client.authState.creds.me, account: this.client.authState.creds.account };\n\n    return response;\n  }\n\n  //Business Controller\n  public async fetchCatalog(instanceName: string, data: getCollectionsDto) {\n    const jid = data.number ? createJid(data.number) : this.client?.user?.id;\n    const limit = data.limit || 10;\n    const cursor = null;\n\n    const onWhatsapp = (await this.whatsappNumber({ numbers: [jid] }))?.shift();\n\n    if (!onWhatsapp.exists) {\n      throw new BadRequestException(onWhatsapp);\n    }\n\n    try {\n      const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift();\n      const business = await this.fetchBusinessProfile(info?.jid);\n\n      let catalog = await this.getCatalog({ jid: info?.jid, limit, cursor });\n      let nextPageCursor = catalog.nextPageCursor;\n      let nextPageCursorJson = nextPageCursor ? JSON.parse(atob(nextPageCursor)) : null;\n      let pagination = nextPageCursorJson?.pagination_cursor\n        ? JSON.parse(atob(nextPageCursorJson.pagination_cursor))\n        : null;\n      let fetcherHasMore = pagination?.fetcher_has_more === true ? true : false;\n\n      let productsCatalog = catalog.products || [];\n      let countLoops = 0;\n      while (fetcherHasMore && countLoops < 4) {\n        catalog = await this.getCatalog({ jid: info?.jid, limit, cursor: nextPageCursor });\n        nextPageCursor = catalog.nextPageCursor;\n        nextPageCursorJson = nextPageCursor ? JSON.parse(atob(nextPageCursor)) : null;\n        pagination = nextPageCursorJson?.pagination_cursor\n          ? JSON.parse(atob(nextPageCursorJson.pagination_cursor))\n          : null;\n        fetcherHasMore = pagination?.fetcher_has_more === true ? true : false;\n        productsCatalog = [...productsCatalog, ...catalog.products];\n        countLoops++;\n      }\n\n      return {\n        wuid: info?.jid || jid,\n        numberExists: info?.exists,\n        isBusiness: business.isBusiness,\n        catalogLength: productsCatalog.length,\n        catalog: productsCatalog,\n      };\n    } catch (error) {\n      console.log(error);\n      return { wuid: jid, name: null, isBusiness: false };\n    }\n  }\n\n  public async getCatalog({\n    jid,\n    limit,\n    cursor,\n  }: GetCatalogOptions): Promise<{ products: Product[]; nextPageCursor: string | undefined }> {\n    try {\n      jid = jid ? createJid(jid) : this.instance.wuid;\n\n      const catalog = await this.client.getCatalog({ jid, limit: limit, cursor: cursor });\n\n      if (!catalog) {\n        return { products: undefined, nextPageCursor: undefined };\n      }\n\n      return catalog;\n    } catch (error) {\n      throw new InternalServerErrorException('Error getCatalog', error.toString());\n    }\n  }\n\n  public async fetchCollections(instanceName: string, data: getCollectionsDto) {\n    const jid = data.number ? createJid(data.number) : this.client?.user?.id;\n    const limit = data.limit <= 20 ? data.limit : 20; //(tem esse limite, não sei porque)\n\n    const onWhatsapp = (await this.whatsappNumber({ numbers: [jid] }))?.shift();\n\n    if (!onWhatsapp.exists) {\n      throw new BadRequestException(onWhatsapp);\n    }\n\n    try {\n      const info = (await this.whatsappNumber({ numbers: [jid] }))?.shift();\n      const business = await this.fetchBusinessProfile(info?.jid);\n      const collections = await this.getCollections(info?.jid, limit);\n\n      return {\n        wuid: info?.jid || jid,\n        name: info?.name,\n        numberExists: info?.exists,\n        isBusiness: business.isBusiness,\n        collectionsLength: collections?.length,\n        collections: collections,\n      };\n    } catch {\n      return { wuid: jid, name: null, isBusiness: false };\n    }\n  }\n\n  public async getCollections(jid?: string | undefined, limit?: number): Promise<CatalogCollection[]> {\n    try {\n      jid = jid ? createJid(jid) : this.instance.wuid;\n\n      const result = await this.client.getCollections(jid, limit);\n\n      if (!result) {\n        return [{ id: undefined, name: undefined, products: [], status: undefined }];\n      }\n\n      return result.collections;\n    } catch (error) {\n      throw new InternalServerErrorException('Error getCatalog', error.toString());\n    }\n  }\n\n  public async fetchMessages(query: Query<Message>) {\n    const keyFilters = query?.where?.key as ExtendedIMessageKey;\n\n    const timestampFilter = {};\n    if (query?.where?.messageTimestamp) {\n      if (query.where.messageTimestamp['gte'] && query.where.messageTimestamp['lte']) {\n        timestampFilter['messageTimestamp'] = {\n          gte: Math.floor(new Date(query.where.messageTimestamp['gte']).getTime() / 1000),\n          lte: Math.floor(new Date(query.where.messageTimestamp['lte']).getTime() / 1000),\n        };\n      }\n    }\n\n    const count = await this.prismaRepository.message.count({\n      where: {\n        instanceId: this.instanceId,\n        id: query?.where?.id,\n        source: query?.where?.source,\n        messageType: query?.where?.messageType,\n        ...timestampFilter,\n        AND: [\n          keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {},\n          keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {},\n          keyFilters?.participant ? { key: { path: ['participant'], equals: keyFilters?.participant } } : {},\n          {\n            OR: [\n              keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {},\n              keyFilters?.remoteJidAlt ? { key: { path: ['remoteJidAlt'], equals: keyFilters?.remoteJidAlt } } : {},\n            ],\n          },\n        ],\n      },\n    });\n\n    if (!query?.offset) {\n      query.offset = 50;\n    }\n\n    if (!query?.page) {\n      query.page = 1;\n    }\n\n    const messages = await this.prismaRepository.message.findMany({\n      where: {\n        instanceId: this.instanceId,\n        id: query?.where?.id,\n        source: query?.where?.source,\n        messageType: query?.where?.messageType,\n        ...timestampFilter,\n        AND: [\n          keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {},\n          keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {},\n          keyFilters?.participant ? { key: { path: ['participant'], equals: keyFilters?.participant } } : {},\n          {\n            OR: [\n              keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {},\n              keyFilters?.remoteJidAlt ? { key: { path: ['remoteJidAlt'], equals: keyFilters?.remoteJidAlt } } : {},\n            ],\n          },\n        ],\n      },\n      orderBy: { messageTimestamp: 'desc' },\n      skip: query.offset * (query?.page === 1 ? 0 : (query?.page as number) - 1),\n      take: query.offset,\n      select: {\n        id: true,\n        key: true,\n        pushName: true,\n        messageType: true,\n        message: true,\n        messageTimestamp: true,\n        instanceId: true,\n        source: true,\n        contextInfo: true,\n        MessageUpdate: { select: { status: true } },\n      },\n    });\n\n    const formattedMessages = messages.map((message) => {\n      const messageKey = message.key as { fromMe: boolean; remoteJid: string; id: string; participant?: string };\n\n      if (!message.pushName) {\n        if (messageKey.fromMe) {\n          message.pushName = 'Você';\n        } else if (message.contextInfo) {\n          const contextInfo = message.contextInfo as { participant?: string };\n          if (contextInfo.participant) {\n            message.pushName = contextInfo.participant.split('@')[0];\n          } else if (messageKey.participant) {\n            message.pushName = messageKey.participant.split('@')[0];\n          }\n        }\n      }\n\n      return message;\n    });\n\n    return {\n      messages: {\n        total: count,\n        pages: Math.ceil(count / query.offset),\n        currentPage: query.page,\n        records: formattedMessages,\n      },\n    };\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/base-chatbot.controller.ts",
    "content": "import { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Events } from '@api/types/wa.types';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { TriggerOperator, TriggerType } from '@prisma/client';\nimport { getConversationMessage } from '@utils/getConversationMessage';\n\nimport { BaseChatbotDto } from './base-chatbot.dto';\nimport { ChatbotController, ChatbotControllerInterface, EmitData } from './chatbot.controller';\n\n// Common settings interface for all chatbot integrations\nexport interface ChatbotSettings {\n  expire: number;\n  keywordFinish: string;\n  delayMessage: number;\n  unknownMessage: string;\n  listeningFromMe: boolean;\n  stopBotFromMe: boolean;\n  keepOpen: boolean;\n  debounceTime: number;\n  ignoreJids: string[];\n  splitMessages: boolean;\n  timePerChar: number;\n  [key: string]: any;\n}\n\n// Common bot properties for all chatbot integrations\nexport interface BaseBotData {\n  enabled?: boolean;\n  description: string;\n  expire?: number;\n  keywordFinish?: string;\n  delayMessage?: number;\n  unknownMessage?: string;\n  listeningFromMe?: boolean;\n  stopBotFromMe?: boolean;\n  keepOpen?: boolean;\n  debounceTime?: number;\n  triggerType: string | TriggerType;\n  triggerOperator?: string | TriggerOperator;\n  triggerValue?: string;\n  ignoreJids?: string[];\n  splitMessages?: boolean;\n  timePerChar?: number;\n  [key: string]: any;\n}\n\nexport abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto>\n  extends ChatbotController\n  implements ChatbotControllerInterface\n{\n  public readonly logger: Logger;\n\n  integrationEnabled: boolean;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  // Name of the integration, to be set by the derived class\n  protected abstract readonly integrationName: string;\n\n  // Method to process bot-specific logic\n  protected abstract processBot(\n    waInstance: any,\n    remoteJid: string,\n    bot: BotType,\n    session: any,\n    settings: ChatbotSettings,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void>;\n\n  // Method to get the fallback bot ID from settings\n  protected abstract getFallbackBotId(settings: any): string | undefined;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor);\n\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  // Base create bot implementation\n  public async createBot(instance: InstanceDto, data: BotData) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    // Set default settings if not provided\n    if (\n      !data.expire ||\n      !data.keywordFinish ||\n      !data.delayMessage ||\n      !data.unknownMessage ||\n      !data.listeningFromMe ||\n      !data.stopBotFromMe ||\n      !data.keepOpen ||\n      !data.debounceTime ||\n      !data.ignoreJids ||\n      !data.splitMessages ||\n      !data.timePerChar\n    ) {\n      const defaultSettingCheck = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instanceId,\n        },\n      });\n\n      if (data.expire === undefined || data.expire === null) data.expire = defaultSettingCheck?.expire;\n      if (data.keywordFinish === undefined || data.keywordFinish === null)\n        data.keywordFinish = defaultSettingCheck?.keywordFinish;\n      if (data.delayMessage === undefined || data.delayMessage === null)\n        data.delayMessage = defaultSettingCheck?.delayMessage;\n      if (data.unknownMessage === undefined || data.unknownMessage === null)\n        data.unknownMessage = defaultSettingCheck?.unknownMessage;\n      if (data.listeningFromMe === undefined || data.listeningFromMe === null)\n        data.listeningFromMe = defaultSettingCheck?.listeningFromMe;\n      if (data.stopBotFromMe === undefined || data.stopBotFromMe === null)\n        data.stopBotFromMe = defaultSettingCheck?.stopBotFromMe;\n      if (data.keepOpen === undefined || data.keepOpen === null) data.keepOpen = defaultSettingCheck?.keepOpen;\n      if (data.debounceTime === undefined || data.debounceTime === null)\n        data.debounceTime = defaultSettingCheck?.debounceTime;\n      if (data.ignoreJids === undefined || data.ignoreJids === null) data.ignoreJids = defaultSettingCheck?.ignoreJids;\n      if (data.splitMessages === undefined || data.splitMessages === null)\n        data.splitMessages = defaultSettingCheck?.splitMessages ?? false;\n      if (data.timePerChar === undefined || data.timePerChar === null)\n        data.timePerChar = defaultSettingCheck?.timePerChar ?? 0;\n\n      if (!defaultSettingCheck) {\n        await this.settings(instance, {\n          expire: data.expire,\n          keywordFinish: data.keywordFinish,\n          delayMessage: data.delayMessage,\n          unknownMessage: data.unknownMessage,\n          listeningFromMe: data.listeningFromMe,\n          stopBotFromMe: data.stopBotFromMe,\n          keepOpen: data.keepOpen,\n          debounceTime: data.debounceTime,\n          ignoreJids: data.ignoreJids,\n          splitMessages: data.splitMessages,\n          timePerChar: data.timePerChar,\n        });\n      }\n    }\n\n    const checkTriggerAll = await this.botRepository.findFirst({\n      where: {\n        enabled: true,\n        triggerType: 'all',\n        instanceId: instanceId,\n      },\n    });\n\n    if (checkTriggerAll && data.triggerType === 'all') {\n      throw new Error(\n        `You already have a ${this.integrationName} with an \"All\" trigger, you cannot have more bots while it is active`,\n      );\n    }\n\n    // Check for trigger keyword duplicates\n    if (data.triggerType === 'keyword') {\n      if (!data.triggerOperator || !data.triggerValue) {\n        throw new Error('Trigger operator and value are required');\n      }\n\n      const checkDuplicate = await this.botRepository.findFirst({\n        where: {\n          triggerOperator: data.triggerOperator,\n          triggerValue: data.triggerValue,\n          instanceId: instanceId,\n        },\n      });\n\n      if (checkDuplicate) {\n        throw new Error('Trigger already exists');\n      }\n    }\n\n    // Check for trigger advanced duplicates\n    if (data.triggerType === 'advanced') {\n      if (!data.triggerValue) {\n        throw new Error('Trigger value is required');\n      }\n\n      const checkDuplicate = await this.botRepository.findFirst({\n        where: {\n          triggerValue: data.triggerValue,\n          instanceId: instanceId,\n        },\n      });\n\n      if (checkDuplicate) {\n        throw new Error('Trigger already exists');\n      }\n    }\n\n    // Derived classes should implement the specific duplicate checking before calling this method\n    // and add bot-specific fields to the data object\n\n    try {\n      const botData = {\n        enabled: data?.enabled,\n        description: data.description,\n        expire: data.expire,\n        keywordFinish: data.keywordFinish,\n        delayMessage: data.delayMessage,\n        unknownMessage: data.unknownMessage,\n        listeningFromMe: data.listeningFromMe,\n        stopBotFromMe: data.stopBotFromMe,\n        keepOpen: data.keepOpen,\n        debounceTime: data.debounceTime,\n        instanceId: instanceId,\n        triggerType: data.triggerType,\n        triggerOperator: data.triggerOperator,\n        triggerValue: data.triggerValue,\n        ignoreJids: data.ignoreJids,\n        splitMessages: data.splitMessages,\n        timePerChar: data.timePerChar,\n        ...this.getAdditionalBotData(data),\n      };\n\n      const bot = await this.botRepository.create({\n        data: botData,\n      });\n\n      return bot;\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error(`Error creating ${this.integrationName}`);\n    }\n  }\n\n  // Additional fields needed for specific bot types\n  protected abstract getAdditionalBotData(data: BotData): Record<string, any>;\n\n  // Common implementation for findBot\n  public async findBot(instance: InstanceDto) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    try {\n      const bots = await this.botRepository.findMany({\n        where: {\n          instanceId: instanceId,\n        },\n      });\n\n      return bots;\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error(`Error finding ${this.integrationName}`);\n    }\n  }\n\n  // Common implementation for fetchBot\n  public async fetchBot(instance: InstanceDto, botId: string) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const bot = await this.botRepository.findUnique({\n        where: {\n          id: botId,\n        },\n      });\n\n      if (!bot) {\n        return null;\n      }\n\n      return bot;\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error(`Error fetching ${this.integrationName}`);\n    }\n  }\n\n  // Common implementation for settings\n  public async settings(instance: InstanceDto, data: any) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const existingSettings = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instanceId,\n        },\n      });\n\n      // Get the name of the fallback field for this integration type\n      const fallbackFieldName = this.getFallbackFieldName();\n\n      const settingsData = {\n        expire: data.expire,\n        keywordFinish: data.keywordFinish,\n        delayMessage: data.delayMessage,\n        unknownMessage: data.unknownMessage,\n        listeningFromMe: data.listeningFromMe,\n        stopBotFromMe: data.stopBotFromMe,\n        keepOpen: data.keepOpen,\n        debounceTime: data.debounceTime,\n        ignoreJids: data.ignoreJids,\n        splitMessages: data.splitMessages,\n        timePerChar: data.timePerChar,\n        [fallbackFieldName]: data.fallbackId, // Use the correct field name dynamically\n      };\n\n      if (existingSettings) {\n        const settings = await this.settingsRepository.update({\n          where: {\n            id: existingSettings.id,\n          },\n          data: settingsData,\n        });\n\n        // Map the specific fallback field to a generic 'fallbackId' in the response\n        return {\n          ...settings,\n          fallbackId: settings[fallbackFieldName],\n        };\n      } else {\n        const settings = await this.settingsRepository.create({\n          data: {\n            ...settingsData,\n            Instance: {\n              connect: {\n                id: instanceId,\n              },\n            },\n          },\n        });\n\n        // Map the specific fallback field to a generic 'fallbackId' in the response\n        return {\n          ...settings,\n          fallbackId: settings[fallbackFieldName],\n        };\n      }\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error setting default settings');\n    }\n  }\n\n  // Abstract method to get the field name for the fallback ID\n  protected abstract getFallbackFieldName(): string;\n\n  // Abstract method to get the integration type (dify, n8n, evoai, etc.)\n  protected abstract getIntegrationType(): string;\n\n  // Common implementation for fetchSettings\n  public async fetchSettings(instance: InstanceDto) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const settings = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instanceId,\n        },\n        include: {\n          Fallback: true,\n        },\n      });\n\n      // Get the name of the fallback field for this integration type\n      const fallbackFieldName = this.getFallbackFieldName();\n\n      if (!settings) {\n        return {\n          expire: 300,\n          keywordFinish: 'bye',\n          delayMessage: 1000,\n          unknownMessage: 'Sorry, I dont understand',\n          listeningFromMe: true,\n          stopBotFromMe: true,\n          keepOpen: false,\n          debounceTime: 1,\n          ignoreJids: [],\n          splitMessages: false,\n          timePerChar: 0,\n          fallbackId: '',\n          fallback: null,\n        };\n      }\n\n      // Return with standardized fallbackId field\n      return {\n        ...settings,\n        fallbackId: settings[fallbackFieldName],\n        fallback: settings.Fallback,\n      };\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error fetching settings');\n    }\n  }\n\n  // Common implementation for changeStatus\n  public async changeStatus(instance: InstanceDto, data: any) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const defaultSettingCheck = await this.settingsRepository.findFirst({\n        where: {\n          instanceId,\n        },\n      });\n\n      const remoteJid = data.remoteJid;\n      const status = data.status;\n      const session = await this.getSession(remoteJid, instance);\n\n      if (this.integrationName === 'Typebot') {\n        const typebotData = {\n          remoteJid: remoteJid,\n          status: status,\n          session,\n        };\n        this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n      }\n\n      if (status === 'delete') {\n        await this.sessionRepository.deleteMany({\n          where: {\n            remoteJid: remoteJid,\n            botId: { not: null },\n          },\n        });\n\n        return { bot: { remoteJid: remoteJid, status: status } };\n      }\n\n      if (status === 'closed') {\n        if (defaultSettingCheck?.keepOpen) {\n          await this.sessionRepository.updateMany({\n            where: {\n              remoteJid: remoteJid,\n              botId: { not: null },\n            },\n            data: {\n              status: 'closed',\n            },\n          });\n        } else {\n          await this.sessionRepository.deleteMany({\n            where: {\n              remoteJid: remoteJid,\n              botId: { not: null },\n            },\n          });\n        }\n\n        return { bot: { ...instance, bot: { remoteJid: remoteJid, status: status } } };\n      } else {\n        const session = await this.sessionRepository.updateMany({\n          where: {\n            instanceId: instanceId,\n            remoteJid: remoteJid,\n            botId: { not: null },\n          },\n          data: {\n            status: status,\n          },\n        });\n\n        const botData = {\n          remoteJid: remoteJid,\n          status: status,\n          session,\n        };\n\n        return { bot: { ...instance, bot: botData } };\n      }\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error(`Error changing ${this.integrationName} status`);\n    }\n  }\n\n  // Common implementation for fetchSessions\n  public async fetchSessions(instance: InstanceDto, botId: string, remoteJid?: string) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const bot = await this.botRepository.findFirst({\n        where: {\n          id: botId,\n        },\n      });\n\n      if (bot && bot.instanceId !== instanceId) {\n        throw new Error(`${this.integrationName} not found`);\n      }\n\n      // Get the integration type (dify, n8n, evoai, etc.)\n      const integrationType = this.getIntegrationType();\n\n      return await this.sessionRepository.findMany({\n        where: {\n          instanceId: instanceId,\n          remoteJid,\n          botId: bot ? botId : { not: null },\n          type: integrationType,\n        },\n      });\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error fetching sessions');\n    }\n  }\n\n  // Common implementation for ignoreJid\n  public async ignoreJid(instance: InstanceDto, data: IgnoreJidDto) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const settings = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instanceId,\n        },\n      });\n\n      if (!settings) {\n        throw new Error('Settings not found');\n      }\n\n      let ignoreJids: any = settings?.ignoreJids || [];\n\n      if (data.action === 'add') {\n        if (ignoreJids.includes(data.remoteJid)) return { ignoreJids: ignoreJids };\n\n        ignoreJids.push(data.remoteJid);\n      } else {\n        ignoreJids = ignoreJids.filter((jid) => jid !== data.remoteJid);\n      }\n\n      const updateSettings = await this.settingsRepository.update({\n        where: {\n          id: settings.id,\n        },\n        data: {\n          ignoreJids: ignoreJids,\n        },\n      });\n\n      return {\n        ignoreJids: updateSettings.ignoreJids,\n      };\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error setting default settings');\n    }\n  }\n\n  // Base implementation for updateBot\n  public async updateBot(instance: InstanceDto, botId: string, data: BotData) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const bot = await this.botRepository.findFirst({\n        where: {\n          id: botId,\n        },\n      });\n\n      if (!bot) {\n        throw new Error(`${this.integrationName} not found`);\n      }\n\n      if (bot.instanceId !== instanceId) {\n        throw new Error(`${this.integrationName} not found`);\n      }\n\n      // Check for \"all\" trigger type conflicts\n      if (data.triggerType === 'all') {\n        const checkTriggerAll = await this.botRepository.findFirst({\n          where: {\n            enabled: true,\n            triggerType: 'all',\n            id: {\n              not: botId,\n            },\n            instanceId: instanceId,\n          },\n        });\n\n        if (checkTriggerAll) {\n          throw new Error(\n            `You already have a ${this.integrationName} with an \"All\" trigger, you cannot have more bots while it is active`,\n          );\n        }\n      }\n\n      // Let subclasses check for integration-specific duplicates\n      await this.validateNoDuplicatesOnUpdate(botId, instanceId, data);\n\n      // Check for keyword trigger duplicates\n      if (data.triggerType === 'keyword') {\n        if (!data.triggerOperator || !data.triggerValue) {\n          throw new Error('Trigger operator and value are required');\n        }\n\n        const checkDuplicate = await this.botRepository.findFirst({\n          where: {\n            triggerOperator: data.triggerOperator,\n            triggerValue: data.triggerValue,\n            id: { not: botId },\n            instanceId: instanceId,\n          },\n        });\n\n        if (checkDuplicate) {\n          throw new Error('Trigger already exists');\n        }\n      }\n\n      // Check for advanced trigger duplicates\n      if (data.triggerType === 'advanced') {\n        if (!data.triggerValue) {\n          throw new Error('Trigger value is required');\n        }\n\n        const checkDuplicate = await this.botRepository.findFirst({\n          where: {\n            triggerValue: data.triggerValue,\n            id: { not: botId },\n            instanceId: instanceId,\n          },\n        });\n\n        if (checkDuplicate) {\n          throw new Error('Trigger already exists');\n        }\n      }\n\n      // Combine common fields with bot-specific fields\n      const updateData = {\n        enabled: data?.enabled,\n        description: data.description,\n        expire: data.expire,\n        keywordFinish: data.keywordFinish,\n        delayMessage: data.delayMessage,\n        unknownMessage: data.unknownMessage,\n        listeningFromMe: data.listeningFromMe,\n        stopBotFromMe: data.stopBotFromMe,\n        keepOpen: data.keepOpen,\n        debounceTime: data.debounceTime,\n        instanceId: instanceId,\n        triggerType: data.triggerType,\n        triggerOperator: data.triggerOperator,\n        triggerValue: data.triggerValue,\n        ignoreJids: data.ignoreJids,\n        splitMessages: data.splitMessages,\n        timePerChar: data.timePerChar,\n        ...this.getAdditionalUpdateFields(data),\n      };\n\n      const updatedBot = await this.botRepository.update({\n        where: {\n          id: botId,\n        },\n        data: updateData,\n      });\n\n      return updatedBot;\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error(`Error updating ${this.integrationName}`);\n    }\n  }\n\n  // Abstract method for validating bot-specific duplicates on update\n  protected abstract validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: BotData): Promise<void>;\n\n  // Abstract method for getting additional fields for update\n  protected abstract getAdditionalUpdateFields(data: BotData): Record<string, any>;\n\n  // Base implementation for deleteBot\n  public async deleteBot(instance: InstanceDto, botId: string) {\n    if (!this.integrationEnabled) throw new BadRequestException(`${this.integrationName} is disabled`);\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const bot = await this.botRepository.findFirst({\n        where: {\n          id: botId,\n        },\n      });\n\n      if (!bot) {\n        throw new Error(`${this.integrationName} not found`);\n      }\n\n      if (bot.instanceId !== instanceId) {\n        throw new Error(`${this.integrationName} not found`);\n      }\n\n      await this.prismaRepository.integrationSession.deleteMany({\n        where: {\n          botId: botId,\n        },\n      });\n\n      await this.botRepository.delete({\n        where: {\n          id: botId,\n        },\n      });\n\n      return { bot: { id: botId } };\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error(`Error deleting ${this.integrationName} bot`);\n    }\n  }\n\n  // Base implementation for emit\n  public async emit({ instance, remoteJid, msg }: EmitData) {\n    if (!this.integrationEnabled) return;\n\n    try {\n      const settings = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instance.instanceId,\n        },\n      });\n\n      if (this.checkIgnoreJids(settings?.ignoreJids, remoteJid)) return;\n\n      const session = await this.getSession(remoteJid, instance);\n\n      const content = getConversationMessage(msg);\n\n      // Get integration type\n      // const integrationType = this.getIntegrationType();\n\n      // Find a bot for this message\n      let findBot: any = await this.findBotTrigger(this.botRepository, content, instance, session);\n\n      // If no bot is found, try to use fallback\n      if (!findBot) {\n        const fallback = await this.settingsRepository.findFirst({\n          where: {\n            instanceId: instance.instanceId,\n          },\n        });\n\n        // Get the fallback ID for this integration type\n        const fallbackId = this.getFallbackBotId(fallback);\n\n        if (fallbackId) {\n          const findFallback = await this.botRepository.findFirst({\n            where: {\n              id: fallbackId,\n            },\n          });\n\n          findBot = findFallback;\n        } else {\n          return;\n        }\n      }\n\n      // If we still don't have a bot, return\n      if (!findBot) {\n        return;\n      }\n\n      // Collect settings with fallbacks to default settings\n      let expire = findBot.expire;\n      let keywordFinish = findBot.keywordFinish;\n      let delayMessage = findBot.delayMessage;\n      let unknownMessage = findBot.unknownMessage;\n      let listeningFromMe = findBot.listeningFromMe;\n      let stopBotFromMe = findBot.stopBotFromMe;\n      let keepOpen = findBot.keepOpen;\n      let debounceTime = findBot.debounceTime;\n      let ignoreJids = findBot.ignoreJids;\n      let splitMessages = findBot.splitMessages;\n      let timePerChar = findBot.timePerChar;\n\n      if (expire === undefined || expire === null) expire = settings.expire;\n      if (keywordFinish === undefined || keywordFinish === null) keywordFinish = settings.keywordFinish;\n      if (delayMessage === undefined || delayMessage === null) delayMessage = settings.delayMessage;\n      if (unknownMessage === undefined || unknownMessage === null) unknownMessage = settings.unknownMessage;\n      if (listeningFromMe === undefined || listeningFromMe === null) listeningFromMe = settings.listeningFromMe;\n      if (stopBotFromMe === undefined || stopBotFromMe === null) stopBotFromMe = settings.stopBotFromMe;\n      if (keepOpen === undefined || keepOpen === null) keepOpen = settings.keepOpen;\n      if (debounceTime === undefined || debounceTime === null) debounceTime = settings.debounceTime;\n      if (ignoreJids === undefined || ignoreJids === null) ignoreJids = settings.ignoreJids;\n      if (splitMessages === undefined || splitMessages === null) splitMessages = settings?.splitMessages ?? false;\n      if (timePerChar === undefined || timePerChar === null) timePerChar = settings?.timePerChar ?? 0;\n\n      const key = msg.key as {\n        id: string;\n        remoteJid: string;\n        fromMe: boolean;\n        participant: string;\n      };\n\n      // Handle stopping the bot if message is from me\n      if (stopBotFromMe && key.fromMe && session) {\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'paused',\n          },\n        });\n\n        if (this.integrationName === 'Typebot') {\n          const typebotData = {\n            remoteJid: remoteJid,\n            status: 'paused',\n            session,\n          };\n          this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n        }\n\n        return;\n      }\n\n      // Skip if not listening to messages from me\n      if (!listeningFromMe && key.fromMe) {\n        return;\n      }\n\n      // Skip if session exists but not awaiting user input\n      if (session && session.status === 'closed') {\n        return;\n      }\n\n      // Merged settings\n      const mergedSettings = {\n        ...settings,\n        expire,\n        keywordFinish,\n        delayMessage,\n        unknownMessage,\n        listeningFromMe,\n        stopBotFromMe,\n        keepOpen,\n        debounceTime,\n        ignoreJids,\n        splitMessages,\n        timePerChar,\n      };\n\n      // Process with debounce if needed\n      if (debounceTime && debounceTime > 0) {\n        this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {\n          await this.processBot(\n            this.waMonitor.waInstances[instance.instanceName],\n            remoteJid,\n            findBot,\n            session,\n            mergedSettings,\n            debouncedContent,\n            msg?.pushName,\n            msg,\n          );\n        });\n      } else {\n        await this.processBot(\n          this.waMonitor.waInstances[instance.instanceName],\n          remoteJid,\n          findBot,\n          session,\n          mergedSettings,\n          content,\n          msg?.pushName,\n          msg,\n        );\n      }\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/base-chatbot.dto.ts",
    "content": "import { TriggerOperator, TriggerType } from '@prisma/client';\n\n/**\n * Base DTO for all chatbot integrations\n * Contains common properties shared by all chatbot types\n */\nexport class BaseChatbotDto {\n  enabled?: boolean;\n  description: string;\n  expire?: number;\n  keywordFinish?: string;\n  delayMessage?: number;\n  unknownMessage?: string;\n  listeningFromMe?: boolean;\n  stopBotFromMe?: boolean;\n  keepOpen?: boolean;\n  debounceTime?: number;\n  triggerType: TriggerType;\n  triggerOperator?: TriggerOperator;\n  triggerValue?: string;\n  ignoreJids?: string[];\n  splitMessages?: boolean;\n  timePerChar?: number;\n}\n\n/**\n * Base settings DTO for all chatbot integrations\n */\nexport class BaseChatbotSettingDto {\n  expire?: number;\n  keywordFinish?: string;\n  delayMessage?: number;\n  unknownMessage?: string;\n  listeningFromMe?: boolean;\n  stopBotFromMe?: boolean;\n  keepOpen?: boolean;\n  debounceTime?: number;\n  ignoreJids?: any;\n  splitMessages?: boolean;\n  timePerChar?: number;\n  fallbackId?: string; // Unified fallback ID field for all integrations\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/base-chatbot.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { IntegrationSession } from '@prisma/client';\n\n/**\n * Base class for all chatbot service implementations\n * Contains common methods shared across different chatbot integrations\n */\nexport abstract class BaseChatbotService<BotType = any, SettingsType = any> {\n  protected readonly logger: Logger;\n  protected readonly waMonitor: WAMonitoringService;\n  protected readonly prismaRepository: PrismaRepository;\n  protected readonly configService?: ConfigService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    loggerName: string,\n    configService?: ConfigService,\n  ) {\n    this.waMonitor = waMonitor;\n    this.prismaRepository = prismaRepository;\n    this.logger = new Logger(loggerName);\n    this.configService = configService;\n  }\n\n  /**\n   * Check if a message contains an image\n   */\n  protected isImageMessage(content: string): boolean {\n    return content.includes('imageMessage');\n  }\n\n  /**\n   * Check if a message contains audio\n   */\n  protected isAudioMessage(content: string): boolean {\n    return content.includes('audioMessage');\n  }\n\n  /**\n   * Check if a string is valid JSON\n   */\n  protected isJSON(str: string): boolean {\n    try {\n      JSON.parse(str);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  /**\n   * Determine the media type from a URL based on its extension\n   */\n  protected getMediaType(url: string): string | null {\n    const extension = url.split('.').pop()?.toLowerCase();\n    const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];\n    const audioExtensions = ['mp3', 'wav', 'aac', 'ogg'];\n    const videoExtensions = ['mp4', 'avi', 'mkv', 'mov'];\n    const documentExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];\n\n    if (imageExtensions.includes(extension || '')) return 'image';\n    if (audioExtensions.includes(extension || '')) return 'audio';\n    if (videoExtensions.includes(extension || '')) return 'video';\n    if (documentExtensions.includes(extension || '')) return 'document';\n    return null;\n  }\n\n  /**\n   * Create a new chatbot session\n   */\n  public async createNewSession(instance: InstanceDto | any, data: any, type: string) {\n    try {\n      // Extract pushName safely - if data.pushName is an object with a pushName property, use that\n      const pushNameValue =\n        typeof data.pushName === 'object' && data.pushName?.pushName\n          ? data.pushName.pushName\n          : typeof data.pushName === 'string'\n            ? data.pushName\n            : null;\n\n      // Extract remoteJid safely\n      const remoteJidValue =\n        typeof data.remoteJid === 'object' && data.remoteJid?.remoteJid ? data.remoteJid.remoteJid : data.remoteJid;\n\n      const session = await this.prismaRepository.integrationSession.create({\n        data: {\n          remoteJid: remoteJidValue,\n          pushName: pushNameValue,\n          sessionId: remoteJidValue,\n          status: 'opened',\n          awaitUser: false,\n          botId: data.botId,\n          instanceId: instance.instanceId,\n          type: type,\n        },\n      });\n\n      return { session };\n    } catch (error) {\n      this.logger.error(error);\n      return;\n    }\n  }\n\n  /**\n   * Standard implementation for processing incoming messages\n   * This handles the common workflow across all chatbot types:\n   * 1. Check for existing session or create new one\n   * 2. Handle message based on session state\n   */\n  public async process(\n    instance: any,\n    remoteJid: string,\n    bot: BotType,\n    session: IntegrationSession,\n    settings: SettingsType,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      // For new sessions or sessions awaiting initialization\n      if (!session) {\n        await this.initNewSession(instance, remoteJid, bot, settings, session, content, pushName, msg);\n        return;\n      }\n\n      // If session is paused, ignore the message\n      if (session.status === 'paused') {\n        return;\n      }\n\n      // For existing sessions, keywords might indicate the conversation should end\n      const keywordFinish = (settings as any)?.keywordFinish || '';\n      const normalizedContent = content.toLowerCase().trim();\n      if (keywordFinish.length > 0 && normalizedContent === keywordFinish.toLowerCase()) {\n        // Update session to closed and return\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'closed',\n          },\n        });\n        return;\n      }\n\n      // Forward the message to the chatbot API\n      await this.sendMessageToBot(instance, session, settings, bot, remoteJid, pushName || '', content, msg);\n\n      // Update session to indicate we're waiting for user response\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          status: 'opened',\n          awaitUser: true,\n        },\n      });\n    } catch (error) {\n      this.logger.error(`Error in process: ${error}`);\n      return;\n    }\n  }\n\n  /**\n   * Standard implementation for sending messages to WhatsApp\n   * This handles common patterns like markdown links and formatting\n   */\n  protected async sendMessageWhatsApp(\n    instance: any,\n    remoteJid: string,\n    message: string,\n    settings: SettingsType,\n    linkPreview: boolean = true,\n  ): Promise<void> {\n    if (!message) return;\n\n    const linkRegex = /!?\\[(.*?)\\]\\((.*?)\\)/g;\n    let textBuffer = '';\n    let lastIndex = 0;\n    let match: RegExpExecArray | null;\n\n    const splitMessages = (settings as any)?.splitMessages ?? false;\n\n    while ((match = linkRegex.exec(message)) !== null) {\n      const [fullMatch, altText, url] = match;\n      const mediaType = this.getMediaType(url);\n      const beforeText = message.slice(lastIndex, match.index);\n\n      if (beforeText) {\n        textBuffer += beforeText;\n      }\n\n      if (mediaType) {\n        // Send accumulated text before sending media\n        if (textBuffer.trim()) {\n          await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages, linkPreview);\n          textBuffer = '';\n        }\n\n        // Handle sending the media\n        try {\n          if (mediaType === 'audio') {\n            await instance.audioWhatsapp({\n              number: remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0],\n              delay: (settings as any)?.delayMessage || 1000,\n              audio: url,\n              caption: altText,\n            });\n          } else {\n            await instance.mediaMessage(\n              {\n                number: remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0],\n                delay: (settings as any)?.delayMessage || 1000,\n                mediatype: mediaType,\n                media: url,\n                caption: altText,\n                fileName: mediaType === 'document' ? altText || 'document' : undefined,\n              },\n              null,\n              false,\n            );\n          }\n        } catch (error) {\n          this.logger.error(`Error sending media: ${error}`);\n          // If media fails, at least send the alt text and URL\n          textBuffer += `${altText}: ${url}`;\n        }\n      } else {\n        // It's a regular link, keep it in the text\n        textBuffer += fullMatch;\n      }\n\n      lastIndex = linkRegex.lastIndex;\n    }\n\n    // Add any remaining text after the last match\n    if (lastIndex < message.length) {\n      const remainingText = message.slice(lastIndex);\n      if (remainingText.trim()) {\n        textBuffer += remainingText;\n      }\n    }\n\n    // Send any remaining text\n    if (textBuffer.trim()) {\n      await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages, linkPreview);\n    }\n  }\n\n  /**\n   * Split message by double line breaks and return array of message parts\n   */\n  private splitMessageByDoubleLineBreaks(message: string): string[] {\n    return message.split('\\n\\n').filter((part) => part.trim().length > 0);\n  }\n\n  /**\n   * Send a single message with proper typing indicators and delays\n   */\n  private async sendSingleMessage(\n    instance: any,\n    remoteJid: string,\n    message: string,\n    settings: any,\n    linkPreview: boolean = true,\n  ): Promise<void> {\n    const timePerChar = settings?.timePerChar ?? 0;\n    const minDelay = 1000;\n    const maxDelay = 20000;\n    const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);\n\n    this.logger.debug(`[BaseChatbot] Sending single message with linkPreview: ${linkPreview}`);\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    await new Promise<void>((resolve) => {\n      setTimeout(async () => {\n        await instance.textMessage(\n          {\n            number: remoteJid.includes('@lid') ? remoteJid : remoteJid.split('@')[0],\n            delay: settings?.delayMessage || 1000,\n            text: message,\n            linkPreview,\n          },\n          false,\n        );\n        resolve();\n      }, delay);\n    });\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.sendPresenceUpdate('paused', remoteJid);\n    }\n  }\n\n  /**\n   * Helper method to send formatted text with proper typing indicators and delays\n   */\n  private async sendFormattedText(\n    instance: any,\n    remoteJid: string,\n    text: string,\n    settings: any,\n    splitMessages: boolean,\n    linkPreview: boolean = true,\n  ): Promise<void> {\n    if (splitMessages) {\n      const messageParts = this.splitMessageByDoubleLineBreaks(text);\n\n      this.logger.debug(`[BaseChatbot] Splitting message into ${messageParts.length} parts`);\n\n      for (let index = 0; index < messageParts.length; index++) {\n        const message = messageParts[index];\n\n        this.logger.debug(`[BaseChatbot] Sending message part ${index + 1}/${messageParts.length}`);\n        await this.sendSingleMessage(instance, remoteJid, message, settings, linkPreview);\n      }\n\n      this.logger.debug(`[BaseChatbot] All message parts sent successfully`);\n    } else {\n      this.logger.debug(`[BaseChatbot] Sending single message`);\n      await this.sendSingleMessage(instance, remoteJid, text, settings, linkPreview);\n    }\n  }\n\n  /**\n   * Standard implementation for initializing a new session\n   * This method should be overridden if a subclass needs specific initialization\n   */\n  protected async initNewSession(\n    instance: any,\n    remoteJid: string,\n    bot: BotType,\n    settings: SettingsType,\n    session: IntegrationSession,\n    content: string,\n    pushName?: string | any,\n    msg?: any,\n  ): Promise<void> {\n    // Create a session if none exists\n    if (!session) {\n      // Extract pushName properly - if it's an object with pushName property, use that\n      const pushNameValue =\n        typeof pushName === 'object' && pushName?.pushName\n          ? pushName.pushName\n          : typeof pushName === 'string'\n            ? pushName\n            : null;\n\n      const sessionResult = await this.createNewSession(\n        {\n          instanceName: instance.instanceName,\n          instanceId: instance.instanceId,\n        },\n        {\n          remoteJid,\n          pushName: pushNameValue,\n          botId: (bot as any).id,\n        },\n        this.getBotType(),\n      );\n\n      if (!sessionResult || !sessionResult.session) {\n        this.logger.error('Failed to create new session');\n        return;\n      }\n\n      session = sessionResult.session;\n    }\n\n    // Update session status to opened\n    await this.prismaRepository.integrationSession.update({\n      where: {\n        id: session.id,\n      },\n      data: {\n        status: 'opened',\n        awaitUser: false,\n      },\n    });\n\n    // Forward the message to the chatbot\n    await this.sendMessageToBot(instance, session, settings, bot, remoteJid, pushName || '', content, msg);\n  }\n\n  /**\n   * Get the bot type identifier (e.g., 'dify', 'n8n', 'evoai')\n   * This should match the type field used in the IntegrationSession\n   */\n  protected abstract getBotType(): string;\n\n  /**\n   * Send a message to the chatbot API\n   * This is specific to each chatbot integration\n   */\n  protected abstract sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: SettingsType,\n    bot: BotType,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void>;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatbot.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport {\n  difyController,\n  evoaiController,\n  evolutionBotController,\n  flowiseController,\n  n8nController,\n  openaiController,\n  typebotController,\n} from '@api/server.module';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Logger } from '@config/logger.config';\nimport { IntegrationSession } from '@prisma/client';\nimport { findBotByTrigger } from '@utils/findBotByTrigger';\n\nexport type EmitData = {\n  instance: InstanceDto;\n  remoteJid: string;\n  msg: any;\n  pushName?: string;\n};\n\nexport interface ChatbotControllerInterface {\n  integrationEnabled: boolean;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } };\n\n  createBot(instance: InstanceDto, data: any): Promise<any>;\n  findBot(instance: InstanceDto): Promise<any>;\n  fetchBot(instance: InstanceDto, botId: string): Promise<any>;\n  updateBot(instance: InstanceDto, botId: string, data: any): Promise<any>;\n  deleteBot(instance: InstanceDto, botId: string): Promise<any>;\n\n  settings(instance: InstanceDto, data: any): Promise<any>;\n  fetchSettings(instance: InstanceDto): Promise<any>;\n\n  changeStatus(instance: InstanceDto, botId: string, status: string): Promise<any>;\n  fetchSessions(instance: InstanceDto, botId: string, remoteJid?: string): Promise<any>;\n  ignoreJid(instance: InstanceDto, data: any): Promise<any>;\n\n  emit(data: EmitData): Promise<void>;\n}\n\nexport class ChatbotController {\n  public prismaRepository: PrismaRepository;\n  public waMonitor: WAMonitoringService;\n\n  public readonly logger = new Logger('ChatbotController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    this.prisma = prismaRepository;\n    this.monitor = waMonitor;\n  }\n\n  public set prisma(prisma: PrismaRepository) {\n    this.prismaRepository = prisma;\n  }\n\n  public get prisma() {\n    return this.prismaRepository;\n  }\n\n  public set monitor(waMonitor: WAMonitoringService) {\n    this.waMonitor = waMonitor;\n  }\n\n  public get monitor() {\n    return this.waMonitor;\n  }\n\n  public async emit({\n    instance,\n    remoteJid,\n    msg,\n    pushName,\n    isIntegration = false,\n  }: {\n    instance: InstanceDto;\n    remoteJid: string;\n    msg: any;\n    pushName?: string;\n    isIntegration?: boolean;\n  }): Promise<void> {\n    const emitData = {\n      instance,\n      remoteJid,\n      msg,\n      pushName,\n      isIntegration,\n    };\n    evolutionBotController.emit(emitData);\n\n    typebotController.emit(emitData);\n\n    openaiController.emit(emitData);\n\n    difyController.emit(emitData);\n\n    n8nController.emit(emitData);\n\n    evoaiController.emit(emitData);\n\n    flowiseController.emit(emitData);\n  }\n\n  public processDebounce(\n    userMessageDebounce: any,\n    content: string,\n    remoteJid: string,\n    debounceTime: number,\n    callback: any,\n  ) {\n    if (userMessageDebounce[remoteJid]) {\n      userMessageDebounce[remoteJid].message += `\\n${content}`;\n      this.logger.log('message debounced: ' + userMessageDebounce[remoteJid].message);\n      clearTimeout(userMessageDebounce[remoteJid].timeoutId);\n    } else {\n      userMessageDebounce[remoteJid] = {\n        message: content,\n        timeoutId: null,\n      };\n    }\n\n    userMessageDebounce[remoteJid].timeoutId = setTimeout(() => {\n      const myQuestion = userMessageDebounce[remoteJid].message;\n      this.logger.log('Debounce complete. Processing message: ' + myQuestion);\n\n      delete userMessageDebounce[remoteJid];\n      callback(myQuestion);\n    }, debounceTime * 1000);\n  }\n\n  public checkIgnoreJids(ignoreJids: any, remoteJid: string) {\n    if (ignoreJids && ignoreJids.length > 0) {\n      let ignoreGroups = false;\n      let ignoreContacts = false;\n\n      if (ignoreJids.includes('@g.us')) {\n        ignoreGroups = true;\n      }\n\n      if (ignoreJids.includes('@s.whatsapp.net')) {\n        ignoreContacts = true;\n      }\n\n      if (ignoreGroups && remoteJid.endsWith('@g.us')) {\n        this.logger.warn('Ignoring message from group: ' + remoteJid);\n        return true;\n      }\n\n      if (ignoreContacts && remoteJid.endsWith('@s.whatsapp.net')) {\n        this.logger.warn('Ignoring message from contact: ' + remoteJid);\n        return true;\n      }\n\n      if (ignoreJids.includes(remoteJid)) {\n        this.logger.warn('Ignoring message from jid: ' + remoteJid);\n        return true;\n      }\n\n      return false;\n    }\n\n    return false;\n  }\n\n  public async getSession(remoteJid: string, instance: InstanceDto) {\n    let session = await this.prismaRepository.integrationSession.findFirst({\n      where: {\n        remoteJid: remoteJid,\n        instanceId: instance.instanceId,\n      },\n      orderBy: { createdAt: 'desc' },\n    });\n\n    if (session) {\n      if (session.status !== 'closed' && !session.botId) {\n        this.logger.warn('Session is already opened in another integration');\n        return null;\n      } else if (!session.botId) {\n        session = null;\n      }\n    }\n\n    return session;\n  }\n\n  public async findBotTrigger(\n    botRepository: any,\n    content: string,\n    instance: InstanceDto,\n    session?: IntegrationSession,\n  ) {\n    let findBot: any = null;\n\n    if (!session) {\n      findBot = await findBotByTrigger(botRepository, content, instance.instanceId);\n\n      if (!findBot) {\n        return null;\n      }\n    } else {\n      findBot = await botRepository.findFirst({\n        where: {\n          id: session.botId,\n        },\n      });\n    }\n\n    return findBot;\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatbot.router.ts",
    "content": "import { ChatwootRouter } from '@api/integrations/chatbot/chatwoot/routes/chatwoot.router';\nimport { DifyRouter } from '@api/integrations/chatbot/dify/routes/dify.router';\nimport { OpenaiRouter } from '@api/integrations/chatbot/openai/routes/openai.router';\nimport { TypebotRouter } from '@api/integrations/chatbot/typebot/routes/typebot.router';\nimport { Router } from 'express';\n\nimport { EvoaiRouter } from './evoai/routes/evoai.router';\nimport { EvolutionBotRouter } from './evolutionBot/routes/evolutionBot.router';\nimport { FlowiseRouter } from './flowise/routes/flowise.router';\nimport { N8nRouter } from './n8n/routes/n8n.router';\n\nexport class ChatbotRouter {\n  public readonly router: Router;\n\n  constructor(...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/evolutionBot', new EvolutionBotRouter(...guards).router);\n    this.router.use('/chatwoot', new ChatwootRouter(...guards).router);\n    this.router.use('/typebot', new TypebotRouter(...guards).router);\n    this.router.use('/openai', new OpenaiRouter(...guards).router);\n    this.router.use('/dify', new DifyRouter(...guards).router);\n    this.router.use('/flowise', new FlowiseRouter(...guards).router);\n    this.router.use('/n8n', new N8nRouter(...guards).router);\n    this.router.use('/evoai', new EvoaiRouter(...guards).router);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatbot.schema.ts",
    "content": "export * from '@api/integrations/chatbot/chatwoot/validate/chatwoot.schema';\nexport * from '@api/integrations/chatbot/dify/validate/dify.schema';\nexport * from '@api/integrations/chatbot/evoai/validate/evoai.schema';\nexport * from '@api/integrations/chatbot/evolutionBot/validate/evolutionBot.schema';\nexport * from '@api/integrations/chatbot/flowise/validate/flowise.schema';\nexport * from '@api/integrations/chatbot/n8n/validate/n8n.schema';\nexport * from '@api/integrations/chatbot/openai/validate/openai.schema';\nexport * from '@api/integrations/chatbot/typebot/validate/typebot.schema';\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/controllers/chatwoot.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { ChatwootService } from '@api/integrations/chatbot/chatwoot/services/chatwoot.service';\nimport { Chatwoot, ConfigService, HttpServer } from '@config/env.config';\nimport { BadRequestException } from '@exceptions';\nimport { isURL } from 'class-validator';\n\nexport class ChatwootController {\n  constructor(\n    private readonly chatwootService: ChatwootService,\n    private readonly configService: ConfigService,\n  ) {}\n\n  public async createChatwoot(instance: InstanceDto, data: ChatwootDto) {\n    if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED) throw new BadRequestException('Chatwoot is disabled');\n\n    if (data?.enabled) {\n      if (!isURL(data.url, { require_tld: false })) {\n        throw new BadRequestException('url is not valid');\n      }\n\n      if (!data.accountId) {\n        throw new BadRequestException('accountId is required');\n      }\n\n      if (!data.token) {\n        throw new BadRequestException('token is required');\n      }\n\n      if (data.signMsg !== true && data.signMsg !== false) {\n        throw new BadRequestException('signMsg is required');\n      }\n      if (data.signMsg === false) data.signDelimiter = null;\n    }\n\n    if (!data.nameInbox || data.nameInbox === '') {\n      data.nameInbox = instance.instanceName;\n    }\n\n    const result = await this.chatwootService.create(instance, data);\n\n    const urlServer = this.configService.get<HttpServer>('SERVER').URL;\n\n    const response = {\n      ...result,\n      webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,\n    };\n\n    return response;\n  }\n\n  public async findChatwoot(instance: InstanceDto): Promise<ChatwootDto & { webhook_url: string }> {\n    if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED) throw new BadRequestException('Chatwoot is disabled');\n\n    const result = await this.chatwootService.find(instance);\n\n    const urlServer = this.configService.get<HttpServer>('SERVER').URL;\n\n    if (Object.keys(result || {}).length === 0) {\n      return {\n        enabled: false,\n        url: '',\n        accountId: '',\n        token: '',\n        signMsg: false,\n        nameInbox: '',\n        webhook_url: '',\n      };\n    }\n\n    const response = {\n      ...result,\n      webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,\n    };\n\n    return response;\n  }\n\n  public async receiveWebhook(instance: InstanceDto, data: any) {\n    if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED) throw new BadRequestException('Chatwoot is disabled');\n\n    return this.chatwootService.receiveWebhook(instance, data);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/dto/chatwoot.dto.ts",
    "content": "import { Constructor } from '@api/integrations/integration.dto';\n\nexport class ChatwootDto {\n  enabled?: boolean;\n  accountId?: string;\n  token?: string;\n  url?: string;\n  nameInbox?: string;\n  signMsg?: boolean;\n  signDelimiter?: string;\n  number?: string;\n  reopenConversation?: boolean;\n  conversationPending?: boolean;\n  mergeBrazilContacts?: boolean;\n  importContacts?: boolean;\n  importMessages?: boolean;\n  daysLimitImportMessages?: number;\n  autoCreate?: boolean;\n  organization?: string;\n  logo?: string;\n  ignoreJids?: string[];\n}\n\nexport function ChatwootInstanceMixin<TBase extends Constructor>(Base: TBase) {\n  return class extends Base {\n    chatwootAccountId?: string;\n    chatwootToken?: string;\n    chatwootUrl?: string;\n    chatwootSignMsg?: boolean;\n    chatwootReopenConversation?: boolean;\n    chatwootConversationPending?: boolean;\n    chatwootMergeBrazilContacts?: boolean;\n    chatwootImportContacts?: boolean;\n    chatwootImportMessages?: boolean;\n    chatwootDaysLimitImportMessages?: number;\n    chatwootNameInbox?: string;\n    chatwootOrganization?: string;\n    chatwootLogo?: string;\n    chatwootAutoCreate?: boolean;\n  };\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/libs/postgres.client.ts",
    "content": "import { Chatwoot, configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport postgresql from 'pg';\n\nconst { Pool } = postgresql;\n\nclass Postgres {\n  private logger = new Logger('Postgres');\n  private pool;\n  private connected = false;\n\n  getConnection(connectionString: string) {\n    if (this.connected) {\n      return this.pool;\n    } else {\n      this.pool = new Pool({\n        connectionString,\n        ssl: {\n          rejectUnauthorized: false,\n        },\n      });\n\n      this.pool.on('error', () => {\n        this.logger.error('postgres disconnected');\n        this.connected = false;\n      });\n\n      try {\n        this.connected = true;\n      } catch (e) {\n        this.connected = false;\n        this.logger.error('postgres connect exception caught: ' + e);\n        return null;\n      }\n\n      return this.pool;\n    }\n  }\n\n  getChatwootConnection() {\n    const uri = configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;\n\n    return this.getConnection(uri);\n  }\n}\n\nexport const postgresClient = new Postgres();\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/routes/chatwoot.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { chatwootController } from '@api/server.module';\nimport { chatwootSchema, instanceSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class ChatwootRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ChatwootDto>({\n          request: req,\n          schema: chatwootSchema,\n          ClassRef: ChatwootDto,\n          execute: (instance, data) => chatwootController.createChatwoot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => chatwootController.findChatwoot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('webhook'), async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => chatwootController.receiveWebhook(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '@api/dto/sendMessage.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { postgresClient } from '@api/integrations/chatbot/chatwoot/libs/postgres.client';\nimport { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { CacheService } from '@api/services/cache.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Events } from '@api/types/wa.types';\nimport { Chatwoot, ConfigService, Database, HttpServer } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport ChatwootClient, {\n  ChatwootAPIConfig,\n  contact,\n  contact_inboxes,\n  conversation,\n  conversation_show,\n  generic_id,\n  inbox,\n} from '@figuro/chatwoot-sdk';\nimport { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';\nimport { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageModel } from '@prisma/client';\nimport i18next from '@utils/i18n';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { WAMessageContent, WAMessageKey } from 'baileys';\nimport dayjs from 'dayjs';\nimport FormData from 'form-data';\nimport { Jimp, JimpMime } from 'jimp';\nimport { parsePhoneNumberFromString } from 'libphonenumber-js';\nimport Long from 'long';\nimport mimeTypes from 'mime-types';\nimport path from 'path';\nimport { Readable } from 'stream';\n\ninterface ChatwootMessage {\n  messageId?: number;\n  inboxId?: number;\n  conversationId?: number;\n  contactInboxSourceId?: string;\n  isRead?: boolean;\n}\n\nexport class ChatwootService {\n  private readonly logger = new Logger('ChatwootService');\n\n  // Lock polling delay\n  private readonly LOCK_POLLING_DELAY_MS = 300; // Delay between lock status checks\n\n  private provider: any;\n\n  constructor(\n    private readonly waMonitor: WAMonitoringService,\n    private readonly configService: ConfigService,\n    private readonly prismaRepository: PrismaRepository,\n    private readonly cache: CacheService,\n  ) {}\n\n  private pgClient = postgresClient.getChatwootConnection();\n\n  private async getProvider(instance: InstanceDto): Promise<ChatwootModel | null> {\n    const cacheKey = `${instance.instanceName}:getProvider`;\n    if (await this.cache.has(cacheKey)) {\n      const provider = (await this.cache.get(cacheKey)) as ChatwootModel;\n\n      return provider;\n    }\n\n    const provider = await this.waMonitor.waInstances[instance.instanceName]?.findChatwoot();\n\n    if (!provider) {\n      this.logger.warn('provider not found');\n      return null;\n    }\n\n    this.cache.set(cacheKey, provider);\n\n    return provider;\n  }\n\n  private async clientCw(instance: InstanceDto) {\n    const provider = await this.getProvider(instance);\n\n    if (!provider) {\n      this.logger.error('provider not found');\n      return null;\n    }\n\n    this.provider = provider;\n\n    const client = new ChatwootClient({\n      config: this.getClientCwConfig(),\n    });\n\n    return client;\n  }\n\n  public getClientCwConfig(): ChatwootAPIConfig & { nameInbox: string; mergeBrazilContacts: boolean } {\n    return {\n      basePath: this.provider.url,\n      with_credentials: true,\n      credentials: 'include',\n      token: this.provider.token,\n      nameInbox: this.provider.nameInbox,\n      mergeBrazilContacts: this.provider.mergeBrazilContacts,\n    };\n  }\n\n  public getCache() {\n    return this.cache;\n  }\n\n  public async create(instance: InstanceDto, data: ChatwootDto) {\n    await this.waMonitor.waInstances[instance.instanceName].setChatwoot(data);\n\n    if (data.autoCreate) {\n      this.logger.log('Auto create chatwoot instance');\n      const urlServer = this.configService.get<HttpServer>('SERVER').URL;\n\n      await this.initInstanceChatwoot(\n        instance,\n        data.nameInbox ?? instance.instanceName.split('-cwId-')[0],\n        `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,\n        true,\n        data.number,\n        data.organization,\n        data.logo,\n      );\n    }\n    return data;\n  }\n\n  public async find(instance: InstanceDto): Promise<ChatwootDto> {\n    try {\n      return await this.waMonitor.waInstances[instance.instanceName].findChatwoot();\n    } catch {\n      this.logger.error('chatwoot not found');\n      return { enabled: null, url: '' };\n    }\n  }\n\n  public async getContact(instance: InstanceDto, id: number) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    if (!id) {\n      this.logger.warn('id is required');\n      return null;\n    }\n\n    const contact = await client.contact.getContactable({\n      accountId: this.provider.accountId,\n      id,\n    });\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    return contact;\n  }\n\n  public async initInstanceChatwoot(\n    instance: InstanceDto,\n    inboxName: string,\n    webhookUrl: string,\n    qrcode: boolean,\n    number: string,\n    organization?: string,\n    logo?: string,\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const findInbox: any = await client.inboxes.list({\n      accountId: this.provider.accountId,\n    });\n\n    const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName);\n\n    let inboxId: number;\n\n    this.logger.log('Creating chatwoot inbox');\n    if (!checkDuplicate) {\n      const data = {\n        type: 'api',\n        webhook_url: webhookUrl,\n      };\n\n      const inbox = await client.inboxes.create({\n        accountId: this.provider.accountId,\n        data: {\n          name: inboxName,\n          channel: data as any,\n        },\n      });\n\n      if (!inbox) {\n        this.logger.warn('inbox not found');\n        return null;\n      }\n\n      inboxId = inbox.id;\n    } else {\n      const inbox = findInbox.payload.find((inbox) => inbox.name === inboxName);\n\n      if (!inbox) {\n        this.logger.warn('inbox not found');\n        return null;\n      }\n\n      inboxId = inbox.id;\n    }\n    this.logger.log(`Inbox created - inboxId: ${inboxId}`);\n\n    if (!this.configService.get<Chatwoot>('CHATWOOT').BOT_CONTACT) {\n      this.logger.log('Chatwoot bot contact is disabled');\n\n      return true;\n    }\n\n    this.logger.log('Creating chatwoot bot contact');\n    const contact =\n      (await this.findContact(instance, '123456')) ||\n      ((await this.createContact(\n        instance,\n        '123456',\n        inboxId,\n        false,\n        organization ? organization : 'EvolutionAPI',\n        logo ? logo : 'https://evolution-api.com/files/evolution-api-favicon.png',\n      )) as any);\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    const contactId = contact.id || contact.payload.contact.id;\n    this.logger.log(`Contact created - contactId: ${contactId}`);\n\n    if (qrcode) {\n      this.logger.log('QR code enabled');\n      const data = {\n        contact_id: contactId.toString(),\n        inbox_id: inboxId.toString(),\n      };\n\n      const conversation = await client.conversations.create({\n        accountId: this.provider.accountId,\n        data,\n      });\n\n      if (!conversation) {\n        this.logger.warn('conversation not found');\n        return null;\n      }\n\n      let contentMsg = 'init';\n\n      if (number) {\n        contentMsg = `init:${number}`;\n      }\n\n      const message = await client.messages.create({\n        accountId: this.provider.accountId,\n        conversationId: conversation.id,\n        data: {\n          content: contentMsg,\n          message_type: 'outgoing',\n        },\n      });\n\n      if (!message) {\n        this.logger.warn('conversation not found');\n        return null;\n      }\n      this.logger.log('Init message sent');\n    }\n\n    return true;\n  }\n\n  public async createContact(\n    instance: InstanceDto,\n    phoneNumber: string,\n    inboxId: number,\n    isGroup: boolean,\n    name?: string,\n    avatar_url?: string,\n    jid?: string,\n  ) {\n    try {\n      const client = await this.clientCw(instance);\n\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      let data: any = {};\n      if (!isGroup) {\n        data = {\n          inbox_id: inboxId,\n          name: name || phoneNumber,\n          identifier: jid,\n          avatar_url: avatar_url,\n        };\n\n        if ((jid && jid.includes('@')) || !jid) {\n          data['phone_number'] = `+${phoneNumber}`;\n        }\n      } else {\n        data = {\n          inbox_id: inboxId,\n          name: name || phoneNumber,\n          identifier: phoneNumber,\n          avatar_url: avatar_url,\n        };\n      }\n\n      const contact = await client.contacts.create({\n        accountId: this.provider.accountId,\n        data,\n      });\n\n      if (!contact) {\n        this.logger.warn('contact not found');\n        return null;\n      }\n\n      const findContact = await this.findContact(instance, phoneNumber);\n\n      const contactId = findContact?.id;\n\n      await this.addLabelToContact(this.provider.nameInbox, contactId);\n\n      return contact;\n    } catch (error) {\n      if ((error.status === 422 || error.response?.status === 422) && jid) {\n        this.logger.warn(`Contact with identifier ${jid} creation failed (422). Checking if it already exists...`);\n        const existingContact = await this.findContactByIdentifier(instance, jid);\n        if (existingContact) {\n          const contactId = existingContact.id;\n          await this.addLabelToContact(this.provider.nameInbox, contactId);\n          return existingContact;\n        }\n      }\n\n      this.logger.error('Error creating contact');\n      console.log(error);\n      return null;\n    }\n  }\n\n  public async updateContact(instance: InstanceDto, id: number, data: any) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    if (!id) {\n      this.logger.warn('id is required');\n      return null;\n    }\n\n    try {\n      const contact = await client.contacts.update({\n        accountId: this.provider.accountId,\n        id,\n        data,\n      });\n\n      return contact;\n    } catch {\n      return null;\n    }\n  }\n\n  public async addLabelToContact(nameInbox: string, contactId: number) {\n    try {\n      const uri = this.configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;\n\n      if (!uri) return false;\n\n      const sqlTags = `SELECT id, taggings_count FROM tags WHERE name = $1 LIMIT 1`;\n      const tagData = (await this.pgClient.query(sqlTags, [nameInbox]))?.rows[0];\n      let tagId = tagData?.id;\n      const taggingsCount = tagData?.taggings_count || 0;\n\n      const sqlTag = `INSERT INTO tags (name, taggings_count) \n                      VALUES ($1, $2) \n                      ON CONFLICT (name) \n                      DO UPDATE SET taggings_count = tags.taggings_count + 1 \n                      RETURNING id`;\n\n      tagId = (await this.pgClient.query(sqlTag, [nameInbox, taggingsCount + 1]))?.rows[0]?.id;\n\n      const sqlCheckTagging = `SELECT 1 FROM taggings \n                               WHERE tag_id = $1 AND taggable_type = 'Contact' AND taggable_id = $2 AND context = 'labels' LIMIT 1`;\n\n      const taggingExists = (await this.pgClient.query(sqlCheckTagging, [tagId, contactId]))?.rowCount > 0;\n\n      if (!taggingExists) {\n        const sqlInsertLabel = `INSERT INTO taggings (tag_id, taggable_type, taggable_id, context, created_at) \n                                VALUES ($1, 'Contact', $2, 'labels', NOW())`;\n\n        await this.pgClient.query(sqlInsertLabel, [tagId, contactId]);\n      }\n\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  public async findContactByIdentifier(instance: InstanceDto, identifier: string) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    // Direct search by query (q) - most common way to search by identifier/email/phone\n    const contact = (await (client as any).get('contacts/search', {\n      params: {\n        q: identifier,\n        sort: 'name',\n      },\n    })) as any;\n\n    if (contact && contact.data && contact.data.payload && contact.data.payload.length > 0) {\n      return contact.data.payload[0];\n    }\n\n    // Fallback for older API versions or different response structures\n    if (contact && contact.payload && contact.payload.length > 0) {\n      return contact.payload[0];\n    }\n\n    // Try search by attribute\n    const contactByAttr = (await (client as any).post('contacts/filter', {\n      payload: [\n        {\n          attribute_key: 'identifier',\n          filter_operator: 'equal_to',\n          values: [identifier],\n          query_operator: null,\n        },\n      ],\n    })) as any;\n\n    if (contactByAttr && contactByAttr.payload && contactByAttr.payload.length > 0) {\n      return contactByAttr.payload[0];\n    }\n\n    // Check inside data property if using axios interceptors wrapper\n    if (contactByAttr && contactByAttr.data && contactByAttr.data.payload && contactByAttr.data.payload.length > 0) {\n      return contactByAttr.data.payload[0];\n    }\n\n    return null;\n  }\n\n  public async findContact(instance: InstanceDto, phoneNumber: string) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    let query: any;\n    const isGroup = phoneNumber.includes('@g.us');\n\n    if (!isGroup) {\n      query = `+${phoneNumber}`;\n    } else {\n      query = phoneNumber;\n    }\n\n    let contact: any;\n\n    if (isGroup) {\n      contact = await client.contacts.search({\n        accountId: this.provider.accountId,\n        q: query,\n      });\n    } else {\n      contact = await chatwootRequest(this.getClientCwConfig(), {\n        method: 'POST',\n        url: `/api/v1/accounts/${this.provider.accountId}/contacts/filter`,\n        body: {\n          payload: this.getFilterPayload(query),\n        },\n      });\n    }\n\n    if (!contact && contact?.payload?.length === 0) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    if (!isGroup) {\n      return contact.payload.length > 1 ? this.findContactInContactList(contact.payload, query) : contact.payload[0];\n    } else {\n      return contact.payload.find((contact) => contact.identifier === query);\n    }\n  }\n\n  private async mergeContacts(baseId: number, mergeId: number) {\n    try {\n      const contact = await chatwootRequest(this.getClientCwConfig(), {\n        method: 'POST',\n        url: `/api/v1/accounts/${this.provider.accountId}/actions/contact_merge`,\n        body: {\n          base_contact_id: baseId,\n          mergee_contact_id: mergeId,\n        },\n      });\n\n      return contact;\n    } catch {\n      this.logger.error('Error merging contacts');\n      return null;\n    }\n  }\n\n  private async mergeBrazilianContacts(contacts: any[]) {\n    try {\n      const contact = await chatwootRequest(this.getClientCwConfig(), {\n        method: 'POST',\n        url: `/api/v1/accounts/${this.provider.accountId}/actions/contact_merge`,\n        body: {\n          base_contact_id: contacts.find((contact) => contact.phone_number.length === 14)?.id,\n          mergee_contact_id: contacts.find((contact) => contact.phone_number.length === 13)?.id,\n        },\n      });\n\n      return contact;\n    } catch {\n      this.logger.error('Error merging contacts');\n      return null;\n    }\n  }\n\n  private findContactInContactList(contacts: any[], query: string) {\n    const phoneNumbers = this.getNumbers(query);\n    const searchableFields = this.getSearchableFields();\n\n    // eslint-disable-next-line prettier/prettier\n    if (contacts.length === 2 && this.getClientCwConfig().mergeBrazilContacts && query.startsWith('+55')) {\n      const contact = this.mergeBrazilianContacts(contacts);\n      if (contact) {\n        return contact;\n      }\n    }\n\n    const phone = phoneNumbers.reduce(\n      (savedNumber, number) => (number.length > savedNumber.length ? number : savedNumber),\n      '',\n    );\n\n    const contact_with9 = contacts.find((contact) => contact.phone_number === phone);\n    if (contact_with9) {\n      return contact_with9;\n    }\n\n    for (const contact of contacts) {\n      for (const field of searchableFields) {\n        if (contact[field] && phoneNumbers.includes(contact[field])) {\n          return contact;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  private getNumbers(query: string) {\n    const numbers = [];\n    numbers.push(query);\n\n    if (query.startsWith('+55') && query.length === 14) {\n      const withoutNine = query.slice(0, 5) + query.slice(6);\n      numbers.push(withoutNine);\n    } else if (query.startsWith('+55') && query.length === 13) {\n      const withNine = query.slice(0, 5) + '9' + query.slice(5);\n      numbers.push(withNine);\n    }\n\n    return numbers;\n  }\n\n  private getSearchableFields() {\n    return ['phone_number'];\n  }\n\n  private getFilterPayload(query: string) {\n    const filterPayload = [];\n\n    const numbers = this.getNumbers(query);\n    const fieldsToSearch = this.getSearchableFields();\n\n    fieldsToSearch.forEach((field, index1) => {\n      numbers.forEach((number, index2) => {\n        const queryOperator = fieldsToSearch.length - 1 === index1 && numbers.length - 1 === index2 ? null : 'OR';\n        filterPayload.push({\n          attribute_key: field,\n          filter_operator: 'equal_to',\n          values: [number.replace('+', '')],\n          query_operator: queryOperator,\n        });\n      });\n    });\n\n    return filterPayload;\n  }\n\n  public async createConversation(instance: InstanceDto, body: any) {\n    const isLid = body.key.addressingMode === 'lid';\n    const isGroup = body.key.remoteJid.endsWith('@g.us');\n    const phoneNumber = isLid && !isGroup ? body.key.remoteJidAlt : body.key.remoteJid;\n    const { remoteJid } = body.key;\n    const cacheKey = `${instance.instanceName}:createConversation-${remoteJid}`;\n    const lockKey = `${instance.instanceName}:lock:createConversation-${remoteJid}`;\n    const maxWaitTime = 5000; // 5 seconds\n    const client = await this.clientCw(instance);\n    if (!client) return null;\n\n    try {\n      // Processa atualização de contatos já criados @lid\n      if (phoneNumber && remoteJid && !isGroup) {\n        const contact = await this.findContact(instance, phoneNumber.split('@')[0]);\n        if (contact && contact.identifier !== remoteJid) {\n          this.logger.verbose(\n            `Identifier needs update: (contact.identifier: ${contact.identifier}, phoneNumber: ${phoneNumber}, body.key.remoteJidAlt: ${remoteJid}`,\n          );\n          const updateContact = await this.updateContact(instance, contact.id, {\n            identifier: phoneNumber,\n            phone_number: `+${phoneNumber.split('@')[0]}`,\n          });\n\n          if (updateContact === null) {\n            const baseContact = await this.findContact(instance, phoneNumber.split('@')[0]);\n            if (baseContact) {\n              await this.mergeContacts(baseContact.id, contact.id);\n              this.logger.verbose(\n                `Merge contacts: (${baseContact.id}) ${baseContact.phone_number} and (${contact.id}) ${contact.phone_number}`,\n              );\n            }\n          }\n        }\n      }\n      this.logger.verbose(`--- Start createConversation ---`);\n      this.logger.verbose(`Instance: ${JSON.stringify(instance)}`);\n\n      // If it already exists in the cache, return conversationId\n      if (await this.cache.has(cacheKey)) {\n        const conversationId = (await this.cache.get(cacheKey)) as number;\n        this.logger.verbose(`Found conversation to: ${phoneNumber}, conversation ID: ${conversationId}`);\n        let conversationExists: any;\n        try {\n          conversationExists = await client.conversations.get({\n            accountId: this.provider.accountId,\n            conversationId: conversationId,\n          });\n          this.logger.verbose(\n            `Conversation exists: ID: ${conversationExists.id} - Name: ${conversationExists.meta.sender.name} - Identifier: ${conversationExists.meta.sender.identifier}`,\n          );\n        } catch (error) {\n          this.logger.error(`Error getting conversation: ${error}`);\n          conversationExists = false;\n        }\n        if (!conversationExists) {\n          this.logger.verbose('Conversation does not exist, re-calling createConversation');\n          this.cache.delete(cacheKey);\n          return await this.createConversation(instance, body);\n        }\n        return conversationId;\n      }\n\n      // If lock already exists, wait until release or timeout\n      if (await this.cache.has(lockKey)) {\n        this.logger.verbose(`Operação de criação já em andamento para ${remoteJid}, aguardando resultado...`);\n        const start = Date.now();\n        while (await this.cache.has(lockKey)) {\n          if (Date.now() - start > maxWaitTime) {\n            this.logger.warn(`Timeout aguardando lock para ${remoteJid}`);\n            break;\n          }\n          await new Promise((res) => setTimeout(res, this.LOCK_POLLING_DELAY_MS));\n          if (await this.cache.has(cacheKey)) {\n            const conversationId = (await this.cache.get(cacheKey)) as number;\n            this.logger.verbose(`Resolves creation of: ${remoteJid}, conversation ID: ${conversationId}`);\n            return conversationId;\n          }\n        }\n      }\n\n      // Adquire lock\n      await this.cache.set(lockKey, true, 30);\n      this.logger.verbose(`Bloqueio adquirido para: ${lockKey}`);\n\n      try {\n        /*\n        Double check after lock\n        Utilizei uma nova verificação para evitar que outra thread execute entre o terminio do while e o set lock\n        */\n        if (await this.cache.has(cacheKey)) {\n          return (await this.cache.get(cacheKey)) as number;\n        }\n\n        const chatId = isGroup ? remoteJid : phoneNumber.split('@')[0].split(':')[0];\n        let nameContact = !body.key.fromMe ? body.pushName : chatId;\n        const filterInbox = await this.getInbox(instance);\n        if (!filterInbox) return null;\n\n        if (isGroup) {\n          this.logger.verbose(`Processing group conversation`);\n          const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId);\n          this.logger.verbose(`Group metadata: JID:${group.JID} - Subject:${group?.subject || group?.Name}`);\n\n          const participantJid = isLid && !body.key.fromMe ? body.key.participantAlt : body.key.participant;\n          nameContact = `${group.subject} (GROUP)`;\n\n          const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(\n            participantJid.split('@')[0],\n          );\n          this.logger.verbose(`Participant profile picture URL: ${JSON.stringify(picture_url)}`);\n\n          const findParticipant = await this.findContact(instance, participantJid.split('@')[0]);\n\n          if (findParticipant) {\n            this.logger.verbose(\n              `Found participant: ID:${findParticipant.id} - Name: ${findParticipant.name} - identifier: ${findParticipant.identifier}`,\n            );\n            if (!findParticipant.name || findParticipant.name === chatId) {\n              await this.updateContact(instance, findParticipant.id, {\n                name: body.pushName,\n                avatar_url: picture_url.profilePictureUrl || null,\n              });\n            }\n          } else {\n            await this.createContact(\n              instance,\n              participantJid.split('@')[0].split(':')[0],\n              filterInbox.id,\n              false,\n              body.pushName,\n              picture_url.profilePictureUrl || null,\n              participantJid,\n            );\n          }\n        }\n\n        const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId);\n        this.logger.verbose(`Contact profile picture URL: ${JSON.stringify(picture_url)}`);\n\n        this.logger.verbose(`Searching contact for: ${chatId}`);\n        let contact = await this.findContact(instance, chatId);\n\n        if (contact) {\n          this.logger.verbose(`Found contact: ID:${contact.id} - Name:${contact.name}`);\n          if (!body.key.fromMe) {\n            const waProfilePictureFile =\n              picture_url?.profilePictureUrl?.split('#')[0].split('?')[0].split('/').pop() || '';\n            const chatwootProfilePictureFile = contact?.thumbnail?.split('#')[0].split('?')[0].split('/').pop() || '';\n            const pictureNeedsUpdate = waProfilePictureFile !== chatwootProfilePictureFile;\n            const nameNeedsUpdate = !contact.name || contact.name === chatId;\n            this.logger.verbose(`Picture needs update: ${pictureNeedsUpdate}`);\n            this.logger.verbose(`Name needs update: ${nameNeedsUpdate}`);\n            if (pictureNeedsUpdate || nameNeedsUpdate) {\n              contact = await this.updateContact(instance, contact.id, {\n                ...(nameNeedsUpdate && { name: nameContact }),\n                ...(waProfilePictureFile === '' && { avatar: null }),\n                ...(pictureNeedsUpdate && { avatar_url: picture_url?.profilePictureUrl }),\n              });\n            }\n          }\n        } else {\n          contact = await this.createContact(\n            instance,\n            chatId,\n            filterInbox.id,\n            isGroup,\n            nameContact,\n            picture_url.profilePictureUrl || null,\n            phoneNumber,\n          );\n        }\n\n        if (!contact) {\n          this.logger.warn(`Contact not created or found`);\n          return null;\n        }\n\n        const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id;\n        this.logger.verbose(`Contact ID: ${contactId}`);\n\n        const contactConversations = (await client.contacts.listConversations({\n          accountId: this.provider.accountId,\n          id: contactId,\n        })) as any;\n\n        if (!contactConversations || !contactConversations.payload) {\n          this.logger.error(`No conversations found or payload is undefined`);\n          return null;\n        }\n\n        let inboxConversation = contactConversations.payload.find(\n          (conversation) => conversation.inbox_id == filterInbox.id,\n        );\n        if (inboxConversation) {\n          if (this.provider.reopenConversation) {\n            this.logger.verbose(\n              `Found conversation in reopenConversation mode: ID: ${inboxConversation.id} - Name: ${inboxConversation.meta.sender.name} - Identifier: ${inboxConversation.meta.sender.identifier}`,\n            );\n            if (inboxConversation && this.provider.conversationPending && inboxConversation.status !== 'open') {\n              await client.conversations.toggleStatus({\n                accountId: this.provider.accountId,\n                conversationId: inboxConversation.id,\n                data: {\n                  status: 'pending',\n                },\n              });\n            }\n          } else {\n            inboxConversation = contactConversations.payload.find(\n              (conversation) =>\n                conversation && conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id,\n            );\n            this.logger.verbose(`Found conversation: ${JSON.stringify(inboxConversation)}`);\n          }\n\n          if (inboxConversation) {\n            this.logger.verbose(`Returning existing conversation ID: ${inboxConversation.id}`);\n            this.cache.set(cacheKey, inboxConversation.id, 1800);\n            return inboxConversation.id;\n          }\n        }\n\n        const data = {\n          contact_id: contactId.toString(),\n          inbox_id: filterInbox.id.toString(),\n        };\n\n        if (this.provider.conversationPending) {\n          data['status'] = 'pending';\n        }\n\n        const conversation = await client.conversations.create({\n          accountId: this.provider.accountId,\n          data,\n        });\n\n        if (!conversation) {\n          this.logger.warn(`Conversation not created or found`);\n          return null;\n        }\n\n        this.logger.verbose(`New conversation created of ${remoteJid} with ID: ${conversation.id}`);\n        this.cache.set(cacheKey, conversation.id, 1800);\n        return conversation.id;\n      } finally {\n        await this.cache.delete(lockKey);\n        this.logger.verbose(`Block released for: ${lockKey}`);\n      }\n    } catch (error) {\n      this.logger.error(`Error in createConversation: ${error}`);\n      return null;\n    }\n  }\n\n  public async getInbox(instance: InstanceDto): Promise<inbox | null> {\n    const cacheKey = `${instance.instanceName}:getInbox`;\n    if (await this.cache.has(cacheKey)) {\n      return (await this.cache.get(cacheKey)) as inbox;\n    }\n\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const inbox = (await client.inboxes.list({\n      accountId: this.provider.accountId,\n    })) as any;\n\n    if (!inbox) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    const findByName = inbox.payload.find((inbox) => inbox.name === this.getClientCwConfig().nameInbox);\n\n    if (!findByName) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    this.cache.set(cacheKey, findByName);\n    return findByName;\n  }\n\n  public async createMessage(\n    instance: InstanceDto,\n    conversationId: number,\n    content: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    privateMessage?: boolean,\n    attachments?: {\n      content: unknown;\n      encoding: string;\n      filename: string;\n    }[],\n    messageBody?: any,\n    sourceId?: string,\n    quotedMsg?: MessageModel,\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const replyToIds = await this.getReplyToIds(messageBody, instance);\n\n    const sourceReplyId = quotedMsg?.chatwootMessageId || null;\n\n    const message = await client.messages.create({\n      accountId: this.provider.accountId,\n      conversationId: conversationId,\n      data: {\n        content: content,\n        message_type: messageType,\n        attachments: attachments,\n        private: privateMessage || false,\n        source_id: sourceId,\n        content_attributes: {\n          ...replyToIds,\n        },\n        source_reply_id: sourceReplyId ? sourceReplyId.toString() : null,\n      },\n    });\n\n    if (!message) {\n      this.logger.warn('message not found');\n      return null;\n    }\n\n    return message;\n  }\n\n  public async getOpenConversationByContact(\n    instance: InstanceDto,\n    inbox: inbox,\n    contact: generic_id & contact,\n  ): Promise<conversation> {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const conversations = (await client.contacts.listConversations({\n      accountId: this.provider.accountId,\n      id: contact.id,\n    })) as any;\n\n    return (\n      conversations.payload.find(\n        (conversation) => conversation.inbox_id === inbox.id && conversation.status === 'open',\n      ) || undefined\n    );\n  }\n\n  public async createBotMessage(\n    instance: InstanceDto,\n    content: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    attachments?: {\n      content: unknown;\n      encoding: string;\n      filename: string;\n    }[],\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    const contact = await this.findContact(instance, '123456');\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    const filterInbox = await this.getInbox(instance);\n\n    if (!filterInbox) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    const conversation = await this.getOpenConversationByContact(instance, filterInbox, contact);\n\n    if (!conversation) {\n      this.logger.warn('conversation not found');\n      return;\n    }\n\n    const message = await client.messages.create({\n      accountId: this.provider.accountId,\n      conversationId: conversation.id,\n      data: {\n        content: content,\n        message_type: messageType,\n        attachments: attachments,\n      },\n    });\n\n    if (!message) {\n      this.logger.warn('message not found');\n      return null;\n    }\n\n    return message;\n  }\n\n  private async sendData(\n    conversationId: number,\n    fileStream: Readable,\n    fileName: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    content?: string,\n    instance?: InstanceDto,\n    messageBody?: any,\n    sourceId?: string,\n    quotedMsg?: MessageModel,\n  ) {\n    if (sourceId && this.isImportHistoryAvailable()) {\n      const messageAlreadySaved = await chatwootImport.getExistingSourceIds([sourceId], conversationId);\n      if (messageAlreadySaved) {\n        if (messageAlreadySaved.size > 0) {\n          this.logger.warn('Message already saved on chatwoot');\n          return null;\n        }\n      }\n    }\n    const data = new FormData();\n\n    if (content) {\n      data.append('content', content);\n    }\n\n    data.append('message_type', messageType);\n\n    data.append('attachments[]', fileStream, { filename: fileName });\n\n    const sourceReplyId = quotedMsg?.chatwootMessageId || null;\n\n    if (messageBody && instance) {\n      const replyToIds = await this.getReplyToIds(messageBody, instance);\n\n      if (replyToIds.in_reply_to || replyToIds.in_reply_to_external_id) {\n        const content = JSON.stringify({\n          ...replyToIds,\n        });\n        data.append('content_attributes', content);\n      }\n    }\n\n    if (sourceReplyId) {\n      data.append('source_reply_id', sourceReplyId.toString());\n    }\n\n    if (sourceId) {\n      data.append('source_id', sourceId);\n    }\n\n    const config = {\n      method: 'post',\n      maxBodyLength: Infinity,\n      url: `${this.provider.url}/api/v1/accounts/${this.provider.accountId}/conversations/${conversationId}/messages`,\n      headers: {\n        api_access_token: this.provider.token,\n        ...data.getHeaders(),\n      },\n      data: data,\n    };\n\n    try {\n      const { data } = await axios.request(config);\n\n      return data;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public async createBotQr(\n    instance: InstanceDto,\n    content: string,\n    messageType: 'incoming' | 'outgoing' | undefined,\n    fileStream?: Readable,\n    fileName?: string,\n  ) {\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      this.logger.warn('client not found');\n      return null;\n    }\n\n    if (!this.configService.get<Chatwoot>('CHATWOOT').BOT_CONTACT) {\n      this.logger.log('Chatwoot bot contact is disabled');\n\n      return true;\n    }\n\n    const contact = await this.findContact(instance, '123456');\n\n    if (!contact) {\n      this.logger.warn('contact not found');\n      return null;\n    }\n\n    const filterInbox = await this.getInbox(instance);\n\n    if (!filterInbox) {\n      this.logger.warn('inbox not found');\n      return null;\n    }\n\n    const conversation = await this.getOpenConversationByContact(instance, filterInbox, contact);\n\n    if (!conversation) {\n      this.logger.warn('conversation not found');\n      return;\n    }\n\n    const data = new FormData();\n\n    if (content) {\n      data.append('content', content);\n    }\n\n    data.append('message_type', messageType);\n\n    if (fileStream && fileName) {\n      data.append('attachments[]', fileStream, { filename: fileName });\n    }\n\n    const config = {\n      method: 'post',\n      maxBodyLength: Infinity,\n      url: `${this.provider.url}/api/v1/accounts/${this.provider.accountId}/conversations/${conversation.id}/messages`,\n      headers: {\n        api_access_token: this.provider.token,\n        ...data.getHeaders(),\n      },\n      data: data,\n    };\n\n    try {\n      const { data } = await axios.request(config);\n\n      return data;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public async sendAttachment(waInstance: any, number: string, media: any, caption?: string, options?: Options) {\n    try {\n      const parsedMedia = path.parse(decodeURIComponent(media));\n      let mimeType = mimeTypes.lookup(parsedMedia?.ext) || '';\n      let fileName = parsedMedia?.name + parsedMedia?.ext;\n\n      if (!mimeType) {\n        const parts = media.split('/');\n        fileName = decodeURIComponent(parts[parts.length - 1]);\n\n        const response = await axios.get(media, {\n          responseType: 'arraybuffer',\n        });\n        mimeType = response.headers['content-type'];\n      }\n\n      let type = 'document';\n\n      switch (mimeType.split('/')[0]) {\n        case 'image':\n          type = 'image';\n          break;\n        case 'video':\n          type = 'video';\n          break;\n        case 'audio':\n          type = 'audio';\n          break;\n        default:\n          type = 'document';\n          break;\n      }\n\n      if (type === 'audio') {\n        const data: SendAudioDto = {\n          number: number,\n          audio: media,\n          delay: Math.floor(Math.random() * (2000 - 500 + 1)) + 500,\n          quoted: options?.quoted,\n        };\n\n        sendTelemetry('/message/sendWhatsAppAudio');\n\n        const messageSent = await waInstance?.audioWhatsapp(data, null, true);\n\n        return messageSent;\n      }\n\n      const documentExtensions = ['.gif', '.svg', '.tiff', '.tif', '.dxf', '.dwg'];\n      if (type === 'image' && parsedMedia && documentExtensions.includes(parsedMedia?.ext)) {\n        type = 'document';\n      }\n\n      const data: SendMediaDto = {\n        number: number,\n        mediatype: type as any,\n        fileName: fileName,\n        media: media,\n        delay: 1200,\n        quoted: options?.quoted,\n      };\n\n      sendTelemetry('/message/sendMedia');\n\n      if (caption) {\n        data.caption = caption;\n      }\n\n      const messageSent = await waInstance?.mediaMessage(data, null, true);\n\n      return messageSent;\n    } catch (error) {\n      this.logger.error(error);\n      throw error; // Re-throw para que o erro seja tratado pelo caller\n    }\n  }\n\n  public async onSendMessageError(instance: InstanceDto, conversation: number, error?: any) {\n    this.logger.verbose(`onSendMessageError ${JSON.stringify(error)}`);\n\n    const client = await this.clientCw(instance);\n\n    if (!client) {\n      return;\n    }\n\n    if (error && error?.status === 400 && error?.message[0]?.exists === false) {\n      client.messages.create({\n        accountId: this.provider.accountId,\n        conversationId: conversation,\n        data: {\n          content: `${i18next.t('cw.message.numbernotinwhatsapp')}`,\n          message_type: 'outgoing',\n          private: true,\n        },\n      });\n\n      return;\n    }\n\n    client.messages.create({\n      accountId: this.provider.accountId,\n      conversationId: conversation,\n      data: {\n        content: i18next.t('cw.message.notsent', {\n          error: error ? `_${error.toString()}_` : '',\n        }),\n        message_type: 'outgoing',\n        private: true,\n      },\n    });\n  }\n\n  public async receiveWebhook(instance: InstanceDto, body: any) {\n    try {\n      await new Promise((resolve) => setTimeout(resolve, 500));\n\n      const client = await this.clientCw(instance);\n\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      if (\n        this.provider.reopenConversation === false &&\n        body.event === 'conversation_status_changed' &&\n        body.status === 'resolved' &&\n        body.meta?.sender?.identifier\n      ) {\n        const keyToDelete = `${instance.instanceName}:createConversation-${body.meta.sender.identifier}`;\n        this.cache.delete(keyToDelete);\n      }\n\n      if (\n        !body?.conversation ||\n        body.private ||\n        (body.event === 'message_updated' && !body.content_attributes?.deleted)\n      ) {\n        return { message: 'bot' };\n      }\n\n      const chatId =\n        body.conversation.meta.sender?.identifier || body.conversation.meta.sender?.phone_number.replace('+', '');\n      // Chatwoot to Whatsapp\n      const messageReceived = body.content\n        ? body.content\n            .replaceAll(/(?<!\\*)\\*((?!\\s)([^\\n*]+?)(?<!\\s))\\*(?!\\*)/g, '_$1_') // Substitui * por _\n            .replaceAll(/\\*{2}((?!\\s)([^\\n*]+?)(?<!\\s))\\*{2}/g, '*$1*') // Substitui ** por *\n            .replaceAll(/~{2}((?!\\s)([^\\n*]+?)(?<!\\s))~{2}/g, '~$1~') // Substitui ~~ por ~\n            .replaceAll(/(?<!`)`((?!\\s)([^`*]+?)(?<!\\s))`(?!`)/g, '```$1```') // Substitui ` por ```\n        : body.content;\n\n      const senderName = body?.conversation?.messages[0]?.sender?.available_name || body?.sender?.name;\n      const waInstance = this.waMonitor.waInstances[instance.instanceName];\n      instance.instanceId = waInstance.instanceId;\n\n      if (body.event === 'message_updated' && body.content_attributes?.deleted) {\n        const message = await this.prismaRepository.message.findFirst({\n          where: {\n            chatwootMessageId: body.id,\n            instanceId: instance.instanceId,\n          },\n        });\n\n        if (message) {\n          const key = message.key as WAMessageKey;\n\n          await waInstance?.client.sendMessage(key.remoteJid, { delete: key });\n\n          await this.prismaRepository.message.deleteMany({\n            where: {\n              instanceId: instance.instanceId,\n              chatwootMessageId: body.id,\n            },\n          });\n        }\n        return { message: 'bot' };\n      }\n\n      const cwBotContact = this.configService.get<Chatwoot>('CHATWOOT').BOT_CONTACT;\n\n      if (chatId === '123456' && body.message_type === 'outgoing') {\n        const command = messageReceived.replace('/', '');\n\n        if (cwBotContact && (command.includes('init') || command.includes('iniciar'))) {\n          const state = waInstance?.connectionStatus?.state;\n\n          if (state !== 'open') {\n            const number = command.split(':')[1];\n            await waInstance.connectToWhatsapp(number);\n          } else {\n            await this.createBotMessage(\n              instance,\n              i18next.t('cw.inbox.alreadyConnected', {\n                inboxName: body.inbox.name,\n              }),\n              'incoming',\n            );\n          }\n        }\n\n        if (command === 'clearcache') {\n          waInstance.clearCacheChatwoot();\n          await this.createBotMessage(\n            instance,\n            i18next.t('cw.inbox.clearCache', {\n              inboxName: body.inbox.name,\n            }),\n            'incoming',\n          );\n        }\n\n        if (command === 'status') {\n          const state = waInstance?.connectionStatus?.state;\n\n          if (!state) {\n            await this.createBotMessage(\n              instance,\n              i18next.t('cw.inbox.notFound', {\n                inboxName: body.inbox.name,\n              }),\n              'incoming',\n            );\n          }\n\n          if (state) {\n            await this.createBotMessage(\n              instance,\n              i18next.t('cw.inbox.status', {\n                inboxName: body.inbox.name,\n                state: state,\n              }),\n              'incoming',\n            );\n          }\n        }\n\n        if (cwBotContact && (command === 'disconnect' || command === 'desconectar')) {\n          const msgLogout = i18next.t('cw.inbox.disconnect', {\n            inboxName: body.inbox.name,\n          });\n\n          await this.createBotMessage(instance, msgLogout, 'incoming');\n\n          await waInstance?.client?.logout('Log out instance: ' + instance.instanceName);\n          await waInstance?.client?.ws?.close();\n        }\n      }\n\n      if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') {\n        if (body?.conversation?.messages[0]?.source_id?.substring(0, 5) === 'WAID:') {\n          return { message: 'bot' };\n        }\n\n        if (!waInstance && body.conversation?.id) {\n          this.onSendMessageError(instance, body.conversation?.id, 'Instance not found');\n          return { message: 'bot' };\n        }\n\n        let formatText: string;\n        if (senderName === null || senderName === undefined) {\n          formatText = messageReceived;\n        } else {\n          const formattedDelimiter = this.provider.signDelimiter\n            ? this.provider.signDelimiter.replaceAll('\\\\n', '\\n')\n            : '\\n';\n          const textToConcat = this.provider.signMsg ? [`*${senderName}:*`] : [];\n          textToConcat.push(messageReceived);\n\n          formatText = textToConcat.join(formattedDelimiter);\n        }\n\n        for (const message of body.conversation.messages) {\n          if (message.attachments && message.attachments.length > 0) {\n            for (const attachment of message.attachments) {\n              if (!messageReceived) {\n                formatText = null;\n              }\n\n              const options: Options = {\n                quoted: await this.getQuotedMessage(body, instance),\n              };\n\n              const messageSent = await this.sendAttachment(\n                waInstance,\n                chatId,\n                attachment.data_url,\n                formatText,\n                options,\n              );\n              if (!messageSent && body.conversation?.id) {\n                this.onSendMessageError(instance, body.conversation?.id);\n              }\n\n              await this.updateChatwootMessageId(\n                {\n                  ...messageSent,\n                },\n                {\n                  messageId: body.id,\n                  inboxId: body.inbox?.id,\n                  conversationId: body.conversation?.id,\n                  contactInboxSourceId: body.conversation?.contact_inbox?.source_id,\n                },\n                instance,\n              );\n            }\n          } else {\n            const data: SendTextDto = {\n              number: chatId,\n              text: formatText,\n              delay: Math.floor(Math.random() * (2000 - 500 + 1)) + 500,\n              quoted: await this.getQuotedMessage(body, instance),\n            };\n\n            sendTelemetry('/message/sendText');\n\n            let messageSent: any;\n            try {\n              messageSent = await waInstance?.textMessage(data, true);\n              if (!messageSent) {\n                throw new Error('Message not sent');\n              }\n\n              if (Long.isLong(messageSent?.messageTimestamp)) {\n                messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber();\n              }\n\n              await this.updateChatwootMessageId(\n                {\n                  ...messageSent,\n                },\n                {\n                  messageId: body.id,\n                  inboxId: body.inbox?.id,\n                  conversationId: body.conversation?.id,\n                  contactInboxSourceId: body.conversation?.contact_inbox?.source_id,\n                },\n                instance,\n              );\n            } catch (error) {\n              if (!messageSent && body.conversation?.id) {\n                this.onSendMessageError(instance, body.conversation?.id, error);\n              }\n              throw error;\n            }\n          }\n        }\n\n        const chatwootRead = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_READ;\n        if (chatwootRead) {\n          const lastMessage = await this.prismaRepository.message.findFirst({\n            where: {\n              key: {\n                path: ['fromMe'],\n                equals: false,\n              },\n              instanceId: instance.instanceId,\n            },\n          });\n          if (lastMessage && !lastMessage.chatwootIsRead) {\n            const key = lastMessage.key as WAMessageKey;\n\n            waInstance?.markMessageAsRead({\n              readMessages: [\n                {\n                  id: key.id,\n                  fromMe: key.fromMe,\n                  remoteJid: key.remoteJid,\n                },\n              ],\n            });\n            const updateMessage = {\n              chatwootMessageId: lastMessage.chatwootMessageId,\n              chatwootConversationId: lastMessage.chatwootConversationId,\n              chatwootInboxId: lastMessage.chatwootInboxId,\n              chatwootContactInboxSourceId: lastMessage.chatwootContactInboxSourceId,\n              chatwootIsRead: true,\n            };\n\n            await this.prismaRepository.message.updateMany({\n              where: {\n                instanceId: instance.instanceId,\n                key: {\n                  path: ['id'],\n                  equals: key.id,\n                },\n              },\n              data: updateMessage,\n            });\n          }\n        }\n      }\n\n      if (body.message_type === 'template' && body.event === 'message_created') {\n        const data: SendTextDto = {\n          number: chatId,\n          text: body.content.replace(/\\\\\\r\\n|\\\\\\n|\\n/g, '\\n'),\n          delay: Math.floor(Math.random() * (2000 - 500 + 1)) + 500,\n        };\n\n        sendTelemetry('/message/sendText');\n\n        await waInstance?.textMessage(data);\n      }\n\n      return { message: 'bot' };\n    } catch (error) {\n      this.logger.error(error);\n\n      return { message: 'bot' };\n    }\n  }\n\n  private async updateChatwootMessageId(\n    message: MessageModel,\n    chatwootMessageIds: ChatwootMessage,\n    instance: InstanceDto,\n  ) {\n    const key = message.key as WAMessageKey;\n\n    if (!chatwootMessageIds.messageId || !key?.id) {\n      return;\n    }\n\n    // Use raw SQL to avoid JSON path issues\n    const result = await this.prismaRepository.$executeRaw`\n      UPDATE \"Message\" \n      SET \n        \"chatwootMessageId\" = ${chatwootMessageIds.messageId},\n        \"chatwootConversationId\" = ${chatwootMessageIds.conversationId},\n        \"chatwootInboxId\" = ${chatwootMessageIds.inboxId},\n        \"chatwootContactInboxSourceId\" = ${chatwootMessageIds.contactInboxSourceId},\n        \"chatwootIsRead\" = ${chatwootMessageIds.isRead || false}\n      WHERE \"instanceId\" = ${instance.instanceId} \n      AND \"key\"->>'id' = ${key.id}\n    `;\n\n    this.logger.verbose(`Update result: ${result} rows affected`);\n\n    if (this.isImportHistoryAvailable()) {\n      try {\n        await chatwootImport.updateMessageSourceID(chatwootMessageIds.messageId, key.id);\n      } catch (error) {\n        this.logger.error(`Error updating Chatwoot message source ID: ${error}`);\n      }\n    }\n  }\n\n  private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageModel> {\n    // Use raw SQL query to avoid JSON path issues with Prisma\n    const messages = await this.prismaRepository.$queryRaw`\n      SELECT * FROM \"Message\" \n      WHERE \"instanceId\" = ${instance.instanceId} \n      AND \"key\"->>'id' = ${keyId}\n      LIMIT 1\n    `;\n\n    return (messages as MessageModel[])[0] || null;\n  }\n\n  private async getReplyToIds(\n    msg: any,\n    instance: InstanceDto,\n  ): Promise<{ in_reply_to: string; in_reply_to_external_id: string }> {\n    let inReplyTo = null;\n    let inReplyToExternalId = null;\n\n    if (msg) {\n      inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId ?? msg.contextInfo?.stanzaId;\n      if (inReplyToExternalId) {\n        const message = await this.getMessageByKeyId(instance, inReplyToExternalId);\n        if (message?.chatwootMessageId) {\n          inReplyTo = message.chatwootMessageId;\n        }\n      }\n    }\n\n    return {\n      in_reply_to: inReplyTo,\n      in_reply_to_external_id: inReplyToExternalId,\n    };\n  }\n\n  private async getQuotedMessage(msg: any, instance: InstanceDto): Promise<Quoted> {\n    if (msg?.content_attributes?.in_reply_to) {\n      const message = await this.prismaRepository.message.findFirst({\n        where: {\n          chatwootMessageId: msg?.content_attributes?.in_reply_to,\n          instanceId: instance.instanceId,\n        },\n      });\n\n      const key = message?.key as WAMessageKey;\n      const messageContent = message?.message as WAMessageContent;\n\n      if (messageContent && key?.id) {\n        return {\n          key: key,\n          message: messageContent,\n        };\n      }\n    }\n\n    return null;\n  }\n\n  private isMediaMessage(message: any) {\n    const media = [\n      'imageMessage',\n      'documentMessage',\n      'documentWithCaptionMessage',\n      'audioMessage',\n      'videoMessage',\n      'stickerMessage',\n      'viewOnceMessageV2',\n    ];\n\n    const messageKeys = Object.keys(message);\n\n    const result = messageKeys.some((key) => media.includes(key));\n\n    return result;\n  }\n\n  private isInteractiveButtonMessage(messageType: string, message: any) {\n    return messageType === 'interactiveMessage' && message.interactiveMessage?.nativeFlowMessage?.buttons?.length > 0;\n  }\n\n  private getAdsMessage(msg: any) {\n    interface AdsMessage {\n      title: string;\n      body: string;\n      thumbnailUrl: string;\n      sourceUrl: string;\n    }\n\n    const adsMessage: AdsMessage | undefined = {\n      title: msg.extendedTextMessage?.contextInfo?.externalAdReply?.title || msg.contextInfo?.externalAdReply?.title,\n      body: msg.extendedTextMessage?.contextInfo?.externalAdReply?.body || msg.contextInfo?.externalAdReply?.body,\n      thumbnailUrl:\n        msg.extendedTextMessage?.contextInfo?.externalAdReply?.thumbnailUrl ||\n        msg.contextInfo?.externalAdReply?.thumbnailUrl,\n      sourceUrl:\n        msg.extendedTextMessage?.contextInfo?.externalAdReply?.sourceUrl || msg.contextInfo?.externalAdReply?.sourceUrl,\n    };\n\n    return adsMessage;\n  }\n\n  private getReactionMessage(msg: any) {\n    interface ReactionMessage {\n      key: {\n        id: string;\n        fromMe: boolean;\n        remoteJid: string;\n        participant?: string;\n      };\n      text: string;\n    }\n    const reactionMessage: ReactionMessage | undefined = msg?.reactionMessage;\n\n    return reactionMessage;\n  }\n\n  private getTypeMessage(msg: any) {\n    const types = {\n      conversation: msg.conversation,\n      imageMessage: msg.imageMessage?.caption,\n      videoMessage: msg.videoMessage?.caption,\n      extendedTextMessage: msg.extendedTextMessage?.text,\n      messageContextInfo: msg.messageContextInfo?.stanzaId,\n      stickerMessage: undefined,\n      documentMessage: msg.documentMessage?.caption,\n      documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption,\n      audioMessage: msg.audioMessage ? (msg.audioMessage.caption ?? '') : undefined,\n      contactMessage: msg.contactMessage?.vcard,\n      contactsArrayMessage: msg.contactsArrayMessage,\n      locationMessage: msg.locationMessage,\n      liveLocationMessage: msg.liveLocationMessage,\n      listMessage: msg.listMessage,\n      listResponseMessage: msg.listResponseMessage,\n      viewOnceMessageV2:\n        msg?.message?.viewOnceMessageV2?.message?.imageMessage?.url ||\n        msg?.message?.viewOnceMessageV2?.message?.videoMessage?.url ||\n        msg?.message?.viewOnceMessageV2?.message?.audioMessage?.url,\n    };\n\n    return types;\n  }\n\n  private getMessageContent(types: any) {\n    const typeKey = Object.keys(types).find((key) => types[key] !== undefined);\n\n    let result = typeKey ? types[typeKey] : undefined;\n\n    // Remove externalAdReplyBody| in Chatwoot (Already Have)\n    if (result && typeof result === 'string' && result.includes('externalAdReplyBody|')) {\n      result = result.split('externalAdReplyBody|').filter(Boolean).join('');\n    }\n\n    if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') {\n      const latitude = result.degreesLatitude;\n      const longitude = result.degreesLongitude;\n\n      const locationName = result?.name;\n      const locationAddress = result?.address;\n\n      const formattedLocation =\n        `*${i18next.t('cw.locationMessage.location')}:*\\n\\n` +\n        `_${i18next.t('cw.locationMessage.latitude')}:_ ${latitude} \\n` +\n        `_${i18next.t('cw.locationMessage.longitude')}:_ ${longitude} \\n` +\n        (locationName ? `_${i18next.t('cw.locationMessage.locationName')}:_ ${locationName}\\n` : '') +\n        (locationAddress ? `_${i18next.t('cw.locationMessage.locationAddress')}:_ ${locationAddress} \\n` : '') +\n        `_${i18next.t('cw.locationMessage.locationUrl')}:_ ` +\n        `https://www.google.com/maps/search/?api=1&query=${latitude},${longitude}`;\n\n      return formattedLocation;\n    }\n\n    if (typeKey === 'contactMessage') {\n      const vCardData = result.split('\\n');\n      const contactInfo = {};\n\n      vCardData.forEach((line) => {\n        const [key, value] = line.split(':');\n        if (key && value) {\n          contactInfo[key] = value;\n        }\n      });\n\n      let formattedContact =\n        `*${i18next.t('cw.contactMessage.contact')}:*\\n\\n` +\n        `_${i18next.t('cw.contactMessage.name')}:_ ${contactInfo['FN']}`;\n\n      let numberCount = 1;\n      Object.keys(contactInfo).forEach((key) => {\n        if (key.startsWith('item') && key.includes('TEL')) {\n          const phoneNumber = contactInfo[key];\n          formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n          numberCount++;\n        } else if (key.includes('TEL')) {\n          const phoneNumber = contactInfo[key];\n          formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n          numberCount++;\n        }\n      });\n\n      return formattedContact;\n    }\n\n    if (typeKey === 'contactsArrayMessage') {\n      const formattedContacts = result.contacts.map((contact) => {\n        const vCardData = contact.vcard.split('\\n');\n        const contactInfo = {};\n\n        vCardData.forEach((line) => {\n          const [key, value] = line.split(':');\n          if (key && value) {\n            contactInfo[key] = value;\n          }\n        });\n\n        let formattedContact = `*${i18next.t('cw.contactMessage.contact')}:*\\n\\n_${i18next.t(\n          'cw.contactMessage.name',\n        )}:_ ${contact.displayName}`;\n\n        let numberCount = 1;\n        Object.keys(contactInfo).forEach((key) => {\n          if (key.startsWith('item') && key.includes('TEL')) {\n            const phoneNumber = contactInfo[key];\n            formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n            numberCount++;\n          } else if (key.includes('TEL')) {\n            const phoneNumber = contactInfo[key];\n            formattedContact += `\\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;\n            numberCount++;\n          }\n        });\n\n        return formattedContact;\n      });\n\n      const formattedContactsArray = formattedContacts.join('\\n\\n');\n\n      return formattedContactsArray;\n    }\n\n    if (typeKey === 'listMessage') {\n      const listTitle = result?.title || 'Unknown';\n      const listDescription = result?.description || 'Unknown';\n      const listFooter = result?.footerText || 'Unknown';\n\n      let formattedList =\n        '*List Menu:*\\n\\n' +\n        '_Title_: ' +\n        listTitle +\n        '\\n' +\n        '_Description_: ' +\n        listDescription +\n        '\\n' +\n        '_Footer_: ' +\n        listFooter;\n\n      if (result.sections && result.sections.length > 0) {\n        result.sections.forEach((section, sectionIndex) => {\n          formattedList += '\\n\\n*Section ' + (sectionIndex + 1) + ':* ' + section.title || 'Unknown\\n';\n\n          if (section.rows && section.rows.length > 0) {\n            section.rows.forEach((row, rowIndex) => {\n              formattedList += '\\n*Line ' + (rowIndex + 1) + ':*\\n';\n              formattedList += '_▪️ Title:_ ' + (row.title || 'Unknown') + '\\n';\n              formattedList += '_▪️ Description:_ ' + (row.description || 'Unknown') + '\\n';\n              formattedList += '_▪️ ID:_ ' + (row.rowId || 'Unknown') + '\\n';\n            });\n          } else {\n            formattedList += '\\nNo lines found in this section.\\n';\n          }\n        });\n      } else {\n        formattedList += '\\nNo sections found.\\n';\n      }\n\n      return formattedList;\n    }\n\n    if (typeKey === 'listResponseMessage') {\n      const responseTitle = result?.title || 'Unknown';\n      const responseDescription = result?.description || 'Unknown';\n      const responseRowId = result?.singleSelectReply?.selectedRowId || 'Unknown';\n\n      const formattedResponseList =\n        '*List Response:*\\n\\n' +\n        '_Title_: ' +\n        responseTitle +\n        '\\n' +\n        '_Description_: ' +\n        responseDescription +\n        '\\n' +\n        '_ID_: ' +\n        responseRowId;\n      return formattedResponseList;\n    }\n\n    return result;\n  }\n\n  public getConversationMessage(msg: any) {\n    const types = this.getTypeMessage(msg);\n\n    const messageContent = this.getMessageContent(types);\n\n    return messageContent;\n  }\n\n  public async eventWhatsapp(event: string, instance: InstanceDto, body: any) {\n    try {\n      const waInstance = this.waMonitor.waInstances[instance.instanceName];\n\n      if (!waInstance) {\n        this.logger.warn('wa instance not found');\n        return null;\n      }\n\n      const client = await this.clientCw(instance);\n\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      if (this.provider?.ignoreJids && this.provider?.ignoreJids.length > 0) {\n        const ignoreJids: any = this.provider?.ignoreJids;\n\n        let ignoreGroups = false;\n        let ignoreContacts = false;\n\n        if (ignoreJids.includes('@g.us')) {\n          ignoreGroups = true;\n        }\n\n        if (ignoreJids.includes('@s.whatsapp.net')) {\n          ignoreContacts = true;\n        }\n\n        if (ignoreGroups && body?.key?.remoteJid.endsWith('@g.us')) {\n          this.logger.warn('Ignoring message from group: ' + body?.key?.remoteJid);\n          return;\n        }\n\n        if (ignoreContacts && body?.key?.remoteJid.endsWith('@s.whatsapp.net')) {\n          this.logger.warn('Ignoring message from contact: ' + body?.key?.remoteJid);\n          return;\n        }\n\n        if (ignoreJids.includes(body?.key?.remoteJid)) {\n          this.logger.warn('Ignoring message from jid: ' + body?.key?.remoteJid);\n          return;\n        }\n      }\n\n      if (event === 'messages.upsert' || event === 'send.message') {\n        this.logger.info(`[${event}] New message received - Instance: ${JSON.stringify(body, null, 2)}`);\n        if (body.key.remoteJid === 'status@broadcast') {\n          return;\n        }\n\n        if (body.message?.ephemeralMessage?.message) {\n          body.message = {\n            ...body.message?.ephemeralMessage?.message,\n          };\n        }\n\n        const originalMessage = await this.getConversationMessage(body.message);\n        const bodyMessage = originalMessage\n          ? originalMessage\n              .replaceAll(/\\*((?!\\s)([^\\n*]+?)(?<!\\s))\\*/g, '**$1**')\n              .replaceAll(/_((?!\\s)([^\\n_]+?)(?<!\\s))_/g, '*$1*')\n              .replaceAll(/~((?!\\s)([^\\n~]+?)(?<!\\s))~/g, '~~$1~~')\n          : originalMessage;\n\n        if (bodyMessage && bodyMessage.includes('/survey/responses/') && bodyMessage.includes('http')) {\n          return;\n        }\n\n        const quotedId = body.contextInfo?.stanzaId || body.message?.contextInfo?.stanzaId;\n\n        let quotedMsg = null;\n\n        if (quotedId)\n          quotedMsg = await this.prismaRepository.message.findFirst({\n            where: {\n              key: {\n                path: ['id'],\n                equals: quotedId,\n              },\n              chatwootMessageId: {\n                not: null,\n              },\n            },\n          });\n\n        const isMedia = this.isMediaMessage(body.message);\n\n        const adsMessage = this.getAdsMessage(body);\n\n        const reactionMessage = this.getReactionMessage(body.message);\n        const isInteractiveButtonMessage = this.isInteractiveButtonMessage(body.messageType, body.message);\n\n        if (!bodyMessage && !isMedia && !reactionMessage && !isInteractiveButtonMessage) {\n          this.logger.warn('no body message found');\n          return;\n        }\n\n        const getConversation = await this.createConversation(instance, body);\n\n        if (!getConversation) {\n          this.logger.warn('conversation not found');\n          return;\n        }\n\n        const messageType = body.key.fromMe ? 'outgoing' : 'incoming';\n\n        if (isMedia) {\n          const downloadBase64 = await waInstance?.getBase64FromMediaMessage({\n            message: {\n              ...body,\n            },\n          });\n\n          let nameFile: string;\n          const messageBody = body?.message[body?.messageType];\n          const originalFilename =\n            messageBody?.fileName || messageBody?.filename || messageBody?.message?.documentMessage?.fileName;\n          if (originalFilename) {\n            const parsedFile = path.parse(originalFilename);\n            if (parsedFile.name && parsedFile.ext) {\n              nameFile = `${parsedFile.name}-${Math.floor(Math.random() * (99 - 10 + 1) + 10)}${parsedFile.ext}`;\n            }\n          }\n\n          if (!nameFile) {\n            nameFile = `${Math.random().toString(36).substring(7)}.${mimeTypes.extension(downloadBase64.mimetype) || ''}`;\n          }\n\n          const fileData = Buffer.from(downloadBase64.base64, 'base64');\n\n          const fileStream = new Readable();\n          fileStream._read = () => {};\n          fileStream.push(fileData);\n          fileStream.push(null);\n\n          if (body.key.remoteJid.includes('@g.us')) {\n            const participantName = body.pushName;\n            const rawPhoneNumber =\n              body.key.addressingMode === 'lid' && !body.key.fromMe && body.key.participantAlt\n                ? body.key.participantAlt.split('@')[0].split(':')[0]\n                : body.key.participant.split('@')[0].split(':')[0];\n            const formattedPhoneNumber = parsePhoneNumberFromString(`+${rawPhoneNumber}`).formatInternational();\n\n            let content: string;\n\n            if (!body.key.fromMe) {\n              content = bodyMessage\n                ? `**${formattedPhoneNumber} - ${participantName}:**\\n\\n${bodyMessage}`\n                : `**${formattedPhoneNumber} - ${participantName}:**`;\n            } else {\n              content = bodyMessage || '';\n            }\n\n            const send = await this.sendData(\n              getConversation,\n              fileStream,\n              nameFile,\n              messageType,\n              content,\n              instance,\n              body,\n              'WAID:' + body.key.id,\n              quotedMsg,\n            );\n\n            if (!send) {\n              this.logger.warn('message not sent');\n              return;\n            }\n\n            return send;\n          } else {\n            const send = await this.sendData(\n              getConversation,\n              fileStream,\n              nameFile,\n              messageType,\n              bodyMessage,\n              instance,\n              body,\n              'WAID:' + body.key.id,\n              quotedMsg,\n            );\n\n            if (!send) {\n              this.logger.warn('message not sent');\n              return;\n            }\n\n            return send;\n          }\n        }\n\n        if (reactionMessage) {\n          if (reactionMessage.text) {\n            const send = await this.createMessage(\n              instance,\n              getConversation,\n              reactionMessage.text,\n              messageType,\n              false,\n              [],\n              {\n                message: { extendedTextMessage: { contextInfo: { stanzaId: reactionMessage.key.id } } },\n              },\n              'WAID:' + body.key.id,\n              quotedMsg,\n            );\n            if (!send) {\n              this.logger.warn('message not sent');\n              return;\n            }\n          }\n\n          return;\n        }\n\n        if (isInteractiveButtonMessage) {\n          const buttons = body.message.interactiveMessage.nativeFlowMessage.buttons;\n          this.logger.info('is Interactive Button Message: ' + JSON.stringify(buttons));\n\n          for (const button of buttons) {\n            const buttonParams = JSON.parse(button.buttonParamsJson);\n            const paymentSettings = buttonParams.payment_settings;\n\n            if (button.name === 'payment_info' && paymentSettings[0].type === 'pix_static_code') {\n              const pixSettings = paymentSettings[0].pix_static_code;\n              const pixKeyType = (() => {\n                switch (pixSettings.key_type) {\n                  case 'EVP':\n                    return 'Chave Aleatória';\n                  case 'EMAIL':\n                    return 'E-mail';\n                  case 'PHONE':\n                    return 'Telefone';\n                  default:\n                    return pixSettings.key_type;\n                }\n              })();\n              const pixKey = pixSettings.key_type === 'PHONE' ? pixSettings.key.replace('+55', '') : pixSettings.key;\n              const content = `*${pixSettings.merchant_name}*\\nChave PIX: ${pixKey} (${pixKeyType})`;\n\n              const send = await this.createMessage(\n                instance,\n                getConversation,\n                content,\n                messageType,\n                false,\n                [],\n                body,\n                'WAID:' + body.key.id,\n                quotedMsg,\n              );\n              if (!send) this.logger.warn('message not sent');\n            } else {\n              this.logger.warn('Interactive Button Message not mapped');\n            }\n          }\n          return;\n        }\n\n        const isAdsMessage = (adsMessage && adsMessage.title) || adsMessage.body || adsMessage.thumbnailUrl;\n        if (isAdsMessage) {\n          const imgBuffer = await axios.get(adsMessage.thumbnailUrl, { responseType: 'arraybuffer' });\n\n          const extension = mimeTypes.extension(imgBuffer.headers['content-type']);\n          const mimeType = extension && mimeTypes.lookup(extension);\n\n          if (!mimeType) {\n            this.logger.warn('mimetype of Ads message not found');\n            return;\n          }\n\n          const random = Math.random().toString(36).substring(7);\n          const nameFile = `${random}.${mimeTypes.extension(mimeType)}`;\n          const fileData = Buffer.from(imgBuffer.data, 'binary');\n\n          const img = await Jimp.read(fileData);\n          await img.cover({\n            w: 320,\n            h: 180,\n          });\n          const processedBuffer = await img.getBuffer(JimpMime.png);\n\n          const fileStream = new Readable();\n          fileStream._read = () => {}; // _read is required but you can noop it\n          fileStream.push(processedBuffer);\n          fileStream.push(null);\n\n          const truncStr = (str: string, len: number) => {\n            if (!str) return '';\n\n            return str.length > len ? str.substring(0, len) + '...' : str;\n          };\n\n          const title = truncStr(adsMessage.title, 40);\n          const description = truncStr(adsMessage?.body, 75);\n\n          const send = await this.sendData(\n            getConversation,\n            fileStream,\n            nameFile,\n            messageType,\n            `${bodyMessage}\\n\\n\\n**${title}**\\n${description}\\n${adsMessage.sourceUrl}`,\n            instance,\n            body,\n            'WAID:' + body.key.id,\n          );\n\n          if (!send) {\n            this.logger.warn('message not sent');\n            return;\n          }\n\n          return send;\n        }\n\n        if (body.key.remoteJid.includes('@g.us')) {\n          const participantName = body.pushName;\n          const rawPhoneNumber =\n            body.key.addressingMode === 'lid' && !body.key.fromMe && body.key.participantAlt\n              ? body.key.participantAlt.split('@')[0].split(':')[0]\n              : body.key.participant.split('@')[0].split(':')[0];\n          const formattedPhoneNumber = parsePhoneNumberFromString(`+${rawPhoneNumber}`).formatInternational();\n\n          let content: string;\n\n          if (!body.key.fromMe) {\n            content = `**${formattedPhoneNumber} - ${participantName}:**\\n\\n${bodyMessage}`;\n          } else {\n            content = `${bodyMessage}`;\n          }\n\n          const send = await this.createMessage(\n            instance,\n            getConversation,\n            content,\n            messageType,\n            false,\n            [],\n            body,\n            'WAID:' + body.key.id,\n            quotedMsg,\n          );\n\n          if (!send) {\n            this.logger.warn('message not sent');\n            return;\n          }\n\n          return send;\n        } else {\n          const send = await this.createMessage(\n            instance,\n            getConversation,\n            bodyMessage,\n            messageType,\n            false,\n            [],\n            body,\n            'WAID:' + body.key.id,\n            quotedMsg,\n          );\n\n          if (!send) {\n            this.logger.warn('message not sent');\n            return;\n          }\n\n          return send;\n        }\n      }\n\n      if (event === Events.MESSAGES_DELETE) {\n        const chatwootDelete = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_DELETE;\n\n        if (chatwootDelete === true) {\n          if (!body?.key?.id) {\n            this.logger.warn('message id not found');\n            return;\n          }\n\n          const message = await this.getMessageByKeyId(instance, body.key.id);\n\n          if (message?.chatwootMessageId && message?.chatwootConversationId) {\n            await this.prismaRepository.message.deleteMany({\n              where: {\n                key: {\n                  path: ['id'],\n                  equals: body.key.id,\n                },\n                instanceId: instance.instanceId,\n              },\n            });\n\n            return await client.messages.delete({\n              accountId: this.provider.accountId,\n              conversationId: message.chatwootConversationId,\n              messageId: message.chatwootMessageId,\n            });\n          }\n        }\n      }\n\n      if (event === 'messages.edit' || event === 'send.message.update') {\n        const editedMessageContentRaw =\n          body?.editedMessage?.conversation ??\n          body?.editedMessage?.extendedTextMessage?.text ??\n          body?.editedMessage?.imageMessage?.caption ??\n          body?.editedMessage?.videoMessage?.caption ??\n          body?.editedMessage?.documentMessage?.caption ??\n          (typeof body?.text === 'string' ? body.text : undefined);\n\n        const editedMessageContent = (editedMessageContentRaw ?? '').trim();\n\n        if (!editedMessageContent) {\n          this.logger.info('[CW.EDIT] Conteúdo vazio — ignorando (DELETE tratará se for revoke).');\n          return;\n        }\n\n        const message = await this.getMessageByKeyId(instance, body?.key?.id);\n\n        if (!message) {\n          this.logger.warn('Message not found for edit event');\n          return;\n        }\n\n        const key = message.key as WAMessageKey;\n\n        const messageType = key?.fromMe ? 'outgoing' : 'incoming';\n\n        if (message && message.chatwootConversationId && message.chatwootMessageId) {\n          // Criar nova mensagem com formato: \"Mensagem editada:\\n\\nteste1\"\n          const editedText = `\\n\\n\\`${i18next.t('cw.message.edited')}:\\`\\n\\n${editedMessageContent}`;\n\n          const send = await this.createMessage(\n            instance,\n            message.chatwootConversationId,\n            editedText,\n            messageType,\n            false,\n            [],\n            {\n              message: { extendedTextMessage: { contextInfo: { stanzaId: key.id } } },\n            },\n            'WAID:' + body.key.id,\n            null,\n          );\n          if (!send) {\n            this.logger.warn('edited message not sent');\n            return;\n          }\n        }\n        return;\n      }\n\n      if (event === 'messages.read') {\n        if (!body?.key?.id || !body?.key?.remoteJid) {\n          this.logger.warn('message id not found');\n          return;\n        }\n\n        const message = await this.getMessageByKeyId(instance, body.key.id);\n        const conversationId = message?.chatwootConversationId;\n        const contactInboxSourceId = message?.chatwootContactInboxSourceId;\n\n        if (conversationId) {\n          let sourceId = contactInboxSourceId;\n          const inbox = (await this.getInbox(instance)) as inbox & {\n            inbox_identifier?: string;\n          };\n\n          if (!sourceId && inbox) {\n            const conversation = (await client.conversations.get({\n              accountId: this.provider.accountId,\n              conversationId: conversationId,\n            })) as conversation_show & {\n              last_non_activity_message: { conversation: { contact_inbox: contact_inboxes } };\n            };\n            sourceId = conversation.last_non_activity_message?.conversation?.contact_inbox?.source_id;\n          }\n\n          if (sourceId && inbox?.inbox_identifier) {\n            const url =\n              `/public/api/v1/inboxes/${inbox.inbox_identifier}/contacts/${sourceId}` +\n              `/conversations/${conversationId}/update_last_seen`;\n            await chatwootRequest(this.getClientCwConfig(), {\n              method: 'POST',\n              url: url,\n            });\n          }\n        }\n        return;\n      }\n\n      if (event === 'status.instance') {\n        const data = body;\n        const inbox = await this.getInbox(instance);\n\n        if (!inbox) {\n          this.logger.warn('inbox not found');\n          return;\n        }\n\n        const msgStatus = i18next.t('cw.inbox.status', {\n          inboxName: inbox.name,\n          state: data.status,\n        });\n\n        await this.createBotMessage(instance, msgStatus, 'incoming');\n      }\n\n      if (event === 'connection.update' && body.status === 'open') {\n        const waInstance = this.waMonitor.waInstances[instance.instanceName];\n        if (!waInstance) return;\n\n        const now = Date.now();\n        const timeSinceLastNotification = now - (waInstance.lastConnectionNotification || 0);\n\n        // Se a conexão foi estabelecida via QR code, notifica imediatamente.\n        if (waInstance.qrCode && waInstance.qrCode.count > 0) {\n          const msgConnection = i18next.t('cw.inbox.connected');\n          await this.createBotMessage(instance, msgConnection, 'incoming');\n          waInstance.qrCode.count = 0;\n          waInstance.lastConnectionNotification = now;\n          chatwootImport.clearAll(instance);\n        }\n        // Se não foi via QR code, verifica o throttling.\n        else if (timeSinceLastNotification >= 30000) {\n          const msgConnection = i18next.t('cw.inbox.connected');\n          await this.createBotMessage(instance, msgConnection, 'incoming');\n          waInstance.lastConnectionNotification = now;\n        } else {\n          this.logger.warn(\n            `Connection notification skipped for ${instance.instanceName} - too frequent (${timeSinceLastNotification}ms since last)`,\n          );\n        }\n      }\n\n      if (event === 'qrcode.updated') {\n        if (body.statusCode === 500) {\n          const erroQRcode = `🚨 ${i18next.t('qrlimitreached')}`;\n          return await this.createBotMessage(instance, erroQRcode, 'incoming');\n        } else {\n          const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64');\n\n          const fileStream = new Readable();\n          fileStream._read = () => {};\n          fileStream.push(fileData);\n          fileStream.push(null);\n\n          await this.createBotQr(\n            instance,\n            i18next.t('qrgeneratedsuccesfully'),\n            'incoming',\n            fileStream,\n            `${instance.instanceName}.png`,\n          );\n\n          let msgQrCode = `⚡️${i18next.t('qrgeneratedsuccesfully')}\\n\\n${i18next.t('scanqr')}`;\n\n          if (body?.qrcode?.pairingCode) {\n            msgQrCode =\n              msgQrCode +\n              `\\n\\n*Pairing Code:* ${body.qrcode.pairingCode.substring(0, 4)}-${body.qrcode.pairingCode.substring(\n                4,\n                8,\n              )}`;\n          }\n\n          await this.createBotMessage(instance, msgQrCode, 'incoming');\n        }\n      }\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public normalizeJidIdentifier(remoteJid: string) {\n    if (!remoteJid) {\n      return '';\n    }\n    if (remoteJid.includes('@lid')) {\n      return remoteJid;\n    }\n    return remoteJid.replace(/:\\d+/, '').split('@')[0];\n  }\n\n  public startImportHistoryMessages(instance: InstanceDto) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    this.createBotMessage(instance, i18next.t('cw.import.startImport'), 'incoming');\n  }\n\n  public isImportHistoryAvailable() {\n    const uri = this.configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;\n\n    return uri && uri !== 'postgres://user:password@hostname:port/dbname';\n  }\n\n  public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageModel[]) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    chatwootImport.addHistoryMessages(instance, messagesRaw);\n  }\n\n  public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactModel[]) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    return chatwootImport.addHistoryContacts(instance, contactsRaw);\n  }\n\n  public async importHistoryMessages(instance: InstanceDto) {\n    if (!this.isImportHistoryAvailable()) {\n      return;\n    }\n\n    this.createBotMessage(instance, i18next.t('cw.import.importingMessages'), 'incoming');\n\n    const totalMessagesImported = await chatwootImport.importHistoryMessages(\n      instance,\n      this,\n      await this.getInbox(instance),\n      this.provider,\n    );\n    this.updateContactAvatarInRecentConversations(instance);\n\n    const msg = Number.isInteger(totalMessagesImported)\n      ? i18next.t('cw.import.messagesImported', { totalMessagesImported })\n      : i18next.t('cw.import.messagesException');\n\n    this.createBotMessage(instance, msg, 'incoming');\n\n    return totalMessagesImported;\n  }\n\n  public async updateContactAvatarInRecentConversations(instance: InstanceDto, limitContacts = 100) {\n    try {\n      if (!this.isImportHistoryAvailable()) {\n        return;\n      }\n\n      const client = await this.clientCw(instance);\n      if (!client) {\n        this.logger.warn('client not found');\n        return null;\n      }\n\n      const inbox = await this.getInbox(instance);\n      if (!inbox) {\n        this.logger.warn('inbox not found');\n        return null;\n      }\n\n      const recentContacts = await chatwootImport.getContactsOrderByRecentConversations(\n        inbox,\n        this.provider,\n        limitContacts,\n      );\n\n      const contactIdentifiers = recentContacts\n        .map((contact) => contact.identifier)\n        .filter((identifier) => identifier !== null);\n\n      const contactsWithProfilePicture = (\n        await this.prismaRepository.contact.findMany({\n          where: {\n            instanceId: instance.instanceId,\n            id: {\n              in: contactIdentifiers,\n            },\n            profilePicUrl: {\n              not: null,\n            },\n          },\n        })\n      ).reduce((acc: Map<string, ContactModel>, contact: ContactModel) => acc.set(contact.id, contact), new Map());\n\n      recentContacts.forEach(async (contact) => {\n        if (contactsWithProfilePicture.has(contact.identifier)) {\n          client.contacts.update({\n            accountId: this.provider.accountId,\n            id: contact.id,\n            data: {\n              avatar_url: contactsWithProfilePicture.get(contact.identifier).profilePictureUrl || null,\n            },\n          });\n        }\n      });\n    } catch (error) {\n      this.logger.error(`Error on update avatar in recent conversations: ${error.toString()}`);\n    }\n  }\n\n  public async syncLostMessages(\n    instance: InstanceDto,\n    chatwootConfig: ChatwootDto,\n    prepareMessage: (message: any) => any,\n  ) {\n    try {\n      if (!this.isImportHistoryAvailable()) {\n        return;\n      }\n      if (!this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE) {\n        return;\n      }\n\n      const inbox = await this.getInbox(instance);\n\n      const sqlMessages = `select * from messages m\n      where account_id = ${chatwootConfig.accountId}\n      and inbox_id = ${inbox.id}\n      and created_at >= now() - interval '6h'\n      order by created_at desc`;\n\n      const messagesData = (await this.pgClient.query(sqlMessages))?.rows;\n      const ids: string[] = messagesData\n        .filter((message) => !!message.source_id)\n        .map((message) => message.source_id.replace('WAID:', ''));\n\n      const savedMessages = await this.prismaRepository.message.findMany({\n        where: {\n          Instance: { name: instance.instanceName },\n          messageTimestamp: { gte: Number(dayjs().subtract(6, 'hours').unix()) },\n          AND: ids.map((id) => ({ key: { path: ['id'], not: id } })),\n        },\n      });\n\n      const filteredMessages = savedMessages.filter(\n        (msg: any) => !chatwootImport.isIgnorePhoneNumber(msg.key?.remoteJid),\n      );\n      const messagesRaw: any[] = [];\n      for (const m of filteredMessages) {\n        if (!m.message || !m.key || !m.messageTimestamp) {\n          continue;\n        }\n\n        if (Long.isLong(m?.messageTimestamp)) {\n          m.messageTimestamp = m.messageTimestamp?.toNumber();\n        }\n\n        messagesRaw.push(prepareMessage(m as any));\n      }\n\n      this.addHistoryMessages(\n        instance,\n        messagesRaw.filter((msg) => !chatwootImport.isIgnorePhoneNumber(msg.key?.remoteJid)),\n      );\n\n      await chatwootImport.importHistoryMessages(instance, this, inbox, this.provider);\n      const waInstance = this.waMonitor.waInstances[instance.instanceName];\n      waInstance.clearCacheChatwoot();\n    } catch {\n      return;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { postgresClient } from '@api/integrations/chatbot/chatwoot/libs/postgres.client';\nimport { ChatwootService } from '@api/integrations/chatbot/chatwoot/services/chatwoot.service';\nimport { Chatwoot, configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { inbox } from '@figuro/chatwoot-sdk';\nimport { Chatwoot as ChatwootModel, Contact, Message } from '@prisma/client';\nimport { proto } from 'baileys';\n\ntype ChatwootUser = {\n  user_type: string;\n  user_id: number;\n};\n\ntype FksChatwoot = {\n  phone_number: string;\n  contact_id: string;\n  conversation_id: string;\n};\n\ntype firstLastTimestamp = {\n  first: number;\n  last: number;\n};\n\ntype IWebMessageInfo = Omit<proto.IWebMessageInfo, 'key'> & Partial<Pick<proto.IWebMessageInfo, 'key'>>;\n\nclass ChatwootImport {\n  private logger = new Logger('ChatwootImport');\n  private repositoryMessagesCache = new Map<string, Set<string>>();\n  private historyMessages = new Map<string, Message[]>();\n  private historyContacts = new Map<string, Contact[]>();\n\n  public getRepositoryMessagesCache(instance: InstanceDto) {\n    return this.repositoryMessagesCache.has(instance.instanceName)\n      ? this.repositoryMessagesCache.get(instance.instanceName)\n      : null;\n  }\n\n  public setRepositoryMessagesCache(instance: InstanceDto, repositoryMessagesCache: Set<string>) {\n    this.repositoryMessagesCache.set(instance.instanceName, repositoryMessagesCache);\n  }\n\n  public deleteRepositoryMessagesCache(instance: InstanceDto) {\n    this.repositoryMessagesCache.delete(instance.instanceName);\n  }\n\n  public addHistoryMessages(instance: InstanceDto, messagesRaw: Message[]) {\n    const actualValue = this.historyMessages.has(instance.instanceName)\n      ? this.historyMessages.get(instance.instanceName)\n      : [];\n    this.historyMessages.set(instance.instanceName, [...actualValue, ...messagesRaw]);\n  }\n\n  public addHistoryContacts(instance: InstanceDto, contactsRaw: Contact[]) {\n    const actualValue = this.historyContacts.has(instance.instanceName)\n      ? this.historyContacts.get(instance.instanceName)\n      : [];\n    this.historyContacts.set(instance.instanceName, actualValue.concat(contactsRaw));\n  }\n\n  public deleteHistoryMessages(instance: InstanceDto) {\n    this.historyMessages.delete(instance.instanceName);\n  }\n\n  public deleteHistoryContacts(instance: InstanceDto) {\n    this.historyContacts.delete(instance.instanceName);\n  }\n\n  public clearAll(instance: InstanceDto) {\n    this.deleteRepositoryMessagesCache(instance);\n    this.deleteHistoryMessages(instance);\n    this.deleteHistoryContacts(instance);\n  }\n\n  public getHistoryMessagesLenght(instance: InstanceDto) {\n    return this.historyMessages.get(instance.instanceName)?.length ?? 0;\n  }\n\n  public async importHistoryContacts(instance: InstanceDto, provider: ChatwootDto) {\n    try {\n      if (this.getHistoryMessagesLenght(instance) > 0) {\n        return;\n      }\n\n      const pgClient = postgresClient.getChatwootConnection();\n\n      let totalContactsImported = 0;\n\n      const contacts = this.historyContacts.get(instance.instanceName) || [];\n      if (contacts.length === 0) {\n        return 0;\n      }\n\n      let contactsChunk: Contact[] = this.sliceIntoChunks(contacts, 3000);\n      while (contactsChunk.length > 0) {\n        const labelSql = `SELECT id FROM labels WHERE title = '${provider.nameInbox}' AND account_id = ${provider.accountId} LIMIT 1`;\n\n        let labelId = (await pgClient.query(labelSql))?.rows[0]?.id;\n\n        if (!labelId) {\n          // creating label in chatwoot db and getting the id\n          const sqlLabel = `INSERT INTO labels (title, color, show_on_sidebar, account_id, created_at, updated_at) VALUES ('${provider.nameInbox}', '#34039B', true, ${provider.accountId}, NOW(), NOW()) RETURNING id`;\n\n          labelId = (await pgClient.query(sqlLabel))?.rows[0]?.id;\n        }\n\n        // inserting contacts in chatwoot db\n        let sqlInsert = `INSERT INTO contacts\n          (name, phone_number, account_id, identifier, created_at, updated_at) VALUES `;\n        const bindInsert = [provider.accountId];\n\n        for (const contact of contactsChunk) {\n          const isGroup = this.isIgnorePhoneNumber(contact.remoteJid);\n\n          const contactName = isGroup ? `${contact.pushName} (GROUP)` : contact.pushName;\n          bindInsert.push(contactName);\n          const bindName = `$${bindInsert.length}`;\n\n          let bindPhoneNumber: string;\n          if (!isGroup) {\n            bindInsert.push(`+${contact.remoteJid.split('@')[0]}`);\n            bindPhoneNumber = `$${bindInsert.length}`;\n          } else {\n            bindPhoneNumber = 'NULL';\n          }\n          bindInsert.push(contact.remoteJid);\n          const bindIdentifier = `$${bindInsert.length}`;\n\n          sqlInsert += `(${bindName}, ${bindPhoneNumber}, $1, ${bindIdentifier}, NOW(), NOW()),`;\n        }\n        if (sqlInsert.slice(-1) === ',') {\n          sqlInsert = sqlInsert.slice(0, -1);\n        }\n        sqlInsert += ` ON CONFLICT (identifier, account_id)\n                       DO UPDATE SET\n                        name = EXCLUDED.name,\n                        phone_number = EXCLUDED.phone_number,\n                        updated_at = NOW()`;\n\n        totalContactsImported += (await pgClient.query(sqlInsert, bindInsert))?.rowCount ?? 0;\n\n        const sqlTags = `SELECT id FROM tags WHERE name = '${provider.nameInbox}' LIMIT 1`;\n\n        const tagData = (await pgClient.query(sqlTags))?.rows[0];\n        let tagId = tagData?.id;\n\n        const sqlTag = `INSERT INTO tags (name, taggings_count) VALUES ('${provider.nameInbox}', ${totalContactsImported}) ON CONFLICT (name) DO UPDATE SET taggings_count = tags.taggings_count + ${totalContactsImported} RETURNING id`;\n\n        tagId = (await pgClient.query(sqlTag))?.rows[0]?.id;\n\n        await pgClient.query(sqlTag);\n\n        let sqlInsertLabel = `INSERT INTO taggings (tag_id, taggable_type, taggable_id, context, created_at) VALUES `;\n\n        contactsChunk.forEach((contact) => {\n          const bindTaggableId = `(SELECT id FROM contacts WHERE identifier = '${contact.remoteJid}' AND account_id = ${provider.accountId})`;\n          sqlInsertLabel += `($1, $2, ${bindTaggableId}, $3, NOW()),`;\n        });\n\n        if (sqlInsertLabel.slice(-1) === ',') {\n          sqlInsertLabel = sqlInsertLabel.slice(0, -1);\n        }\n\n        await pgClient.query(sqlInsertLabel, [tagId, 'Contact', 'labels']);\n\n        contactsChunk = this.sliceIntoChunks(contacts, 3000);\n      }\n\n      this.deleteHistoryContacts(instance);\n\n      return totalContactsImported;\n    } catch (error) {\n      this.logger.error(`Error on import history contacts: ${error.toString()}`);\n    }\n  }\n\n  public async getExistingSourceIds(sourceIds: string[], conversationId?: number): Promise<Set<string>> {\n    try {\n      const existingSourceIdsSet = new Set<string>();\n\n      if (sourceIds.length === 0) {\n        return existingSourceIdsSet;\n      }\n\n      // Ensure all sourceIds are consistently prefixed with 'WAID:' as required by downstream systems and database queries.\n      const formattedSourceIds = sourceIds.map((sourceId) => `WAID:${sourceId.replace('WAID:', '')}`);\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const params = conversationId ? [formattedSourceIds, conversationId] : [formattedSourceIds];\n\n      const query = conversationId\n        ? 'SELECT source_id FROM messages WHERE source_id = ANY($1) AND conversation_id = $2'\n        : 'SELECT source_id FROM messages WHERE source_id = ANY($1)';\n\n      const result = await pgClient.query(query, params);\n      for (const row of result.rows) {\n        existingSourceIdsSet.add(row.source_id);\n      }\n\n      return existingSourceIdsSet;\n    } catch (error) {\n      this.logger.error(`Error on getExistingSourceIds: ${error.toString()}`);\n      return new Set<string>();\n    }\n  }\n\n  public async importHistoryMessages(\n    instance: InstanceDto,\n    chatwootService: ChatwootService,\n    inbox: inbox,\n    provider: ChatwootModel,\n  ) {\n    try {\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const chatwootUser = await this.getChatwootUser(provider);\n      if (!chatwootUser) {\n        throw new Error('User not found to import messages.');\n      }\n\n      let totalMessagesImported = 0;\n\n      let messagesOrdered = this.historyMessages.get(instance.instanceName) || [];\n      if (messagesOrdered.length === 0) {\n        return 0;\n      }\n\n      // ordering messages by number and timestamp asc\n      messagesOrdered.sort((a, b) => {\n        const aKey = a.key as {\n          remoteJid: string;\n        };\n\n        const bKey = b.key as {\n          remoteJid: string;\n        };\n\n        const aMessageTimestamp = a.messageTimestamp as any as number;\n        const bMessageTimestamp = b.messageTimestamp as any as number;\n\n        return parseInt(aKey.remoteJid) - parseInt(bKey.remoteJid) || aMessageTimestamp - bMessageTimestamp;\n      });\n\n      const allMessagesMappedByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesOrdered);\n      // Map structure: +552199999999 => { first message timestamp from number, last message timestamp from number}\n      const phoneNumbersWithTimestamp = new Map<string, firstLastTimestamp>();\n      allMessagesMappedByPhoneNumber.forEach((messages: Message[], phoneNumber: string) => {\n        phoneNumbersWithTimestamp.set(phoneNumber, {\n          first: messages[0]?.messageTimestamp as any as number,\n          last: messages[messages.length - 1]?.messageTimestamp as any as number,\n        });\n      });\n\n      const existingSourceIds = await this.getExistingSourceIds(messagesOrdered.map((message: any) => message.key.id));\n      messagesOrdered = messagesOrdered.filter((message: any) => !existingSourceIds.has(message.key.id));\n      // processing messages in batch\n      const batchSize = 4000;\n      let messagesChunk: Message[] = this.sliceIntoChunks(messagesOrdered, batchSize);\n      while (messagesChunk.length > 0) {\n        // Map structure: +552199999999 => Message[]\n        const messagesByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesChunk);\n\n        if (messagesByPhoneNumber.size > 0) {\n          const fksByNumber = await this.selectOrCreateFksFromChatwoot(\n            provider,\n            inbox,\n            phoneNumbersWithTimestamp,\n            messagesByPhoneNumber,\n          );\n\n          // inserting messages in chatwoot db\n          let sqlInsertMsg = `INSERT INTO messages\n            (content, processed_message_content, account_id, inbox_id, conversation_id, message_type, private, content_type,\n            sender_type, sender_id, source_id, created_at, updated_at) VALUES `;\n          const bindInsertMsg = [provider.accountId, inbox.id];\n\n          messagesByPhoneNumber.forEach((messages: any[], phoneNumber: string) => {\n            const fksChatwoot = fksByNumber.get(phoneNumber);\n\n            messages.forEach((message) => {\n              if (!message.message) {\n                return;\n              }\n\n              if (!fksChatwoot?.conversation_id || !fksChatwoot?.contact_id) {\n                return;\n              }\n\n              const contentMessage = this.getContentMessage(chatwootService, message);\n              if (!contentMessage) {\n                return;\n              }\n\n              bindInsertMsg.push(contentMessage);\n              const bindContent = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(fksChatwoot.conversation_id);\n              const bindConversationId = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.key.fromMe ? '1' : '0');\n              const bindMessageType = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.key.fromMe ? chatwootUser.user_type : 'Contact');\n              const bindSenderType = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.key.fromMe ? chatwootUser.user_id : fksChatwoot.contact_id);\n              const bindSenderId = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push('WAID:' + message.key.id);\n              const bindSourceId = `$${bindInsertMsg.length}`;\n\n              bindInsertMsg.push(message.messageTimestamp as number);\n              const bindmessageTimestamp = `$${bindInsertMsg.length}`;\n\n              sqlInsertMsg += `(${bindContent}, ${bindContent}, $1, $2, ${bindConversationId}, ${bindMessageType}, FALSE, 0,\n                  ${bindSenderType},${bindSenderId},${bindSourceId}, to_timestamp(${bindmessageTimestamp}), to_timestamp(${bindmessageTimestamp})),`;\n            });\n          });\n          if (bindInsertMsg.length > 2) {\n            if (sqlInsertMsg.slice(-1) === ',') {\n              sqlInsertMsg = sqlInsertMsg.slice(0, -1);\n            }\n            totalMessagesImported += (await pgClient.query(sqlInsertMsg, bindInsertMsg))?.rowCount ?? 0;\n          }\n        }\n        messagesChunk = this.sliceIntoChunks(messagesOrdered, batchSize);\n      }\n\n      this.deleteHistoryMessages(instance);\n      this.deleteRepositoryMessagesCache(instance);\n\n      const providerData: ChatwootDto = {\n        ...provider,\n        ignoreJids: Array.isArray(provider.ignoreJids) ? provider.ignoreJids.map((event) => String(event)) : [],\n      };\n\n      this.importHistoryContacts(instance, providerData);\n\n      return totalMessagesImported;\n    } catch (error) {\n      this.logger.error(`Error on import history messages: ${error.toString()}`);\n\n      this.deleteHistoryMessages(instance);\n      this.deleteRepositoryMessagesCache(instance);\n    }\n  }\n\n  public async selectOrCreateFksFromChatwoot(\n    provider: ChatwootModel,\n    inbox: inbox,\n    phoneNumbersWithTimestamp: Map<string, firstLastTimestamp>,\n    messagesByPhoneNumber: Map<string, Message[]>,\n  ): Promise<Map<string, FksChatwoot>> {\n    const pgClient = postgresClient.getChatwootConnection();\n\n    const bindValues = [provider.accountId, inbox.id];\n    const phoneNumberBind = Array.from(messagesByPhoneNumber.keys())\n      .map((phoneNumber) => {\n        const phoneNumberTimestamp = phoneNumbersWithTimestamp.get(phoneNumber);\n\n        if (phoneNumberTimestamp) {\n          bindValues.push(phoneNumber);\n          let bindStr = `($${bindValues.length},`;\n\n          bindValues.push(phoneNumberTimestamp.first);\n          bindStr += `$${bindValues.length},`;\n\n          bindValues.push(phoneNumberTimestamp.last);\n          return `${bindStr}$${bindValues.length})`;\n        }\n      })\n      .join(',');\n\n    // select (or insert when necessary) data from tables contacts, contact_inboxes, conversations from chatwoot db\n    const sqlFromChatwoot = `WITH\n              phone_number AS (\n                SELECT phone_number, created_at::INTEGER, last_activity_at::INTEGER FROM (\n                  VALUES \n                   ${phoneNumberBind}\n                 ) as t (phone_number, created_at, last_activity_at)\n              ),\n\n              only_new_phone_number AS (\n                SELECT * FROM phone_number\n                WHERE phone_number NOT IN (\n                  SELECT phone_number\n                  FROM contacts\n                    JOIN contact_inboxes ci ON ci.contact_id = contacts.id AND ci.inbox_id = $2\n                    JOIN conversations con ON con.contact_inbox_id = ci.id \n                      AND con.account_id = $1\n                      AND con.inbox_id = $2\n                      AND con.contact_id = contacts.id\n                  WHERE contacts.account_id = $1\n                )\n              ),\n\n              new_contact AS (\n                INSERT INTO contacts (name, phone_number, account_id, identifier, created_at, updated_at)\n                SELECT REPLACE(p.phone_number, '+', ''), p.phone_number, $1, CONCAT(REPLACE(p.phone_number, '+', ''),\n                  '@s.whatsapp.net'), to_timestamp(p.created_at), to_timestamp(p.last_activity_at)\n                FROM only_new_phone_number AS p\n                ON CONFLICT(identifier, account_id) DO UPDATE SET updated_at = EXCLUDED.updated_at\n                RETURNING id, phone_number, created_at, updated_at\n              ),\n\n              new_contact_inbox AS (\n                INSERT INTO contact_inboxes (contact_id, inbox_id, source_id, created_at, updated_at)\n                SELECT new_contact.id, $2, gen_random_uuid(), new_contact.created_at, new_contact.updated_at\n                FROM new_contact \n                RETURNING id, contact_id, created_at, updated_at\n              ),\n\n              new_conversation AS (\n                INSERT INTO conversations (account_id, inbox_id, status, contact_id,\n                  contact_inbox_id, uuid, last_activity_at, created_at, updated_at)\n                SELECT $1, $2, 0, new_contact_inbox.contact_id, new_contact_inbox.id, gen_random_uuid(),\n                  new_contact_inbox.updated_at, new_contact_inbox.created_at, new_contact_inbox.updated_at\n                FROM new_contact_inbox\n                RETURNING id, contact_id\n              )\n\n              SELECT new_contact.phone_number, new_conversation.contact_id, new_conversation.id AS conversation_id\n              FROM new_conversation \n              JOIN new_contact ON new_conversation.contact_id = new_contact.id\n\n              UNION\n\n              SELECT p.phone_number, c.id contact_id, con.id conversation_id\n                FROM phone_number p\n              JOIN contacts c ON c.phone_number = p.phone_number\n              JOIN contact_inboxes ci ON ci.contact_id = c.id AND ci.inbox_id = $2\n              JOIN conversations con ON con.contact_inbox_id = ci.id AND con.account_id = $1\n                AND con.inbox_id = $2 AND con.contact_id = c.id`;\n\n    const fksFromChatwoot = await pgClient.query(sqlFromChatwoot, bindValues);\n\n    return new Map(fksFromChatwoot.rows.map((item: FksChatwoot) => [item.phone_number, item]));\n  }\n\n  public async getChatwootUser(provider: ChatwootModel): Promise<ChatwootUser> {\n    try {\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const sqlUser = `SELECT owner_type AS user_type, owner_id AS user_id\n                         FROM access_tokens\n                       WHERE token = $1`;\n\n      return (await pgClient.query(sqlUser, [provider.token]))?.rows[0] || false;\n    } catch (error) {\n      this.logger.error(`Error on getChatwootUser: ${error.toString()}`);\n    }\n  }\n\n  public createMessagesMapByPhoneNumber(messages: Message[]): Map<string, Message[]> {\n    return messages.reduce((acc: Map<string, Message[]>, message: Message) => {\n      const key = message?.key as {\n        remoteJid: string;\n      };\n      if (!this.isIgnorePhoneNumber(key?.remoteJid)) {\n        const phoneNumber = key?.remoteJid?.split('@')[0];\n        if (phoneNumber) {\n          const phoneNumberPlus = `+${phoneNumber}`;\n          const messages = acc.has(phoneNumberPlus) ? acc.get(phoneNumberPlus) : [];\n          messages.push(message);\n          acc.set(phoneNumberPlus, messages);\n        }\n      }\n\n      return acc;\n    }, new Map());\n  }\n\n  public async getContactsOrderByRecentConversations(\n    inbox: inbox,\n    provider: ChatwootModel,\n    limit = 50,\n  ): Promise<{ id: number; phone_number: string; identifier: string }[]> {\n    try {\n      const pgClient = postgresClient.getChatwootConnection();\n\n      const sql = `SELECT contacts.id, contacts.identifier, contacts.phone_number\n                     FROM conversations\n                   JOIN contacts ON contacts.id = conversations.contact_id\n                   WHERE conversations.account_id = $1\n                     AND inbox_id = $2\n                   ORDER BY conversations.last_activity_at DESC\n                   LIMIT $3`;\n\n      return (await pgClient.query(sql, [provider.accountId, inbox.id, limit]))?.rows;\n    } catch (error) {\n      this.logger.error(`Error on get recent conversations: ${error.toString()}`);\n    }\n  }\n\n  public getContentMessage(chatwootService: ChatwootService, msg: IWebMessageInfo) {\n    const contentMessage = chatwootService.getConversationMessage(msg.message);\n    if (contentMessage) {\n      return contentMessage;\n    }\n\n    if (!configService.get<Chatwoot>('CHATWOOT').IMPORT.PLACEHOLDER_MEDIA_MESSAGE) {\n      return '';\n    }\n\n    const types = {\n      documentMessage: msg.message.documentMessage,\n      documentWithCaptionMessage: msg.message.documentWithCaptionMessage?.message?.documentMessage,\n      imageMessage: msg.message.imageMessage,\n      videoMessage: msg.message.videoMessage,\n      audioMessage: msg.message.audioMessage,\n      stickerMessage: msg.message.stickerMessage,\n      templateMessage: msg.message.templateMessage?.hydratedTemplate?.hydratedContentText,\n    };\n\n    const typeKey = Object.keys(types).find((key) => types[key] !== undefined && types[key] !== null);\n    switch (typeKey) {\n      case 'documentMessage': {\n        const doc = msg.message.documentMessage;\n        const fileName = doc?.fileName || 'document';\n        const caption = doc?.caption ? ` ${doc.caption}` : '';\n        return `_<File: ${fileName}${caption}>_`;\n      }\n\n      case 'documentWithCaptionMessage': {\n        const doc = msg.message.documentWithCaptionMessage?.message?.documentMessage;\n        const fileName = doc?.fileName || 'document';\n        const caption = doc?.caption ? ` ${doc.caption}` : '';\n        return `_<File: ${fileName}${caption}>_`;\n      }\n\n      case 'templateMessage': {\n        const template = msg.message.templateMessage?.hydratedTemplate;\n        return (\n          (template?.hydratedTitleText ? `*${template.hydratedTitleText}*\\n` : '') +\n          (template?.hydratedContentText || '')\n        );\n      }\n\n      case 'imageMessage':\n        return '_<Image Message>_';\n\n      case 'videoMessage':\n        return '_<Video Message>_';\n\n      case 'audioMessage':\n        return '_<Audio Message>_';\n\n      case 'stickerMessage':\n        return '_<Sticker Message>_';\n\n      default:\n        return '';\n    }\n  }\n\n  public sliceIntoChunks(arr: any[], chunkSize: number) {\n    return arr.splice(0, chunkSize);\n  }\n\n  public isGroup(remoteJid: string) {\n    return remoteJid.includes('@g.us');\n  }\n\n  public isIgnorePhoneNumber(remoteJid: string) {\n    return this.isGroup(remoteJid) || remoteJid === 'status@broadcast' || remoteJid === '0@s.whatsapp.net';\n  }\n\n  public updateMessageSourceID(messageId: string | number, sourceId: string) {\n    const pgClient = postgresClient.getChatwootConnection();\n\n    const sql = `UPDATE messages SET source_id = $1, status = 0, created_at = NOW(), updated_at = NOW() WHERE id = $2;`;\n\n    return pgClient.query(sql, [`WAID:${sourceId}`, messageId]);\n  }\n}\n\nexport const chatwootImport = new ChatwootImport();\n"
  },
  {
    "path": "src/api/integrations/chatbot/chatwoot/validate/chatwoot.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const chatwootSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean', enum: [true, false] },\n    accountId: { type: 'string' },\n    token: { type: 'string' },\n    url: { type: 'string' },\n    signMsg: { type: 'boolean', enum: [true, false] },\n    signDelimiter: { type: ['string', 'null'] },\n    nameInbox: { type: ['string', 'null'] },\n    reopenConversation: { type: 'boolean', enum: [true, false] },\n    conversationPending: { type: 'boolean', enum: [true, false] },\n    autoCreate: { type: 'boolean', enum: [true, false] },\n    importContacts: { type: 'boolean', enum: [true, false] },\n    mergeBrazilContacts: { type: 'boolean', enum: [true, false] },\n    importMessages: { type: 'boolean', enum: [true, false] },\n    daysLimitImportMessages: { type: 'number' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n  },\n  required: ['enabled', 'accountId', 'token', 'url', 'signMsg', 'reopenConversation', 'conversationPending'],\n  ...isNotEmpty('enabled', 'accountId', 'token', 'url', 'signMsg', 'reopenConversation', 'conversationPending'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/dify/controllers/dify.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { DifyDto } from '@api/integrations/chatbot/dify/dto/dify.dto';\nimport { DifyService } from '@api/integrations/chatbot/dify/services/dify.service';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Dify } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { Dify as DifyModel, IntegrationSession } from '@prisma/client';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\n\nexport class DifyController extends BaseChatbotController<DifyModel, DifyDto> {\n  constructor(\n    private readonly difyService: DifyService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.dify;\n    this.settingsRepository = this.prismaRepository.difySetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  public readonly logger = new Logger('DifyController');\n  protected readonly integrationName = 'Dify';\n\n  integrationEnabled = configService.get<Dify>('DIFY').ENABLED;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.fallbackId;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'difyIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'dify';\n  }\n\n  protected getAdditionalBotData(data: DifyDto): Record<string, any> {\n    return {\n      botType: data.botType,\n      apiUrl: data.apiUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  // Implementation for bot-specific updates\n  protected getAdditionalUpdateFields(data: DifyDto): Record<string, any> {\n    return {\n      botType: data.botType,\n      apiUrl: data.apiUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  // Implementation for bot-specific duplicate validation on update\n  protected async validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: DifyDto): Promise<void> {\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        id: {\n          not: botId,\n        },\n        instanceId: instanceId,\n        botType: data.botType,\n        apiUrl: data.apiUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Dify already exists');\n    }\n  }\n\n  // Override createBot to add Dify-specific validation\n  public async createBot(instance: InstanceDto, data: DifyDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    // Dify-specific duplicate check\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        instanceId: instanceId,\n        botType: data.botType,\n        apiUrl: data.apiUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Dify already exists');\n    }\n\n    // Let the base class handle the rest\n    return super.createBot(instance, data);\n  }\n\n  // Process Dify-specific bot logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: DifyModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    await this.difyService.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/dify/dto/dify.dto.ts",
    "content": "import { $Enums } from '@prisma/client';\n\nimport { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class DifyDto extends BaseChatbotDto {\n  botType?: $Enums.DifyBotType;\n  apiUrl?: string;\n  apiKey?: string;\n}\n\nexport class DifySettingDto extends BaseChatbotSettingDto {\n  difyIdFallback?: string;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/dify/routes/dify.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { DifyDto, DifySettingDto } from '@api/integrations/chatbot/dify/dto/dify.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { difyController } from '@api/server.module';\nimport {\n  difyIgnoreJidSchema,\n  difySchema,\n  difySettingSchema,\n  difyStatusSchema,\n  instanceSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class DifyRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<DifyDto>({\n          request: req,\n          schema: difySchema,\n          ClassRef: DifyDto,\n          execute: (instance, data) => difyController.createBot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => difyController.findBot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:difyId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => difyController.fetchBot(instance, req.params.difyId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:difyId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<DifyDto>({\n          request: req,\n          schema: difySchema,\n          ClassRef: DifyDto,\n          execute: (instance, data) => difyController.updateBot(instance, req.params.difyId, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:difyId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => difyController.deleteBot(instance, req.params.difyId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<DifySettingDto>({\n          request: req,\n          schema: difySettingSchema,\n          ClassRef: DifySettingDto,\n          execute: (instance, data) => difyController.settings(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => difyController.fetchSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: difyStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => difyController.changeStatus(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:difyId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => difyController.fetchSessions(instance, req.params.difyId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: difyIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => difyController.ignoreJid(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/dify/services/dify.service.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService, HttpServer } from '@config/env.config';\nimport { Dify, DifySetting, IntegrationSession } from '@prisma/client';\nimport axios from 'axios';\nimport { isURL } from 'class-validator';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\nimport { OpenaiService } from '../../openai/services/openai.service';\n\nexport class DifyService extends BaseChatbotService<Dify, DifySetting> {\n  private openaiService: OpenaiService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'DifyService', configService);\n    this.openaiService = openaiService;\n  }\n\n  /**\n   * Return the bot type for Dify\n   */\n  protected getBotType(): string {\n    return 'dify';\n  }\n\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: DifySetting,\n    dify: Dify,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      let endpoint: string = dify.apiUrl;\n\n      if (!endpoint) {\n        this.logger.error('No Dify endpoint defined');\n        return;\n      }\n\n      // Handle audio messages - transcribe using OpenAI Whisper\n      let processedContent = content;\n      if (this.isAudioMessage(content) && msg) {\n        try {\n          this.logger.debug(`[Dify] Downloading audio for Whisper transcription`);\n          const transcription = await this.openaiService.speechToText(msg, instance);\n          if (transcription) {\n            processedContent = `[audio] ${transcription}`;\n          }\n        } catch (err) {\n          this.logger.error(`[Dify] Failed to transcribe audio: ${err}`);\n        }\n      }\n\n      if (dify.botType === 'chatBot') {\n        endpoint += '/chat-messages';\n        const payload: any = {\n          inputs: {\n            remoteJid: remoteJid,\n            pushName: pushName,\n            instanceName: instance.instanceName,\n            serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n            apiKey: instance.token,\n          },\n          query: processedContent,\n          response_mode: 'blocking',\n          conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId,\n          user: remoteJid,\n        };\n\n        // Handle image messages\n        if (this.isImageMessage(content)) {\n          const media = content.split('|');\n\n          if (msg.message.mediaUrl || msg.message.base64) {\n            let mediaBase64 = msg.message.base64 || null;\n\n            if (msg.message.mediaUrl && isURL(msg.message.mediaUrl)) {\n              const result = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' });\n              mediaBase64 = Buffer.from(result.data).toString('base64');\n            }\n\n            if (mediaBase64) {\n              payload.files = [\n                {\n                  type: 'image',\n                  transfer_method: 'remote_url',\n                  url: mediaBase64,\n                },\n              ];\n            }\n          } else {\n            payload.files = [\n              {\n                type: 'image',\n                transfer_method: 'remote_url',\n                url: media[1].split('?')[0],\n              },\n            ];\n          }\n          payload.query = media[2] || content;\n        }\n\n        if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n          await instance.client.presenceSubscribe(remoteJid);\n          await instance.client.sendPresenceUpdate('composing', remoteJid);\n        }\n\n        const response = await axios.post(endpoint, payload, {\n          headers: {\n            Authorization: `Bearer ${dify.apiKey}`,\n          },\n        });\n\n        if (instance.integration === Integration.WHATSAPP_BAILEYS)\n          await instance.client.sendPresenceUpdate('paused', remoteJid);\n\n        const message = response?.data?.answer;\n        const conversationId = response?.data?.conversation_id;\n\n        if (message) {\n          await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n        }\n\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'opened',\n            awaitUser: true,\n            sessionId: session.sessionId === remoteJid ? conversationId : session.sessionId,\n          },\n        });\n      }\n\n      if (dify.botType === 'textGenerator') {\n        endpoint += '/completion-messages';\n        const payload: any = {\n          inputs: {\n            query: processedContent,\n            pushName: pushName,\n            remoteJid: remoteJid,\n            instanceName: instance.instanceName,\n            serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n            apiKey: instance.token,\n          },\n          response_mode: 'blocking',\n          conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId,\n          user: remoteJid,\n        };\n\n        // Handle image messages\n        if (this.isImageMessage(content)) {\n          const media = content.split('|');\n\n          if (msg.message.mediaUrl || msg.message.base64) {\n            let mediaBase64 = msg.message.base64 || null;\n\n            if (msg.message.mediaUrl && isURL(msg.message.mediaUrl)) {\n              const result = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' });\n              mediaBase64 = Buffer.from(result.data).toString('base64');\n            }\n\n            if (mediaBase64) {\n              payload.files = [\n                {\n                  type: 'image',\n                  transfer_method: 'remote_url',\n                  url: mediaBase64,\n                },\n              ];\n            }\n          } else {\n            payload.files = [\n              {\n                type: 'image',\n                transfer_method: 'remote_url',\n                url: media[1].split('?')[0],\n              },\n            ];\n            payload.inputs.query = media[2] || content;\n          }\n        }\n\n        if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n          await instance.client.presenceSubscribe(remoteJid);\n          await instance.client.sendPresenceUpdate('composing', remoteJid);\n        }\n\n        const response = await axios.post(endpoint, payload, {\n          headers: {\n            Authorization: `Bearer ${dify.apiKey}`,\n          },\n        });\n\n        if (instance.integration === Integration.WHATSAPP_BAILEYS)\n          await instance.client.sendPresenceUpdate('paused', remoteJid);\n\n        const message = response?.data?.answer;\n        const conversationId = response?.data?.conversation_id;\n\n        if (message) {\n          await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n        }\n\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'opened',\n            awaitUser: true,\n            sessionId: session.sessionId === remoteJid ? conversationId : session.sessionId,\n          },\n        });\n      }\n\n      if (dify.botType === 'agent') {\n        endpoint += '/chat-messages';\n        const payload: any = {\n          inputs: {\n            remoteJid: remoteJid,\n            pushName: pushName,\n            instanceName: instance.instanceName,\n            serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n            apiKey: instance.token,\n          },\n          query: processedContent,\n          response_mode: 'streaming',\n          conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId,\n          user: remoteJid,\n        };\n\n        // Handle image messages\n        if (this.isImageMessage(content)) {\n          const media = content.split('|');\n\n          if (msg.message.mediaUrl || msg.message.base64) {\n            payload.files = [\n              {\n                type: 'image',\n                transfer_method: 'remote_url',\n                url: msg.message.mediaUrl || msg.message.base64,\n              },\n            ];\n          } else {\n            payload.files = [\n              {\n                type: 'image',\n                transfer_method: 'remote_url',\n                url: media[1].split('?')[0],\n              },\n            ];\n            payload.query = media[2] || content;\n          }\n        }\n\n        if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n          await instance.client.presenceSubscribe(remoteJid);\n          await instance.client.sendPresenceUpdate('composing', remoteJid);\n        }\n\n        const response = await axios.post(endpoint, payload, {\n          headers: {\n            Authorization: `Bearer ${dify.apiKey}`,\n          },\n        });\n\n        let conversationId;\n        let answer = '';\n\n        const data = response.data.replaceAll('data: ', '');\n        const events = data.split('\\n').filter((line) => line.trim() !== '');\n\n        for (const eventString of events) {\n          if (eventString.trim().startsWith('{')) {\n            const event = JSON.parse(eventString);\n\n            if (event?.event === 'agent_message') {\n              console.log('event:', event);\n              conversationId = conversationId ?? event?.conversation_id;\n              answer += event?.answer;\n            }\n          }\n        }\n\n        if (instance.integration === Integration.WHATSAPP_BAILEYS)\n          await instance.client.sendPresenceUpdate('paused', remoteJid);\n\n        if (answer) {\n          await this.sendMessageWhatsApp(instance, remoteJid, answer, settings, true);\n        }\n\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'opened',\n            awaitUser: true,\n            sessionId: session.sessionId === remoteJid ? conversationId : session.sessionId,\n          },\n        });\n      }\n    } catch (error) {\n      this.logger.error(error.response?.data || error);\n      return;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/dify/validate/dify.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const difySchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    botType: { type: 'string', enum: ['chatBot', 'textGenerator', 'agent', 'workflow'] },\n    apiUrl: { type: 'string' },\n    apiKey: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: ['enabled', 'botType', 'triggerType'],\n  ...isNotEmpty('enabled', 'botType', 'triggerType'),\n};\n\nexport const difyStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const difySettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    difyIdFallback: { type: 'string' },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: [\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ],\n  ...isNotEmpty(\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ),\n};\n\nexport const difyIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/evoai/controllers/evoai.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { EvoaiDto } from '@api/integrations/chatbot/evoai/dto/evoai.dto';\nimport { EvoaiService } from '@api/integrations/chatbot/evoai/services/evoai.service';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Evoai } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { Evoai as EvoaiModel, IntegrationSession } from '@prisma/client';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\n\nexport class EvoaiController extends BaseChatbotController<EvoaiModel, EvoaiDto> {\n  constructor(\n    private readonly evoaiService: EvoaiService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.evoai;\n    this.settingsRepository = this.prismaRepository.evoaiSetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  public readonly logger = new Logger('EvoaiController');\n  protected readonly integrationName = 'Evoai';\n\n  integrationEnabled = configService.get<Evoai>('EVOAI').ENABLED;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.evoaiIdFallback;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'evoaiIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'evoai';\n  }\n\n  protected getAdditionalBotData(data: EvoaiDto): Record<string, any> {\n    return {\n      agentUrl: data.agentUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  // Implementation for bot-specific updates\n  protected getAdditionalUpdateFields(data: EvoaiDto): Record<string, any> {\n    return {\n      agentUrl: data.agentUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  // Implementation for bot-specific duplicate validation on update\n  protected async validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: EvoaiDto): Promise<void> {\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        id: {\n          not: botId,\n        },\n        instanceId: instanceId,\n        agentUrl: data.agentUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Evoai already exists');\n    }\n  }\n\n  // Override createBot to add EvoAI-specific validation\n  public async createBot(instance: InstanceDto, data: EvoaiDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('Evoai is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    // EvoAI-specific duplicate check\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        instanceId: instanceId,\n        agentUrl: data.agentUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Evoai already exists');\n    }\n\n    // Let the base class handle the rest\n    return super.createBot(instance, data);\n  }\n\n  // Process Evoai-specific bot logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: EvoaiModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    await this.evoaiService.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evoai/dto/evoai.dto.ts",
    "content": "import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class EvoaiDto extends BaseChatbotDto {\n  agentUrl?: string;\n  apiKey?: string;\n}\n\nexport class EvoaiSettingDto extends BaseChatbotSettingDto {\n  evoaiIdFallback?: string;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evoai/routes/evoai.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { evoaiController } from '@api/server.module';\nimport {\n  evoaiIgnoreJidSchema,\n  evoaiSchema,\n  evoaiSettingSchema,\n  evoaiStatusSchema,\n  instanceSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { EvoaiDto, EvoaiSettingDto } from '../dto/evoai.dto';\n\nexport class EvoaiRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EvoaiDto>({\n          request: req,\n          schema: evoaiSchema,\n          ClassRef: EvoaiDto,\n          execute: (instance, data) => evoaiController.createBot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evoaiController.findBot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:evoaiId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evoaiController.fetchBot(instance, req.params.evoaiId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:evoaiId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EvoaiDto>({\n          request: req,\n          schema: evoaiSchema,\n          ClassRef: EvoaiDto,\n          execute: (instance, data) => evoaiController.updateBot(instance, req.params.evoaiId, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:evoaiId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evoaiController.deleteBot(instance, req.params.evoaiId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EvoaiSettingDto>({\n          request: req,\n          schema: evoaiSettingSchema,\n          ClassRef: EvoaiSettingDto,\n          execute: (instance, data) => evoaiController.settings(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evoaiController.fetchSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: evoaiStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => evoaiController.changeStatus(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:evoaiId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evoaiController.fetchSessions(instance, req.params.evoaiId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: evoaiIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => evoaiController.ignoreJid(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evoai/services/evoai.service.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService, HttpServer } from '@config/env.config';\nimport { Evoai, EvoaiSetting, IntegrationSession } from '@prisma/client';\nimport axios from 'axios';\nimport { downloadMediaMessage } from 'baileys';\nimport { isURL } from 'class-validator';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\nimport { OpenaiService } from '../../openai/services/openai.service';\n\nexport class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {\n  private openaiService: OpenaiService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'EvoaiService', configService);\n    this.openaiService = openaiService;\n  }\n\n  /**\n   * Return the bot type for EvoAI\n   */\n  protected getBotType(): string {\n    return 'evoai';\n  }\n\n  /**\n   * Implement the abstract method to send message to EvoAI API\n   * Handles audio transcription, image processing, and complex JSON-RPC payload\n   */\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: EvoaiSetting,\n    evoai: Evoai,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      this.logger.debug(`[EvoAI] Sending message to bot with content: ${content}`);\n\n      let processedContent = content;\n\n      // Handle audio messages - transcribe using OpenAI Whisper\n      if (this.isAudioMessage(content) && msg) {\n        try {\n          this.logger.debug(`[EvoAI] Downloading audio for Whisper transcription`);\n          const transcription = await this.openaiService.speechToText(msg, instance);\n          if (transcription) {\n            processedContent = `[audio] ${transcription}`;\n          }\n        } catch (err) {\n          this.logger.error(`[EvoAI] Failed to transcribe audio: ${err}`);\n        }\n      }\n\n      const endpoint: string = evoai.agentUrl;\n\n      if (!endpoint) {\n        this.logger.error('No EvoAI endpoint defined');\n        return;\n      }\n\n      const callId = `req-${uuidv4().substring(0, 8)}`;\n      const messageId = remoteJid.split('@')[0] || uuidv4(); // Use phone number as messageId\n\n      // Prepare message parts\n      const parts = [\n        {\n          type: 'text',\n          text: processedContent,\n        },\n      ];\n\n      // Handle image message if present\n      if (this.isImageMessage(content) && msg) {\n        const media = content.split('|');\n        parts[0].text = media[2] || content;\n\n        try {\n          if (msg.message.mediaUrl || msg.message.base64) {\n            let mediaBase64 = msg.message.base64 || null;\n\n            if (msg.message.mediaUrl && isURL(msg.message.mediaUrl)) {\n              const result = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' });\n              mediaBase64 = Buffer.from(result.data).toString('base64');\n            }\n\n            if (mediaBase64) {\n              parts.push({\n                type: 'file',\n                file: {\n                  name: msg.key.id + '.jpeg',\n                  mimeType: 'image/jpeg',\n                  bytes: mediaBase64,\n                },\n              } as any);\n            }\n          } else {\n            // Download the image\n            const mediaBuffer = await downloadMediaMessage(msg, 'buffer', {});\n            const fileContent = Buffer.from(mediaBuffer).toString('base64');\n            const fileName = media[2] || `${msg.key?.id || 'image'}.jpg`;\n\n            parts.push({\n              type: 'file',\n              file: {\n                name: fileName,\n                mimeType: 'image/jpeg',\n                bytes: fileContent,\n              },\n            } as any);\n          }\n        } catch (fileErr) {\n          this.logger.error(`[EvoAI] Failed to process image: ${fileErr}`);\n        }\n      }\n\n      const payload = {\n        jsonrpc: '2.0',\n        id: callId,\n        method: 'message/send',\n        params: {\n          contextId: session.sessionId,\n          message: {\n            role: 'user',\n            parts,\n            messageId: messageId,\n            metadata: {\n              messageKey: msg?.key,\n            },\n          },\n          metadata: {\n            remoteJid: remoteJid,\n            pushName: pushName,\n            fromMe: msg?.key?.fromMe,\n            instanceName: instance.instanceName,\n            serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n            apiKey: instance.token,\n          },\n        },\n      };\n\n      this.logger.debug(`[EvoAI] Sending request to: ${endpoint}`);\n      // Redact base64 file bytes from payload log\n      const redactedPayload = JSON.parse(JSON.stringify(payload));\n      if (redactedPayload?.params?.message?.parts) {\n        redactedPayload.params.message.parts = redactedPayload.params.message.parts.map((part) => {\n          if (part.type === 'file' && part.file && part.file.bytes) {\n            return { ...part, file: { ...part.file, bytes: '[base64 omitted]' } };\n          }\n          return part;\n        });\n      }\n      this.logger.debug(`[EvoAI] Payload: ${JSON.stringify(redactedPayload)}`);\n\n      if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n        await instance.client.presenceSubscribe(remoteJid);\n        await instance.client.sendPresenceUpdate('composing', remoteJid);\n      }\n\n      const response = await axios.post(endpoint, payload, {\n        headers: {\n          'x-api-key': evoai.apiKey,\n          'Content-Type': 'application/json',\n        },\n      });\n\n      this.logger.debug(`[EvoAI] Response: ${JSON.stringify(response.data)}`);\n\n      if (instance.integration === Integration.WHATSAPP_BAILEYS)\n        await instance.client.sendPresenceUpdate('paused', remoteJid);\n\n      let message = undefined;\n      const result = response?.data?.result;\n\n      // Extract message from artifacts array\n      if (result?.artifacts && Array.isArray(result.artifacts) && result.artifacts.length > 0) {\n        const artifact = result.artifacts[0];\n        if (artifact?.parts && Array.isArray(artifact.parts)) {\n          const textPart = artifact.parts.find((p) => p.type === 'text' && p.text);\n          if (textPart) message = textPart.text;\n        }\n      }\n\n      this.logger.debug(`[EvoAI] Extracted message to send: ${message}`);\n\n      if (message) {\n        await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n      }\n    } catch (error) {\n      this.logger.error(\n        `[EvoAI] Error sending message: ${error?.response?.data ? JSON.stringify(error.response.data) : error}`,\n      );\n      return;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evoai/validate/evoai.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const evoaiSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    agentUrl: { type: 'string' },\n    apiKey: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: ['enabled', 'agentUrl', 'triggerType'],\n  ...isNotEmpty('enabled', 'agentUrl', 'triggerType'),\n};\n\nexport const evoaiStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const evoaiSettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    botIdFallback: { type: 'string' },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: [\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ],\n  ...isNotEmpty(\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ),\n};\n\nexport const evoaiIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/evolutionBot/controllers/evolutionBot.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Logger } from '@config/logger.config';\nimport { EvolutionBot, IntegrationSession } from '@prisma/client';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\nimport { EvolutionBotDto } from '../dto/evolutionBot.dto';\nimport { EvolutionBotService } from '../services/evolutionBot.service';\n\nexport class EvolutionBotController extends BaseChatbotController<EvolutionBot, EvolutionBotDto> {\n  constructor(\n    private readonly evolutionBotService: EvolutionBotService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.evolutionBot;\n    this.settingsRepository = this.prismaRepository.evolutionBotSetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  public readonly logger = new Logger('EvolutionBotController');\n  protected readonly integrationName = 'EvolutionBot';\n\n  integrationEnabled = true; // Set to true by default or use config value if available\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  // Implementation of abstract methods required by BaseChatbotController\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.botIdFallback;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'botIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'evolution';\n  }\n\n  protected getAdditionalBotData(data: EvolutionBotDto): Record<string, any> {\n    return {\n      apiUrl: data.apiUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  // Implementation for bot-specific updates\n  protected getAdditionalUpdateFields(data: EvolutionBotDto): Record<string, any> {\n    return {\n      apiUrl: data.apiUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  // Implementation for bot-specific duplicate validation on update\n  protected async validateNoDuplicatesOnUpdate(\n    botId: string,\n    instanceId: string,\n    data: EvolutionBotDto,\n  ): Promise<void> {\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        id: {\n          not: botId,\n        },\n        instanceId: instanceId,\n        apiUrl: data.apiUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Evolution Bot already exists');\n    }\n  }\n\n  // Process bot-specific logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: EvolutionBot,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    await this.evolutionBotService.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evolutionBot/dto/evolutionBot.dto.ts",
    "content": "import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class EvolutionBotDto extends BaseChatbotDto {\n  apiUrl: string;\n  apiKey: string;\n}\n\nexport class EvolutionBotSettingDto extends BaseChatbotSettingDto {\n  botIdFallback?: string;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evolutionBot/routes/evolutionBot.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { evolutionBotController } from '@api/server.module';\nimport { instanceSchema } from '@validate/instance.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { EvolutionBotDto, EvolutionBotSettingDto } from '../dto/evolutionBot.dto';\nimport {\n  evolutionBotIgnoreJidSchema,\n  evolutionBotSchema,\n  evolutionBotSettingSchema,\n  evolutionBotStatusSchema,\n} from '../validate/evolutionBot.schema';\n\nexport class EvolutionBotRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EvolutionBotDto>({\n          request: req,\n          schema: evolutionBotSchema,\n          ClassRef: EvolutionBotDto,\n          execute: (instance, data) => evolutionBotController.createBot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evolutionBotController.findBot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:evolutionBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evolutionBotController.fetchBot(instance, req.params.evolutionBotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:evolutionBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EvolutionBotDto>({\n          request: req,\n          schema: evolutionBotSchema,\n          ClassRef: EvolutionBotDto,\n          execute: (instance, data) => evolutionBotController.updateBot(instance, req.params.evolutionBotId, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:evolutionBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evolutionBotController.deleteBot(instance, req.params.evolutionBotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EvolutionBotSettingDto>({\n          request: req,\n          schema: evolutionBotSettingSchema,\n          ClassRef: EvolutionBotSettingDto,\n          execute: (instance, data) => evolutionBotController.settings(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evolutionBotController.fetchSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: evolutionBotStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => evolutionBotController.changeStatus(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:evolutionBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => evolutionBotController.fetchSessions(instance, req.params.evolutionBotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: evolutionBotIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => evolutionBotController.ignoreJid(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evolutionBot/services/evolutionBot.service.ts",
    "content": "/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService, HttpServer } from '@config/env.config';\nimport { EvolutionBot, EvolutionBotSetting, IntegrationSession } from '@prisma/client';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { isURL } from 'class-validator';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\nimport { OpenaiService } from '../../openai/services/openai.service';\n\nexport class EvolutionBotService extends BaseChatbotService<EvolutionBot, EvolutionBotSetting> {\n  private openaiService: OpenaiService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'EvolutionBotService', configService);\n    this.openaiService = openaiService;\n  }\n\n  /**\n   * Get the bot type identifier\n   */\n  protected getBotType(): string {\n    return 'evolution';\n  }\n\n  /**\n   * Send a message to the Evolution Bot API\n   */\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: EvolutionBotSetting,\n    bot: EvolutionBot,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      const payload: any = {\n        inputs: {\n          sessionId: session.id,\n          remoteJid: remoteJid,\n          pushName: pushName,\n          fromMe: msg?.key?.fromMe,\n          instanceName: instance.instanceName,\n          serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n          apiKey: instance.token,\n        },\n        query: content,\n        conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId,\n        user: remoteJid,\n      };\n\n      if (this.isAudioMessage(content) && msg) {\n        try {\n          this.logger.debug(`[EvolutionBot] Downloading audio for Whisper transcription`);\n          const transcription = await this.openaiService.speechToText(msg, instance);\n          if (transcription) {\n            payload.query = `[audio] ${transcription}`;\n          }\n        } catch (err) {\n          this.logger.error(`[EvolutionBot] Failed to transcribe audio: ${err}`);\n        }\n      }\n\n      if (this.isImageMessage(content) && msg) {\n        const media = content.split('|');\n\n        if (msg.message.mediaUrl || msg.message.base64) {\n          payload.files = [\n            {\n              type: 'image',\n              url: msg.message.base64 || msg.message.mediaUrl,\n            },\n          ];\n        } else {\n          payload.files = [\n            {\n              type: 'image',\n              url: media[1].split('?')[0],\n            },\n          ];\n        }\n\n        payload.query = media[2] || content;\n      }\n\n      if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n        await instance.client.presenceSubscribe(remoteJid);\n        await instance.client.sendPresenceUpdate('composing', remoteJid);\n      }\n\n      const endpoint = bot.apiUrl;\n\n      if (!endpoint) {\n        this.logger.error('No Evolution Bot endpoint defined');\n        return;\n      }\n\n      let headers: any = {\n        'Content-Type': 'application/json',\n      };\n\n      if (bot.apiKey) {\n        headers = {\n          ...headers,\n          Authorization: `Bearer ${bot.apiKey}`,\n        };\n      }\n\n      // Sanitize payload for logging (remove sensitive data)\n      const sanitizedPayload = {\n        ...payload,\n        inputs: {\n          ...payload.inputs,\n          apiKey: payload.inputs.apiKey ? '[REDACTED]' : undefined,\n        },\n      };\n\n      const response = await axios.post(endpoint, payload, {\n        headers,\n      });\n\n      if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n        await instance.client.sendPresenceUpdate('paused', remoteJid);\n      }\n\n      let message = response?.data?.message;\n      const rawLinkPreview = response?.data?.linkPreview;\n\n      // Validate linkPreview is boolean and default to true for backward compatibility\n      const linkPreview = typeof rawLinkPreview === 'boolean' ? rawLinkPreview : true;\n\n      if (message && typeof message === 'string' && message.startsWith(\"'\") && message.endsWith(\"'\")) {\n        const innerContent = message.slice(1, -1);\n        if (!innerContent.includes(\"'\")) {\n          message = innerContent;\n        }\n      }\n\n      if (message) {\n        // Use the base class method that handles splitMessages functionality\n        await this.sendMessageWhatsApp(instance, remoteJid, message, settings, linkPreview);\n      } else {\n        this.logger.warn(`[EvolutionBot] No message content received from bot response`);\n      }\n\n      // Send telemetry\n      sendTelemetry('/message/sendText');\n    } catch (error) {\n      this.logger.error(`Error in sendMessageToBot: ${error.message || JSON.stringify(error)}`);\n      return;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/evolutionBot/validate/evolutionBot.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const evolutionBotSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    apiUrl: { type: 'string' },\n    apiKey: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: ['enabled', 'apiUrl', 'triggerType'],\n  ...isNotEmpty('enabled', 'apiUrl', 'triggerType'),\n};\n\nexport const evolutionBotStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const evolutionBotSettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    botIdFallback: { type: 'string' },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: [\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ],\n  ...isNotEmpty(\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ),\n};\n\nexport const evolutionBotIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/flowise/controllers/flowise.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Flowise } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { Flowise as FlowiseModel, IntegrationSession } from '@prisma/client';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\nimport { FlowiseDto } from '../dto/flowise.dto';\nimport { FlowiseService } from '../services/flowise.service';\n\nexport class FlowiseController extends BaseChatbotController<FlowiseModel, FlowiseDto> {\n  constructor(\n    private readonly flowiseService: FlowiseService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.flowise;\n    this.settingsRepository = this.prismaRepository.flowiseSetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  public readonly logger = new Logger('FlowiseController');\n  protected readonly integrationName = 'Flowise';\n\n  integrationEnabled = configService.get<Flowise>('FLOWISE').ENABLED;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.flowiseIdFallback;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'flowiseIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'flowise';\n  }\n\n  protected getAdditionalBotData(data: FlowiseDto): Record<string, any> {\n    return {\n      apiUrl: data.apiUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  protected getAdditionalUpdateFields(data: FlowiseDto): Record<string, any> {\n    return {\n      apiUrl: data.apiUrl,\n      apiKey: data.apiKey,\n    };\n  }\n\n  protected async validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: FlowiseDto): Promise<void> {\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        id: { not: botId },\n        instanceId: instanceId,\n        apiUrl: data.apiUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Flowise already exists');\n    }\n  }\n\n  // Process Flowise-specific bot logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: FlowiseModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    await this.flowiseService.processBot(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n\n  // Override createBot to add module availability check and Flowise-specific validation\n  public async createBot(instance: InstanceDto, data: FlowiseDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('Flowise is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    // Flowise-specific duplicate check\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        instanceId: instanceId,\n        apiUrl: data.apiUrl,\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Flowise already exists');\n    }\n\n    // Let the base class handle the rest\n    return super.createBot(instance, data);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/flowise/dto/flowise.dto.ts",
    "content": "import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class FlowiseDto extends BaseChatbotDto {\n  apiUrl: string;\n  apiKey?: string;\n}\n\nexport class FlowiseSettingDto extends BaseChatbotSettingDto {\n  flowiseIdFallback?: string;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/flowise/routes/flowise.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { flowiseController } from '@api/server.module';\nimport { instanceSchema } from '@validate/instance.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { FlowiseDto, FlowiseSettingDto } from '../dto/flowise.dto';\nimport {\n  flowiseIgnoreJidSchema,\n  flowiseSchema,\n  flowiseSettingSchema,\n  flowiseStatusSchema,\n} from '../validate/flowise.schema';\n\nexport class FlowiseRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<FlowiseDto>({\n          request: req,\n          schema: flowiseSchema,\n          ClassRef: FlowiseDto,\n          execute: (instance, data) => flowiseController.createBot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => flowiseController.findBot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:flowiseId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => flowiseController.fetchBot(instance, req.params.flowiseId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:flowiseId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<FlowiseDto>({\n          request: req,\n          schema: flowiseSchema,\n          ClassRef: FlowiseDto,\n          execute: (instance, data) => flowiseController.updateBot(instance, req.params.flowiseId, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:flowiseId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => flowiseController.deleteBot(instance, req.params.flowiseId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<FlowiseSettingDto>({\n          request: req,\n          schema: flowiseSettingSchema,\n          ClassRef: FlowiseSettingDto,\n          execute: (instance, data) => flowiseController.settings(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => flowiseController.fetchSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: flowiseStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => flowiseController.changeStatus(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:flowiseId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => flowiseController.fetchSessions(instance, req.params.flowiseId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: flowiseIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => flowiseController.ignoreJid(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/flowise/services/flowise.service.ts",
    "content": "/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService, HttpServer } from '@config/env.config';\nimport { Flowise as FlowiseModel, IntegrationSession } from '@prisma/client';\nimport axios from 'axios';\nimport { isURL } from 'class-validator';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\nimport { OpenaiService } from '../../openai/services/openai.service';\n\nexport class FlowiseService extends BaseChatbotService<FlowiseModel> {\n  private openaiService: OpenaiService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'FlowiseService', configService);\n    this.openaiService = openaiService;\n  }\n\n  // Return the bot type for Flowise\n  protected getBotType(): string {\n    return 'flowise';\n  }\n\n  // Process Flowise-specific bot logic\n  public async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: FlowiseModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    await this.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n\n  // Implement the abstract method to send message to Flowise API\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: any,\n    bot: FlowiseModel,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    const payload: any = {\n      question: content,\n      overrideConfig: {\n        sessionId: remoteJid,\n        vars: {\n          messageId: msg?.key?.id,\n          fromMe: msg?.key?.fromMe,\n          remoteJid: remoteJid,\n          pushName: pushName,\n          instanceName: instance.instanceName,\n          serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n          apiKey: instance.token,\n        },\n      },\n    };\n\n    // Handle audio messages\n    if (this.isAudioMessage(content) && msg) {\n      try {\n        this.logger.debug(`[Flowise] Downloading audio for Whisper transcription`);\n        const transcription = await this.openaiService.speechToText(msg, instance);\n        if (transcription) {\n          payload.question = `[audio] ${transcription}`;\n        }\n      } catch (err) {\n        this.logger.error(`[Flowise] Failed to transcribe audio: ${err}`);\n      }\n    }\n\n    if (this.isImageMessage(content)) {\n      const media = content.split('|');\n\n      if (msg.message.mediaUrl || msg.message.base64) {\n        payload.uploads = [\n          {\n            data: msg.message.base64 || msg.message.mediaUrl,\n            type: 'url',\n            name: 'Flowise.png',\n            mime: 'image/png',\n          },\n        ];\n      } else {\n        payload.uploads = [\n          {\n            data: media[1].split('?')[0],\n            type: 'url',\n            name: 'Flowise.png',\n            mime: 'image/png',\n          },\n        ];\n        payload.question = media[2] || content;\n      }\n    }\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    let headers: any = {\n      'Content-Type': 'application/json',\n    };\n\n    if (bot.apiKey) {\n      headers = {\n        ...headers,\n        Authorization: `Bearer ${bot.apiKey}`,\n      };\n    }\n\n    const endpoint = bot.apiUrl;\n\n    if (!endpoint) {\n      this.logger.error('No Flowise endpoint defined');\n      return;\n    }\n\n    const response = await axios.post(endpoint, payload, {\n      headers,\n    });\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.sendPresenceUpdate('paused', remoteJid);\n    }\n\n    const message = response?.data?.text;\n\n    if (message) {\n      // Use the base class method to send the message to WhatsApp\n      await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n    }\n  }\n\n  // The service is now complete with just the abstract method implementations\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/flowise/validate/flowise.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const flowiseSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    apiUrl: { type: 'string' },\n    apiKey: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: ['enabled', 'apiUrl', 'triggerType'],\n  ...isNotEmpty('enabled', 'apiUrl', 'triggerType'),\n};\n\nexport const flowiseStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const flowiseSettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    flowiseIdFallback: { type: 'string' },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: [\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n  ],\n  ...isNotEmpty(\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n  ),\n};\n\nexport const flowiseIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/n8n/controllers/n8n.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { N8nDto } from '@api/integrations/chatbot/n8n/dto/n8n.dto';\nimport { N8nService } from '@api/integrations/chatbot/n8n/services/n8n.service';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { IntegrationSession, N8n as N8nModel } from '@prisma/client';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\n\nexport class N8nController extends BaseChatbotController<N8nModel, N8nDto> {\n  constructor(\n    private readonly n8nService: N8nService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.n8n;\n    this.settingsRepository = this.prismaRepository.n8nSetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  public readonly logger = new Logger('N8nController');\n  protected readonly integrationName = 'N8n';\n\n  integrationEnabled = configService.get('N8N').ENABLED;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.fallbackId;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'n8nIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'n8n';\n  }\n\n  protected getAdditionalBotData(data: N8nDto): Record<string, any> {\n    return {\n      webhookUrl: data.webhookUrl,\n      basicAuthUser: data.basicAuthUser,\n      basicAuthPass: data.basicAuthPass,\n    };\n  }\n\n  // Implementation for bot-specific updates\n  protected getAdditionalUpdateFields(data: N8nDto): Record<string, any> {\n    return {\n      webhookUrl: data.webhookUrl,\n      basicAuthUser: data.basicAuthUser,\n      basicAuthPass: data.basicAuthPass,\n    };\n  }\n\n  // Implementation for bot-specific duplicate validation on update\n  protected async validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: N8nDto): Promise<void> {\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        id: {\n          not: botId,\n        },\n        instanceId: instanceId,\n        webhookUrl: data.webhookUrl,\n        basicAuthUser: data.basicAuthUser,\n        basicAuthPass: data.basicAuthPass,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('N8n already exists');\n    }\n  }\n\n  // Bots\n  public async createBot(instance: InstanceDto, data: N8nDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('N8n is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    // Check for N8n-specific duplicate\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        instanceId: instanceId,\n        webhookUrl: data.webhookUrl,\n        basicAuthUser: data.basicAuthUser,\n        basicAuthPass: data.basicAuthPass,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('N8n already exists');\n    }\n\n    // Let the base class handle the rest of the bot creation process\n    return super.createBot(instance, data);\n  }\n\n  // Process N8n-specific bot logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: N8nModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    // Use the base class pattern instead of calling n8nService.process directly\n    await this.n8nService.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/n8n/dto/n8n.dto.ts",
    "content": "import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class N8nDto extends BaseChatbotDto {\n  // N8n specific fields\n  webhookUrl?: string;\n  basicAuthUser?: string;\n  basicAuthPass?: string;\n}\n\nexport class N8nSettingDto extends BaseChatbotSettingDto {\n  // N8n has no specific fields\n}\n\nexport class N8nMessageDto {\n  chatInput: string;\n  sessionId: string;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/n8n/routes/n8n.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { n8nController } from '@api/server.module';\nimport {\n  instanceSchema,\n  n8nIgnoreJidSchema,\n  n8nSchema,\n  n8nSettingSchema,\n  n8nStatusSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { N8nDto, N8nSettingDto } from '../dto/n8n.dto';\n\nexport class N8nRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<N8nDto>({\n          request: req,\n          schema: n8nSchema,\n          ClassRef: N8nDto,\n          execute: (instance, data) => n8nController.createBot(instance, data),\n        });\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => n8nController.findBot(instance),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:n8nId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => n8nController.fetchBot(instance, req.params.n8nId),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:n8nId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<N8nDto>({\n          request: req,\n          schema: n8nSchema,\n          ClassRef: N8nDto,\n          execute: (instance, data) => n8nController.updateBot(instance, req.params.n8nId, data),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:n8nId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => n8nController.deleteBot(instance, req.params.n8nId),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<N8nSettingDto>({\n          request: req,\n          schema: n8nSettingSchema,\n          ClassRef: N8nSettingDto,\n          execute: (instance, data) => n8nController.settings(instance, data),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => n8nController.fetchSettings(instance),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: n8nStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => n8nController.changeStatus(instance, data),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:n8nId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => n8nController.fetchSessions(instance, req.params.n8nId),\n        });\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: n8nIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => n8nController.ignoreJid(instance, data),\n        });\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/n8n/services/n8n.service.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { ConfigService, HttpServer } from '@config/env.config';\nimport { IntegrationSession, N8n, N8nSetting } from '@prisma/client';\nimport axios from 'axios';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\nimport { OpenaiService } from '../../openai/services/openai.service';\n\nexport class N8nService extends BaseChatbotService<N8n, N8nSetting> {\n  private openaiService: OpenaiService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    prismaRepository: PrismaRepository,\n    configService: ConfigService,\n    openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'N8nService', configService);\n    this.openaiService = openaiService;\n  }\n\n  /**\n   * Return the bot type for N8n\n   */\n  protected getBotType(): string {\n    return 'n8n';\n  }\n\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: N8nSetting,\n    n8n: N8n,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ) {\n    try {\n      if (!session) {\n        this.logger.error('Session is null in sendMessageToBot');\n        return;\n      }\n\n      const endpoint: string = n8n.webhookUrl;\n      const payload: any = {\n        chatInput: content,\n        sessionId: session.sessionId,\n        remoteJid: remoteJid,\n        pushName: pushName,\n        keyId: msg?.key?.id,\n        fromMe: msg?.key?.fromMe,\n        quotedMessage: msg?.contextInfo?.quotedMessage,\n        instanceName: instance.instanceName,\n        serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n        apiKey: instance.token,\n      };\n\n      // Handle audio messages\n      if (this.isAudioMessage(content) && msg) {\n        try {\n          this.logger.debug(`[N8n] Downloading audio for Whisper transcription`);\n          const transcription = await this.openaiService.speechToText(msg, instance);\n          if (transcription) {\n            payload.chatInput = `[audio] ${transcription}`;\n          }\n        } catch (err) {\n          this.logger.error(`[N8n] Failed to transcribe audio: ${err}`);\n        }\n      }\n\n      const headers: Record<string, string> = {};\n      if (n8n.basicAuthUser && n8n.basicAuthPass) {\n        const auth = Buffer.from(`${n8n.basicAuthUser}:${n8n.basicAuthPass}`).toString('base64');\n        headers['Authorization'] = `Basic ${auth}`;\n      }\n      const response = await axios.post(endpoint, payload, { headers });\n      const message = response?.data?.output || response?.data?.answer;\n\n      // Use base class method instead of custom implementation\n      await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          status: 'opened',\n          awaitUser: true,\n        },\n      });\n    } catch (error) {\n      this.logger.error(error.response?.data || error);\n      return;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/n8n/validate/n8n.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const n8nSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    webhookUrl: { type: 'string' },\n    basicAuthUser: { type: 'string' },\n    basicAuthPassword: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: ['enabled', 'webhookUrl', 'triggerType'],\n  ...isNotEmpty('enabled', 'webhookUrl', 'triggerType'),\n};\n\nexport const n8nStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const n8nSettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    botIdFallback: { type: 'string' },\n    splitMessages: { type: 'boolean' },\n    timePerChar: { type: 'integer' },\n  },\n  required: [\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ],\n  ...isNotEmpty(\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n    'splitMessages',\n    'timePerChar',\n  ),\n};\n\nexport const n8nIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/openai/controllers/openai.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { OpenaiCredsDto, OpenaiDto } from '@api/integrations/chatbot/openai/dto/openai.dto';\nimport { OpenaiService } from '@api/integrations/chatbot/openai/services/openai.service';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Openai } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { IntegrationSession, OpenaiBot } from '@prisma/client';\nimport OpenAI from 'openai';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\n\nexport class OpenaiController extends BaseChatbotController<OpenaiBot, OpenaiDto> {\n  constructor(\n    private readonly openaiService: OpenaiService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.openaiBot;\n    this.settingsRepository = this.prismaRepository.openaiSetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n    this.credsRepository = this.prismaRepository.openaiCreds;\n  }\n\n  public readonly logger = new Logger('OpenaiController');\n  protected readonly integrationName = 'Openai';\n\n  integrationEnabled = configService.get<Openai>('OPENAI').ENABLED;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n  private client: OpenAI;\n  private credsRepository: any;\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.openaiIdFallback;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'openaiIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'openai';\n  }\n\n  protected getAdditionalBotData(data: OpenaiDto): Record<string, any> {\n    return {\n      openaiCredsId: data.openaiCredsId,\n      botType: data.botType,\n      assistantId: data.assistantId,\n      functionUrl: data.functionUrl,\n      model: data.model,\n      systemMessages: data.systemMessages,\n      assistantMessages: data.assistantMessages,\n      userMessages: data.userMessages,\n      maxTokens: data.maxTokens,\n    };\n  }\n\n  // Implementation for bot-specific updates\n  protected getAdditionalUpdateFields(data: OpenaiDto): Record<string, any> {\n    return {\n      openaiCredsId: data.openaiCredsId,\n      botType: data.botType,\n      assistantId: data.assistantId,\n      functionUrl: data.functionUrl,\n      model: data.model,\n      systemMessages: data.systemMessages,\n      assistantMessages: data.assistantMessages,\n      userMessages: data.userMessages,\n      maxTokens: data.maxTokens,\n    };\n  }\n\n  // Implementation for bot-specific duplicate validation on update\n  protected async validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: OpenaiDto): Promise<void> {\n    let whereDuplication: any = {\n      id: {\n        not: botId,\n      },\n      instanceId: instanceId,\n    };\n\n    if (data.botType === 'assistant') {\n      if (!data.assistantId) throw new Error('Assistant ID is required');\n\n      whereDuplication = {\n        ...whereDuplication,\n        assistantId: data.assistantId,\n        botType: data.botType,\n      };\n    } else if (data.botType === 'chatCompletion') {\n      if (!data.model) throw new Error('Model is required');\n      if (!data.maxTokens) throw new Error('Max tokens is required');\n\n      whereDuplication = {\n        ...whereDuplication,\n        model: data.model,\n        maxTokens: data.maxTokens,\n        botType: data.botType,\n      };\n    } else {\n      throw new Error('Bot type is required');\n    }\n\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: whereDuplication,\n    });\n\n    if (checkDuplicate) {\n      throw new Error('OpenAI Bot already exists');\n    }\n  }\n\n  // Override createBot to handle OpenAI-specific credential logic\n  public async createBot(instance: InstanceDto, data: OpenaiDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('Openai is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    // OpenAI specific validation\n    let whereDuplication: any = {\n      instanceId: instanceId,\n    };\n\n    if (data.botType === 'assistant') {\n      if (!data.assistantId) throw new Error('Assistant ID is required');\n\n      whereDuplication = {\n        ...whereDuplication,\n        assistantId: data.assistantId,\n        botType: data.botType,\n      };\n    } else if (data.botType === 'chatCompletion') {\n      if (!data.model) throw new Error('Model is required');\n      if (!data.maxTokens) throw new Error('Max tokens is required');\n\n      whereDuplication = {\n        ...whereDuplication,\n        model: data.model,\n        maxTokens: data.maxTokens,\n        botType: data.botType,\n      };\n    } else {\n      throw new Error('Bot type is required');\n    }\n\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: whereDuplication,\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Openai Bot already exists');\n    }\n\n    // Check if settings exist and create them if not\n    const existingSettings = await this.settingsRepository.findFirst({\n      where: {\n        instanceId: instanceId,\n      },\n    });\n\n    if (!existingSettings) {\n      // Create default settings with the OpenAI credentials\n      await this.settings(instance, {\n        openaiCredsId: data.openaiCredsId,\n        expire: data.expire || 300,\n        keywordFinish: data.keywordFinish || 'bye',\n        delayMessage: data.delayMessage || 1000,\n        unknownMessage: data.unknownMessage || 'Sorry, I dont understand',\n        listeningFromMe: data.listeningFromMe !== undefined ? data.listeningFromMe : true,\n        stopBotFromMe: data.stopBotFromMe !== undefined ? data.stopBotFromMe : true,\n        keepOpen: data.keepOpen !== undefined ? data.keepOpen : false,\n        debounceTime: data.debounceTime || 1,\n        ignoreJids: data.ignoreJids || [],\n        speechToText: false,\n      });\n    } else if (!existingSettings.openaiCredsId && data.openaiCredsId) {\n      // Update settings with OpenAI credentials if they're missing\n      await this.settingsRepository.update({\n        where: {\n          id: existingSettings.id,\n        },\n        data: {\n          OpenaiCreds: {\n            connect: {\n              id: data.openaiCredsId,\n            },\n          },\n        },\n      });\n    }\n\n    // Let the base class handle the rest of the bot creation process\n    return super.createBot(instance, data);\n  }\n\n  // Process OpenAI-specific bot logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: OpenaiBot,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    await this.openaiService.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n\n  // Credentials - OpenAI specific functionality\n  public async createOpenaiCreds(instance: InstanceDto, data: OpenaiCredsDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('Openai is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    if (!data.apiKey) throw new BadRequestException('API Key is required');\n    if (!data.name) throw new BadRequestException('Name is required');\n\n    // Check if API key already exists\n    const existingApiKey = await this.credsRepository.findFirst({\n      where: {\n        apiKey: data.apiKey,\n      },\n    });\n\n    if (existingApiKey) {\n      throw new BadRequestException('This API key is already registered. Please use a different API key.');\n    }\n\n    // Check if name already exists for this instance\n    const existingName = await this.credsRepository.findFirst({\n      where: {\n        name: data.name,\n        instanceId: instanceId,\n      },\n    });\n\n    if (existingName) {\n      throw new BadRequestException('This credential name is already in use. Please choose a different name.');\n    }\n\n    try {\n      const creds = await this.credsRepository.create({\n        data: {\n          name: data.name,\n          apiKey: data.apiKey,\n          instanceId: instanceId,\n        },\n      });\n\n      return creds;\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error creating openai creds');\n    }\n  }\n\n  public async findOpenaiCreds(instance: InstanceDto) {\n    if (!this.integrationEnabled) throw new BadRequestException('Openai is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    const creds = await this.credsRepository.findMany({\n      where: {\n        instanceId: instanceId,\n      },\n      include: {\n        OpenaiAssistant: true,\n      },\n    });\n\n    return creds;\n  }\n\n  public async deleteCreds(instance: InstanceDto, openaiCredsId: string) {\n    if (!this.integrationEnabled) throw new BadRequestException('Openai is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    const creds = await this.credsRepository.findFirst({\n      where: {\n        id: openaiCredsId,\n      },\n    });\n\n    if (!creds) {\n      throw new Error('Openai Creds not found');\n    }\n\n    if (creds.instanceId !== instanceId) {\n      throw new Error('Openai Creds not found');\n    }\n\n    try {\n      await this.credsRepository.delete({\n        where: {\n          id: openaiCredsId,\n        },\n      });\n\n      return { openaiCreds: { id: openaiCredsId } };\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error deleting openai creds');\n    }\n  }\n\n  // Override the settings method to handle the OpenAI credentials\n  public async settings(instance: InstanceDto, data: any) {\n    if (!this.integrationEnabled) throw new BadRequestException('Openai is disabled');\n\n    try {\n      const instanceId = await this.prismaRepository.instance\n        .findFirst({\n          where: {\n            name: instance.instanceName,\n          },\n        })\n        .then((instance) => instance.id);\n\n      const existingSettings = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instanceId,\n        },\n      });\n\n      // Convert keywordFinish to string if it's an array\n      const keywordFinish = data.keywordFinish;\n\n      // Additional OpenAI-specific fields\n      const settingsData = {\n        expire: data.expire,\n        keywordFinish,\n        delayMessage: data.delayMessage,\n        unknownMessage: data.unknownMessage,\n        listeningFromMe: data.listeningFromMe,\n        stopBotFromMe: data.stopBotFromMe,\n        keepOpen: data.keepOpen,\n        debounceTime: data.debounceTime,\n        ignoreJids: data.ignoreJids,\n        splitMessages: data.splitMessages,\n        timePerChar: data.timePerChar,\n        openaiIdFallback: data.fallbackId,\n        OpenaiCreds: data.openaiCredsId\n          ? {\n              connect: {\n                id: data.openaiCredsId,\n              },\n            }\n          : undefined,\n        speechToText: data.speechToText,\n      };\n\n      if (existingSettings) {\n        const settings = await this.settingsRepository.update({\n          where: {\n            id: existingSettings.id,\n          },\n          data: settingsData,\n        });\n\n        // Map the specific fallback field to a generic 'fallbackId' in the response\n        return {\n          ...settings,\n          fallbackId: settings.openaiIdFallback,\n        };\n      } else {\n        const settings = await this.settingsRepository.create({\n          data: {\n            ...settingsData,\n            Instance: {\n              connect: {\n                id: instanceId,\n              },\n            },\n          },\n        });\n\n        // Map the specific fallback field to a generic 'fallbackId' in the response\n        return {\n          ...settings,\n          fallbackId: settings.openaiIdFallback,\n        };\n      }\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error setting default settings');\n    }\n  }\n\n  // Models - OpenAI specific functionality\n  public async getModels(instance: InstanceDto, openaiCredsId?: string) {\n    if (!this.integrationEnabled) throw new BadRequestException('Openai is disabled');\n\n    const instanceId = await this.prismaRepository.instance\n      .findFirst({\n        where: {\n          name: instance.instanceName,\n        },\n      })\n      .then((instance) => instance.id);\n\n    if (!instanceId) throw new Error('Instance not found');\n\n    let apiKey: string;\n\n    if (openaiCredsId) {\n      // Use specific credential ID if provided\n      const creds = await this.credsRepository.findFirst({\n        where: {\n          id: openaiCredsId,\n          instanceId: instanceId, // Ensure the credential belongs to this instance\n        },\n      });\n\n      if (!creds) throw new Error('OpenAI credentials not found for the provided ID');\n\n      apiKey = creds.apiKey;\n    } else {\n      // Use default credentials from settings if no ID provided\n      const defaultSettings = await this.settingsRepository.findFirst({\n        where: {\n          instanceId: instanceId,\n        },\n        include: {\n          OpenaiCreds: true,\n        },\n      });\n\n      if (!defaultSettings) throw new Error('Settings not found');\n\n      if (!defaultSettings.OpenaiCreds)\n        throw new Error(\n          'OpenAI credentials not found. Please create credentials and associate them with the settings.',\n        );\n\n      apiKey = defaultSettings.OpenaiCreds.apiKey;\n    }\n\n    try {\n      this.client = new OpenAI({ apiKey });\n\n      const models: any = await this.client.models.list();\n\n      return models?.body?.data;\n    } catch (error) {\n      this.logger.error(error);\n      throw new Error('Error fetching models');\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/openai/dto/openai.dto.ts",
    "content": "import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class OpenaiCredsDto {\n  name: string;\n  apiKey: string;\n}\n\nexport class OpenaiDto extends BaseChatbotDto {\n  openaiCredsId: string;\n  botType: string;\n  assistantId?: string;\n  functionUrl?: string;\n  model?: string;\n  systemMessages?: string[];\n  assistantMessages?: string[];\n  userMessages?: string[];\n  maxTokens?: number;\n}\n\nexport class OpenaiSettingDto extends BaseChatbotSettingDto {\n  openaiCredsId?: string;\n  openaiIdFallback?: string;\n  speechToText?: boolean;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/openai/routes/openai.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { OpenaiCredsDto, OpenaiDto, OpenaiSettingDto } from '@api/integrations/chatbot/openai/dto/openai.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { openaiController } from '@api/server.module';\nimport {\n  instanceSchema,\n  openaiCredsSchema,\n  openaiIgnoreJidSchema,\n  openaiSchema,\n  openaiSettingSchema,\n  openaiStatusSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class OpenaiRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('creds'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<OpenaiCredsDto>({\n          request: req,\n          schema: openaiCredsSchema,\n          ClassRef: OpenaiCredsDto,\n          execute: (instance, data) => openaiController.createOpenaiCreds(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('creds'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.findOpenaiCreds(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('creds/:openaiCredsId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.deleteCreds(instance, req.params.openaiCredsId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<OpenaiDto>({\n          request: req,\n          schema: openaiSchema,\n          ClassRef: OpenaiDto,\n          execute: (instance, data) => openaiController.createBot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.findBot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:openaiBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.fetchBot(instance, req.params.openaiBotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:openaiBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<OpenaiDto>({\n          request: req,\n          schema: openaiSchema,\n          ClassRef: OpenaiDto,\n          execute: (instance, data) => openaiController.updateBot(instance, req.params.openaiBotId, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:openaiBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.deleteBot(instance, req.params.openaiBotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<OpenaiSettingDto>({\n          request: req,\n          schema: openaiSettingSchema,\n          ClassRef: OpenaiSettingDto,\n          execute: (instance, data) => openaiController.settings(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.fetchSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: openaiStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => openaiController.changeStatus(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:openaiBotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.fetchSessions(instance, req.params.openaiBotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: openaiIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => openaiController.ignoreJid(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('getModels'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => openaiController.getModels(instance, req.query.openaiCredsId as string),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/openai/services/openai.service.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Integration } from '@api/types/wa.types';\nimport { ConfigService, Language, Openai as OpenaiConfig } from '@config/env.config';\nimport { IntegrationSession, OpenaiBot, OpenaiSetting } from '@prisma/client';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\nimport { downloadMediaMessage } from 'baileys';\nimport { isURL } from 'class-validator';\nimport FormData from 'form-data';\nimport OpenAI from 'openai';\nimport P from 'pino';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\n\n/**\n * OpenAI service that extends the common BaseChatbotService\n * Handles both Assistant API and ChatCompletion API\n */\nexport class OpenaiService extends BaseChatbotService<OpenaiBot, OpenaiSetting> {\n  protected client: OpenAI;\n\n  constructor(waMonitor: WAMonitoringService, prismaRepository: PrismaRepository, configService: ConfigService) {\n    super(waMonitor, prismaRepository, 'OpenaiService', configService);\n  }\n\n  /**\n   * Return the bot type for OpenAI\n   */\n  protected getBotType(): string {\n    return 'openai';\n  }\n\n  /**\n   * Initialize the OpenAI client with the provided API key\n   */\n  protected initClient(apiKey: string) {\n    this.client = new OpenAI({ apiKey });\n    return this.client;\n  }\n\n  /**\n   * Process a message based on the bot type (assistant or chat completion)\n   */\n  public async process(\n    instance: any,\n    remoteJid: string,\n    openaiBot: OpenaiBot,\n    session: IntegrationSession,\n    settings: OpenaiSetting,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void> {\n    try {\n      this.logger.log(`Starting process for remoteJid: ${remoteJid}, bot type: ${openaiBot.botType}`);\n\n      // Handle audio message transcription\n      if (content.startsWith('audioMessage|') && msg) {\n        this.logger.log('Detected audio message, attempting to transcribe');\n\n        // Get OpenAI credentials for transcription\n        const creds = await this.prismaRepository.openaiCreds.findUnique({\n          where: { id: openaiBot.openaiCredsId },\n        });\n\n        if (!creds) {\n          this.logger.error(`OpenAI credentials not found. CredsId: ${openaiBot.openaiCredsId}`);\n          return;\n        }\n\n        // Initialize OpenAI client for transcription\n        this.initClient(creds.apiKey);\n\n        // Transcribe the audio\n        const transcription = await this.speechToText(msg, instance);\n\n        if (transcription) {\n          this.logger.log(`Audio transcribed: ${transcription}`);\n          // Replace the audio message identifier with the transcription\n          content = transcription;\n        } else {\n          this.logger.error('Failed to transcribe audio');\n          await this.sendMessageWhatsApp(\n            instance,\n            remoteJid,\n            \"Sorry, I couldn't transcribe your audio message. Could you please type your message instead?\",\n            settings,\n            true,\n          );\n          return;\n        }\n      } else {\n        // Get the OpenAI credentials\n        const creds = await this.prismaRepository.openaiCreds.findUnique({\n          where: { id: openaiBot.openaiCredsId },\n        });\n\n        if (!creds) {\n          this.logger.error(`OpenAI credentials not found. CredsId: ${openaiBot.openaiCredsId}`);\n          return;\n        }\n\n        // Initialize OpenAI client\n        this.initClient(creds.apiKey);\n      }\n\n      // Handle keyword finish\n      const keywordFinish = settings?.keywordFinish || '';\n      const normalizedContent = content.toLowerCase().trim();\n      if (keywordFinish.length > 0 && normalizedContent === keywordFinish.toLowerCase()) {\n        if (settings?.keepOpen) {\n          await this.prismaRepository.integrationSession.update({\n            where: {\n              id: session.id,\n            },\n            data: {\n              status: 'closed',\n            },\n          });\n        } else {\n          await this.prismaRepository.integrationSession.delete({\n            where: {\n              id: session.id,\n            },\n          });\n        }\n\n        await sendTelemetry('/openai/session/finish');\n        return;\n      }\n\n      // If session is new or doesn't exist\n      if (!session) {\n        const data = {\n          remoteJid,\n          pushName,\n          botId: openaiBot.id,\n        };\n\n        const createSession = await this.createNewSession(\n          { instanceName: instance.instanceName, instanceId: instance.instanceId },\n          data,\n          this.getBotType(),\n        );\n\n        await this.initNewSession(\n          instance,\n          remoteJid,\n          openaiBot,\n          settings,\n          createSession.session,\n          content,\n          pushName,\n          msg,\n        );\n\n        await sendTelemetry('/openai/session/start');\n        return;\n      }\n\n      // If session exists but is paused\n      if (session.status === 'paused') {\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'opened',\n            awaitUser: true,\n          },\n        });\n\n        return;\n      }\n\n      // Process with the appropriate API based on bot type\n      await this.sendMessageToBot(instance, session, settings, openaiBot, remoteJid, pushName || '', content, msg);\n    } catch (error) {\n      this.logger.error(`Error in process: ${error.message || JSON.stringify(error)}`);\n      return;\n    }\n  }\n\n  /**\n   * Send message to OpenAI - this handles both Assistant API and ChatCompletion API\n   */\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: OpenaiSetting,\n    openaiBot: OpenaiBot,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    this.logger.log(`Sending message to bot for remoteJid: ${remoteJid}, bot type: ${openaiBot.botType}`);\n\n    if (!this.client) {\n      this.logger.log('Client not initialized, initializing now');\n      const creds = await this.prismaRepository.openaiCreds.findUnique({\n        where: { id: openaiBot.openaiCredsId },\n      });\n\n      if (!creds) {\n        this.logger.error(`OpenAI credentials not found in sendMessageToBot. CredsId: ${openaiBot.openaiCredsId}`);\n        return;\n      }\n\n      this.initClient(creds.apiKey);\n    }\n\n    try {\n      let message: string;\n\n      // Handle different bot types\n      if (openaiBot.botType === 'assistant') {\n        this.logger.log('Processing with Assistant API');\n        message = await this.processAssistantMessage(\n          instance,\n          session,\n          openaiBot,\n          remoteJid,\n          pushName,\n          false, // Not fromMe\n          content,\n          msg,\n        );\n      } else {\n        this.logger.log('Processing with ChatCompletion API');\n        message = await this.processChatCompletionMessage(instance, openaiBot, remoteJid, content, msg);\n      }\n\n      this.logger.log(`Got response from OpenAI: ${message?.substring(0, 50)}${message?.length > 50 ? '...' : ''}`);\n\n      // Send the response\n      if (message) {\n        this.logger.log('Sending message to WhatsApp');\n        await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);\n      } else {\n        this.logger.error('No message to send to WhatsApp');\n      }\n\n      // Update session status\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          status: 'opened',\n          awaitUser: true,\n        },\n      });\n    } catch (error) {\n      this.logger.error(`Error in sendMessageToBot: ${error.message || JSON.stringify(error)}`);\n      if (error.response) {\n        this.logger.error(`API Response data: ${JSON.stringify(error.response.data || {})}`);\n      }\n      return;\n    }\n  }\n\n  /**\n   * Process message using the OpenAI Assistant API\n   */\n  private async processAssistantMessage(\n    instance: any,\n    session: IntegrationSession,\n    openaiBot: OpenaiBot,\n    remoteJid: string,\n    pushName: string,\n    fromMe: boolean,\n    content: string,\n    msg?: any,\n  ): Promise<string> {\n    const messageData: any = {\n      role: fromMe ? 'assistant' : 'user',\n      content: [{ type: 'text', text: content }],\n    };\n\n    // Handle image messages\n    if (this.isImageMessage(content)) {\n      const media = content.split('|');\n\n      if (msg.message.mediaUrl || msg.message.base64) {\n        let mediaBase64 = msg.message.base64 || null;\n\n        if (msg.message.mediaUrl && isURL(msg.message.mediaUrl)) {\n          const result = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' });\n          mediaBase64 = Buffer.from(result.data).toString('base64');\n        }\n\n        if (mediaBase64) {\n          messageData.content = [\n            { type: 'text', text: media[2] || content },\n            { type: 'image_url', image_url: { url: mediaBase64 } },\n          ];\n        }\n      } else {\n        const url = media[1].split('?')[0];\n\n        messageData.content = [\n          { type: 'text', text: media[2] || content },\n          {\n            type: 'image_url',\n            image_url: {\n              url: url,\n            },\n          },\n        ];\n      }\n    }\n\n    // Get thread ID from session or create new thread\n    let threadId = session.sessionId;\n\n    // Create a new thread if one doesn't exist or invalid format\n    if (!threadId || threadId === remoteJid) {\n      const newThread = await this.client.beta.threads.create();\n      threadId = newThread.id;\n\n      // Save the new thread ID to the session\n      await this.prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          sessionId: threadId,\n        },\n      });\n      this.logger.log(`Created new thread ID: ${threadId} for session: ${session.id}`);\n    }\n\n    // Add message to thread\n    await this.client.beta.threads.messages.create(threadId, messageData);\n\n    if (fromMe) {\n      sendTelemetry('/message/sendText');\n      return '';\n    }\n\n    // Run the assistant\n    const runAssistant = await this.client.beta.threads.runs.create(threadId, {\n      assistant_id: openaiBot.assistantId,\n    });\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    // Wait for the assistant to complete\n    const response = await this.getAIResponse(threadId, runAssistant.id, openaiBot.functionUrl, remoteJid, pushName);\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      await instance.client.sendPresenceUpdate('paused', remoteJid);\n    }\n\n    // Extract the response text safely with type checking\n    let responseText = \"I couldn't generate a proper response. Please try again.\";\n    try {\n      const messages = response?.data || [];\n      if (messages.length > 0) {\n        const messageContent = messages[0]?.content || [];\n        if (messageContent.length > 0) {\n          const textContent = messageContent[0];\n          if (textContent && 'text' in textContent && textContent.text && 'value' in textContent.text) {\n            responseText = textContent.text.value;\n          }\n        }\n      }\n    } catch (error) {\n      this.logger.error(`Error extracting response text: ${error}`);\n    }\n\n    // Update session with the thread ID to ensure continuity\n    await this.prismaRepository.integrationSession.update({\n      where: {\n        id: session.id,\n      },\n      data: {\n        status: 'opened',\n        awaitUser: true,\n        sessionId: threadId, // Ensure thread ID is saved consistently\n      },\n    });\n\n    // Return fallback message if unable to extract text\n    return responseText;\n  }\n\n  /**\n   * Process message using the OpenAI ChatCompletion API\n   */\n  private async processChatCompletionMessage(\n    instance: any,\n    openaiBot: OpenaiBot,\n    remoteJid: string,\n    content: string,\n    msg?: any,\n  ): Promise<string> {\n    this.logger.log('Starting processChatCompletionMessage');\n\n    // Check if client is initialized\n    if (!this.client) {\n      this.logger.log('Client not initialized in processChatCompletionMessage, initializing now');\n      const creds = await this.prismaRepository.openaiCreds.findUnique({\n        where: { id: openaiBot.openaiCredsId },\n      });\n\n      if (!creds) {\n        this.logger.error(`OpenAI credentials not found. CredsId: ${openaiBot.openaiCredsId}`);\n        return 'Error: OpenAI credentials not found';\n      }\n\n      this.initClient(creds.apiKey);\n    }\n\n    // Check if model is defined\n    if (!openaiBot.model) {\n      this.logger.error('OpenAI model not defined');\n      return 'Error: OpenAI model not configured';\n    }\n\n    this.logger.log(`Using model: ${openaiBot.model}, max tokens: ${openaiBot.maxTokens || 500}`);\n\n    // Get existing conversation history from the session\n    const session = await this.prismaRepository.integrationSession.findFirst({\n      where: {\n        remoteJid,\n        botId: openaiBot.id,\n        status: 'opened',\n      },\n    });\n\n    let conversationHistory = [];\n\n    if (session && session.context) {\n      try {\n        const sessionData =\n          typeof session.context === 'string' ? JSON.parse(session.context as string) : session.context;\n\n        conversationHistory = sessionData.history || [];\n        this.logger.log(`Retrieved conversation history from session, ${conversationHistory.length} messages`);\n      } catch (error) {\n        this.logger.error(`Error parsing session context: ${error.message}`);\n        // Continue with empty history if we can't parse the session data\n        conversationHistory = [];\n      }\n    }\n\n    // Log bot data\n    this.logger.log(`Bot data - systemMessages: ${JSON.stringify(openaiBot.systemMessages || [])}`);\n    this.logger.log(`Bot data - assistantMessages: ${JSON.stringify(openaiBot.assistantMessages || [])}`);\n    this.logger.log(`Bot data - userMessages: ${JSON.stringify(openaiBot.userMessages || [])}`);\n\n    // Prepare system messages\n    const systemMessages: any = openaiBot.systemMessages || [];\n    const messagesSystem: any[] = systemMessages.map((message) => {\n      return {\n        role: 'system',\n        content: message,\n      };\n    });\n\n    // Prepare assistant messages\n    const assistantMessages: any = openaiBot.assistantMessages || [];\n    const messagesAssistant: any[] = assistantMessages.map((message) => {\n      return {\n        role: 'assistant',\n        content: message,\n      };\n    });\n\n    // Prepare user messages\n    const userMessages: any = openaiBot.userMessages || [];\n    const messagesUser: any[] = userMessages.map((message) => {\n      return {\n        role: 'user',\n        content: message,\n      };\n    });\n\n    // Prepare current message\n    const messageData: any = {\n      role: 'user',\n      content: [{ type: 'text', text: content }],\n    };\n\n    // Handle image messages\n    if (this.isImageMessage(content)) {\n      this.logger.log('Found image message');\n      const media = content.split('|');\n\n      if (msg.message.mediaUrl || msg.message.base64) {\n        messageData.content = [\n          { type: 'text', text: media[2] || content },\n          { type: 'image_url', image_url: { url: msg.message.base64 || msg.message.mediaUrl } },\n        ];\n      } else {\n        const url = media[1].split('?')[0];\n\n        messageData.content = [\n          { type: 'text', text: media[2] || content },\n          {\n            type: 'image_url',\n            image_url: {\n              url: url,\n            },\n          },\n        ];\n      }\n    }\n\n    // Combine all messages: system messages, pre-defined messages, conversation history, and current message\n    const messages: any[] = [\n      ...messagesSystem,\n      ...messagesAssistant,\n      ...messagesUser,\n      ...conversationHistory,\n      messageData,\n    ];\n\n    this.logger.log(`Final messages payload: ${JSON.stringify(messages)}`);\n\n    if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n      this.logger.log('Setting typing indicator');\n      await instance.client.presenceSubscribe(remoteJid);\n      await instance.client.sendPresenceUpdate('composing', remoteJid);\n    }\n\n    // Send the request to OpenAI\n    try {\n      this.logger.log('Sending request to OpenAI API');\n      const completions = await this.client.chat.completions.create({\n        model: openaiBot.model,\n        messages: messages,\n        max_tokens: openaiBot.maxTokens || 500, // Add default if maxTokens is missing\n      });\n\n      if (instance.integration === Integration.WHATSAPP_BAILEYS) {\n        await instance.client.sendPresenceUpdate('paused', remoteJid);\n      }\n\n      const responseContent = completions.choices[0].message.content;\n      this.logger.log(`Received response from OpenAI: ${JSON.stringify(completions.choices[0])}`);\n\n      // Add the current exchange to the conversation history and update the session\n      conversationHistory.push(messageData);\n      conversationHistory.push({\n        role: 'assistant',\n        content: responseContent,\n      });\n\n      // Limit history length to avoid token limits (keep last 10 messages)\n      if (conversationHistory.length > 10) {\n        conversationHistory = conversationHistory.slice(conversationHistory.length - 10);\n      }\n\n      // Save the updated conversation history to the session\n      if (session) {\n        await this.prismaRepository.integrationSession.update({\n          where: { id: session.id },\n          data: {\n            context: JSON.stringify({\n              history: conversationHistory,\n            }),\n          },\n        });\n        this.logger.log(`Updated session with conversation history, now ${conversationHistory.length} messages`);\n      }\n\n      return responseContent;\n    } catch (error) {\n      this.logger.error(`Error calling OpenAI: ${error.message || JSON.stringify(error)}`);\n      if (error.response) {\n        this.logger.error(`API Response status: ${error.response.status}`);\n        this.logger.error(`API Response data: ${JSON.stringify(error.response.data || {})}`);\n      }\n      return `Sorry, there was an error: ${error.message || 'Unknown error'}`;\n    }\n  }\n\n  /**\n   * Wait for and retrieve the AI response\n   */\n  private async getAIResponse(\n    threadId: string,\n    runId: string,\n    functionUrl: string | null,\n    remoteJid: string,\n    pushName: string,\n  ) {\n    let status = await this.client.beta.threads.runs.retrieve(threadId, runId);\n\n    let maxRetries = 60; // 1 minute with 1s intervals\n    const checkInterval = 1000; // 1 second\n\n    while (\n      status.status !== 'completed' &&\n      status.status !== 'failed' &&\n      status.status !== 'cancelled' &&\n      status.status !== 'expired' &&\n      maxRetries > 0\n    ) {\n      await new Promise((resolve) => setTimeout(resolve, checkInterval));\n      status = await this.client.beta.threads.runs.retrieve(threadId, runId);\n\n      // Handle tool calls\n      if (status.status === 'requires_action' && status.required_action?.type === 'submit_tool_outputs') {\n        const toolCalls = status.required_action.submit_tool_outputs.tool_calls;\n        const toolOutputs = [];\n\n        for (const toolCall of toolCalls) {\n          if (functionUrl) {\n            try {\n              const payloadData = JSON.parse(toolCall.function.arguments);\n\n              // Add context\n              payloadData.remoteJid = remoteJid;\n              payloadData.pushName = pushName;\n\n              const response = await axios.post(functionUrl, {\n                functionName: toolCall.function.name,\n                functionArguments: payloadData,\n              });\n\n              toolOutputs.push({\n                tool_call_id: toolCall.id,\n                output: JSON.stringify(response.data),\n              });\n            } catch (error) {\n              this.logger.error(`Error calling function: ${error}`);\n              toolOutputs.push({\n                tool_call_id: toolCall.id,\n                output: JSON.stringify({ error: 'Function call failed' }),\n              });\n            }\n          } else {\n            toolOutputs.push({\n              tool_call_id: toolCall.id,\n              output: JSON.stringify({ error: 'No function URL configured' }),\n            });\n          }\n        }\n\n        await this.client.beta.threads.runs.submitToolOutputs(threadId, runId, {\n          tool_outputs: toolOutputs,\n        });\n      }\n\n      maxRetries--;\n    }\n\n    if (status.status === 'completed') {\n      const messages = await this.client.beta.threads.messages.list(threadId);\n      return messages;\n    } else {\n      this.logger.error(`Assistant run failed with status: ${status.status}`);\n      return { data: [{ content: [{ text: { value: 'Failed to get a response from the assistant.' } }] }] };\n    }\n  }\n\n  protected isImageMessage(content: string): boolean {\n    return content.includes('imageMessage');\n  }\n\n  /**\n   * Implementation of speech-to-text transcription for audio messages\n   */\n  public async speechToText(msg: any, instance: any): Promise<string | null> {\n    const settings = await this.prismaRepository.openaiSetting.findFirst({\n      where: {\n        instanceId: instance.instanceId,\n      },\n    });\n\n    if (!settings) {\n      this.logger.error(`OpenAI settings not found. InstanceId: ${instance.instanceId}`);\n      return null;\n    }\n\n    const creds = await this.prismaRepository.openaiCreds.findUnique({\n      where: { id: settings.openaiCredsId },\n    });\n\n    if (!creds) {\n      this.logger.error(`OpenAI credentials not found. CredsId: ${settings.openaiCredsId}`);\n      return null;\n    }\n\n    let audio: Buffer;\n\n    if (msg.message.mediaUrl) {\n      audio = await axios.get(msg.message.mediaUrl, { responseType: 'arraybuffer' }).then((response) => {\n        return Buffer.from(response.data, 'binary');\n      });\n    } else if (msg.message.base64) {\n      audio = Buffer.from(msg.message.base64, 'base64');\n    } else {\n      // Fallback for raw WhatsApp audio messages that need downloadMediaMessage\n      audio = await downloadMediaMessage(\n        { key: msg.key, message: msg?.message },\n        'buffer',\n        {},\n        {\n          logger: P({ level: 'error' }) as any,\n          reuploadRequest: instance,\n        },\n      );\n    }\n\n    const lang = this.configService.get<Language>('LANGUAGE').includes('pt')\n      ? 'pt'\n      : this.configService.get<Language>('LANGUAGE');\n\n    const formData = new FormData();\n    formData.append('file', audio, 'audio.ogg');\n    formData.append('model', 'whisper-1');\n    formData.append('language', lang);\n\n    const apiKey = creds?.apiKey || this.configService.get<OpenaiConfig>('OPENAI').API_KEY_GLOBAL;\n\n    const response = await axios.post('https://api.openai.com/v1/audio/transcriptions', formData, {\n      headers: {\n        'Content-Type': 'multipart/form-data',\n        Authorization: `Bearer ${apiKey}`,\n      },\n    });\n\n    return response?.data?.text;\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/openai/validate/openai.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const openaiSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    openaiCredsId: { type: 'string' },\n    botType: { type: 'string', enum: ['assistant', 'chatCompletion'] },\n    assistantId: { type: 'string' },\n    functionUrl: { type: 'string' },\n    model: { type: 'string' },\n    systemMessages: { type: 'array', items: { type: 'string' } },\n    assistantMessages: { type: 'array', items: { type: 'string' } },\n    userMessages: { type: 'array', items: { type: 'string' } },\n    maxTokens: { type: 'integer' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n  },\n  required: ['enabled', 'openaiCredsId', 'botType', 'triggerType'],\n  ...isNotEmpty('enabled', 'openaiCredsId', 'botType', 'triggerType'),\n};\n\nexport const openaiCredsSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    name: { type: 'string' },\n    apiKey: { type: 'string' },\n  },\n  required: ['name', 'apiKey'],\n  ...isNotEmpty('name', 'apiKey'),\n};\n\nexport const openaiStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const openaiSettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    openaiCredsId: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    speechToText: { type: 'boolean' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n    openaiIdFallback: { type: 'string' },\n  },\n  required: [\n    'openaiCredsId',\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n  ],\n  ...isNotEmpty(\n    'openaiCredsId',\n    'expire',\n    'keywordFinish',\n    'delayMessage',\n    'unknownMessage',\n    'listeningFromMe',\n    'stopBotFromMe',\n    'keepOpen',\n    'debounceTime',\n    'ignoreJids',\n  ),\n};\n\nexport const openaiIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/chatbot/typebot/controllers/typebot.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { TypebotDto } from '@api/integrations/chatbot/typebot/dto/typebot.dto';\nimport { TypebotService } from '@api/integrations/chatbot/typebot/services/typebot.service';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Events } from '@api/types/wa.types';\nimport { configService, Typebot } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport { IntegrationSession, Typebot as TypebotModel } from '@prisma/client';\nimport axios from 'axios';\n\nimport { BaseChatbotController } from '../../base-chatbot.controller';\n\nexport class TypebotController extends BaseChatbotController<TypebotModel, TypebotDto> {\n  constructor(\n    private readonly typebotService: TypebotService,\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n  ) {\n    super(prismaRepository, waMonitor);\n\n    this.botRepository = this.prismaRepository.typebot;\n    this.settingsRepository = this.prismaRepository.typebotSetting;\n    this.sessionRepository = this.prismaRepository.integrationSession;\n  }\n\n  public readonly logger = new Logger('TypebotController');\n  protected readonly integrationName = 'Typebot';\n\n  integrationEnabled = configService.get<Typebot>('TYPEBOT').ENABLED;\n  botRepository: any;\n  settingsRepository: any;\n  sessionRepository: any;\n  userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};\n\n  protected getFallbackBotId(settings: any): string | undefined {\n    return settings?.typebotIdFallback;\n  }\n\n  protected getFallbackFieldName(): string {\n    return 'typebotIdFallback';\n  }\n\n  protected getIntegrationType(): string {\n    return 'typebot';\n  }\n\n  protected getAdditionalBotData(data: TypebotDto): Record<string, any> {\n    return {\n      url: data.url,\n      typebot: data.typebot,\n    };\n  }\n\n  // Implementation for bot-specific updates\n  protected getAdditionalUpdateFields(data: TypebotDto): Record<string, any> {\n    return {\n      url: data.url,\n      typebot: data.typebot,\n    };\n  }\n\n  // Implementation for bot-specific duplicate validation on update\n  protected async validateNoDuplicatesOnUpdate(botId: string, instanceId: string, data: TypebotDto): Promise<void> {\n    const checkDuplicate = await this.botRepository.findFirst({\n      where: {\n        url: data.url,\n        typebot: data.typebot,\n        id: {\n          not: botId,\n        },\n        instanceId: instanceId,\n      },\n    });\n\n    if (checkDuplicate) {\n      throw new Error('Typebot already exists');\n    }\n  }\n\n  // Process Typebot-specific bot logic\n  protected async processBot(\n    instance: any,\n    remoteJid: string,\n    bot: TypebotModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ) {\n    // Map to the original processTypebot method signature\n    await this.typebotService.processTypebot(\n      instance,\n      remoteJid,\n      msg,\n      session,\n      bot,\n      bot.url,\n      settings.expire,\n      bot.typebot,\n      settings.keywordFinish,\n      settings.delayMessage,\n      settings.unknownMessage,\n      settings.listeningFromMe,\n      settings.stopBotFromMe,\n      settings.keepOpen,\n      content,\n      {}, // prefilledVariables (optional)\n    );\n  }\n\n  // TypeBot specific method for starting a bot from API\n  public async startBot(instance: InstanceDto, data: any) {\n    if (!this.integrationEnabled) throw new BadRequestException('Typebot is disabled');\n\n    if (data.remoteJid === 'status@broadcast') return;\n\n    const instanceData = await this.prismaRepository.instance.findFirst({\n      where: {\n        name: instance.instanceName,\n      },\n    });\n\n    if (!instanceData) throw new Error('Instance not found');\n\n    const remoteJid = data.remoteJid;\n    const url = data.url;\n    const typebot = data.typebot;\n    const startSession = data.startSession;\n    const variables = data.variables;\n    let expire = data?.typebot?.expire;\n    let keywordFinish = data?.typebot?.keywordFinish;\n    let delayMessage = data?.typebot?.delayMessage;\n    let unknownMessage = data?.typebot?.unknownMessage;\n    let listeningFromMe = data?.typebot?.listeningFromMe;\n    let stopBotFromMe = data?.typebot?.stopBotFromMe;\n    let keepOpen = data?.typebot?.keepOpen;\n    let debounceTime = data?.typebot?.debounceTime;\n    let ignoreJids = data?.typebot?.ignoreJids;\n\n    const defaultSettingCheck = await this.settingsRepository.findFirst({\n      where: {\n        instanceId: instanceData.id,\n      },\n    });\n\n    if (this.checkIgnoreJids(defaultSettingCheck?.ignoreJids, remoteJid)) throw new Error('Jid not allowed');\n\n    if (\n      !expire ||\n      !keywordFinish ||\n      !delayMessage ||\n      !unknownMessage ||\n      !listeningFromMe ||\n      !stopBotFromMe ||\n      !keepOpen ||\n      !debounceTime ||\n      !ignoreJids\n    ) {\n      if (expire === undefined || expire === null) expire = defaultSettingCheck.expire;\n      if (keywordFinish === undefined || keywordFinish === null) keywordFinish = defaultSettingCheck.keywordFinish;\n      if (delayMessage === undefined || delayMessage === null) delayMessage = defaultSettingCheck.delayMessage;\n      if (unknownMessage === undefined || unknownMessage === null) unknownMessage = defaultSettingCheck.unknownMessage;\n      if (listeningFromMe === undefined || listeningFromMe === null)\n        listeningFromMe = defaultSettingCheck.listeningFromMe;\n      if (stopBotFromMe === undefined || stopBotFromMe === null) stopBotFromMe = defaultSettingCheck.stopBotFromMe;\n      if (keepOpen === undefined || keepOpen === null) keepOpen = defaultSettingCheck.keepOpen;\n      if (debounceTime === undefined || debounceTime === null) debounceTime = defaultSettingCheck.debounceTime;\n      if (ignoreJids === undefined || ignoreJids === null) ignoreJids = defaultSettingCheck.ignoreJids;\n\n      if (!defaultSettingCheck) {\n        await this.settings(instance, {\n          expire: expire,\n          keywordFinish: keywordFinish,\n          delayMessage: delayMessage,\n          unknownMessage: unknownMessage,\n          listeningFromMe: listeningFromMe,\n          stopBotFromMe: stopBotFromMe,\n          keepOpen: keepOpen,\n          debounceTime: debounceTime,\n          ignoreJids: ignoreJids,\n        });\n      }\n    }\n\n    const prefilledVariables: any = {};\n\n    if (variables?.length) {\n      variables.forEach((variable: { name: string | number; value: string }) => {\n        prefilledVariables[variable.name] = variable.value;\n      });\n    }\n\n    if (startSession) {\n      let findBot: any = await this.botRepository.findFirst({\n        where: {\n          url: url,\n          typebot: typebot,\n          instanceId: instanceData.id,\n        },\n      });\n\n      if (!findBot) {\n        findBot = await this.botRepository.create({\n          data: {\n            enabled: true,\n            url: url,\n            typebot: typebot,\n            instanceId: instanceData.id,\n            expire: expire,\n            keywordFinish: keywordFinish,\n            delayMessage: delayMessage,\n            unknownMessage: unknownMessage,\n            listeningFromMe: listeningFromMe,\n            stopBotFromMe: stopBotFromMe,\n            keepOpen: keepOpen,\n          },\n        });\n      }\n\n      await this.prismaRepository.integrationSession.deleteMany({\n        where: {\n          remoteJid: remoteJid,\n          instanceId: instanceData.id,\n          botId: { not: null },\n        },\n      });\n\n      // Use the original processTypebot method with all parameters\n      await this.typebotService.processTypebot(\n        this.waMonitor.waInstances[instanceData.name],\n        remoteJid,\n        null, // msg\n        null, // session\n        findBot,\n        url,\n        expire,\n        typebot,\n        keywordFinish,\n        delayMessage,\n        unknownMessage,\n        listeningFromMe,\n        stopBotFromMe,\n        keepOpen,\n        'init',\n        prefilledVariables,\n      );\n    } else {\n      const id = Math.floor(Math.random() * 10000000000).toString();\n\n      try {\n        const version = configService.get<Typebot>('TYPEBOT').API_VERSION;\n        let url: string;\n        let reqData: {};\n        if (version === 'latest') {\n          url = `${data.url}/api/v1/typebots/${data.typebot}/startChat`;\n\n          reqData = {\n            prefilledVariables: prefilledVariables,\n          };\n        } else {\n          url = `${data.url}/api/v1/sendMessage`;\n\n          reqData = {\n            startParams: {\n              publicId: data.typebot,\n              prefilledVariables: prefilledVariables,\n            },\n          };\n        }\n        const request = await axios.post(url, reqData);\n\n        await this.typebotService.sendWAMessage(\n          instanceData,\n          null,\n          {\n            expire: expire,\n            keywordFinish: keywordFinish,\n            delayMessage: delayMessage,\n            unknownMessage: unknownMessage,\n            listeningFromMe: listeningFromMe,\n            stopBotFromMe: stopBotFromMe,\n            keepOpen: keepOpen,\n          },\n          remoteJid,\n          request.data.messages,\n          request.data.input,\n          request.data.clientSideActions,\n        );\n\n        this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.TYPEBOT_START, {\n          remoteJid: remoteJid,\n          url: url,\n          typebot: typebot,\n          variables: variables,\n          sessionId: id,\n        });\n      } catch (error) {\n        this.logger.error(error);\n        return;\n      }\n    }\n\n    return {\n      typebot: {\n        ...instance,\n        typebot: {\n          url: url,\n          remoteJid: remoteJid,\n          typebot: typebot,\n          prefilledVariables: prefilledVariables,\n        },\n      },\n    };\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/typebot/dto/typebot.dto.ts",
    "content": "import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';\n\nexport class PrefilledVariables {\n  remoteJid?: string;\n  pushName?: string;\n  messageType?: string;\n  additionalData?: { [key: string]: any };\n}\n\nexport class TypebotDto extends BaseChatbotDto {\n  url: string;\n  typebot: string;\n}\n\nexport class TypebotSettingDto extends BaseChatbotSettingDto {\n  typebotIdFallback?: string;\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/typebot/routes/typebot.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { IgnoreJidDto } from '@api/dto/chatbot.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { TypebotDto, TypebotSettingDto } from '@api/integrations/chatbot/typebot/dto/typebot.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { typebotController } from '@api/server.module';\nimport {\n  instanceSchema,\n  typebotIgnoreJidSchema,\n  typebotSchema,\n  typebotSettingSchema,\n  typebotStartSchema,\n  typebotStatusSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class TypebotRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<TypebotDto>({\n          request: req,\n          schema: typebotSchema,\n          ClassRef: TypebotDto,\n          execute: (instance, data) => typebotController.createBot(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => typebotController.findBot(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetch/:typebotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => typebotController.fetchBot(instance, req.params.typebotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .put(this.routerPath('update/:typebotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<TypebotDto>({\n          request: req,\n          schema: typebotSchema,\n          ClassRef: TypebotDto,\n          execute: (instance, data) => typebotController.updateBot(instance, req.params.typebotId, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete/:typebotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => typebotController.deleteBot(instance, req.params.typebotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('settings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<TypebotSettingDto>({\n          request: req,\n          schema: typebotSettingSchema,\n          ClassRef: TypebotSettingDto,\n          execute: (instance, data) => typebotController.settings(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => typebotController.fetchSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('start'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: typebotStartSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => typebotController.startBot(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('changeStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: typebotStatusSchema,\n          ClassRef: InstanceDto,\n          execute: (instance, data) => typebotController.changeStatus(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchSessions/:typebotId'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => typebotController.fetchSessions(instance, req.params.typebotId),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<IgnoreJidDto>({\n          request: req,\n          schema: typebotIgnoreJidSchema,\n          ClassRef: IgnoreJidDto,\n          execute: (instance, data) => typebotController.ignoreJid(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/typebot/services/typebot.service.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Events } from '@api/types/wa.types';\nimport { Auth, ConfigService, HttpServer, Typebot } from '@config/env.config';\nimport { Instance, IntegrationSession, Message, Typebot as TypebotModel } from '@prisma/client';\nimport { getConversationMessage } from '@utils/getConversationMessage';\nimport { sendTelemetry } from '@utils/sendTelemetry';\nimport axios from 'axios';\n\nimport { BaseChatbotService } from '../../base-chatbot.service';\nimport { OpenaiService } from '../../openai/services/openai.service';\n\nexport class TypebotService extends BaseChatbotService<TypebotModel, any> {\n  private openaiService: OpenaiService;\n\n  constructor(\n    waMonitor: WAMonitoringService,\n    configService: ConfigService,\n    prismaRepository: PrismaRepository,\n    openaiService: OpenaiService,\n  ) {\n    super(waMonitor, prismaRepository, 'TypebotService', configService);\n    this.openaiService = openaiService;\n  }\n\n  /**\n   * Get the bot type identifier\n   */\n  protected getBotType(): string {\n    return 'typebot';\n  }\n\n  /**\n   * Base class wrapper - calls the original processTypebot method\n   */\n  protected async sendMessageToBot(\n    instance: any,\n    session: IntegrationSession,\n    settings: any,\n    bot: TypebotModel,\n    remoteJid: string,\n    pushName: string,\n    content: string,\n    msg?: any,\n  ): Promise<void> {\n    // Map the base class call to the original processTypebot method\n    await this.processTypebot(\n      instance,\n      remoteJid,\n      msg,\n      session,\n      bot,\n      bot.url,\n      settings.expire,\n      bot.typebot,\n      settings.keywordFinish,\n      settings.delayMessage,\n      settings.unknownMessage,\n      settings.listeningFromMe,\n      settings.stopBotFromMe,\n      settings.keepOpen,\n      content,\n    );\n  }\n\n  /**\n   * Simplified wrapper for controller compatibility\n   */\n  public async processTypebotSimple(\n    instance: any,\n    remoteJid: string,\n    bot: TypebotModel,\n    session: IntegrationSession,\n    settings: any,\n    content: string,\n    pushName?: string,\n    msg?: any,\n  ): Promise<void> {\n    return this.process(instance, remoteJid, bot, session, settings, content, pushName, msg);\n  }\n\n  /**\n   * Create a new TypeBot session with prefilled variables\n   */\n  public async createNewSession(instance: Instance, data: any) {\n    if (data.remoteJid === 'status@broadcast') return;\n    const id = Math.floor(Math.random() * 10000000000).toString();\n\n    try {\n      const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;\n      let url: string;\n      let reqData: {};\n      if (version === 'latest') {\n        url = `${data.url}/api/v1/typebots/${data.typebot}/startChat`;\n\n        reqData = {\n          prefilledVariables: {\n            ...data.prefilledVariables,\n            remoteJid: data.remoteJid,\n            pushName: data.pushName || data.prefilledVariables?.pushName || '',\n            instanceName: instance.name,\n            serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n            apiKey: this.configService.get<Auth>('AUTHENTICATION').API_KEY.KEY,\n            ownerJid: instance.number,\n          },\n        };\n      } else {\n        url = `${data.url}/api/v1/sendMessage`;\n\n        reqData = {\n          startParams: {\n            publicId: data.typebot,\n            prefilledVariables: {\n              ...data.prefilledVariables,\n              remoteJid: data.remoteJid,\n              pushName: data.pushName || data.prefilledVariables?.pushName || '',\n              instanceName: instance.name,\n              serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n              apiKey: this.configService.get<Auth>('AUTHENTICATION').API_KEY.KEY,\n              ownerJid: instance.number,\n            },\n          },\n        };\n      }\n      const request = await axios.post(url, reqData);\n\n      let session = null;\n      if (request?.data?.sessionId) {\n        session = await this.prismaRepository.integrationSession.create({\n          data: {\n            remoteJid: data.remoteJid,\n            pushName: data.pushName || '',\n            sessionId: `${id}-${request.data.sessionId}`,\n            status: 'opened',\n            parameters: {\n              ...data.prefilledVariables,\n              remoteJid: data.remoteJid,\n              pushName: data.pushName || '',\n              instanceName: instance.name,\n              serverUrl: this.configService.get<HttpServer>('SERVER').URL,\n              apiKey: this.configService.get<Auth>('AUTHENTICATION').API_KEY.KEY,\n              ownerJid: instance.number,\n            },\n            awaitUser: false,\n            botId: data.botId,\n            type: 'typebot',\n            Instance: {\n              connect: {\n                id: instance.id,\n              },\n            },\n          },\n        });\n      }\n\n      const typebotData = {\n        remoteJid: data.remoteJid,\n        status: 'opened',\n        session,\n      };\n      this.waMonitor.waInstances[instance.name].sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n\n      return { ...request.data, session };\n    } catch (error) {\n      this.logger.error(error);\n      return;\n    }\n  }\n\n  /**\n   * Send WhatsApp message with complex TypeBot formatting\n   */\n  public async sendWAMessage(\n    instanceDb: Instance,\n    session: IntegrationSession,\n    settings: {\n      expire: number;\n      keywordFinish: string;\n      delayMessage: number;\n      unknownMessage: string;\n      listeningFromMe: boolean;\n      stopBotFromMe: boolean;\n      keepOpen: boolean;\n    },\n    remoteJid: string,\n    messages: any,\n    input: any,\n    clientSideActions: any,\n  ) {\n    const waInstance = this.waMonitor.waInstances[instanceDb.name];\n    await this.processMessages(\n      waInstance,\n      session,\n      settings,\n      messages,\n      input,\n      clientSideActions,\n      this.applyFormatting.bind(this),\n      this.prismaRepository,\n    ).catch((err) => {\n      console.error('Erro ao processar mensagens:', err);\n    });\n  }\n\n  /**\n   * Apply rich text formatting for TypeBot messages\n   */\n  private applyFormatting(element: any): string {\n    let text = '';\n\n    if (element.text) {\n      text += element.text;\n    }\n\n    if (element.children && element.type !== 'a') {\n      for (const child of element.children) {\n        text += this.applyFormatting(child);\n      }\n    }\n\n    if (element.type === 'p' && element.type !== 'inline-variable') {\n      text = text.trim() + '\\n';\n    }\n\n    if (element.type === 'inline-variable') {\n      text = text.trim();\n    }\n\n    if (element.type === 'ol') {\n      text =\n        '\\n' +\n        text\n          .split('\\n')\n          .map((line, index) => (line ? `${index + 1}. ${line}` : ''))\n          .join('\\n');\n    }\n\n    if (element.type === 'li') {\n      text = text\n        .split('\\n')\n        .map((line) => (line ? `  ${line}` : ''))\n        .join('\\n');\n    }\n\n    let formats = '';\n\n    if (element.bold) {\n      formats += '*';\n    }\n\n    if (element.italic) {\n      formats += '_';\n    }\n\n    if (element.underline) {\n      formats += '~';\n    }\n\n    let formattedText = `${formats}${text}${formats.split('').reverse().join('')}`;\n\n    if (element.url) {\n      formattedText = element.children[0]?.text ? `[${formattedText}]\\n(${element.url})` : `${element.url}`;\n    }\n\n    return formattedText;\n  }\n\n  /**\n   * Process TypeBot messages with full feature support\n   */\n  private async processMessages(\n    instance: any,\n    session: IntegrationSession,\n    settings: {\n      expire: number;\n      keywordFinish: string;\n      delayMessage: number;\n      unknownMessage: string;\n      listeningFromMe: boolean;\n      stopBotFromMe: boolean;\n      keepOpen: boolean;\n    },\n    messages: any,\n    input: any,\n    clientSideActions: any,\n    applyFormatting: any,\n    prismaRepository: PrismaRepository,\n  ) {\n    // Helper function to find wait time\n    const findItemAndGetSecondsToWait = (array: any[], targetId: string) => {\n      if (!array) return null;\n\n      for (const item of array) {\n        if (item.lastBubbleBlockId === targetId) {\n          return item.wait?.secondsToWaitFor;\n        }\n      }\n      return null;\n    };\n\n    for (const message of messages) {\n      if (message.type === 'text') {\n        let formattedText = '';\n\n        for (const richText of message.content.richText) {\n          for (const element of richText.children) {\n            formattedText += applyFormatting(element);\n          }\n          formattedText += '\\n';\n        }\n\n        formattedText = formattedText.replace(/\\*\\*/g, '').replace(/__/, '').replace(/~~/, '').replace(/\\n$/, '');\n\n        formattedText = formattedText.replace(/\\n$/, '');\n\n        if (formattedText.includes('[list]')) {\n          await this.processListMessage(instance, formattedText, session.remoteJid);\n        } else if (formattedText.includes('[buttons]')) {\n          await this.processButtonMessage(instance, formattedText, session.remoteJid);\n        } else {\n          await this.sendMessageWhatsApp(instance, session.remoteJid, formattedText, settings, true);\n        }\n\n        sendTelemetry('/message/sendText');\n      }\n\n      if (message.type === 'image') {\n        await instance.mediaMessage(\n          {\n            number: session.remoteJid,\n            delay: settings?.delayMessage || 1000,\n            mediatype: 'image',\n            media: message.content.url,\n          },\n          null,\n          false,\n        );\n\n        sendTelemetry('/message/sendMedia');\n      }\n\n      if (message.type === 'video') {\n        await instance.mediaMessage(\n          {\n            number: session.remoteJid,\n            delay: settings?.delayMessage || 1000,\n            mediatype: 'video',\n            media: message.content.url,\n          },\n          null,\n          false,\n        );\n\n        sendTelemetry('/message/sendMedia');\n      }\n\n      if (message.type === 'audio') {\n        await instance.audioWhatsapp(\n          {\n            number: session.remoteJid,\n            delay: settings?.delayMessage || 1000,\n            encoding: true,\n            audio: message.content.url,\n          },\n          false,\n        );\n\n        sendTelemetry('/message/sendWhatsAppAudio');\n      }\n\n      const wait = findItemAndGetSecondsToWait(clientSideActions, message.id);\n\n      if (wait) {\n        await new Promise((resolve) => setTimeout(resolve, wait * 1000));\n      }\n    }\n\n    // Process input choices\n    if (input) {\n      if (input.type === 'choice input') {\n        let formattedText = '';\n\n        const items = input.items;\n\n        for (const item of items) {\n          formattedText += `▶️ ${item.content}\\n`;\n        }\n\n        formattedText = formattedText.replace(/\\n$/, '');\n\n        if (formattedText.includes('[list]')) {\n          await this.processListMessage(instance, formattedText, session.remoteJid);\n        } else if (formattedText.includes('[buttons]')) {\n          await this.processButtonMessage(instance, formattedText, session.remoteJid);\n        } else {\n          await this.sendMessageWhatsApp(instance, session.remoteJid, formattedText, settings, true);\n        }\n\n        sendTelemetry('/message/sendText');\n      }\n\n      await prismaRepository.integrationSession.update({\n        where: {\n          id: session.id,\n        },\n        data: {\n          awaitUser: true,\n        },\n      });\n    } else {\n      let statusChange = 'closed';\n      if (!settings?.keepOpen) {\n        await prismaRepository.integrationSession.deleteMany({\n          where: {\n            id: session.id,\n          },\n        });\n        statusChange = 'delete';\n      } else {\n        await prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'closed',\n          },\n        });\n      }\n\n      const typebotData = {\n        remoteJid: session.remoteJid,\n        status: statusChange,\n        session,\n      };\n      instance.sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n    }\n  }\n\n  /**\n   * Process list messages for WhatsApp\n   */\n  private async processListMessage(instance: any, formattedText: string, remoteJid: string) {\n    const listJson = {\n      number: remoteJid,\n      title: '',\n      description: '',\n      buttonText: '',\n      footerText: '',\n      sections: [],\n    };\n\n    const titleMatch = formattedText.match(/\\[title\\]([\\s\\S]*?)(?=\\[description\\])/);\n    const descriptionMatch = formattedText.match(/\\[description\\]([\\s\\S]*?)(?=\\[buttonText\\])/);\n    const buttonTextMatch = formattedText.match(/\\[buttonText\\]([\\s\\S]*?)(?=\\[footerText\\])/);\n    const footerTextMatch = formattedText.match(/\\[footerText\\]([\\s\\S]*?)(?=\\[menu\\])/);\n\n    if (titleMatch) listJson.title = titleMatch[1].trim();\n    if (descriptionMatch) listJson.description = descriptionMatch[1].trim();\n    if (buttonTextMatch) listJson.buttonText = buttonTextMatch[1].trim();\n    if (footerTextMatch) listJson.footerText = footerTextMatch[1].trim();\n\n    const menuContent = formattedText.match(/\\[menu\\]([\\s\\S]*?)\\[\\/menu\\]/)?.[1];\n    if (menuContent) {\n      const sections = menuContent.match(/\\[section\\]([\\s\\S]*?)(?=\\[section\\]|\\[\\/section\\]|\\[\\/menu\\])/g);\n      if (sections) {\n        sections.forEach((section) => {\n          const sectionTitle = section.match(/title: (.*?)(?:\\n|$)/)?.[1]?.trim();\n          const rows = section.match(/\\[row\\]([\\s\\S]*?)(?=\\[row\\]|\\[\\/row\\]|\\[\\/section\\]|\\[\\/menu\\])/g);\n\n          const sectionData = {\n            title: sectionTitle,\n            rows:\n              rows?.map((row) => ({\n                title: row.match(/title: (.*?)(?:\\n|$)/)?.[1]?.trim(),\n                description: row.match(/description: (.*?)(?:\\n|$)/)?.[1]?.trim(),\n                rowId: row.match(/rowId: (.*?)(?:\\n|$)/)?.[1]?.trim(),\n              })) || [],\n          };\n\n          listJson.sections.push(sectionData);\n        });\n      }\n    }\n\n    await instance.listMessage(listJson);\n  }\n\n  /**\n   * Process button messages for WhatsApp\n   */\n  private async processButtonMessage(instance: any, formattedText: string, remoteJid: string) {\n    const buttonJson = {\n      number: remoteJid,\n      thumbnailUrl: undefined,\n      title: '',\n      description: '',\n      footer: '',\n      buttons: [],\n    };\n\n    const thumbnailUrlMatch = formattedText.match(/\\[thumbnailUrl\\]([\\s\\S]*?)(?=\\[title\\])/);\n    const titleMatch = formattedText.match(/\\[title\\]([\\s\\S]*?)(?=\\[description\\])/);\n    const descriptionMatch = formattedText.match(/\\[description\\]([\\s\\S]*?)(?=\\[footer\\])/);\n    const footerMatch = formattedText.match(/\\[footer\\]([\\s\\S]*?)(?=\\[(?:reply|pix|copy|call|url))/);\n\n    if (titleMatch) buttonJson.title = titleMatch[1].trim();\n    if (thumbnailUrlMatch) buttonJson.thumbnailUrl = thumbnailUrlMatch[1].trim();\n    if (descriptionMatch) buttonJson.description = descriptionMatch[1].trim();\n    if (footerMatch) buttonJson.footer = footerMatch[1].trim();\n\n    const buttonTypes = {\n      reply: /\\[reply\\]([\\s\\S]*?)(?=\\[(?:reply|pix|copy|call|url)|$)/g,\n      pix: /\\[pix\\]([\\s\\S]*?)(?=\\[(?:reply|pix|copy|call|url)|$)/g,\n      copy: /\\[copy\\]([\\s\\S]*?)(?=\\[(?:reply|pix|copy|call|url)|$)/g,\n      call: /\\[call\\]([\\s\\S]*?)(?=\\[(?:reply|pix|copy|call|url)|$)/g,\n      url: /\\[url\\]([\\s\\S]*?)(?=\\[(?:reply|pix|copy|call|url)|$)/g,\n    };\n\n    for (const [type, pattern] of Object.entries(buttonTypes)) {\n      let match;\n      while ((match = pattern.exec(formattedText)) !== null) {\n        const content = match[1].trim();\n        const button: any = { type };\n\n        switch (type) {\n          case 'pix':\n            button.currency = content.match(/currency: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.name = content.match(/name: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.keyType = content.match(/keyType: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.key = content.match(/key: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            break;\n\n          case 'reply':\n            button.displayText = content.match(/displayText: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.id = content.match(/id: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            break;\n\n          case 'copy':\n            button.displayText = content.match(/displayText: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.copyCode = content.match(/copyCode: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            break;\n\n          case 'call':\n            button.displayText = content.match(/displayText: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.phoneNumber = content.match(/phone: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            break;\n\n          case 'url':\n            button.displayText = content.match(/displayText: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            button.url = content.match(/url: (.*?)(?:\\n|$)/)?.[1]?.trim();\n            break;\n        }\n\n        if (Object.keys(button).length > 1) {\n          buttonJson.buttons.push(button);\n        }\n      }\n    }\n\n    await instance.buttonMessage(buttonJson);\n  }\n\n  /**\n   * Original TypeBot processing method with full functionality\n   */\n  public async processTypebot(\n    waInstance: any,\n    remoteJid: string,\n    msg: Message,\n    session: IntegrationSession,\n    findTypebot: TypebotModel,\n    url: string,\n    expire: number,\n    typebot: string,\n    keywordFinish: string,\n    delayMessage: number,\n    unknownMessage: string,\n    listeningFromMe: boolean,\n    stopBotFromMe: boolean,\n    keepOpen: boolean,\n    content: string,\n    prefilledVariables?: any,\n  ) {\n    // Get the database instance record\n    const instance = await this.prismaRepository.instance.findFirst({\n      where: {\n        name: waInstance.instanceName,\n      },\n    });\n\n    if (!instance) {\n      this.logger.error('Instance not found in database');\n      return;\n    }\n    // Handle session expiration\n    if (session && expire && expire > 0) {\n      const now = Date.now();\n      const sessionUpdatedAt = new Date(session.updatedAt).getTime();\n      const diff = now - sessionUpdatedAt;\n      const diffInMinutes = Math.floor(diff / 1000 / 60);\n\n      if (diffInMinutes > expire) {\n        if (keepOpen) {\n          await this.prismaRepository.integrationSession.update({\n            where: {\n              id: session.id,\n            },\n            data: {\n              status: 'closed',\n            },\n          });\n        } else {\n          await this.prismaRepository.integrationSession.deleteMany({\n            where: {\n              botId: findTypebot.id,\n              remoteJid: remoteJid,\n            },\n          });\n        }\n\n        const data = await this.createNewSession(instance, {\n          enabled: findTypebot?.enabled,\n          url: url,\n          typebot: typebot,\n          expire: expire,\n          keywordFinish: keywordFinish,\n          delayMessage: delayMessage,\n          unknownMessage: unknownMessage,\n          listeningFromMe: listeningFromMe,\n          remoteJid: remoteJid,\n          pushName: msg.pushName,\n          botId: findTypebot.id,\n          prefilledVariables: prefilledVariables,\n        });\n\n        if (data?.session) {\n          session = data.session;\n        }\n\n        if (!data?.messages || data.messages.length === 0) {\n          const content = getConversationMessage(msg.message);\n\n          if (!content) {\n            if (unknownMessage) {\n              await this.sendMessageWhatsApp(\n                waInstance,\n                remoteJid,\n                unknownMessage,\n                {\n                  delayMessage,\n                  expire,\n                  keywordFinish,\n                  listeningFromMe,\n                  stopBotFromMe,\n                  keepOpen,\n                  unknownMessage,\n                },\n                true,\n              );\n              sendTelemetry('/message/sendText');\n            }\n            return;\n          }\n\n          if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {\n            let statusChange = 'closed';\n            if (keepOpen) {\n              await this.prismaRepository.integrationSession.update({\n                where: {\n                  id: session.id,\n                },\n                data: {\n                  status: 'closed',\n                },\n              });\n            } else {\n              statusChange = 'delete';\n              await this.prismaRepository.integrationSession.deleteMany({\n                where: {\n                  botId: findTypebot.id,\n                  remoteJid: remoteJid,\n                },\n              });\n            }\n\n            const typebotData = {\n              remoteJid: remoteJid,\n              status: statusChange,\n              session,\n            };\n            waInstance.sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n\n            return;\n          }\n\n          try {\n            const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;\n            let urlTypebot: string;\n            let reqData: {};\n            if (version === 'latest') {\n              urlTypebot = `${url}/api/v1/sessions/${data?.sessionId}/continueChat`;\n              reqData = {\n                message: content,\n              };\n            } else {\n              urlTypebot = `${url}/api/v1/sendMessage`;\n              reqData = {\n                message: content,\n                sessionId: data?.sessionId,\n              };\n            }\n\n            const request = await axios.post(urlTypebot, reqData);\n\n            await this.sendWAMessage(\n              instance,\n              session,\n              {\n                expire: expire,\n                keywordFinish: keywordFinish,\n                delayMessage: delayMessage,\n                unknownMessage: unknownMessage,\n                listeningFromMe: listeningFromMe,\n                stopBotFromMe: stopBotFromMe,\n                keepOpen: keepOpen,\n              },\n              remoteJid,\n              request?.data?.messages,\n              request?.data?.input,\n              request?.data?.clientSideActions,\n            );\n          } catch (error) {\n            this.logger.error(error);\n            return;\n          }\n        }\n\n        if (data?.messages && data.messages.length > 0) {\n          await this.sendWAMessage(\n            instance,\n            session,\n            {\n              expire: expire,\n              keywordFinish: keywordFinish,\n              delayMessage: delayMessage,\n              unknownMessage: unknownMessage,\n              listeningFromMe: listeningFromMe,\n              stopBotFromMe: stopBotFromMe,\n              keepOpen: keepOpen,\n            },\n            remoteJid,\n            data.messages,\n            data.input,\n            data.clientSideActions,\n          );\n        }\n\n        return;\n      }\n    }\n\n    if (session && session.status !== 'opened') {\n      return;\n    }\n\n    // Handle new sessions\n    if (!session) {\n      const data = await this.createNewSession(instance, {\n        enabled: findTypebot?.enabled,\n        url: url,\n        typebot: typebot,\n        expire: expire,\n        keywordFinish: keywordFinish,\n        delayMessage: delayMessage,\n        unknownMessage: unknownMessage,\n        listeningFromMe: listeningFromMe,\n        remoteJid: remoteJid,\n        pushName: msg?.pushName,\n        botId: findTypebot.id,\n        prefilledVariables: prefilledVariables,\n      });\n\n      if (data?.session) {\n        session = data.session;\n      }\n\n      if (data?.messages && data.messages.length > 0) {\n        await this.sendWAMessage(\n          instance,\n          session,\n          {\n            expire: expire,\n            keywordFinish: keywordFinish,\n            delayMessage: delayMessage,\n            unknownMessage: unknownMessage,\n            listeningFromMe: listeningFromMe,\n            stopBotFromMe: stopBotFromMe,\n            keepOpen: keepOpen,\n          },\n          remoteJid,\n          data.messages,\n          data.input,\n          data.clientSideActions,\n        );\n      }\n\n      if (!data?.messages || data.messages.length === 0) {\n        if (!content) {\n          if (unknownMessage) {\n            await this.sendMessageWhatsApp(\n              waInstance,\n              remoteJid,\n              unknownMessage,\n              {\n                delayMessage,\n                expire,\n                keywordFinish,\n                listeningFromMe,\n                stopBotFromMe,\n                keepOpen,\n                unknownMessage,\n              },\n              true,\n            );\n            sendTelemetry('/message/sendText');\n          }\n          return;\n        }\n\n        if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {\n          let statusChange = 'closed';\n          if (keepOpen) {\n            await this.prismaRepository.integrationSession.update({\n              where: {\n                id: session.id,\n              },\n              data: {\n                status: 'closed',\n              },\n            });\n          } else {\n            statusChange = 'delete';\n            await this.prismaRepository.integrationSession.deleteMany({\n              where: {\n                botId: findTypebot.id,\n                remoteJid: remoteJid,\n              },\n            });\n          }\n\n          const typebotData = {\n            remoteJid: remoteJid,\n            status: statusChange,\n            session,\n          };\n          waInstance.sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n\n          return;\n        }\n\n        let request: any;\n        try {\n          const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;\n          let urlTypebot: string;\n          let reqData: {};\n          if (version === 'latest') {\n            urlTypebot = `${url}/api/v1/sessions/${data?.sessionId}/continueChat`;\n            reqData = {\n              message: content,\n            };\n          } else {\n            urlTypebot = `${url}/api/v1/sendMessage`;\n            reqData = {\n              message: content,\n              sessionId: data?.sessionId,\n            };\n          }\n          request = await axios.post(urlTypebot, reqData);\n\n          await this.sendWAMessage(\n            instance,\n            session,\n            {\n              expire: expire,\n              keywordFinish: keywordFinish,\n              delayMessage: delayMessage,\n              unknownMessage: unknownMessage,\n              listeningFromMe: listeningFromMe,\n              stopBotFromMe: stopBotFromMe,\n              keepOpen: keepOpen,\n            },\n            remoteJid,\n            request?.data?.messages,\n            request?.data?.input,\n            request?.data?.clientSideActions,\n          );\n        } catch (error) {\n          this.logger.error(error);\n          return;\n        }\n      }\n      return;\n    }\n\n    // Update existing session\n    await this.prismaRepository.integrationSession.update({\n      where: {\n        id: session.id,\n      },\n      data: {\n        status: 'opened',\n        awaitUser: false,\n      },\n    });\n\n    if (!content) {\n      if (unknownMessage) {\n        await this.sendMessageWhatsApp(\n          waInstance,\n          remoteJid,\n          unknownMessage,\n          {\n            delayMessage,\n            expire,\n            keywordFinish,\n            listeningFromMe,\n            stopBotFromMe,\n            keepOpen,\n            unknownMessage,\n          },\n          true,\n        );\n        sendTelemetry('/message/sendText');\n      }\n      return;\n    }\n\n    if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {\n      let statusChange = 'closed';\n      if (keepOpen) {\n        await this.prismaRepository.integrationSession.update({\n          where: {\n            id: session.id,\n          },\n          data: {\n            status: 'closed',\n          },\n        });\n      } else {\n        statusChange = 'delete';\n        await this.prismaRepository.integrationSession.deleteMany({\n          where: {\n            botId: findTypebot.id,\n            remoteJid: remoteJid,\n          },\n        });\n      }\n\n      const typebotData = {\n        remoteJid: remoteJid,\n        status: statusChange,\n        session,\n      };\n\n      waInstance.sendDataWebhook(Events.TYPEBOT_CHANGE_STATUS, typebotData);\n\n      return;\n    }\n\n    // Continue existing chat\n    const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;\n    let urlTypebot: string;\n    let reqData: { message: string; sessionId?: string };\n    if (version === 'latest') {\n      urlTypebot = `${url}/api/v1/sessions/${session.sessionId.split('-')[1]}/continueChat`;\n      reqData = {\n        message: content,\n      };\n    } else {\n      urlTypebot = `${url}/api/v1/sendMessage`;\n      reqData = {\n        message: content,\n        sessionId: session.sessionId.split('-')[1],\n      };\n    }\n\n    // Handle audio transcription if OpenAI service is available\n    if (this.isAudioMessage(content) && msg) {\n      try {\n        this.logger.debug(`[TypeBot] Downloading audio for Whisper transcription`);\n        const transcription = await this.openaiService.speechToText(msg, instance);\n        if (transcription) {\n          reqData.message = `[audio] ${transcription}`;\n        }\n      } catch (err) {\n        this.logger.error(`[TypeBot] Failed to transcribe audio: ${err}`);\n      }\n    }\n\n    const request = await axios.post(urlTypebot, reqData);\n\n    await this.sendWAMessage(\n      instance,\n      session,\n      {\n        expire: expire,\n        keywordFinish: keywordFinish,\n        delayMessage: delayMessage,\n        unknownMessage: unknownMessage,\n        listeningFromMe: listeningFromMe,\n        stopBotFromMe: stopBotFromMe,\n        keepOpen: keepOpen,\n      },\n      remoteJid,\n      request?.data?.messages,\n      request?.data?.input,\n      request?.data?.clientSideActions,\n    );\n\n    return;\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/chatbot/typebot/validate/typebot.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const typebotSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean' },\n    description: { type: 'string' },\n    url: { type: 'string' },\n    typebot: { type: 'string' },\n    triggerType: { type: 'string', enum: ['all', 'keyword', 'none', 'advanced'] },\n    triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex'] },\n    triggerValue: { type: 'string' },\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n  },\n  required: ['enabled', 'url', 'typebot', 'triggerType'],\n  ...isNotEmpty('enabled', 'url', 'typebot', 'triggerType'),\n};\n\nexport const typebotStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    status: { type: 'string', enum: ['opened', 'closed', 'paused', 'delete'] },\n  },\n  required: ['remoteJid', 'status'],\n  ...isNotEmpty('remoteJid', 'status'),\n};\n\nexport const typebotStartSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    url: { type: 'string' },\n    typebot: { type: 'string' },\n  },\n  required: ['remoteJid', 'url', 'typebot'],\n  ...isNotEmpty('remoteJid', 'url', 'typebot'),\n};\n\nexport const typebotSettingSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    expire: { type: 'integer' },\n    keywordFinish: { type: 'string' },\n    delayMessage: { type: 'integer' },\n    unknownMessage: { type: 'string' },\n    listeningFromMe: { type: 'boolean' },\n    stopBotFromMe: { type: 'boolean' },\n    keepOpen: { type: 'boolean' },\n    debounceTime: { type: 'integer' },\n    typebotIdFallback: { type: 'string' },\n    ignoreJids: { type: 'array', items: { type: 'string' } },\n  },\n  required: ['expire', 'keywordFinish', 'delayMessage', 'unknownMessage', 'listeningFromMe', 'stopBotFromMe'],\n  ...isNotEmpty('expire', 'keywordFinish', 'delayMessage', 'unknownMessage', 'listeningFromMe', 'stopBotFromMe'),\n};\n\nexport const typebotIgnoreJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    remoteJid: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['remoteJid', 'action'],\n  ...isNotEmpty('remoteJid', 'action'),\n};\n"
  },
  {
    "path": "src/api/integrations/event/event.controller.ts",
    "content": "import { EventDto } from '@api/integrations/event/event.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { wa } from '@api/types/wa.types';\n\nexport type EmitData = {\n  instanceName: string;\n  origin: string;\n  event: string;\n  data: any;\n  serverUrl: string;\n  dateTime: string;\n  sender: string;\n  apiKey?: string;\n  local?: boolean;\n  integration?: string[];\n  extra?: Record<string, any>;\n};\n\nexport interface EventControllerInterface {\n  set(instanceName: string, data: any): Promise<any>;\n  get(instanceName: string): Promise<any>;\n  emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    local,\n    extra,\n  }: EmitData): Promise<void>;\n}\n\nexport class EventController {\n  public prismaRepository: PrismaRepository;\n  protected waMonitor: WAMonitoringService;\n  private integrationStatus: boolean;\n  private integrationName: string;\n\n  constructor(\n    prismaRepository: PrismaRepository,\n    waMonitor: WAMonitoringService,\n    integrationStatus: boolean,\n    integrationName: string,\n  ) {\n    this.prisma = prismaRepository;\n    this.monitor = waMonitor;\n    this.status = integrationStatus;\n    this.name = integrationName;\n  }\n\n  public set prisma(prisma: PrismaRepository) {\n    this.prismaRepository = prisma;\n  }\n\n  public get prisma() {\n    return this.prismaRepository;\n  }\n\n  public set monitor(waMonitor: WAMonitoringService) {\n    this.waMonitor = waMonitor;\n  }\n\n  public get monitor() {\n    return this.waMonitor;\n  }\n\n  public set name(name: string) {\n    this.integrationName = name;\n  }\n\n  public get name() {\n    return this.integrationName;\n  }\n\n  public set status(status: boolean) {\n    this.integrationStatus = status;\n  }\n\n  public get status() {\n    return this.integrationStatus;\n  }\n\n  public async set(instanceName: string, data: EventDto): Promise<wa.LocalEvent> {\n    if (!this.status) {\n      return;\n    }\n\n    if (!data[this.name]?.enabled) {\n      data[this.name].events = [];\n    } else {\n      if (0 === data[this.name].events.length) {\n        data[this.name].events = EventController.events;\n      }\n    }\n\n    return this.prisma[this.name].upsert({\n      where: {\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n      update: {\n        enabled: data[this.name]?.enabled,\n        events: data[this.name].events,\n      },\n      create: {\n        enabled: data[this.name]?.enabled,\n        events: data[this.name].events,\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n    });\n  }\n\n  public async get(instanceName: string): Promise<wa.LocalEvent> {\n    if (!this.status) {\n      return;\n    }\n\n    if (undefined === this.monitor.waInstances[instanceName]) {\n      return null;\n    }\n\n    const data = await this.prisma[this.name].findUnique({\n      where: {\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n    });\n\n    if (!data) {\n      return null;\n    }\n\n    return data;\n  }\n\n  public static readonly events = [\n    'APPLICATION_STARTUP',\n    'QRCODE_UPDATED',\n    'MESSAGES_SET',\n    'MESSAGES_UPSERT',\n    'MESSAGES_EDITED',\n    'MESSAGES_UPDATE',\n    'MESSAGES_DELETE',\n    'SEND_MESSAGE',\n    'SEND_MESSAGE_UPDATE',\n    'CONTACTS_SET',\n    'CONTACTS_UPSERT',\n    'CONTACTS_UPDATE',\n    'PRESENCE_UPDATE',\n    'CHATS_SET',\n    'CHATS_UPSERT',\n    'CHATS_UPDATE',\n    'CHATS_DELETE',\n    'GROUPS_UPSERT',\n    'GROUP_UPDATE',\n    'GROUP_PARTICIPANTS_UPDATE',\n    'CONNECTION_UPDATE',\n    'LABELS_EDIT',\n    'LABELS_ASSOCIATION',\n    'CALL',\n    'TYPEBOT_START',\n    'TYPEBOT_CHANGE_STATUS',\n    'REMOVE_INSTANCE',\n    'LOGOUT_INSTANCE',\n    'INSTANCE_CREATE',\n    'INSTANCE_DELETE',\n    'STATUS_INSTANCE',\n  ];\n}\n"
  },
  {
    "path": "src/api/integrations/event/event.dto.ts",
    "content": "import { Constructor } from '@api/integrations/integration.dto';\nimport { JsonValue } from '@prisma/client/runtime/library';\n\nexport class EventDto {\n  webhook?: {\n    enabled?: boolean;\n    events?: string[];\n    url?: string;\n    headers?: JsonValue;\n    byEvents?: boolean;\n    base64?: boolean;\n  };\n\n  websocket?: {\n    enabled?: boolean;\n    events?: string[];\n  };\n\n  sqs?: {\n    enabled?: boolean;\n    events?: string[];\n  };\n\n  rabbitmq?: {\n    enabled?: boolean;\n    events?: string[];\n  };\n\n  nats?: {\n    enabled?: boolean;\n    events?: string[];\n  };\n\n  pusher?: {\n    enabled?: boolean;\n    appId?: string;\n    key?: string;\n    secret?: string;\n    cluster?: string;\n    useTLS?: boolean;\n    events?: string[];\n  };\n\n  kafka?: {\n    enabled?: boolean;\n    events?: string[];\n  };\n}\n\nexport function EventInstanceMixin<TBase extends Constructor>(Base: TBase) {\n  return class extends Base {\n    webhook?: {\n      enabled?: boolean;\n      events?: string[];\n      headers?: JsonValue;\n      url?: string;\n      byEvents?: boolean;\n      base64?: boolean;\n    };\n\n    websocket?: {\n      enabled?: boolean;\n      events?: string[];\n    };\n\n    sqs?: {\n      enabled?: boolean;\n      events?: string[];\n    };\n\n    rabbitmq?: {\n      enabled?: boolean;\n      events?: string[];\n    };\n\n    nats?: {\n      enabled?: boolean;\n      events?: string[];\n    };\n\n    pusher?: {\n      enabled?: boolean;\n      appId?: string;\n      key?: string;\n      secret?: string;\n      cluster?: string;\n      useTLS?: boolean;\n      events?: string[];\n    };\n\n    kafka?: {\n      enabled?: boolean;\n      events?: string[];\n    };\n  };\n}\n"
  },
  {
    "path": "src/api/integrations/event/event.manager.ts",
    "content": "import { KafkaController } from '@api/integrations/event/kafka/kafka.controller';\nimport { NatsController } from '@api/integrations/event/nats/nats.controller';\nimport { PusherController } from '@api/integrations/event/pusher/pusher.controller';\nimport { RabbitmqController } from '@api/integrations/event/rabbitmq/rabbitmq.controller';\nimport { SqsController } from '@api/integrations/event/sqs/sqs.controller';\nimport { WebhookController } from '@api/integrations/event/webhook/webhook.controller';\nimport { WebsocketController } from '@api/integrations/event/websocket/websocket.controller';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Server } from 'http';\n\nexport class EventManager {\n  private prismaRepository: PrismaRepository;\n  private waMonitor: WAMonitoringService;\n  private websocketController: WebsocketController;\n  private webhookController: WebhookController;\n  private rabbitmqController: RabbitmqController;\n  private natsController: NatsController;\n  private sqsController: SqsController;\n  private pusherController: PusherController;\n  private kafkaController: KafkaController;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    this.prisma = prismaRepository;\n    this.monitor = waMonitor;\n\n    this.websocket = new WebsocketController(prismaRepository, waMonitor);\n    this.webhook = new WebhookController(prismaRepository, waMonitor);\n    this.rabbitmq = new RabbitmqController(prismaRepository, waMonitor);\n    this.nats = new NatsController(prismaRepository, waMonitor);\n    this.sqs = new SqsController(prismaRepository, waMonitor);\n    this.pusher = new PusherController(prismaRepository, waMonitor);\n    this.kafka = new KafkaController(prismaRepository, waMonitor);\n  }\n\n  public set prisma(prisma: PrismaRepository) {\n    this.prismaRepository = prisma;\n  }\n\n  public get prisma() {\n    return this.prismaRepository;\n  }\n\n  public set monitor(waMonitor: WAMonitoringService) {\n    this.waMonitor = waMonitor;\n  }\n\n  public get monitor() {\n    return this.waMonitor;\n  }\n\n  public set websocket(websocket: WebsocketController) {\n    this.websocketController = websocket;\n  }\n\n  public get websocket() {\n    return this.websocketController;\n  }\n\n  public set webhook(webhook: WebhookController) {\n    this.webhookController = webhook;\n  }\n\n  public get webhook() {\n    return this.webhookController;\n  }\n\n  public set rabbitmq(rabbitmq: RabbitmqController) {\n    this.rabbitmqController = rabbitmq;\n  }\n\n  public get rabbitmq() {\n    return this.rabbitmqController;\n  }\n\n  public set nats(nats: NatsController) {\n    this.natsController = nats;\n  }\n\n  public get nats() {\n    return this.natsController;\n  }\n\n  public set sqs(sqs: SqsController) {\n    this.sqsController = sqs;\n  }\n\n  public get sqs() {\n    return this.sqsController;\n  }\n\n  public set pusher(pusher: PusherController) {\n    this.pusherController = pusher;\n  }\n  public get pusher() {\n    return this.pusherController;\n  }\n\n  public set kafka(kafka: KafkaController) {\n    this.kafkaController = kafka;\n  }\n  public get kafka() {\n    return this.kafkaController;\n  }\n\n  public init(httpServer: Server): void {\n    this.websocket.init(httpServer);\n    this.rabbitmq.init();\n    this.nats.init();\n    this.sqs.init();\n    this.pusher.init();\n    this.kafka.init();\n  }\n\n  public async emit(eventData: {\n    instanceName: string;\n    origin: string;\n    event: string;\n    data: object;\n    serverUrl: string;\n    dateTime: string;\n    sender: string;\n    apiKey?: string;\n    local?: boolean;\n    integration?: string[];\n    extra?: Record<string, any>;\n  }): Promise<void> {\n    await this.websocket.emit(eventData);\n    await this.rabbitmq.emit(eventData);\n    await this.nats.emit(eventData);\n    await this.sqs.emit(eventData);\n    await this.webhook.emit(eventData);\n    await this.pusher.emit(eventData);\n    await this.kafka.emit(eventData);\n  }\n\n  public async setInstance(instanceName: string, data: any): Promise<any> {\n    if (data.websocket) {\n      await this.websocket.set(instanceName, {\n        websocket: {\n          enabled: true,\n          events: data.websocket?.events,\n        },\n      });\n    }\n\n    if (data.rabbitmq) {\n      await this.rabbitmq.set(instanceName, {\n        rabbitmq: {\n          enabled: true,\n          events: data.rabbitmq?.events,\n        },\n      });\n    }\n\n    if (data.nats) {\n      await this.nats.set(instanceName, {\n        nats: {\n          enabled: true,\n          events: data.nats?.events,\n        },\n      });\n    }\n\n    if (data.sqs) {\n      await this.sqs.set(instanceName, {\n        sqs: {\n          enabled: true,\n          events: data.sqs?.events,\n        },\n      });\n    }\n\n    if (data.webhook) {\n      await this.webhook.set(instanceName, {\n        webhook: {\n          enabled: true,\n          events: data.webhook?.events,\n          url: data.webhook?.url,\n          headers: data.webhook?.headers,\n          base64: data.webhook?.base64,\n          byEvents: data.webhook?.byEvents,\n        },\n      });\n    }\n\n    if (data.pusher) {\n      await this.pusher.set(instanceName, {\n        pusher: {\n          enabled: true,\n          events: data.pusher?.events,\n          appId: data.pusher?.appId,\n          key: data.pusher?.key,\n          secret: data.pusher?.secret,\n          cluster: data.pusher?.cluster,\n          useTLS: data.pusher?.useTLS,\n        },\n      });\n    }\n\n    if (data.kafka) {\n      await this.kafka.set(instanceName, {\n        kafka: {\n          enabled: true,\n          events: data.kafka?.events,\n        },\n      });\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/event.router.ts",
    "content": "import { KafkaRouter } from '@api/integrations/event/kafka/kafka.router';\nimport { NatsRouter } from '@api/integrations/event/nats/nats.router';\nimport { PusherRouter } from '@api/integrations/event/pusher/pusher.router';\nimport { RabbitmqRouter } from '@api/integrations/event/rabbitmq/rabbitmq.router';\nimport { SqsRouter } from '@api/integrations/event/sqs/sqs.router';\nimport { WebhookRouter } from '@api/integrations/event/webhook/webhook.router';\nimport { WebsocketRouter } from '@api/integrations/event/websocket/websocket.router';\nimport { Router } from 'express';\n\nexport class EventRouter {\n  public readonly router: Router;\n\n  constructor(configService: any, ...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/webhook', new WebhookRouter(configService, ...guards).router);\n    this.router.use('/websocket', new WebsocketRouter(...guards).router);\n    this.router.use('/rabbitmq', new RabbitmqRouter(...guards).router);\n    this.router.use('/nats', new NatsRouter(...guards).router);\n    this.router.use('/pusher', new PusherRouter(...guards).router);\n    this.router.use('/sqs', new SqsRouter(...guards).router);\n    this.router.use('/kafka', new KafkaRouter(...guards).router);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/event.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nimport { EventController } from './event.controller';\n\nexport * from '@api/integrations/event/pusher/pusher.schema';\nexport * from '@api/integrations/event/webhook/webhook.schema';\n\nexport const eventSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    websocket: {\n      $ref: '#/$defs/event',\n    },\n    rabbitmq: {\n      $ref: '#/$defs/event',\n    },\n    nats: {\n      $ref: '#/$defs/event',\n    },\n    sqs: {\n      $ref: '#/$defs/event',\n    },\n    kafka: {\n      $ref: '#/$defs/event',\n    },\n  },\n  $defs: {\n    event: {\n      type: 'object',\n      properties: {\n        enabled: { type: 'boolean', enum: [true, false] },\n        events: {\n          type: 'array',\n          minItems: 0,\n          items: {\n            type: 'string',\n            enum: EventController.events,\n          },\n        },\n      },\n      required: ['enabled'],\n    },\n  },\n};\n"
  },
  {
    "path": "src/api/integrations/event/kafka/kafka.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Kafka, Log } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { Consumer, ConsumerConfig, Kafka as KafkaJS, KafkaConfig, Producer, ProducerConfig } from 'kafkajs';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\n\nexport class KafkaController extends EventController implements EventControllerInterface {\n  private kafkaClient: KafkaJS | null = null;\n  private producer: Producer | null = null;\n  private consumer: Consumer | null = null;\n  private readonly logger = new Logger('KafkaController');\n  private reconnectAttempts = 0;\n  private maxReconnectAttempts = 10;\n  private reconnectDelay = 5000; // 5 seconds\n  private isReconnecting = false;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, configService.get<Kafka>('KAFKA')?.ENABLED, 'kafka');\n  }\n\n  public async init(): Promise<void> {\n    if (!this.status) {\n      return;\n    }\n\n    await this.connect();\n  }\n\n  private async connect(): Promise<void> {\n    try {\n      const kafkaConfig = configService.get<Kafka>('KAFKA');\n\n      const clientConfig: KafkaConfig = {\n        clientId: kafkaConfig.CLIENT_ID || 'evolution-api',\n        brokers: kafkaConfig.BROKERS || ['localhost:9092'],\n        connectionTimeout: kafkaConfig.CONNECTION_TIMEOUT || 3000,\n        requestTimeout: kafkaConfig.REQUEST_TIMEOUT || 30000,\n        retry: {\n          initialRetryTime: 100,\n          retries: 8,\n        },\n      };\n\n      // Add SASL authentication if configured\n      if (kafkaConfig.SASL?.ENABLED) {\n        clientConfig.sasl = {\n          mechanism: (kafkaConfig.SASL.MECHANISM as any) || 'plain',\n          username: kafkaConfig.SASL.USERNAME,\n          password: kafkaConfig.SASL.PASSWORD,\n        };\n      }\n\n      // Add SSL configuration if enabled\n      if (kafkaConfig.SSL?.ENABLED) {\n        clientConfig.ssl = {\n          rejectUnauthorized: kafkaConfig.SSL.REJECT_UNAUTHORIZED !== false,\n          ca: kafkaConfig.SSL.CA ? [kafkaConfig.SSL.CA] : undefined,\n          key: kafkaConfig.SSL.KEY,\n          cert: kafkaConfig.SSL.CERT,\n        };\n      }\n\n      this.kafkaClient = new KafkaJS(clientConfig);\n\n      // Initialize producer\n      const producerConfig: ProducerConfig = {\n        maxInFlightRequests: 1,\n        idempotent: true,\n        transactionTimeout: 30000,\n      };\n\n      this.producer = this.kafkaClient.producer(producerConfig);\n      await this.producer.connect();\n\n      // Initialize consumer for global events if enabled\n      if (kafkaConfig.GLOBAL_ENABLED) {\n        await this.initGlobalConsumer();\n      }\n\n      this.reconnectAttempts = 0;\n      this.isReconnecting = false;\n\n      this.logger.info('Kafka initialized successfully');\n\n      // Create topics if they don't exist\n      if (kafkaConfig.AUTO_CREATE_TOPICS) {\n        await this.createTopics();\n      }\n    } catch (error) {\n      this.logger.error({\n        local: 'KafkaController.connect',\n        message: 'Failed to connect to Kafka',\n        error: error.message || error,\n      });\n      this.scheduleReconnect();\n      throw error;\n    }\n  }\n\n  private async initGlobalConsumer(): Promise<void> {\n    try {\n      const kafkaConfig = configService.get<Kafka>('KAFKA');\n\n      const consumerConfig: ConsumerConfig = {\n        groupId: kafkaConfig.CONSUMER_GROUP_ID || 'evolution-api-consumers',\n        sessionTimeout: 30000,\n        heartbeatInterval: 3000,\n      };\n\n      this.consumer = this.kafkaClient.consumer(consumerConfig);\n      await this.consumer.connect();\n\n      // Subscribe to global topics\n      const events = kafkaConfig.EVENTS;\n      if (events) {\n        const eventKeys = Object.keys(events).filter((event) => events[event]);\n\n        for (const event of eventKeys) {\n          const topicName = this.getTopicName(event, true);\n          await this.consumer.subscribe({ topic: topicName });\n        }\n\n        // Start consuming messages\n        await this.consumer.run({\n          eachMessage: async ({ topic, message }) => {\n            try {\n              const data = JSON.parse(message.value?.toString() || '{}');\n              this.logger.debug(`Received message from topic ${topic}: ${JSON.stringify(data)}`);\n\n              // Process the message here if needed\n              // This is where you can add custom message processing logic\n            } catch (error) {\n              this.logger.error(`Error processing message from topic ${topic}: ${error}`);\n            }\n          },\n        });\n\n        this.logger.info('Global Kafka consumer initialized');\n      }\n    } catch (error) {\n      this.logger.error(`Failed to initialize global Kafka consumer: ${error}`);\n    }\n  }\n\n  private async createTopics(): Promise<void> {\n    try {\n      const kafkaConfig = configService.get<Kafka>('KAFKA');\n      const admin = this.kafkaClient.admin();\n      await admin.connect();\n\n      const topics = [];\n\n      // Create global topics if enabled\n      if (kafkaConfig.GLOBAL_ENABLED && kafkaConfig.EVENTS) {\n        const eventKeys = Object.keys(kafkaConfig.EVENTS).filter((event) => kafkaConfig.EVENTS[event]);\n\n        for (const event of eventKeys) {\n          const topicName = this.getTopicName(event, true);\n          topics.push({\n            topic: topicName,\n            numPartitions: kafkaConfig.NUM_PARTITIONS || 1,\n            replicationFactor: kafkaConfig.REPLICATION_FACTOR || 1,\n          });\n        }\n      }\n\n      if (topics.length > 0) {\n        await admin.createTopics({\n          topics,\n          waitForLeaders: true,\n        });\n\n        this.logger.info(`Created ${topics.length} Kafka topics`);\n      }\n\n      await admin.disconnect();\n    } catch (error) {\n      this.logger.error(`Failed to create Kafka topics: ${error}`);\n    }\n  }\n\n  private getTopicName(event: string, isGlobal: boolean = false, instanceName?: string): string {\n    const kafkaConfig = configService.get<Kafka>('KAFKA');\n    const prefix = kafkaConfig.TOPIC_PREFIX || 'evolution';\n\n    if (isGlobal) {\n      return `${prefix}.global.${event.toLowerCase().replace(/_/g, '.')}`;\n    } else {\n      return `${prefix}.${instanceName}.${event.toLowerCase().replace(/_/g, '.')}`;\n    }\n  }\n\n  private handleConnectionLoss(): void {\n    if (this.isReconnecting) {\n      return;\n    }\n\n    this.cleanup();\n    this.scheduleReconnect();\n  }\n\n  private scheduleReconnect(): void {\n    if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n      this.logger.error(\n        `Maximum reconnect attempts (${this.maxReconnectAttempts}) reached. Stopping reconnection attempts.`,\n      );\n      return;\n    }\n\n    if (this.isReconnecting) {\n      return;\n    }\n\n    this.isReconnecting = true;\n    this.reconnectAttempts++;\n\n    const delay = this.reconnectDelay * Math.pow(2, Math.min(this.reconnectAttempts - 1, 5));\n\n    this.logger.info(\n      `Scheduling Kafka reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`,\n    );\n\n    setTimeout(async () => {\n      try {\n        this.logger.info(\n          `Attempting to reconnect to Kafka (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`,\n        );\n        await this.connect();\n        this.logger.info('Successfully reconnected to Kafka');\n      } catch (error) {\n        this.logger.error({\n          local: 'KafkaController.scheduleReconnect',\n          message: `Reconnection attempt ${this.reconnectAttempts} failed`,\n          error: error.message || error,\n        });\n        this.isReconnecting = false;\n        this.scheduleReconnect();\n      }\n    }, delay);\n  }\n\n  private async ensureConnection(): Promise<boolean> {\n    if (!this.producer) {\n      this.logger.warn('Kafka producer is not available, attempting to reconnect...');\n      if (!this.isReconnecting) {\n        this.scheduleReconnect();\n      }\n      return false;\n    }\n    return true;\n  }\n\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('kafka')) {\n      return;\n    }\n\n    if (!this.status) {\n      return;\n    }\n\n    if (!(await this.ensureConnection())) {\n      this.logger.warn(`Failed to emit event ${event} for instance ${instanceName}: No Kafka connection`);\n      return;\n    }\n\n    const instanceKafka = await this.get(instanceName);\n    const kafkaLocal = instanceKafka?.events;\n    const kafkaGlobal = configService.get<Kafka>('KAFKA').GLOBAL_ENABLED;\n    const kafkaEvents = configService.get<Kafka>('KAFKA').EVENTS;\n    const we = event.replace(/[.-]/gm, '_').toUpperCase();\n    const logEnabled = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');\n\n    const message = {\n      ...(extra ?? {}),\n      event,\n      instance: instanceName,\n      data,\n      server_url: serverUrl,\n      date_time: dateTime,\n      sender,\n      apikey: apiKey,\n      timestamp: Date.now(),\n    };\n\n    const messageValue = JSON.stringify(message);\n\n    // Instance-specific events\n    if (instanceKafka?.enabled && this.producer && Array.isArray(kafkaLocal) && kafkaLocal.includes(we)) {\n      const topicName = this.getTopicName(event, false, instanceName);\n\n      let retry = 0;\n      while (retry < 3) {\n        try {\n          await this.producer.send({\n            topic: topicName,\n            messages: [\n              {\n                key: instanceName,\n                value: messageValue,\n                headers: {\n                  event,\n                  instance: instanceName,\n                  origin,\n                  timestamp: dateTime,\n                },\n              },\n            ],\n          });\n\n          if (logEnabled) {\n            const logData = {\n              local: `${origin}.sendData-Kafka`,\n              ...message,\n            };\n            this.logger.log(logData);\n          }\n\n          break;\n        } catch (error) {\n          this.logger.error({\n            local: 'KafkaController.emit',\n            message: `Error publishing local Kafka message (attempt ${retry + 1}/3)`,\n            error: error.message || error,\n          });\n          retry++;\n          if (retry >= 3) {\n            this.handleConnectionLoss();\n          }\n        }\n      }\n    }\n\n    // Global events\n    if (kafkaGlobal && kafkaEvents[we] && this.producer) {\n      const topicName = this.getTopicName(event, true);\n\n      let retry = 0;\n      while (retry < 3) {\n        try {\n          await this.producer.send({\n            topic: topicName,\n            messages: [\n              {\n                key: `${instanceName}-${event}`,\n                value: messageValue,\n                headers: {\n                  event,\n                  instance: instanceName,\n                  origin,\n                  timestamp: dateTime,\n                },\n              },\n            ],\n          });\n\n          if (logEnabled) {\n            const logData = {\n              local: `${origin}.sendData-Kafka-Global`,\n              ...message,\n            };\n            this.logger.log(logData);\n          }\n\n          break;\n        } catch (error) {\n          this.logger.error({\n            local: 'KafkaController.emit',\n            message: `Error publishing global Kafka message (attempt ${retry + 1}/3)`,\n            error: error.message || error,\n          });\n          retry++;\n          if (retry >= 3) {\n            this.handleConnectionLoss();\n          }\n        }\n      }\n    }\n  }\n\n  public async cleanup(): Promise<void> {\n    try {\n      if (this.consumer) {\n        await this.consumer.disconnect();\n        this.consumer = null;\n      }\n      if (this.producer) {\n        await this.producer.disconnect();\n        this.producer = null;\n      }\n      this.kafkaClient = null;\n    } catch (error) {\n      this.logger.warn({\n        local: 'KafkaController.cleanup',\n        message: 'Error during cleanup',\n        error: error.message || error,\n      });\n      this.producer = null;\n      this.consumer = null;\n      this.kafkaClient = null;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/kafka/kafka.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { eventSchema, instanceSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class KafkaRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: eventSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.kafka.set(instance.instanceName, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.kafka.get(instance.instanceName),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/event/kafka/kafka.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nimport { EventController } from '../event.controller';\n\nexport const kafkaSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean', enum: [true, false] },\n    events: {\n      type: 'array',\n      minItems: 0,\n      items: {\n        type: 'string',\n        enum: EventController.events,\n      },\n    },\n  },\n  required: ['enabled'],\n};\n"
  },
  {
    "path": "src/api/integrations/event/nats/nats.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Log, Nats } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { connect, NatsConnection, StringCodec } from 'nats';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\n\nexport class NatsController extends EventController implements EventControllerInterface {\n  public natsClient: NatsConnection | null = null;\n  private readonly logger = new Logger('NatsController');\n  private readonly sc = StringCodec();\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, configService.get<Nats>('NATS')?.ENABLED, 'nats');\n  }\n\n  public async init(): Promise<void> {\n    if (!this.status) {\n      return;\n    }\n\n    try {\n      const uri = configService.get<Nats>('NATS').URI;\n\n      this.natsClient = await connect({ servers: uri });\n\n      this.logger.info('NATS initialized');\n\n      if (configService.get<Nats>('NATS')?.GLOBAL_ENABLED) {\n        await this.initGlobalSubscriptions();\n      }\n    } catch (error) {\n      this.logger.error('Failed to connect to NATS:');\n      this.logger.error(error);\n      throw error;\n    }\n  }\n\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('nats')) {\n      return;\n    }\n\n    if (!this.status || !this.natsClient) {\n      return;\n    }\n\n    const instanceNats = await this.get(instanceName);\n    const natsLocal = instanceNats?.events;\n    const natsGlobal = configService.get<Nats>('NATS').GLOBAL_ENABLED;\n    const natsEvents = configService.get<Nats>('NATS').EVENTS;\n    const prefixKey = configService.get<Nats>('NATS').PREFIX_KEY;\n    const we = event.replace(/[.-]/gm, '_').toUpperCase();\n    const logEnabled = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');\n\n    const message = {\n      ...(extra ?? {}),\n      event,\n      instance: instanceName,\n      data,\n      server_url: serverUrl,\n      date_time: dateTime,\n      sender,\n      apikey: apiKey,\n    };\n\n    // Instância específica\n    if (instanceNats?.enabled) {\n      if (Array.isArray(natsLocal) && natsLocal.includes(we)) {\n        const subject = `${instanceName}.${event.toLowerCase()}`;\n\n        try {\n          this.natsClient.publish(subject, this.sc.encode(JSON.stringify(message)));\n\n          if (logEnabled) {\n            const logData = {\n              local: `${origin}.sendData-NATS`,\n              ...message,\n            };\n            this.logger.log(logData);\n          }\n        } catch (error) {\n          this.logger.error(`Failed to publish to NATS (instance): ${error}`);\n        }\n      }\n    }\n\n    // Global\n    if (natsGlobal && natsEvents[we]) {\n      try {\n        const subject = prefixKey ? `${prefixKey}.${event.toLowerCase()}` : event.toLowerCase();\n\n        this.natsClient.publish(subject, this.sc.encode(JSON.stringify(message)));\n\n        if (logEnabled) {\n          const logData = {\n            local: `${origin}.sendData-NATS-Global`,\n            ...message,\n          };\n          this.logger.log(logData);\n        }\n      } catch (error) {\n        this.logger.error(`Failed to publish to NATS (global): ${error}`);\n      }\n    }\n  }\n\n  private async initGlobalSubscriptions(): Promise<void> {\n    this.logger.info('Initializing global subscriptions');\n\n    const events = configService.get<Nats>('NATS').EVENTS;\n    const prefixKey = configService.get<Nats>('NATS').PREFIX_KEY;\n\n    if (!events) {\n      this.logger.warn('No events to initialize on NATS');\n      return;\n    }\n\n    const eventKeys = Object.keys(events);\n\n    for (const event of eventKeys) {\n      if (events[event] === false) continue;\n\n      const subject = prefixKey ? `${prefixKey}.${event.toLowerCase()}` : event.toLowerCase();\n\n      // Criar uma subscription para cada evento\n      try {\n        const subscription = this.natsClient.subscribe(subject);\n        this.logger.info(`Subscribed to: ${subject}`);\n\n        // Processar mensagens (exemplo básico)\n        (async () => {\n          for await (const msg of subscription) {\n            try {\n              const data = JSON.parse(this.sc.decode(msg.data));\n              // Aqui você pode adicionar a lógica de processamento\n              this.logger.debug(`Received message on ${subject}:`);\n              this.logger.debug(data);\n            } catch (error) {\n              this.logger.error(`Error processing message on ${subject}:`);\n              this.logger.error(error);\n            }\n          }\n        })();\n      } catch (error) {\n        this.logger.error(`Failed to subscribe to ${subject}:`);\n        this.logger.error(error);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/nats/nats.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { eventSchema, instanceSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class NatsRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: eventSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.nats.set(instance.instanceName, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.nats.get(instance.instanceName),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/event/pusher/pusher.controller.ts",
    "content": "import { EventDto } from '@api/integrations/event/event.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { wa } from '@api/types/wa.types';\nimport { configService, Log, Pusher as ConfigPusher } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport Pusher from 'pusher';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\nexport class PusherController extends EventController implements EventControllerInterface {\n  private readonly logger = new Logger('PusherController');\n  private pusherClients: { [instanceName: string]: Pusher } = {};\n  private globalPusherClient: Pusher | null = null;\n  private pusherConfig: ConfigPusher = configService.get<ConfigPusher>('PUSHER');\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, configService.get<ConfigPusher>('PUSHER')?.ENABLED, 'pusher');\n    this.init();\n  }\n  public async init(): Promise<void> {\n    if (!this.status) {\n      return;\n    }\n    if (this.pusherConfig.GLOBAL?.ENABLED) {\n      const { APP_ID, KEY, SECRET, CLUSTER, USE_TLS } = this.pusherConfig.GLOBAL;\n      if (APP_ID && KEY && SECRET && CLUSTER) {\n        this.globalPusherClient = new Pusher({\n          appId: APP_ID,\n          key: KEY,\n          secret: SECRET,\n          cluster: CLUSTER,\n          useTLS: USE_TLS,\n        });\n        this.logger.info('Pusher global client initialized');\n      }\n    }\n    const instances = await this.prismaRepository.instance.findMany({\n      where: {\n        Pusher: {\n          isNot: null,\n        },\n      },\n      include: {\n        Pusher: true,\n      },\n    });\n    instances.forEach((instance) => {\n      if (\n        instance.Pusher.enabled &&\n        instance.Pusher.appId &&\n        instance.Pusher.key &&\n        instance.Pusher.secret &&\n        instance.Pusher.cluster\n      ) {\n        this.pusherClients[instance.name] = new Pusher({\n          appId: instance.Pusher.appId,\n          key: instance.Pusher.key,\n          secret: instance.Pusher.secret,\n          cluster: instance.Pusher.cluster,\n          useTLS: instance.Pusher.useTLS,\n        });\n        this.logger.info(`Pusher client initialized for instance ${instance.name}`);\n      } else {\n        delete this.pusherClients[instance.name];\n        this.logger.warn(`Pusher client disabled or misconfigured for instance ${instance.name}`);\n      }\n    });\n  }\n  override async set(instanceName: string, data: EventDto): Promise<wa.LocalPusher> {\n    if (!data.pusher?.enabled) {\n      data.pusher.events = [];\n    } else if (data.pusher.events.length === 0) {\n      data.pusher.events = EventController.events;\n    }\n    const instance = await this.prisma.pusher.upsert({\n      where: {\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n      update: {\n        enabled: data.pusher.enabled,\n        events: data.pusher.events,\n        appId: data.pusher.appId,\n        key: data.pusher.key,\n        secret: data.pusher.secret,\n        cluster: data.pusher.cluster,\n        useTLS: data.pusher.useTLS,\n      },\n      create: {\n        enabled: data.pusher.enabled,\n        events: data.pusher.events,\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n        appId: data.pusher.appId,\n        key: data.pusher.key,\n        secret: data.pusher.secret,\n        cluster: data.pusher.cluster,\n        useTLS: data.pusher.useTLS,\n      },\n    });\n    if (instance.enabled && instance.appId && instance.key && instance.secret && instance.cluster) {\n      this.pusherClients[instanceName] = new Pusher({\n        appId: instance.appId,\n        key: instance.key,\n        secret: instance.secret,\n        cluster: instance.cluster,\n        useTLS: instance.useTLS,\n      });\n      this.logger.info(`Pusher client initialized for instance ${instanceName}`);\n    } else {\n      delete this.pusherClients[instanceName];\n      this.logger.warn(`Pusher client disabled or misconfigured for instance ${instanceName}`);\n    }\n    return instance;\n  }\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    local,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('pusher')) {\n      return;\n    }\n    if (!this.status) {\n      return;\n    }\n    const instance = (await this.get(instanceName)) as wa.LocalPusher;\n    const we = event.replace(/[.-]/gm, '_').toUpperCase();\n    const enabledLog = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');\n    const eventName = event.replace(/_/g, '.').toLowerCase();\n    const pusherData = {\n      ...(extra ?? {}),\n      event,\n      instance: instanceName,\n      data,\n      destination: instance?.appId || this.pusherConfig.GLOBAL?.APP_ID,\n      date_time: dateTime,\n      sender,\n      server_url: serverUrl,\n      apikey: apiKey,\n    };\n    if (event == 'qrcode.updated') {\n      delete pusherData.data.qrcode.base64;\n    }\n    const payload = JSON.stringify(pusherData);\n    const payloadSize = Buffer.byteLength(payload, 'utf8');\n    const MAX_SIZE = 10240;\n    if (payloadSize > MAX_SIZE) {\n      this.logger.error({\n        local: `${origin}.sendData-Pusher`,\n        message: 'Payload size exceeds Pusher limit',\n        event,\n        instanceName,\n        payloadSize,\n      });\n      return;\n    }\n    if (local && instance && instance.enabled) {\n      const pusherLocalEvents = instance.events;\n      if (Array.isArray(pusherLocalEvents) && pusherLocalEvents.includes(we)) {\n        if (enabledLog) {\n          this.logger.log({\n            local: `${origin}.sendData-Pusher`,\n            appId: instance.appId,\n            ...pusherData,\n          });\n        }\n        try {\n          const pusher = this.pusherClients[instanceName];\n          if (pusher) {\n            pusher.trigger(instanceName, eventName, pusherData);\n          } else {\n            this.logger.error(`Pusher client not found for instance ${instanceName}`);\n          }\n        } catch (error) {\n          this.logger.error({\n            local: `${origin}.sendData-Pusher`,\n            message: error?.message,\n            error,\n          });\n        }\n      }\n    }\n    if (this.pusherConfig.GLOBAL?.ENABLED) {\n      const globalEvents = this.pusherConfig.EVENTS;\n      if (globalEvents[we]) {\n        if (enabledLog) {\n          this.logger.log({\n            local: `${origin}.sendData-Pusher-Global`,\n            appId: this.pusherConfig.GLOBAL?.APP_ID,\n            ...pusherData,\n          });\n        }\n        try {\n          if (this.globalPusherClient) {\n            this.globalPusherClient.trigger(instanceName, eventName, pusherData);\n          } else {\n            this.logger.error('Global Pusher client not initialized');\n          }\n        } catch (error) {\n          this.logger.error({\n            local: `${origin}.sendData-Pusher-Global`,\n            message: error?.message,\n            error,\n          });\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/pusher/pusher.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { instanceSchema, pusherSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\nexport class PusherRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: pusherSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.pusher.set(instance.instanceName, data),\n        });\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.pusher.get(instance.instanceName),\n        });\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/event/pusher/pusher.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nimport { EventController } from '../event.controller';\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\nexport const pusherSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    pusher: {\n      type: 'object',\n      properties: {\n        enabled: { type: 'boolean' },\n        appId: { type: 'string' },\n        key: { type: 'string' },\n        secret: { type: 'string' },\n        cluster: { type: 'string' },\n        useTLS: { type: 'boolean' },\n        events: {\n          type: 'array',\n          minItems: 0,\n          items: {\n            type: 'string',\n            enum: EventController.events,\n          },\n        },\n      },\n      required: ['enabled', 'appId', 'key', 'secret', 'cluster', 'useTLS'],\n      ...isNotEmpty('enabled', 'appId', 'key', 'secret', 'cluster', 'useTLS'),\n    },\n  },\n  required: ['pusher'],\n};\n"
  },
  {
    "path": "src/api/integrations/event/rabbitmq/rabbitmq.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { configService, Log, Rabbitmq } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport * as amqp from 'amqplib/callback_api';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\n\nexport class RabbitmqController extends EventController implements EventControllerInterface {\n  public amqpChannel: amqp.Channel | null = null;\n  private amqpConnection: amqp.Connection | null = null;\n  private readonly logger = new Logger('RabbitmqController');\n  private reconnectAttempts = 0;\n  private maxReconnectAttempts = 10;\n  private reconnectDelay = 5000; // 5 seconds\n  private isReconnecting = false;\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, configService.get<Rabbitmq>('RABBITMQ')?.ENABLED, 'rabbitmq');\n  }\n\n  public async init(): Promise<void> {\n    if (!this.status) {\n      return;\n    }\n\n    await this.connect();\n  }\n\n  private async connect(): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n      const uri = configService.get<Rabbitmq>('RABBITMQ').URI;\n      const frameMax = configService.get<Rabbitmq>('RABBITMQ').FRAME_MAX;\n      const rabbitmqExchangeName = configService.get<Rabbitmq>('RABBITMQ').EXCHANGE_NAME;\n\n      const url = new URL(uri);\n      const connectionOptions = {\n        protocol: url.protocol.slice(0, -1),\n        hostname: url.hostname,\n        port: url.port || 5672,\n        username: url.username || 'guest',\n        password: url.password || 'guest',\n        vhost: url.pathname.slice(1) || '/',\n        frameMax: frameMax,\n        heartbeat: 30, // Add heartbeat of 30 seconds\n      };\n\n      amqp.connect(connectionOptions, (error: Error, connection: amqp.Connection) => {\n        if (error) {\n          this.logger.error({\n            local: 'RabbitmqController.connect',\n            message: 'Failed to connect to RabbitMQ',\n            error: error.message || error,\n          });\n          reject(error);\n          return;\n        }\n\n        // Connection event handlers\n        connection.on('error', (err: Error) => {\n          this.logger.error({\n            local: 'RabbitmqController.connectionError',\n            message: 'RabbitMQ connection error',\n            error: err.message || err,\n          });\n          this.handleConnectionLoss();\n        });\n\n        connection.on('close', () => {\n          this.logger.warn('RabbitMQ connection closed');\n          this.handleConnectionLoss();\n        });\n\n        connection.createChannel((channelError: Error, channel: amqp.Channel) => {\n          if (channelError) {\n            this.logger.error({\n              local: 'RabbitmqController.createChannel',\n              message: 'Failed to create RabbitMQ channel',\n              error: channelError.message || channelError,\n            });\n            reject(channelError);\n            return;\n          }\n\n          // Channel event handlers\n          channel.on('error', (err: Error) => {\n            this.logger.error({\n              local: 'RabbitmqController.channelError',\n              message: 'RabbitMQ channel error',\n              error: err.message || err,\n            });\n            this.handleConnectionLoss();\n          });\n\n          channel.on('close', () => {\n            this.logger.warn('RabbitMQ channel closed');\n            this.handleConnectionLoss();\n          });\n\n          const exchangeName = rabbitmqExchangeName;\n\n          channel.assertExchange(exchangeName, 'topic', {\n            durable: true,\n            autoDelete: false,\n          });\n\n          this.amqpConnection = connection;\n          this.amqpChannel = channel;\n          this.reconnectAttempts = 0; // Reset reconnect attempts on successful connection\n          this.isReconnecting = false;\n\n          this.logger.info('AMQP initialized successfully');\n\n          resolve();\n        });\n      });\n    })\n      .then(() => {\n        if (configService.get<Rabbitmq>('RABBITMQ')?.GLOBAL_ENABLED) {\n          this.initGlobalQueues();\n        }\n      })\n      .catch((error) => {\n        this.logger.error({\n          local: 'RabbitmqController.init',\n          message: 'Failed to initialize AMQP',\n          error: error.message || error,\n        });\n        this.scheduleReconnect();\n        throw error;\n      });\n  }\n\n  private handleConnectionLoss(): void {\n    if (this.isReconnecting) {\n      return; // Already attempting to reconnect\n    }\n\n    this.cleanup();\n    this.scheduleReconnect();\n  }\n\n  private scheduleReconnect(): void {\n    if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n      this.logger.error(\n        `Maximum reconnect attempts (${this.maxReconnectAttempts}) reached. Stopping reconnection attempts.`,\n      );\n      return;\n    }\n\n    if (this.isReconnecting) {\n      return; // Already scheduled\n    }\n\n    this.isReconnecting = true;\n    this.reconnectAttempts++;\n\n    const delay = this.reconnectDelay * Math.pow(2, Math.min(this.reconnectAttempts - 1, 5)); // Exponential backoff with max delay\n\n    this.logger.info(\n      `Scheduling RabbitMQ reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`,\n    );\n\n    setTimeout(async () => {\n      try {\n        this.logger.info(\n          `Attempting to reconnect to RabbitMQ (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`,\n        );\n        await this.connect();\n        this.logger.info('Successfully reconnected to RabbitMQ');\n      } catch (error) {\n        this.logger.error({\n          local: 'RabbitmqController.scheduleReconnect',\n          message: `Reconnection attempt ${this.reconnectAttempts} failed`,\n          error: error.message || error,\n        });\n        this.isReconnecting = false;\n        this.scheduleReconnect();\n      }\n    }, delay);\n  }\n\n  private set channel(channel: amqp.Channel) {\n    this.amqpChannel = channel;\n  }\n\n  public get channel(): amqp.Channel {\n    return this.amqpChannel;\n  }\n\n  private async ensureConnection(): Promise<boolean> {\n    if (!this.amqpChannel) {\n      this.logger.warn('AMQP channel is not available, attempting to reconnect...');\n      if (!this.isReconnecting) {\n        this.scheduleReconnect();\n      }\n      return false;\n    }\n    return true;\n  }\n\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('rabbitmq')) {\n      return;\n    }\n\n    if (!this.status) {\n      return;\n    }\n\n    if (!(await this.ensureConnection())) {\n      this.logger.warn(`Failed to emit event ${event} for instance ${instanceName}: No AMQP connection`);\n      return;\n    }\n\n    const instanceRabbitmq = await this.get(instanceName);\n    const rabbitmqLocal = instanceRabbitmq?.events;\n    const rabbitmqGlobal = configService.get<Rabbitmq>('RABBITMQ').GLOBAL_ENABLED;\n    const rabbitmqEvents = configService.get<Rabbitmq>('RABBITMQ').EVENTS;\n    const prefixKey = configService.get<Rabbitmq>('RABBITMQ').PREFIX_KEY;\n    const rabbitmqExchangeName = configService.get<Rabbitmq>('RABBITMQ').EXCHANGE_NAME;\n    const we = event.replace(/[.-]/gm, '_').toUpperCase();\n    const logEnabled = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');\n\n    const message = {\n      ...(extra ?? {}),\n      event,\n      instance: instanceName,\n      data,\n      server_url: serverUrl,\n      date_time: dateTime,\n      sender,\n      apikey: apiKey,\n    };\n\n    if (instanceRabbitmq?.enabled && this.amqpChannel) {\n      if (Array.isArray(rabbitmqLocal) && rabbitmqLocal.includes(we)) {\n        const exchangeName = instanceName ?? rabbitmqExchangeName;\n\n        let retry = 0;\n\n        while (retry < 3) {\n          try {\n            await this.amqpChannel.assertExchange(exchangeName, 'topic', {\n              durable: true,\n              autoDelete: false,\n            });\n\n            const eventName = event.replace(/_/g, '.').toLowerCase();\n\n            const queueName = `${instanceName}.${eventName}`;\n\n            await this.amqpChannel.assertQueue(queueName, {\n              durable: true,\n              autoDelete: false,\n              arguments: {\n                'x-queue-type': 'quorum',\n              },\n            });\n\n            await this.amqpChannel.bindQueue(queueName, exchangeName, eventName);\n\n            await this.amqpChannel.publish(exchangeName, event, Buffer.from(JSON.stringify(message)));\n\n            if (logEnabled) {\n              const logData = {\n                local: `${origin}.sendData-RabbitMQ`,\n                ...message,\n              };\n\n              this.logger.log(logData);\n            }\n\n            break;\n          } catch (error) {\n            this.logger.error({\n              local: 'RabbitmqController.emit',\n              message: `Error publishing local RabbitMQ message (attempt ${retry + 1}/3)`,\n              error: error.message || error,\n            });\n            retry++;\n            if (retry >= 3) {\n              this.handleConnectionLoss();\n            }\n          }\n        }\n      }\n    }\n\n    if (rabbitmqGlobal && rabbitmqEvents[we] && this.amqpChannel) {\n      const exchangeName = rabbitmqExchangeName;\n\n      let retry = 0;\n\n      while (retry < 3) {\n        try {\n          await this.amqpChannel.assertExchange(exchangeName, 'topic', {\n            durable: true,\n            autoDelete: false,\n          });\n\n          const queueName = prefixKey\n            ? `${prefixKey}.${event.replace(/_/g, '.').toLowerCase()}`\n            : event.replace(/_/g, '.').toLowerCase();\n\n          await this.amqpChannel.assertQueue(queueName, {\n            durable: true,\n            autoDelete: false,\n            arguments: {\n              'x-queue-type': 'quorum',\n            },\n          });\n\n          await this.amqpChannel.bindQueue(queueName, exchangeName, event);\n\n          await this.amqpChannel.publish(exchangeName, event, Buffer.from(JSON.stringify(message)));\n\n          if (logEnabled) {\n            const logData = {\n              local: `${origin}.sendData-RabbitMQ-Global`,\n              ...message,\n            };\n\n            this.logger.log(logData);\n          }\n\n          break;\n        } catch (error) {\n          this.logger.error({\n            local: 'RabbitmqController.emit',\n            message: `Error publishing global RabbitMQ message (attempt ${retry + 1}/3)`,\n            error: error.message || error,\n          });\n          retry++;\n          if (retry >= 3) {\n            this.handleConnectionLoss();\n          }\n        }\n      }\n    }\n  }\n\n  private async initGlobalQueues(): Promise<void> {\n    this.logger.info('Initializing global queues');\n\n    if (!(await this.ensureConnection())) {\n      this.logger.error('Cannot initialize global queues: No AMQP connection');\n      return;\n    }\n\n    const rabbitmqExchangeName = configService.get<Rabbitmq>('RABBITMQ').EXCHANGE_NAME;\n    const events = configService.get<Rabbitmq>('RABBITMQ').EVENTS;\n    const prefixKey = configService.get<Rabbitmq>('RABBITMQ').PREFIX_KEY;\n\n    if (!events) {\n      this.logger.warn('No events to initialize on AMQP');\n      return;\n    }\n\n    const eventKeys = Object.keys(events);\n\n    for (const event of eventKeys) {\n      if (events[event] === false) continue;\n\n      try {\n        const queueName =\n          prefixKey !== ''\n            ? `${prefixKey}.${event.replace(/_/g, '.').toLowerCase()}`\n            : `${event.replace(/_/g, '.').toLowerCase()}`;\n        const exchangeName = rabbitmqExchangeName;\n\n        await this.amqpChannel.assertExchange(exchangeName, 'topic', {\n          durable: true,\n          autoDelete: false,\n        });\n\n        await this.amqpChannel.assertQueue(queueName, {\n          durable: true,\n          autoDelete: false,\n          arguments: {\n            'x-queue-type': 'quorum',\n          },\n        });\n\n        await this.amqpChannel.bindQueue(queueName, exchangeName, event);\n\n        this.logger.info(`Global queue initialized: ${queueName}`);\n      } catch (error) {\n        this.logger.error({\n          local: 'RabbitmqController.initGlobalQueues',\n          message: `Failed to initialize global queue for event ${event}`,\n          error: error.message || error,\n        });\n        this.handleConnectionLoss();\n        break;\n      }\n    }\n  }\n\n  public async cleanup(): Promise<void> {\n    try {\n      if (this.amqpChannel) {\n        await this.amqpChannel.close();\n        this.amqpChannel = null;\n      }\n      if (this.amqpConnection) {\n        await this.amqpConnection.close();\n        this.amqpConnection = null;\n      }\n    } catch (error) {\n      this.logger.warn({\n        local: 'RabbitmqController.cleanup',\n        message: 'Error during cleanup',\n        error: error.message || error,\n      });\n      this.amqpChannel = null;\n      this.amqpConnection = null;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/rabbitmq/rabbitmq.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { eventSchema, instanceSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class RabbitmqRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: eventSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.rabbitmq.set(instance.instanceName, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.rabbitmq.get(instance.instanceName),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/event/sqs/sqs.controller.ts",
    "content": "import * as s3Service from '@api/integrations/storage/s3/libs/minio.server';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { CreateQueueCommand, DeleteQueueCommand, ListQueuesCommand, SQS } from '@aws-sdk/client-sqs';\nimport { configService, HttpServer, Log, S3, Sqs } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\nimport { EventDto } from '../event.dto';\n\nexport class SqsController extends EventController implements EventControllerInterface {\n  private sqs: SQS;\n  private readonly logger = new Logger('SqsController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, configService.get<Sqs>('SQS')?.ENABLED, 'sqs');\n  }\n\n  public async init(): Promise<void> {\n    if (!this.status) {\n      return;\n    }\n\n    const awsConfig = configService.get<Sqs>('SQS');\n\n    this.sqs = new SQS({\n      credentials: {\n        accessKeyId: awsConfig.ACCESS_KEY_ID,\n        secretAccessKey: awsConfig.SECRET_ACCESS_KEY,\n      },\n\n      region: awsConfig.REGION,\n    });\n\n    this.logger.info('SQS initialized');\n\n    const sqsConfig = configService.get<Sqs>('SQS');\n    if (this.sqs && sqsConfig.GLOBAL_ENABLED) {\n      const sqsEvents = Object.keys(sqsConfig.EVENTS).filter((e) => sqsConfig.EVENTS[e]);\n      await this.saveQueues(sqsConfig.GLOBAL_PREFIX_NAME, sqsEvents, true);\n    }\n  }\n\n  private set channel(sqs: SQS) {\n    this.sqs = sqs;\n  }\n\n  public get channel(): SQS {\n    return this.sqs;\n  }\n\n  override async set(instanceName: string, data: EventDto): Promise<any> {\n    if (!this.status || configService.get<Sqs>('SQS').GLOBAL_ENABLED) {\n      return;\n    }\n\n    if (!data[this.name]?.enabled) {\n      data[this.name].events = [];\n    } else {\n      if (0 === data[this.name].events.length) {\n        data[this.name].events = EventController.events;\n      }\n    }\n\n    await this.saveQueues(instanceName, data[this.name].events, data[this.name]?.enabled);\n\n    const payload: any = {\n      where: {\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n      update: {\n        enabled: data[this.name]?.enabled,\n        events: data[this.name].events,\n      },\n      create: {\n        enabled: data[this.name]?.enabled,\n        events: data[this.name].events,\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n    };\n\n    console.log('*** payload: ', payload);\n    return this.prisma[this.name].upsert(payload);\n  }\n\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('sqs')) {\n      return;\n    }\n\n    if (!this.status) {\n      return;\n    }\n\n    if (this.sqs) {\n      const serverConfig = configService.get<HttpServer>('SERVER');\n      const sqsConfig = configService.get<Sqs>('SQS');\n\n      const we = event.replace(/[.-]/gm, '_').toUpperCase();\n\n      let sqsEvents = [];\n      if (sqsConfig.GLOBAL_ENABLED) {\n        sqsEvents = Object.keys(sqsConfig.EVENTS).filter((e) => sqsConfig.EVENTS[e]);\n      } else {\n        const instanceSqs = await this.get(instanceName);\n        if (instanceSqs?.enabled && Array.isArray(instanceSqs?.events)) {\n          sqsEvents = instanceSqs?.events;\n        }\n      }\n\n      if (Array.isArray(sqsEvents) && sqsEvents.includes(we)) {\n        const prefixName = sqsConfig.GLOBAL_ENABLED ? sqsConfig.GLOBAL_PREFIX_NAME : instanceName;\n        const eventFormatted =\n          sqsConfig.GLOBAL_ENABLED && sqsConfig.GLOBAL_FORCE_SINGLE_QUEUE\n            ? 'singlequeue'\n            : `${event.replace('.', '_').toLowerCase()}`;\n        const queueName = `${prefixName}_${eventFormatted}.fifo`;\n        const sqsUrl = `https://sqs.${sqsConfig.REGION}.amazonaws.com/${sqsConfig.ACCOUNT_ID}/${queueName}`;\n\n        const message = {\n          ...(extra ?? {}),\n          event,\n          instance: instanceName,\n          dataType: 'json',\n          data,\n          server: serverConfig.NAME,\n          server_url: serverUrl,\n          date_time: dateTime,\n          sender,\n          apikey: apiKey,\n        };\n\n        const jsonStr = JSON.stringify(message);\n        const size = Buffer.byteLength(jsonStr, 'utf8');\n        if (size > sqsConfig.MAX_PAYLOAD_SIZE) {\n          if (!configService.get<S3>('S3').ENABLE) {\n            this.logger.error(\n              `${instanceName} - ${eventFormatted} - SQS ignored: payload (${size} bytes) exceeds SQS size limit (${sqsConfig.MAX_PAYLOAD_SIZE} bytes) and S3 storage is not enabled.`,\n            );\n            return;\n          }\n\n          const buffer = Buffer.from(jsonStr, 'utf8');\n          const fullName = `messages/${instanceName}_${eventFormatted}_${Date.now()}.json`;\n\n          await s3Service.uploadFile(fullName, buffer, size, {\n            'Content-Type': 'application/json',\n            'Cache-Control': 'no-store',\n          });\n\n          const fileUrl = await s3Service.getObjectUrl(fullName);\n\n          message.data = { fileUrl };\n          message.dataType = 's3';\n        }\n\n        const messageGroupId = sqsConfig.GLOBAL_ENABLED\n          ? `${serverConfig.NAME}-${eventFormatted}-${instanceName}`\n          : 'evolution';\n        const isGlobalEnabled = sqsConfig.GLOBAL_ENABLED;\n        const params = {\n          MessageBody: JSON.stringify(message),\n          MessageGroupId: messageGroupId,\n          QueueUrl: sqsUrl,\n          ...(!isGlobalEnabled && {\n            MessageDeduplicationId: `${instanceName}_${eventFormatted}_${Date.now()}`,\n          }),\n        };\n\n        this.sqs.sendMessage(params, (err) => {\n          if (err) {\n            this.logger.error({\n              local: `${origin}.sendData-SQS`,\n              params: JSON.stringify(message),\n              sqsUrl: sqsUrl,\n              message: err?.message,\n              hostName: err?.hostname,\n              code: err?.code,\n              stack: err?.stack,\n              name: err?.name,\n              url: queueName,\n              server_url: serverUrl,\n            });\n          } else if (configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS')) {\n            const logData = {\n              local: `${origin}.sendData-SQS`,\n              ...message,\n            };\n\n            this.logger.log(logData);\n          }\n        });\n      }\n    }\n  }\n\n  private async saveQueues(prefixName: string, events: string[], enable: boolean) {\n    if (enable) {\n      const sqsConfig = configService.get<Sqs>('SQS');\n      const eventsFinded = await this.listQueues(prefixName);\n      console.log('eventsFinded', eventsFinded);\n\n      for (const event of events) {\n        const normalizedEvent =\n          sqsConfig.GLOBAL_ENABLED && sqsConfig.GLOBAL_FORCE_SINGLE_QUEUE ? 'singlequeue' : event.toLowerCase();\n        if (eventsFinded.includes(normalizedEvent)) {\n          this.logger.info(`A queue para o evento \"${normalizedEvent}\" já existe. Ignorando criação.`);\n          continue;\n        }\n\n        const queueName = `${prefixName}_${normalizedEvent}.fifo`;\n        try {\n          const isGlobalEnabled = sqsConfig.GLOBAL_ENABLED;\n          const createCommand = new CreateQueueCommand({\n            QueueName: queueName,\n            Attributes: {\n              FifoQueue: 'true',\n              ...(isGlobalEnabled && { ContentBasedDeduplication: 'true' }),\n            },\n          });\n\n          const data = await this.sqs.send(createCommand);\n          this.logger.info(`Queue ${queueName} criada: ${data.QueueUrl}`);\n        } catch (err: any) {\n          this.logger.error(`Erro ao criar queue ${queueName}: ${err.message}`);\n        }\n\n        if (sqsConfig.GLOBAL_ENABLED && sqsConfig.GLOBAL_FORCE_SINGLE_QUEUE) {\n          break;\n        }\n      }\n    }\n  }\n\n  private async listQueues(prefixName: string) {\n    let existingQueues: string[] = [];\n\n    try {\n      const listCommand = new ListQueuesCommand({\n        QueueNamePrefix: `${prefixName}_`,\n      });\n\n      const listData = await this.sqs.send(listCommand);\n      if (listData.QueueUrls && listData.QueueUrls.length > 0) {\n        // Extrai o nome da fila a partir da URL\n        existingQueues = listData.QueueUrls.map((queueUrl) => {\n          const parts = queueUrl.split('/');\n          return parts[parts.length - 1];\n        });\n      }\n    } catch (error: any) {\n      this.logger.error(`Erro ao listar filas para ${prefixName}: ${error.message}`);\n      return;\n    }\n\n    // Mapeia os eventos já existentes nas filas: remove o prefixo e o sufixo \".fifo\"\n    return existingQueues\n      .map((queueName) => {\n        // Espera-se que o nome seja `${instanceName}_${event}.fifo`\n        if (queueName.startsWith(`${prefixName}_`) && queueName.endsWith('.fifo')) {\n          return queueName.substring(prefixName.length + 1, queueName.length - 5).toLowerCase();\n        }\n        return '';\n      })\n      .filter((event) => event !== '');\n  }\n\n  // Para uma futura feature de exclusão forçada das queues\n  private async removeQueuesByInstance(prefixName: string) {\n    try {\n      const listCommand = new ListQueuesCommand({\n        QueueNamePrefix: `${prefixName}_`,\n      });\n      const listData = await this.sqs.send(listCommand);\n\n      if (!listData.QueueUrls || listData.QueueUrls.length === 0) {\n        this.logger.info(`No queues found for ${prefixName}`);\n        return;\n      }\n\n      for (const queueUrl of listData.QueueUrls) {\n        try {\n          const deleteCommand = new DeleteQueueCommand({ QueueUrl: queueUrl });\n          await this.sqs.send(deleteCommand);\n          this.logger.info(`Queue ${queueUrl} deleted`);\n        } catch (err: any) {\n          this.logger.error(`Error deleting queue ${queueUrl}: ${err.message}`);\n        }\n      }\n    } catch (err: any) {\n      this.logger.error(`Error listing queues for ${prefixName}: ${err.message}`);\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/sqs/sqs.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { eventSchema, instanceSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class SqsRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: eventSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.sqs.set(instance.instanceName, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.sqs.get(instance.instanceName),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/event/webhook/webhook.controller.ts",
    "content": "import { EventDto } from '@api/integrations/event/event.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { wa } from '@api/types/wa.types';\nimport { configService, Log, Webhook } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\n// import { BadRequestException } from '@exceptions';\nimport axios, { AxiosInstance } from 'axios';\nimport * as jwt from 'jsonwebtoken';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\n\nexport class WebhookController extends EventController implements EventControllerInterface {\n  private readonly logger = new Logger('WebhookController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, true, 'webhook');\n  }\n\n  override async set(instanceName: string, data: EventDto): Promise<wa.LocalWebHook> {\n    // if (!/^(https?:\\/\\/)/.test(data.webhook.url)) {\n    //   throw new BadRequestException('Invalid \"url\" property');\n    // }\n\n    if (!data.webhook?.enabled) {\n      data.webhook.events = [];\n    } else {\n      if (0 === data.webhook.events.length) {\n        data.webhook.events = EventController.events;\n      }\n    }\n\n    return this.prisma.webhook.upsert({\n      where: {\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n      },\n      update: {\n        enabled: data.webhook?.enabled,\n        events: data.webhook?.events,\n        url: data.webhook?.url,\n        headers: data.webhook?.headers,\n        webhookBase64: data.webhook.base64,\n        webhookByEvents: data.webhook.byEvents,\n      },\n      create: {\n        enabled: data.webhook?.enabled,\n        events: data.webhook?.events,\n        instanceId: this.monitor.waInstances[instanceName].instanceId,\n        url: data.webhook?.url,\n        headers: data.webhook?.headers,\n        webhookBase64: data.webhook.base64,\n        webhookByEvents: data.webhook.byEvents,\n      },\n    });\n  }\n\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    local,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('webhook')) {\n      return;\n    }\n\n    const instance = (await this.get(instanceName)) as wa.LocalWebHook;\n\n    const webhookConfig = configService.get<Webhook>('WEBHOOK');\n    const webhookLocal = instance?.events;\n    const webhookHeaders = { ...((instance?.headers as Record<string, string>) || {}) };\n\n    if (webhookHeaders && 'jwt_key' in webhookHeaders) {\n      const jwtKey = webhookHeaders['jwt_key'];\n      const jwtToken = this.generateJwtToken(jwtKey);\n      webhookHeaders['Authorization'] = `Bearer ${jwtToken}`;\n\n      delete webhookHeaders['jwt_key'];\n    }\n\n    const we = event.replace(/[.-]/gm, '_').toUpperCase();\n    const transformedWe = we.replace(/_/gm, '-').toLowerCase();\n    const enabledLog = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');\n    const regex = /^(https?:\\/\\/)/;\n\n    const webhookData = {\n      ...(extra ?? {}),\n      event,\n      instance: instanceName,\n      data,\n      destination: instance?.url || `${webhookConfig.GLOBAL.URL}/${transformedWe}`,\n      date_time: dateTime,\n      sender,\n      server_url: serverUrl,\n      apikey: apiKey,\n    };\n\n    if (local && instance?.enabled) {\n      if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) {\n        let baseURL: string;\n\n        if (instance?.webhookByEvents) {\n          baseURL = `${instance?.url}/${transformedWe}`;\n        } else {\n          baseURL = instance?.url;\n        }\n\n        if (enabledLog) {\n          const logData = {\n            local: `${origin}.sendData-Webhook`,\n            url: baseURL,\n            ...webhookData,\n          };\n\n          this.logger.log(logData);\n        }\n\n        try {\n          if (instance?.enabled && regex.test(instance.url)) {\n            const httpService = axios.create({\n              baseURL,\n              headers: webhookHeaders as Record<string, string> | undefined,\n              timeout: webhookConfig.REQUEST?.TIMEOUT_MS ?? 30000,\n            });\n\n            await this.retryWebhookRequest(httpService, webhookData, `${origin}.sendData-Webhook`, baseURL, serverUrl);\n          }\n        } catch (error) {\n          this.logger.error({\n            local: `${origin}.sendData-Webhook`,\n            message: `Todas as tentativas falharam: ${error?.message}`,\n            hostName: error?.hostname,\n            syscall: error?.syscall,\n            code: error?.code,\n            error: error?.errno,\n            stack: error?.stack,\n            name: error?.name,\n            url: baseURL,\n            server_url: serverUrl,\n          });\n        }\n      }\n    }\n\n    if (webhookConfig.GLOBAL?.ENABLED) {\n      if (webhookConfig.EVENTS[we]) {\n        let globalURL = webhookConfig.GLOBAL.URL;\n\n        if (webhookConfig.GLOBAL.WEBHOOK_BY_EVENTS) {\n          globalURL = `${globalURL}/${transformedWe}`;\n        }\n\n        if (enabledLog) {\n          const logData = {\n            local: `${origin}.sendData-Webhook-Global`,\n            url: globalURL,\n            ...webhookData,\n          };\n\n          this.logger.log(logData);\n        }\n\n        try {\n          if (regex.test(globalURL)) {\n            const httpService = axios.create({\n              baseURL: globalURL,\n              timeout: webhookConfig.REQUEST?.TIMEOUT_MS ?? 30000,\n            });\n\n            await this.retryWebhookRequest(\n              httpService,\n              webhookData,\n              `${origin}.sendData-Webhook-Global`,\n              globalURL,\n              serverUrl,\n            );\n          }\n        } catch (error) {\n          this.logger.error({\n            local: `${origin}.sendData-Webhook-Global`,\n            message: `Todas as tentativas falharam: ${error?.message}`,\n            hostName: error?.hostname,\n            syscall: error?.syscall,\n            code: error?.code,\n            error: error?.errno,\n            stack: error?.stack,\n            name: error?.name,\n            url: globalURL,\n            server_url: serverUrl,\n          });\n        }\n      }\n    }\n  }\n\n  private async retryWebhookRequest(\n    httpService: AxiosInstance,\n    webhookData: any,\n    origin: string,\n    baseURL: string,\n    serverUrl: string,\n    maxRetries?: number,\n    delaySeconds?: number,\n  ): Promise<void> {\n    const webhookConfig = configService.get<Webhook>('WEBHOOK');\n    const maxRetryAttempts = maxRetries ?? webhookConfig.RETRY?.MAX_ATTEMPTS ?? 10;\n    const initialDelay = delaySeconds ?? webhookConfig.RETRY?.INITIAL_DELAY_SECONDS ?? 5;\n    const useExponentialBackoff = webhookConfig.RETRY?.USE_EXPONENTIAL_BACKOFF ?? true;\n    const maxDelay = webhookConfig.RETRY?.MAX_DELAY_SECONDS ?? 300;\n    const jitterFactor = webhookConfig.RETRY?.JITTER_FACTOR ?? 0.2;\n    const nonRetryableStatusCodes = webhookConfig.RETRY?.NON_RETRYABLE_STATUS_CODES ?? [400, 401, 403, 404, 422];\n\n    let attempts = 0;\n\n    while (attempts < maxRetryAttempts) {\n      try {\n        await httpService.post('', webhookData);\n        if (attempts > 0) {\n          this.logger.log({\n            local: `${origin}`,\n            message: `Sucesso no envio após ${attempts + 1} tentativas`,\n            url: baseURL,\n          });\n        }\n        return;\n      } catch (error) {\n        attempts++;\n\n        const isTimeout = error.code === 'ECONNABORTED';\n\n        if (error?.response?.status && nonRetryableStatusCodes.includes(error.response.status)) {\n          this.logger.error({\n            local: `${origin}`,\n            message: `Erro não recuperável (${error.response.status}): ${error?.message}. Cancelando retentativas.`,\n            statusCode: error?.response?.status,\n            url: baseURL,\n            server_url: serverUrl,\n          });\n          throw error;\n        }\n\n        this.logger.error({\n          local: `${origin}`,\n          message: `Tentativa ${attempts}/${maxRetryAttempts} falhou: ${isTimeout ? 'Timeout da requisição' : error?.message}`,\n          hostName: error?.hostname,\n          syscall: error?.syscall,\n          code: error?.code,\n          isTimeout,\n          statusCode: error?.response?.status,\n          error: error?.errno,\n          stack: error?.stack,\n          name: error?.name,\n          url: baseURL,\n          server_url: serverUrl,\n        });\n\n        if (attempts === maxRetryAttempts) {\n          throw error;\n        }\n\n        let nextDelay = initialDelay;\n        if (useExponentialBackoff) {\n          nextDelay = Math.min(initialDelay * Math.pow(2, attempts - 1), maxDelay);\n\n          const jitter = nextDelay * jitterFactor * (Math.random() * 2 - 1);\n          nextDelay = Math.max(initialDelay, nextDelay + jitter);\n        }\n\n        this.logger.log({\n          local: `${origin}`,\n          message: `Aguardando ${nextDelay.toFixed(1)} segundos antes da próxima tentativa`,\n          url: baseURL,\n        });\n\n        await new Promise((resolve) => setTimeout(resolve, nextDelay * 1000));\n      }\n    }\n  }\n\n  private generateJwtToken(authToken: string): string {\n    try {\n      const payload = {\n        iat: Math.floor(Date.now() / 1000),\n        exp: Math.floor(Date.now() / 1000) + 600, // 10 min expiration\n        app: 'evolution',\n        action: 'webhook',\n      };\n\n      const token = jwt.sign(payload, authToken, { algorithm: 'HS256' });\n      return token;\n    } catch (error) {\n      this.logger.error({\n        local: 'WebhookController.generateJwtToken',\n        message: `JWT generation failed: ${error?.message}`,\n      });\n      throw error;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/webhook/webhook.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { ConfigService } from '@config/env.config';\nimport { instanceSchema, webhookSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class WebhookRouter extends RouterBroker {\n  constructor(\n    readonly configService: ConfigService,\n    ...guards: RequestHandler[]\n  ) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: webhookSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.webhook.set(instance.instanceName, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.webhook.get(instance.instanceName),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/event/webhook/webhook.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nimport { EventController } from '../event.controller';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const webhookSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    webhook: {\n      type: 'object',\n      properties: {\n        enabled: { type: 'boolean' },\n        url: { type: 'string' },\n        headers: { type: 'object' },\n        byEvents: { type: 'boolean' },\n        base64: { type: 'boolean' },\n        events: {\n          type: 'array',\n          minItems: 0,\n          items: {\n            type: 'string',\n            enum: EventController.events,\n          },\n        },\n      },\n      required: ['enabled', 'url'],\n      ...isNotEmpty('enabled', 'url'),\n    },\n  },\n  required: ['webhook'],\n};\n"
  },
  {
    "path": "src/api/integrations/event/websocket/websocket.controller.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { WAMonitoringService } from '@api/services/monitor.service';\nimport { Auth, configService, Cors, Log, Websocket } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { Server } from 'http';\nimport { Server as SocketIO } from 'socket.io';\n\nimport { EmitData, EventController, EventControllerInterface } from '../event.controller';\n\nexport class WebsocketController extends EventController implements EventControllerInterface {\n  private io: SocketIO;\n  private corsConfig: Array<any>;\n  private readonly logger = new Logger('WebsocketController');\n\n  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {\n    super(prismaRepository, waMonitor, configService.get<Websocket>('WEBSOCKET')?.ENABLED, 'websocket');\n\n    this.cors = configService.get<Cors>('CORS').ORIGIN;\n  }\n\n  public init(httpServer: Server): void {\n    if (!this.status) {\n      return;\n    }\n\n    this.socket = new SocketIO(httpServer, {\n      cors: { origin: this.cors },\n      allowRequest: async (req, callback) => {\n        try {\n          const url = new URL(req.url || '', 'http://localhost');\n          const params = new URLSearchParams(url.search);\n\n          const { remoteAddress } = req.socket;\n          const websocketConfig = configService.get<Websocket>('WEBSOCKET');\n          const allowedHosts = websocketConfig.ALLOWED_HOSTS || '127.0.0.1,::1,::ffff:127.0.0.1';\n          const allowAllHosts = allowedHosts.trim() === '*';\n          const isAllowedHost =\n            allowAllHosts ||\n            allowedHosts\n              .split(',')\n              .map((h) => h.trim())\n              .includes(remoteAddress);\n\n          if (params.has('EIO') && isAllowedHost) {\n            return callback(null, true);\n          }\n\n          const apiKey = params.get('apikey') || (req.headers.apikey as string);\n\n          if (!apiKey) {\n            this.logger.error('Connection rejected: apiKey not provided');\n            return callback('apiKey is required', false);\n          }\n\n          const instance = await this.prismaRepository.instance.findFirst({ where: { token: apiKey } });\n\n          if (!instance) {\n            const globalToken = configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;\n            if (apiKey !== globalToken) {\n              this.logger.error('Connection rejected: invalid global token');\n              return callback('Invalid global token', false);\n            }\n          }\n\n          callback(null, true);\n        } catch (error) {\n          this.logger.error('Authentication error:');\n          this.logger.error(error);\n          callback('Authentication error', false);\n        }\n      },\n    });\n\n    this.socket.on('connection', (socket) => {\n      this.logger.info('User connected');\n\n      socket.on('disconnect', () => {\n        this.logger.info('User disconnected');\n      });\n\n      socket.on('sendNode', async (data) => {\n        try {\n          await this.waMonitor.waInstances[data.instanceId].baileysSendNode(data.stanza);\n          this.logger.info('Node sent successfully');\n        } catch (error) {\n          this.logger.error('Error sending node:');\n          this.logger.error(error);\n        }\n      });\n    });\n\n    this.logger.info('Socket.io initialized');\n  }\n\n  private set cors(cors: Array<any>) {\n    this.corsConfig = cors;\n  }\n\n  private get cors(): string | Array<any> {\n    return this.corsConfig?.includes('*') ? '*' : this.corsConfig;\n  }\n\n  private set socket(socket: SocketIO) {\n    this.io = socket;\n  }\n\n  public get socket(): SocketIO {\n    return this.io;\n  }\n\n  public async emit({\n    instanceName,\n    origin,\n    event,\n    data,\n    serverUrl,\n    dateTime,\n    sender,\n    apiKey,\n    integration,\n    extra,\n  }: EmitData): Promise<void> {\n    if (integration && !integration.includes('websocket')) {\n      return;\n    }\n\n    if (!this.status) {\n      return;\n    }\n\n    const configEv = event.replace(/[.-]/gm, '_').toUpperCase();\n    const logEnabled = configService.get<Log>('LOG').LEVEL.includes('WEBSOCKET');\n    const message = {\n      ...(extra ?? {}),\n      event,\n      instance: instanceName,\n      data,\n      server_url: serverUrl,\n      date_time: dateTime,\n      sender,\n      apikey: apiKey,\n    };\n\n    if (configService.get<Websocket>('WEBSOCKET')?.GLOBAL_EVENTS) {\n      this.socket.emit(event, message);\n\n      if (logEnabled) {\n        this.logger.log({ local: `${origin}.sendData-WebsocketGlobal`, ...message });\n      }\n    }\n\n    try {\n      const instance = await this.get(instanceName);\n\n      if (!instance?.enabled) {\n        return;\n      }\n\n      if (Array.isArray(instance?.events) && instance?.events.includes(configEv)) {\n        this.socket.of(`/${instanceName}`).emit(event, message);\n\n        if (logEnabled) {\n          this.logger.log({ local: `${origin}.sendData-Websocket`, ...message });\n        }\n      }\n    } catch (err) {\n      if (logEnabled) {\n        this.logger.log(err);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/event/websocket/websocket.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { EventDto } from '@api/integrations/event/event.dto';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { eventManager } from '@api/server.module';\nimport { eventSchema, instanceSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nexport class WebsocketRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<EventDto>({\n          request: req,\n          schema: eventSchema,\n          ClassRef: EventDto,\n          execute: (instance, data) => eventManager.websocket.set(instance.instanceName, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => eventManager.websocket.get(instance.instanceName),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/integration.dto.ts",
    "content": "import { ChatwootInstanceMixin } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { EventInstanceMixin } from '@api/integrations/event/event.dto';\n\nexport type Constructor<T = {}> = new (...args: any[]) => T;\n\nexport class IntegrationDto extends EventInstanceMixin(ChatwootInstanceMixin(class {})) {}\n"
  },
  {
    "path": "src/api/integrations/storage/s3/controllers/s3.controller.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';\nimport { S3Service } from '@api/integrations/storage/s3/services/s3.service';\n\nexport class S3Controller {\n  constructor(private readonly s3Service: S3Service) {}\n\n  public async getMedia(instance: InstanceDto, data: MediaDto) {\n    return this.s3Service.getMedia(instance, data);\n  }\n\n  public async getMediaUrl(instance: InstanceDto, data: MediaDto) {\n    return this.s3Service.getMediaUrl(instance, data);\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/storage/s3/dto/media.dto.ts",
    "content": "export class MediaDto {\n  id?: string;\n  type?: string;\n  messageId?: number;\n  expiry?: number;\n}\n"
  },
  {
    "path": "src/api/integrations/storage/s3/libs/minio.server.ts",
    "content": "import { ConfigService, S3 } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\nimport * as MinIo from 'minio';\nimport { join } from 'path';\nimport { Readable, Transform } from 'stream';\n\nconst logger = new Logger('S3 Service');\n\nconst BUCKET = new ConfigService().get<S3>('S3');\n\ninterface Metadata extends MinIo.ItemBucketMetadata {\n  'Content-Type': string;\n}\n\nconst minioClient = (() => {\n  if (BUCKET?.ENABLE) {\n    return new MinIo.Client({\n      endPoint: BUCKET.ENDPOINT,\n      port: BUCKET.PORT,\n      useSSL: BUCKET.USE_SSL,\n      accessKey: BUCKET.ACCESS_KEY,\n      secretKey: BUCKET.SECRET_KEY,\n      region: BUCKET.REGION,\n    });\n  }\n})();\n\nconst bucketName = BUCKET.BUCKET_NAME;\n\nconst bucketExists = async () => {\n  if (minioClient) {\n    try {\n      const list = await minioClient.listBuckets();\n      return list.find((bucket) => bucket.name === bucketName);\n    } catch {\n      return false;\n    }\n  }\n};\n\nconst setBucketPolicy = async () => {\n  if (minioClient) {\n    const policy = {\n      Version: '2012-10-17',\n      Statement: [\n        {\n          Effect: 'Allow',\n          Principal: '*',\n          Action: ['s3:GetObject'],\n          Resource: [`arn:aws:s3:::${bucketName}/*`],\n        },\n      ],\n    };\n    await minioClient.setBucketPolicy(bucketName, JSON.stringify(policy));\n  }\n};\n\nconst createBucket = async () => {\n  if (minioClient) {\n    try {\n      const exists = await bucketExists();\n      if (!exists) {\n        await minioClient.makeBucket(bucketName);\n      }\n      if (!BUCKET.SKIP_POLICY) {\n        await setBucketPolicy();\n      }\n      logger.info(`S3 Bucket ${bucketName} - ON`);\n      return true;\n    } catch (error) {\n      logger.error('S3 ERROR:');\n      logger.error(error);\n      return false;\n    }\n  }\n};\n\ncreateBucket();\n\nconst uploadFile = async (fileName: string, file: Buffer | Transform | Readable, size: number, metadata: Metadata) => {\n  if (minioClient) {\n    const objectName = join('evolution-api', fileName);\n    try {\n      metadata['custom-header-application'] = 'evolution-api';\n      return await minioClient.putObject(bucketName, objectName, file, size, metadata);\n    } catch (error) {\n      logger.error(error);\n      return error;\n    }\n  }\n};\n\nconst getObjectUrl = async (fileName: string, expiry?: number) => {\n  if (minioClient) {\n    try {\n      const objectName = join('evolution-api', fileName);\n      if (expiry) {\n        return await minioClient.presignedGetObject(bucketName, objectName, expiry);\n      }\n      return await minioClient.presignedGetObject(bucketName, objectName);\n    } catch (error) {\n      throw new BadRequestException(error?.message);\n    }\n  }\n};\n\nconst uploadTempFile = async (\n  folder: string,\n  fileName: string,\n  file: Buffer | Transform | Readable,\n  size: number,\n  metadata: Metadata,\n) => {\n  if (minioClient) {\n    const objectName = join(folder, fileName);\n    try {\n      metadata['custom-header-application'] = 'evolution-api';\n      return await minioClient.putObject(bucketName, objectName, file, size, metadata);\n    } catch (error) {\n      logger.error(error);\n      return error;\n    }\n  }\n};\n\nconst deleteFile = async (folder: string, fileName: string) => {\n  if (minioClient) {\n    const objectName = join(folder, fileName);\n    try {\n      return await minioClient.removeObject(bucketName, objectName);\n    } catch (error) {\n      logger.error(error);\n      return error;\n    }\n  }\n};\n\nexport { BUCKET, deleteFile, getObjectUrl, uploadFile, uploadTempFile };\n"
  },
  {
    "path": "src/api/integrations/storage/s3/routes/s3.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';\nimport { s3Schema, s3UrlSchema } from '@api/integrations/storage/s3/validate/s3.schema';\nimport { HttpStatus } from '@api/routes/index.router';\nimport { s3Controller } from '@api/server.module';\nimport { RequestHandler, Router } from 'express';\n\nexport class S3Router extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('getMedia'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<MediaDto>({\n          request: req,\n          schema: s3Schema,\n          ClassRef: MediaDto,\n          execute: (instance, data) => s3Controller.getMedia(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('getMediaUrl'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<MediaDto>({\n          request: req,\n          schema: s3UrlSchema,\n          ClassRef: MediaDto,\n          execute: (instance, data) => s3Controller.getMediaUrl(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/integrations/storage/s3/services/s3.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { MediaDto } from '@api/integrations/storage/s3/dto/media.dto';\nimport { getObjectUrl } from '@api/integrations/storage/s3/libs/minio.server';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { Logger } from '@config/logger.config';\nimport { BadRequestException } from '@exceptions';\n\nexport class S3Service {\n  constructor(private readonly prismaRepository: PrismaRepository) {}\n\n  private readonly logger = new Logger('S3Service');\n\n  public async getMedia(instance: InstanceDto, query?: MediaDto) {\n    try {\n      const where: any = {\n        instanceId: instance.instanceId,\n        ...query,\n      };\n\n      const media = await this.prismaRepository.media.findMany({\n        where,\n        select: {\n          id: true,\n          fileName: true,\n          type: true,\n          mimetype: true,\n          createdAt: true,\n          Message: true,\n        },\n      });\n\n      if (!media || media.length === 0) {\n        throw 'Media not found';\n      }\n\n      return media;\n    } catch (error) {\n      throw new BadRequestException(error);\n    }\n  }\n\n  public async getMediaUrl(instance: InstanceDto, data: MediaDto) {\n    const media = (await this.getMedia(instance, { id: data.id }))[0];\n    const mediaUrl = await getObjectUrl(media.fileName, data.expiry);\n    return {\n      mediaUrl,\n      ...media,\n    };\n  }\n}\n"
  },
  {
    "path": "src/api/integrations/storage/s3/validate/s3.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const s3Schema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    id: { type: 'string' },\n    type: { type: 'string' },\n    messageId: { type: 'integer' },\n  },\n  ...isNotEmpty('id', 'type', 'messageId'),\n};\n\nexport const s3UrlSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    id: { type: 'string', pattern: '\\\\d+', minLength: 1 },\n    expiry: { type: 'string', pattern: '\\\\d+', minLength: 1 },\n  },\n  ...isNotEmpty('id'),\n  required: ['id'],\n};\n"
  },
  {
    "path": "src/api/integrations/storage/storage.router.ts",
    "content": "import { S3Router } from '@api/integrations/storage/s3/routes/s3.router';\nimport { Router } from 'express';\n\nexport class StorageRouter {\n  public readonly router: Router;\n\n  constructor(...guards: any[]) {\n    this.router = Router();\n\n    this.router.use('/s3', new S3Router(...guards).router);\n  }\n}\n"
  },
  {
    "path": "src/api/provider/sessions.ts",
    "content": "import { Auth, ConfigService, ProviderSession } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport axios from 'axios';\nimport { execFileSync } from 'child_process';\n\ntype ResponseSuccess = { status: number; data?: any };\ntype ResponseProvider = Promise<[ResponseSuccess?, Error?]>;\n\nexport class ProviderFiles {\n  constructor(private readonly configService: ConfigService) {\n    this.baseUrl = `http://${this.config.HOST}:${this.config.PORT}/session/${this.config.PREFIX}`;\n    this.globalApiToken = this.configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;\n  }\n\n  private readonly logger = new Logger('ProviderFiles');\n\n  private baseUrl: string;\n  private globalApiToken: string;\n\n  private readonly config = Object.freeze(this.configService.get<ProviderSession>('PROVIDER'));\n\n  get isEnabled() {\n    return !!this.config?.ENABLED;\n  }\n\n  public async onModuleInit() {\n    if (this.config.ENABLED) {\n      const url = `http://${this.config.HOST}:${this.config.PORT}`;\n      try {\n        const response = await axios.options(url + '/ping');\n        if (response?.data != 'pong') {\n          throw new Error('Offline file provider.');\n        }\n\n        await axios.post(`${url}/session`, { group: this.config.PREFIX }, { headers: { apikey: this.globalApiToken } });\n      } catch (error) {\n        this.logger.error(['Failed to connect to the file server', error?.message, error?.stack]);\n        const pid = process.pid;\n        execFileSync('kill', ['-9', `${pid}`]);\n      }\n    }\n  }\n\n  public async onModuleDestroy() {\n    //\n  }\n\n  public async create(instance: string): ResponseProvider {\n    try {\n      const response = await axios.post(\n        `${this.baseUrl}`,\n        {\n          instance,\n        },\n        { headers: { apikey: this.globalApiToken } },\n      );\n      return [{ status: response.status, data: response?.data }];\n    } catch (error) {\n      return [\n        {\n          status: error?.response?.status,\n          data: error?.response?.data,\n        },\n        error,\n      ];\n    }\n  }\n\n  public async write(instance: string, key: string, data: any): ResponseProvider {\n    try {\n      const response = await axios.post(`${this.baseUrl}/${instance}/${key}`, data, {\n        headers: { apikey: this.globalApiToken },\n      });\n      return [{ status: response.status, data: response?.data }];\n    } catch (error) {\n      return [\n        {\n          status: error?.response?.status,\n          data: error?.response?.data,\n        },\n        error,\n      ];\n    }\n  }\n\n  public async read(instance: string, key: string): ResponseProvider {\n    try {\n      const response = await axios.get(`${this.baseUrl}/${instance}/${key}`, {\n        headers: { apikey: this.globalApiToken },\n      });\n      return [{ status: response.status, data: response?.data }];\n    } catch (error) {\n      return [\n        {\n          status: error?.response?.status,\n          data: error?.response?.data,\n        },\n        error,\n      ];\n    }\n  }\n\n  public async delete(instance: string, key: string): ResponseProvider {\n    try {\n      const response = await axios.delete(`${this.baseUrl}/${instance}/${key}`, {\n        headers: { apikey: this.globalApiToken },\n      });\n      return [{ status: response.status, data: response?.data }];\n    } catch (error) {\n      return [\n        {\n          status: error?.response?.status,\n          data: error?.response?.data,\n        },\n        error,\n      ];\n    }\n  }\n\n  public async allInstances(): ResponseProvider {\n    try {\n      const response = await axios.get(`${this.baseUrl}/list-instances`, { headers: { apikey: this.globalApiToken } });\n      return [{ status: response.status, data: response?.data as string[] }];\n    } catch (error) {\n      return [\n        {\n          status: error?.response?.status,\n          data: error?.response?.data,\n        },\n        error,\n      ];\n    }\n  }\n\n  public async removeSession(instance: string): ResponseProvider {\n    try {\n      const response = await axios.delete(`${this.baseUrl}/${instance}`, { headers: { apikey: this.globalApiToken } });\n      return [{ status: response.status, data: response?.data }];\n    } catch (error) {\n      return [\n        {\n          status: error?.response?.status,\n          data: error?.response?.data,\n        },\n        error,\n      ];\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/repository/repository.service.ts",
    "content": "import { ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { PrismaClient } from '@prisma/client';\n\nexport class Query<T> {\n  where?: T;\n  sort?: 'asc' | 'desc';\n  page?: number;\n  offset?: number;\n}\n\nexport class PrismaRepository extends PrismaClient {\n  constructor(private readonly configService: ConfigService) {\n    super();\n  }\n\n  private readonly logger = new Logger('PrismaRepository');\n\n  public async onModuleInit() {\n    await this.$connect();\n    this.logger.info('Repository:Prisma - ON');\n  }\n\n  public async onModuleDestroy() {\n    await this.$disconnect();\n    this.logger.warn('Repository:Prisma - OFF');\n  }\n}\n"
  },
  {
    "path": "src/api/routes/business.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { NumberDto } from '@api/dto/chat.dto';\nimport { businessController } from '@api/server.module';\nimport { createMetaErrorResponse } from '@utils/errorResponse';\nimport { catalogSchema, collectionsSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class BusinessRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('getCatalog'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<NumberDto>({\n            request: req,\n            schema: catalogSchema,\n            ClassRef: NumberDto,\n            execute: (instance, data) => businessController.fetchCatalog(instance, data),\n          });\n\n          return res.status(HttpStatus.OK).json(response);\n        } catch (error) {\n          // Log error for debugging\n          console.error('Business catalog error:', error);\n\n          // Use utility function to create standardized error response\n          const errorResponse = createMetaErrorResponse(error, 'business_catalog');\n          return res.status(errorResponse.status).json(errorResponse);\n        }\n      })\n\n      .post(this.routerPath('getCollections'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<NumberDto>({\n            request: req,\n            schema: collectionsSchema,\n            ClassRef: NumberDto,\n            execute: (instance, data) => businessController.fetchCollections(instance, data),\n          });\n\n          return res.status(HttpStatus.OK).json(response);\n        } catch (error) {\n          // Log error for debugging\n          console.error('Business collections error:', error);\n\n          // Use utility function to create standardized error response\n          const errorResponse = createMetaErrorResponse(error, 'business_collections');\n          return res.status(errorResponse.status).json(errorResponse);\n        }\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/call.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { OfferCallDto } from '@api/dto/call.dto';\nimport { callController } from '@api/server.module';\nimport { offerCallSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class CallRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router.post(this.routerPath('offer'), ...guards, async (req, res) => {\n      const response = await this.dataValidate<OfferCallDto>({\n        request: req,\n        schema: offerCallSchema,\n        ClassRef: OfferCallDto,\n        execute: (instance, data) => callController.offerCall(instance, data),\n      });\n\n      return res.status(HttpStatus.CREATED).json(response);\n    });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/chat.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport {\n  ArchiveChatDto,\n  BlockUserDto,\n  DeleteMessage,\n  getBase64FromMediaMessageDto,\n  MarkChatUnreadDto,\n  NumberDto,\n  PrivacySettingDto,\n  ProfileNameDto,\n  ProfilePictureDto,\n  ProfileStatusDto,\n  ReadMessageDto,\n  SendPresenceDto,\n  UpdateMessageDto,\n  WhatsAppNumberDto,\n} from '@api/dto/chat.dto';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { Query } from '@api/repository/repository.service';\nimport { chatController } from '@api/server.module';\nimport { Contact, Message, MessageUpdate } from '@prisma/client';\nimport {\n  archiveChatSchema,\n  blockUserSchema,\n  contactValidateSchema,\n  deleteMessageSchema,\n  markChatUnreadSchema,\n  messageUpSchema,\n  messageValidateSchema,\n  presenceSchema,\n  privacySettingsSchema,\n  profileNameSchema,\n  profilePictureSchema,\n  profileSchema,\n  profileStatusSchema,\n  readMessageSchema,\n  updateMessageSchema,\n  whatsappNumberSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class ChatRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<WhatsAppNumberDto>({\n            request: req,\n            schema: whatsappNumberSchema,\n            ClassRef: WhatsAppNumberDto,\n            execute: (instance, data) => chatController.whatsappNumber(instance, data),\n          });\n\n          return res.status(HttpStatus.OK).json(response);\n        } catch (error) {\n          console.log(error);\n          return res.status(HttpStatus.BAD_REQUEST).json(error);\n        }\n      })\n      .post(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ReadMessageDto>({\n          request: req,\n          schema: readMessageSchema,\n          ClassRef: ReadMessageDto,\n          execute: (instance, data) => chatController.readMessage(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('archiveChat'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ArchiveChatDto>({\n          request: req,\n          schema: archiveChatSchema,\n          ClassRef: ArchiveChatDto,\n          execute: (instance, data) => chatController.archiveChat(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('markChatUnread'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<MarkChatUnreadDto>({\n          request: req,\n          schema: markChatUnreadSchema,\n          ClassRef: MarkChatUnreadDto,\n          execute: (instance, data) => chatController.markChatUnread(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<DeleteMessage>({\n          request: req,\n          schema: deleteMessageSchema,\n          ClassRef: DeleteMessage,\n          execute: (instance, data) => chatController.deleteMessage(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<NumberDto>({\n          request: req,\n          schema: profilePictureSchema,\n          ClassRef: NumberDto,\n          execute: (instance, data) => chatController.fetchProfilePicture(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<getBase64FromMediaMessageDto>({\n          request: req,\n          schema: null,\n          ClassRef: getBase64FromMediaMessageDto,\n          execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      // TODO: corrigir updateMessage para medias tambem\n      .post(this.routerPath('updateMessage'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<UpdateMessageDto>({\n          request: req,\n          schema: updateMessageSchema,\n          ClassRef: UpdateMessageDto,\n          execute: (instance, data) => chatController.updateMessage(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('sendPresence'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<null>({\n          request: req,\n          schema: presenceSchema,\n          ClassRef: SendPresenceDto,\n          execute: (instance, data) => chatController.sendPresence(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('updateBlockStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<BlockUserDto>({\n          request: req,\n          schema: blockUserSchema,\n          ClassRef: BlockUserDto,\n          execute: (instance, data) => chatController.blockUser(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('findContacts'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<Query<Contact>>({\n          request: req,\n          schema: contactValidateSchema,\n          ClassRef: Query<Contact>,\n          execute: (instance, data) => chatController.fetchContacts(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('findMessages'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<Query<Message>>({\n          request: req,\n          schema: messageValidateSchema,\n          ClassRef: Query<Message>,\n          execute: (instance, data) => chatController.fetchMessages(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<Query<MessageUpdate>>({\n          request: req,\n          schema: messageUpSchema,\n          ClassRef: Query<MessageUpdate>,\n          execute: (instance, data) => chatController.fetchStatusMessage(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('findChats'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<Query<Contact>>({\n          request: req,\n          schema: contactValidateSchema,\n          ClassRef: Query<Contact>,\n          execute: (instance, data) => chatController.fetchChats(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('findChatByRemoteJid'), ...guards, async (req, res) => {\n        const instance = req.params as unknown as InstanceDto;\n        const { remoteJid } = req.query as unknown as { remoteJid: string };\n        if (!remoteJid) {\n          return res.status(HttpStatus.BAD_REQUEST).json({ error: 'remoteJid is a required query parameter' });\n        }\n        const response = await chatController.findChatByRemoteJid(instance, remoteJid);\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      // Profile routes\n      .post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ProfilePictureDto>({\n          request: req,\n          schema: profilePictureSchema,\n          ClassRef: ProfilePictureDto,\n          execute: (instance, data) => chatController.fetchBusinessProfile(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('fetchProfile'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<NumberDto>({\n          request: req,\n          schema: profileSchema,\n          ClassRef: NumberDto,\n          execute: (instance, data) => chatController.fetchProfile(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('updateProfileName'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ProfileNameDto>({\n          request: req,\n          schema: profileNameSchema,\n          ClassRef: ProfileNameDto,\n          execute: (instance, data) => chatController.updateProfileName(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ProfileStatusDto>({\n          request: req,\n          schema: profileStatusSchema,\n          ClassRef: ProfileStatusDto,\n          execute: (instance, data) => chatController.updateProfileStatus(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ProfilePictureDto>({\n          request: req,\n          schema: profilePictureSchema,\n          ClassRef: ProfilePictureDto,\n          execute: (instance, data) => chatController.updateProfilePicture(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ProfilePictureDto>({\n          request: req,\n          schema: profilePictureSchema,\n          ClassRef: ProfilePictureDto,\n          execute: (instance) => chatController.removeProfilePicture(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => chatController.fetchPrivacySettings(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<PrivacySettingDto>({\n          request: req,\n          schema: privacySettingsSchema,\n          ClassRef: PrivacySettingDto,\n          execute: (instance, data) => chatController.updatePrivacySettings(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/group.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport {\n  AcceptGroupInvite,\n  CreateGroupDto,\n  GetParticipant,\n  GroupDescriptionDto,\n  GroupInvite,\n  GroupJid,\n  GroupPictureDto,\n  GroupSendInvite,\n  GroupSubjectDto,\n  GroupToggleEphemeralDto,\n  GroupUpdateParticipantDto,\n  GroupUpdateSettingDto,\n} from '@api/dto/group.dto';\nimport { groupController } from '@api/server.module';\nimport {\n  AcceptGroupInviteSchema,\n  createGroupSchema,\n  getParticipantsSchema,\n  groupInviteSchema,\n  groupJidSchema,\n  groupSendInviteSchema,\n  toggleEphemeralSchema,\n  updateGroupDescriptionSchema,\n  updateGroupPictureSchema,\n  updateGroupSubjectSchema,\n  updateParticipantsSchema,\n  updateSettingsSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class GroupRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<CreateGroupDto>({\n          request: req,\n          schema: createGroupSchema,\n          ClassRef: CreateGroupDto,\n          execute: (instance, data) => groupController.createGroup(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupSubjectDto>({\n          request: req,\n          schema: updateGroupSubjectSchema,\n          ClassRef: GroupSubjectDto,\n          execute: (instance, data) => groupController.updateGroupSubject(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupPictureDto>({\n          request: req,\n          schema: updateGroupPictureSchema,\n          ClassRef: GroupPictureDto,\n          execute: (instance, data) => groupController.updateGroupPicture(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupDescriptionDto>({\n          request: req,\n          schema: updateGroupDescriptionSchema,\n          ClassRef: GroupDescriptionDto,\n          execute: (instance, data) => groupController.updateGroupDescription(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupJid>({\n          request: req,\n          schema: groupJidSchema,\n          ClassRef: GroupJid,\n          execute: (instance, data) => groupController.findGroupInfo(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => {\n        const response = await this.getParticipantsValidate<GetParticipant>({\n          request: req,\n          schema: getParticipantsSchema,\n          ClassRef: GetParticipant,\n          execute: (instance, data) => groupController.fetchAllGroups(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('participants'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupJid>({\n          request: req,\n          schema: groupJidSchema,\n          ClassRef: GroupJid,\n          execute: (instance, data) => groupController.findParticipants(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('inviteCode'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupJid>({\n          request: req,\n          schema: groupJidSchema,\n          ClassRef: GroupJid,\n          execute: (instance, data) => groupController.inviteCode(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('inviteInfo'), ...guards, async (req, res) => {\n        const response = await this.inviteCodeValidate<GroupInvite>({\n          request: req,\n          schema: groupInviteSchema,\n          ClassRef: GroupInvite,\n          execute: (instance, data) => groupController.inviteInfo(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('acceptInviteCode'), ...guards, async (req, res) => {\n        const response = await this.inviteCodeValidate<AcceptGroupInvite>({\n          request: req,\n          schema: AcceptGroupInviteSchema,\n          ClassRef: AcceptGroupInvite,\n          execute: (instance, data) => groupController.acceptInviteCode(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('sendInvite'), ...guards, async (req, res) => {\n        const response = await this.groupNoValidate<GroupSendInvite>({\n          request: req,\n          schema: groupSendInviteSchema,\n          ClassRef: GroupSendInvite,\n          execute: (instance, data) => groupController.sendInvite(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupJid>({\n          request: req,\n          schema: groupJidSchema,\n          ClassRef: GroupJid,\n          execute: (instance, data) => groupController.revokeInviteCode(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('updateParticipant'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupUpdateParticipantDto>({\n          request: req,\n          schema: updateParticipantsSchema,\n          ClassRef: GroupUpdateParticipantDto,\n          execute: (instance, data) => groupController.updateGParticipate(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('updateSetting'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupUpdateSettingDto>({\n          request: req,\n          schema: updateSettingsSchema,\n          ClassRef: GroupUpdateSettingDto,\n          execute: (instance, data) => groupController.updateGSetting(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupToggleEphemeralDto>({\n          request: req,\n          schema: toggleEphemeralSchema,\n          ClassRef: GroupToggleEphemeralDto,\n          execute: (instance, data) => groupController.toggleEphemeral(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => {\n        const response = await this.groupValidate<GroupJid>({\n          request: req,\n          schema: {},\n          ClassRef: GroupJid,\n          execute: (instance, data) => groupController.leaveGroup(instance, data),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/index.router.ts",
    "content": "import { authGuard } from '@api/guards/auth.guard';\nimport { instanceExistsGuard, instanceLoggedGuard } from '@api/guards/instance.guard';\nimport Telemetry from '@api/guards/telemetry.guard';\nimport { ChannelRouter } from '@api/integrations/channel/channel.router';\nimport { ChatbotRouter } from '@api/integrations/chatbot/chatbot.router';\nimport { EventRouter } from '@api/integrations/event/event.router';\nimport { StorageRouter } from '@api/integrations/storage/storage.router';\nimport { waMonitor } from '@api/server.module';\nimport { configService, Database, Facebook } from '@config/env.config';\nimport { fetchLatestWaWebVersion } from '@utils/fetchLatestWaWebVersion';\nimport { NextFunction, Request, Response, Router } from 'express';\nimport fs from 'fs';\nimport mimeTypes from 'mime-types';\nimport path from 'path';\n\nimport { BusinessRouter } from './business.router';\nimport { CallRouter } from './call.router';\nimport { ChatRouter } from './chat.router';\nimport { GroupRouter } from './group.router';\nimport { InstanceRouter } from './instance.router';\nimport { LabelRouter } from './label.router';\nimport { ProxyRouter } from './proxy.router';\nimport { MessageRouter } from './sendMessage.router';\nimport { SettingsRouter } from './settings.router';\nimport { TemplateRouter } from './template.router';\nimport { ViewsRouter } from './view.router';\n\nenum HttpStatus {\n  OK = 200,\n  CREATED = 201,\n  NOT_FOUND = 404,\n  FORBIDDEN = 403,\n  BAD_REQUEST = 400,\n  UNAUTHORIZED = 401,\n  INTERNAL_SERVER_ERROR = 500,\n}\n\nconst router: Router = Router();\nconst serverConfig = configService.get('SERVER');\nconst databaseConfig = configService.get<Database>('DATABASE');\nconst guards = [instanceExistsGuard, instanceLoggedGuard, authGuard['apikey']];\n\nconst telemetry = new Telemetry();\n\nconst packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));\n\n// Middleware for metrics IP whitelist\nconst metricsIPWhitelist = (req: Request, res: Response, next: NextFunction) => {\n  const metricsConfig = configService.get('METRICS');\n  const allowedIPs = metricsConfig.ALLOWED_IPS?.split(',').map((ip) => ip.trim()) || ['127.0.0.1'];\n  const clientIPs = [\n    req.ip,\n    req.connection.remoteAddress,\n    req.socket.remoteAddress,\n    req.headers['x-forwarded-for'],\n  ].filter((ip) => ip !== undefined);\n\n  if (allowedIPs.filter((ip) => clientIPs.includes(ip)) === 0) {\n    return res.status(403).send('Forbidden: IP not allowed');\n  }\n\n  next();\n};\n\n// Middleware for metrics Basic Authentication\nconst metricsBasicAuth = (req: Request, res: Response, next: NextFunction) => {\n  const metricsConfig = configService.get('METRICS');\n  const metricsUser = metricsConfig.USER;\n  const metricsPass = metricsConfig.PASSWORD;\n\n  if (!metricsUser || !metricsPass) {\n    return res.status(500).send('Metrics authentication not configured');\n  }\n\n  const auth = req.get('Authorization');\n  if (!auth || !auth.startsWith('Basic ')) {\n    res.set('WWW-Authenticate', 'Basic realm=\"Evolution API Metrics\"');\n    return res.status(401).send('Authentication required');\n  }\n\n  const credentials = Buffer.from(auth.slice(6), 'base64').toString();\n  const [user, pass] = credentials.split(':');\n\n  if (user !== metricsUser || pass !== metricsPass) {\n    return res.status(401).send('Invalid credentials');\n  }\n\n  next();\n};\n\n// Expose Prometheus metrics when enabled by env flag\nconst metricsConfig = configService.get('METRICS');\nif (metricsConfig.ENABLED) {\n  const metricsMiddleware = [];\n\n  // Add IP whitelist if configured\n  if (metricsConfig.ALLOWED_IPS) {\n    metricsMiddleware.push(metricsIPWhitelist);\n  }\n\n  // Add Basic Auth if required\n  if (metricsConfig.AUTH_REQUIRED) {\n    metricsMiddleware.push(metricsBasicAuth);\n  }\n\n  router.get('/metrics', ...metricsMiddleware, async (req, res) => {\n    res.set('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');\n    res.set('Cache-Control', 'no-cache, no-store, must-revalidate');\n\n    const escapeLabel = (value: unknown) =>\n      String(value ?? '')\n        .replace(/\\\\/g, '\\\\\\\\')\n        .replace(/\\n/g, '\\\\n')\n        .replace(/\"/g, '\\\\\"');\n\n    const lines: string[] = [];\n\n    const clientName = databaseConfig.CONNECTION.CLIENT_NAME || 'unknown';\n    const serverUrl = serverConfig.URL || '';\n\n    // environment info\n    lines.push('# HELP evolution_environment_info Environment information');\n    lines.push('# TYPE evolution_environment_info gauge');\n    lines.push(\n      `evolution_environment_info{version=\"${escapeLabel(packageJson.version)}\",clientName=\"${escapeLabel(\n        clientName,\n      )}\",serverUrl=\"${escapeLabel(serverUrl)}\"} 1`,\n    );\n\n    const instances = (waMonitor && waMonitor.waInstances) || {};\n    const instanceEntries = Object.entries(instances);\n\n    // total instances\n    lines.push('# HELP evolution_instances_total Total number of instances');\n    lines.push('# TYPE evolution_instances_total gauge');\n    lines.push(`evolution_instances_total ${instanceEntries.length}`);\n\n    // per-instance status\n    lines.push('# HELP evolution_instance_up 1 if instance state is open, else 0');\n    lines.push('# TYPE evolution_instance_up gauge');\n    lines.push('# HELP evolution_instance_state Instance state as a labelled metric');\n    lines.push('# TYPE evolution_instance_state gauge');\n\n    for (const [name, instance] of instanceEntries) {\n      const state = instance?.connectionStatus?.state || 'unknown';\n      const integration = instance?.integration || '';\n      const up = state === 'open' ? 1 : 0;\n\n      lines.push(\n        `evolution_instance_up{instance=\"${escapeLabel(name)}\",integration=\"${escapeLabel(integration)}\"} ${up}`,\n      );\n      lines.push(\n        `evolution_instance_state{instance=\"${escapeLabel(name)}\",integration=\"${escapeLabel(\n          integration,\n        )}\",state=\"${escapeLabel(state)}\"} 1`,\n      );\n    }\n\n    res.send(lines.join('\\n') + '\\n');\n  });\n}\n\nif (!serverConfig.DISABLE_MANAGER) router.use('/manager', new ViewsRouter().router);\n\nrouter.get('/assets/*', (req, res) => {\n  const fileName = req.params[0];\n\n  // Security: Reject paths containing traversal patterns\n  if (!fileName || fileName.includes('..') || fileName.includes('\\\\') || path.isAbsolute(fileName)) {\n    return res.status(403).send('Forbidden');\n  }\n\n  const basePath = path.join(process.cwd(), 'manager', 'dist');\n  const assetsPath = path.join(basePath, 'assets');\n  const filePath = path.join(assetsPath, fileName);\n\n  // Security: Ensure the resolved path is within the assets directory\n  const resolvedPath = path.resolve(filePath);\n  const resolvedAssetsPath = path.resolve(assetsPath);\n\n  if (!resolvedPath.startsWith(resolvedAssetsPath + path.sep) && resolvedPath !== resolvedAssetsPath) {\n    return res.status(403).send('Forbidden');\n  }\n\n  if (fs.existsSync(resolvedPath)) {\n    res.set('Content-Type', mimeTypes.lookup(resolvedPath) || 'text/css');\n    res.send(fs.readFileSync(resolvedPath));\n  } else {\n    res.status(404).send('File not found');\n  }\n});\n\nrouter\n  .use((req, res, next) => telemetry.collectTelemetry(req, res, next))\n\n  .get('/', async (req, res) => {\n    res.status(HttpStatus.OK).json({\n      status: HttpStatus.OK,\n      message: 'Welcome to the Evolution API, it is working!',\n      version: packageJson.version,\n      clientName: databaseConfig.CONNECTION.CLIENT_NAME,\n      manager: !serverConfig.DISABLE_MANAGER ? `${req.protocol}://${req.get('host')}/manager` : undefined,\n      documentation: `https://doc.evolution-api.com`,\n      whatsappWebVersion: (await fetchLatestWaWebVersion({})).version.join('.'),\n    });\n  })\n  .post('/verify-creds', authGuard['apikey'], async (req, res) => {\n    const facebookConfig = configService.get<Facebook>('FACEBOOK');\n    return res.status(HttpStatus.OK).json({\n      status: HttpStatus.OK,\n      message: 'Credentials are valid',\n      facebookAppId: facebookConfig.APP_ID,\n      facebookConfigId: facebookConfig.CONFIG_ID,\n      facebookUserToken: facebookConfig.USER_TOKEN,\n    });\n  })\n  .use('/instance', new InstanceRouter(configService, ...guards).router)\n  .use('/message', new MessageRouter(...guards).router)\n  .use('/call', new CallRouter(...guards).router)\n  .use('/chat', new ChatRouter(...guards).router)\n  .use('/business', new BusinessRouter(...guards).router)\n  .use('/group', new GroupRouter(...guards).router)\n  .use('/template', new TemplateRouter(configService, ...guards).router)\n  .use('/settings', new SettingsRouter(...guards).router)\n  .use('/proxy', new ProxyRouter(...guards).router)\n  .use('/label', new LabelRouter(...guards).router)\n  .use('', new ChannelRouter(configService, ...guards).router)\n  .use('', new EventRouter(configService, ...guards).router)\n  .use('', new ChatbotRouter(...guards).router)\n  .use('', new StorageRouter(...guards).router);\n\nexport { HttpStatus, router };\n"
  },
  {
    "path": "src/api/routes/instance.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto, SetPresenceDto } from '@api/dto/instance.dto';\nimport { instanceController } from '@api/server.module';\nimport { ConfigService } from '@config/env.config';\nimport { instanceSchema, presenceOnlySchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class InstanceRouter extends RouterBroker {\n  constructor(\n    readonly configService: ConfigService,\n    ...guards: RequestHandler[]\n  ) {\n    super();\n    this.router\n      .post('/create', ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.createInstance(instance),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('restart'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.restartInstance(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('connect'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.connectToWhatsapp(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('connectionState'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.connectionState(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => {\n        const key = req.get('apikey');\n\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.fetchInstances(instance, key),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('setPresence'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<null>({\n          request: req,\n          schema: presenceOnlySchema,\n          ClassRef: SetPresenceDto,\n          execute: (instance, data) => instanceController.setPresence(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .delete(this.routerPath('logout'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.logout(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .delete(this.routerPath('delete'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => instanceController.deleteInstance(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/label.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { HandleLabelDto, LabelDto } from '@api/dto/label.dto';\nimport { labelController } from '@api/server.module';\nimport { handleLabelSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class LabelRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .get(this.routerPath('findLabels'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<LabelDto>({\n          request: req,\n          schema: null,\n          ClassRef: LabelDto,\n          execute: (instance) => labelController.fetchLabels(instance),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      })\n      .post(this.routerPath('handleLabel'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<HandleLabelDto>({\n          request: req,\n          schema: handleLabelSchema,\n          ClassRef: HandleLabelDto,\n          execute: (instance, data) => labelController.handleLabel(instance, data),\n        });\n\n        return res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/proxy.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { ProxyDto } from '@api/dto/proxy.dto';\nimport { proxyController } from '@api/server.module';\nimport { instanceSchema, proxySchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class ProxyRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<ProxyDto>({\n          request: req,\n          schema: proxySchema,\n          ClassRef: ProxyDto,\n          execute: (instance, data) => proxyController.createProxy(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: instanceSchema,\n          ClassRef: InstanceDto,\n          execute: (instance) => proxyController.findProxy(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/sendMessage.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport {\n  SendAudioDto,\n  SendButtonsDto,\n  SendContactDto,\n  SendListDto,\n  SendLocationDto,\n  SendMediaDto,\n  SendPollDto,\n  SendPtvDto,\n  SendReactionDto,\n  SendStatusDto,\n  SendStickerDto,\n  SendTemplateDto,\n  SendTextDto,\n} from '@api/dto/sendMessage.dto';\nimport { sendMessageController } from '@api/server.module';\nimport {\n  audioMessageSchema,\n  buttonsMessageSchema,\n  contactMessageSchema,\n  listMessageSchema,\n  locationMessageSchema,\n  mediaMessageSchema,\n  pollMessageSchema,\n  ptvMessageSchema,\n  reactionMessageSchema,\n  statusMessageSchema,\n  stickerMessageSchema,\n  templateMessageSchema,\n  textMessageSchema,\n} from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\nimport multer from 'multer';\n\nimport { HttpStatus } from './index.router';\n\nconst upload = multer({ storage: multer.memoryStorage() });\n\nexport class MessageRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('sendTemplate'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendTemplateDto>({\n          request: req,\n          schema: templateMessageSchema,\n          ClassRef: SendTemplateDto,\n          execute: (instance, data) => sendMessageController.sendTemplate(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendText'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendTextDto>({\n          request: req,\n          schema: textMessageSchema,\n          ClassRef: SendTextDto,\n          execute: (instance, data) => sendMessageController.sendText(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendMedia'), ...guards, upload.single('file'), async (req, res) => {\n        const bodyData = req.body;\n\n        const response = await this.dataValidate<SendMediaDto>({\n          request: req,\n          schema: mediaMessageSchema,\n          ClassRef: SendMediaDto,\n          execute: (instance) => sendMessageController.sendMedia(instance, bodyData, req.file as any),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendPtv'), ...guards, upload.single('file'), async (req, res) => {\n        const bodyData = req.body;\n\n        const response = await this.dataValidate<SendPtvDto>({\n          request: req,\n          schema: ptvMessageSchema,\n          ClassRef: SendPtvDto,\n          execute: (instance) => sendMessageController.sendPtv(instance, bodyData, req.file as any),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendWhatsAppAudio'), ...guards, upload.single('file'), async (req, res) => {\n        const bodyData = req.body;\n\n        const response = await this.dataValidate<SendAudioDto>({\n          request: req,\n          schema: audioMessageSchema,\n          ClassRef: SendMediaDto,\n          execute: (instance) => sendMessageController.sendWhatsAppAudio(instance, bodyData, req.file as any),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      // TODO: Revisar funcionamento do envio de Status\n      .post(this.routerPath('sendStatus'), ...guards, upload.single('file'), async (req, res) => {\n        const bodyData = req.body;\n\n        const response = await this.dataValidate<SendStatusDto>({\n          request: req,\n          schema: statusMessageSchema,\n          ClassRef: SendStatusDto,\n          execute: (instance) => sendMessageController.sendStatus(instance, bodyData, req.file as any),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendSticker'), ...guards, upload.single('file'), async (req, res) => {\n        const bodyData = req.body;\n\n        const response = await this.dataValidate<SendStickerDto>({\n          request: req,\n          schema: stickerMessageSchema,\n          ClassRef: SendStickerDto,\n          execute: (instance) => sendMessageController.sendSticker(instance, bodyData, req.file as any),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendLocation'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendLocationDto>({\n          request: req,\n          schema: locationMessageSchema,\n          ClassRef: SendLocationDto,\n          execute: (instance, data) => sendMessageController.sendLocation(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendContact'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendContactDto>({\n          request: req,\n          schema: contactMessageSchema,\n          ClassRef: SendContactDto,\n          execute: (instance, data) => sendMessageController.sendContact(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendReaction'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendReactionDto>({\n          request: req,\n          schema: reactionMessageSchema,\n          ClassRef: SendReactionDto,\n          execute: (instance, data) => sendMessageController.sendReaction(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendPoll'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendPollDto>({\n          request: req,\n          schema: pollMessageSchema,\n          ClassRef: SendPollDto,\n          execute: (instance, data) => sendMessageController.sendPoll(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendList'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendListDto>({\n          request: req,\n          schema: listMessageSchema,\n          ClassRef: SendListDto,\n          execute: (instance, data) => sendMessageController.sendList(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      })\n      .post(this.routerPath('sendButtons'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SendButtonsDto>({\n          request: req,\n          schema: buttonsMessageSchema,\n          ClassRef: SendButtonsDto,\n          execute: (instance, data) => sendMessageController.sendButtons(instance, data),\n        });\n\n        return res.status(HttpStatus.CREATED).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/settings.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { SettingsDto } from '@api/dto/settings.dto';\nimport { settingsController } from '@api/server.module';\nimport { settingsSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class SettingsRouter extends RouterBroker {\n  constructor(...guards: RequestHandler[]) {\n    super();\n    this.router\n      .post(this.routerPath('set'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<SettingsDto>({\n          request: req,\n          schema: settingsSchema,\n          ClassRef: SettingsDto,\n          execute: (instance, data) => settingsController.createSettings(instance, data),\n        });\n\n        res.status(HttpStatus.CREATED).json(response);\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        const response = await this.dataValidate<InstanceDto>({\n          request: req,\n          schema: null,\n          ClassRef: InstanceDto,\n          execute: (instance) => settingsController.findSettings(instance),\n        });\n\n        res.status(HttpStatus.OK).json(response);\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/template.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport { InstanceDto } from '@api/dto/instance.dto';\nimport { TemplateDeleteDto, TemplateDto, TemplateEditDto } from '@api/dto/template.dto';\nimport { templateController } from '@api/server.module';\nimport { ConfigService } from '@config/env.config';\nimport { createMetaErrorResponse } from '@utils/errorResponse';\nimport { templateDeleteSchema } from '@validate/templateDelete.schema';\nimport { templateEditSchema } from '@validate/templateEdit.schema';\nimport { instanceSchema, templateSchema } from '@validate/validate.schema';\nimport { RequestHandler, Router } from 'express';\n\nimport { HttpStatus } from './index.router';\n\nexport class TemplateRouter extends RouterBroker {\n  constructor(\n    readonly configService: ConfigService,\n    ...guards: RequestHandler[]\n  ) {\n    super();\n    this.router\n      .post(this.routerPath('create'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<TemplateDto>({\n            request: req,\n            schema: templateSchema,\n            ClassRef: TemplateDto,\n            execute: (instance, data) => templateController.createTemplate(instance, data),\n          });\n\n          res.status(HttpStatus.CREATED).json(response);\n        } catch (error) {\n          // Log error for debugging\n          console.error('Template creation error:', error);\n\n          // Use utility function to create standardized error response\n          const errorResponse = createMetaErrorResponse(error, 'template_creation');\n          res.status(errorResponse.status).json(errorResponse);\n        }\n      })\n      .post(this.routerPath('edit'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<TemplateEditDto>({\n            request: req,\n            schema: templateEditSchema,\n            ClassRef: TemplateEditDto,\n            execute: (instance, data) => templateController.editTemplate(instance, data),\n          });\n\n          res.status(HttpStatus.OK).json(response);\n        } catch (error) {\n          console.error('Template edit error:', error);\n          const errorResponse = createMetaErrorResponse(error, 'template_edit');\n          res.status(errorResponse.status).json(errorResponse);\n        }\n      })\n      .delete(this.routerPath('delete'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<TemplateDeleteDto>({\n            request: req,\n            schema: templateDeleteSchema,\n            ClassRef: TemplateDeleteDto,\n            execute: (instance, data) => templateController.deleteTemplate(instance, data),\n          });\n\n          res.status(HttpStatus.OK).json(response);\n        } catch (error) {\n          console.error('Template delete error:', error);\n          const errorResponse = createMetaErrorResponse(error, 'template_delete');\n          res.status(errorResponse.status).json(errorResponse);\n        }\n      })\n      .get(this.routerPath('find'), ...guards, async (req, res) => {\n        try {\n          const response = await this.dataValidate<InstanceDto>({\n            request: req,\n            schema: instanceSchema,\n            ClassRef: InstanceDto,\n            execute: (instance) => templateController.findTemplate(instance),\n          });\n\n          res.status(HttpStatus.OK).json(response);\n        } catch (error) {\n          // Log error for debugging\n          console.error('Template find error:', error);\n\n          // Use utility function to create standardized error response\n          const errorResponse = createMetaErrorResponse(error, 'template_find');\n          res.status(errorResponse.status).json(errorResponse);\n        }\n      });\n  }\n\n  public readonly router: Router = Router();\n}\n"
  },
  {
    "path": "src/api/routes/view.router.ts",
    "content": "import { RouterBroker } from '@api/abstract/abstract.router';\nimport express, { Router } from 'express';\nimport path from 'path';\n\nexport class ViewsRouter extends RouterBroker {\n  public readonly router: Router;\n\n  constructor() {\n    super();\n    this.router = Router();\n\n    const basePath = path.join(process.cwd(), 'manager', 'dist');\n    const indexPath = path.join(basePath, 'index.html');\n\n    this.router.use(express.static(basePath));\n\n    this.router.get('*', (req, res) => {\n      res.sendFile(indexPath);\n    });\n  }\n}\n"
  },
  {
    "path": "src/api/server.module.ts",
    "content": "import { CacheEngine } from '@cache/cacheengine';\nimport { Chatwoot, configService, ProviderSession } from '@config/env.config';\nimport { eventEmitter } from '@config/event.config';\nimport { Logger } from '@config/logger.config';\n\nimport { BusinessController } from './controllers/business.controller';\nimport { CallController } from './controllers/call.controller';\nimport { ChatController } from './controllers/chat.controller';\nimport { GroupController } from './controllers/group.controller';\nimport { InstanceController } from './controllers/instance.controller';\nimport { LabelController } from './controllers/label.controller';\nimport { ProxyController } from './controllers/proxy.controller';\nimport { SendMessageController } from './controllers/sendMessage.controller';\nimport { SettingsController } from './controllers/settings.controller';\nimport { TemplateController } from './controllers/template.controller';\nimport { ChannelController } from './integrations/channel/channel.controller';\nimport { EvolutionController } from './integrations/channel/evolution/evolution.controller';\nimport { MetaController } from './integrations/channel/meta/meta.controller';\nimport { BaileysController } from './integrations/channel/whatsapp/baileys.controller';\nimport { ChatbotController } from './integrations/chatbot/chatbot.controller';\nimport { ChatwootController } from './integrations/chatbot/chatwoot/controllers/chatwoot.controller';\nimport { ChatwootService } from './integrations/chatbot/chatwoot/services/chatwoot.service';\nimport { DifyController } from './integrations/chatbot/dify/controllers/dify.controller';\nimport { DifyService } from './integrations/chatbot/dify/services/dify.service';\nimport { EvoaiController } from './integrations/chatbot/evoai/controllers/evoai.controller';\nimport { EvoaiService } from './integrations/chatbot/evoai/services/evoai.service';\nimport { EvolutionBotController } from './integrations/chatbot/evolutionBot/controllers/evolutionBot.controller';\nimport { EvolutionBotService } from './integrations/chatbot/evolutionBot/services/evolutionBot.service';\nimport { FlowiseController } from './integrations/chatbot/flowise/controllers/flowise.controller';\nimport { FlowiseService } from './integrations/chatbot/flowise/services/flowise.service';\nimport { N8nController } from './integrations/chatbot/n8n/controllers/n8n.controller';\nimport { N8nService } from './integrations/chatbot/n8n/services/n8n.service';\nimport { OpenaiController } from './integrations/chatbot/openai/controllers/openai.controller';\nimport { OpenaiService } from './integrations/chatbot/openai/services/openai.service';\nimport { TypebotController } from './integrations/chatbot/typebot/controllers/typebot.controller';\nimport { TypebotService } from './integrations/chatbot/typebot/services/typebot.service';\nimport { EventManager } from './integrations/event/event.manager';\nimport { S3Controller } from './integrations/storage/s3/controllers/s3.controller';\nimport { S3Service } from './integrations/storage/s3/services/s3.service';\nimport { ProviderFiles } from './provider/sessions';\nimport { PrismaRepository } from './repository/repository.service';\nimport { CacheService } from './services/cache.service';\nimport { WAMonitoringService } from './services/monitor.service';\nimport { ProxyService } from './services/proxy.service';\nimport { SettingsService } from './services/settings.service';\nimport { TemplateService } from './services/template.service';\n\nconst logger = new Logger('WA MODULE');\n\nlet chatwootCache: CacheService = null;\nif (configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n  chatwootCache = new CacheService(new CacheEngine(configService, ChatwootService.name).getEngine());\n}\n\nexport const cache = new CacheService(new CacheEngine(configService, 'instance').getEngine());\nconst baileysCache = new CacheService(new CacheEngine(configService, 'baileys').getEngine());\n\nlet providerFiles: ProviderFiles = null;\nif (configService.get<ProviderSession>('PROVIDER').ENABLED) {\n  providerFiles = new ProviderFiles(configService);\n}\n\nexport const prismaRepository = new PrismaRepository(configService);\n\nexport const waMonitor = new WAMonitoringService(\n  eventEmitter,\n  configService,\n  prismaRepository,\n  providerFiles,\n  cache,\n  chatwootCache,\n  baileysCache,\n);\n\nconst s3Service = new S3Service(prismaRepository);\nexport const s3Controller = new S3Controller(s3Service);\n\nconst templateService = new TemplateService(waMonitor, prismaRepository, configService);\nexport const templateController = new TemplateController(templateService);\n\nconst proxyService = new ProxyService(waMonitor);\nexport const proxyController = new ProxyController(proxyService, waMonitor);\n\nconst chatwootService = new ChatwootService(waMonitor, configService, prismaRepository, chatwootCache);\nexport const chatwootController = new ChatwootController(chatwootService, configService);\n\nconst settingsService = new SettingsService(waMonitor);\nexport const settingsController = new SettingsController(settingsService);\n\nexport const instanceController = new InstanceController(\n  waMonitor,\n  configService,\n  prismaRepository,\n  eventEmitter,\n  chatwootService,\n  settingsService,\n  proxyController,\n  cache,\n  chatwootCache,\n  baileysCache,\n  providerFiles,\n);\nexport const sendMessageController = new SendMessageController(waMonitor);\nexport const callController = new CallController(waMonitor);\nexport const chatController = new ChatController(waMonitor);\nexport const businessController = new BusinessController(waMonitor);\nexport const groupController = new GroupController(waMonitor);\nexport const labelController = new LabelController(waMonitor);\n\nexport const eventManager = new EventManager(prismaRepository, waMonitor);\nexport const chatbotController = new ChatbotController(prismaRepository, waMonitor);\nexport const channelController = new ChannelController(prismaRepository, waMonitor);\n\n// channels\nexport const evolutionController = new EvolutionController(prismaRepository, waMonitor);\nexport const metaController = new MetaController(prismaRepository, waMonitor);\nexport const baileysController = new BaileysController(waMonitor);\n\nconst openaiService = new OpenaiService(waMonitor, prismaRepository, configService);\nexport const openaiController = new OpenaiController(openaiService, prismaRepository, waMonitor);\n\n// chatbots\nconst typebotService = new TypebotService(waMonitor, configService, prismaRepository, openaiService);\nexport const typebotController = new TypebotController(typebotService, prismaRepository, waMonitor);\n\nconst difyService = new DifyService(waMonitor, prismaRepository, configService, openaiService);\nexport const difyController = new DifyController(difyService, prismaRepository, waMonitor);\n\nconst evolutionBotService = new EvolutionBotService(waMonitor, prismaRepository, configService, openaiService);\nexport const evolutionBotController = new EvolutionBotController(evolutionBotService, prismaRepository, waMonitor);\n\nconst flowiseService = new FlowiseService(waMonitor, prismaRepository, configService, openaiService);\nexport const flowiseController = new FlowiseController(flowiseService, prismaRepository, waMonitor);\n\nconst n8nService = new N8nService(waMonitor, prismaRepository, configService, openaiService);\nexport const n8nController = new N8nController(n8nService, prismaRepository, waMonitor);\n\nconst evoaiService = new EvoaiService(waMonitor, prismaRepository, configService, openaiService);\nexport const evoaiController = new EvoaiController(evoaiService, prismaRepository, waMonitor);\n\nlogger.info('Module - ON');\n"
  },
  {
    "path": "src/api/services/auth.service.ts",
    "content": "import { PrismaRepository } from '@api/repository/repository.service';\nimport { BadRequestException } from '@exceptions';\n\nexport class AuthService {\n  constructor(private readonly prismaRepository: PrismaRepository) {}\n\n  public async checkDuplicateToken(token: string) {\n    if (!token) {\n      return true;\n    }\n\n    const instances = await this.prismaRepository.instance.findMany({\n      where: { token },\n    });\n\n    if (instances.length > 0) {\n      throw new BadRequestException('Token already exists');\n    }\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "src/api/services/cache.service.ts",
    "content": "import { ICache } from '@api/abstract/abstract.cache';\nimport { Logger } from '@config/logger.config';\nimport { BufferJSON } from 'baileys';\n\nexport class CacheService {\n  private readonly logger = new Logger('CacheService');\n\n  constructor(private readonly cache: ICache) {\n    if (cache) {\n      this.logger.verbose(`cacheservice created using cache engine: ${cache.constructor?.name}`);\n    } else {\n      this.logger.verbose(`cacheservice disabled`);\n    }\n  }\n\n  async get(key: string): Promise<any> {\n    if (!this.cache) {\n      return;\n    }\n    return this.cache.get(key);\n  }\n\n  public async hGet(key: string, field: string) {\n    if (!this.cache) {\n      return null;\n    }\n    try {\n      const data = await this.cache.hGet(key, field);\n\n      if (data) {\n        return JSON.parse(data, BufferJSON.reviver);\n      }\n\n      return null;\n    } catch (error) {\n      this.logger.error(error);\n      return null;\n    }\n  }\n\n  async set(key: string, value: any, ttl?: number) {\n    if (!this.cache) {\n      return;\n    }\n    this.cache.set(key, value, ttl);\n  }\n\n  public async hSet(key: string, field: string, value: any) {\n    if (!this.cache) {\n      return;\n    }\n    try {\n      const json = JSON.stringify(value, BufferJSON.replacer);\n\n      await this.cache.hSet(key, field, json);\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async has(key: string) {\n    if (!this.cache) {\n      return;\n    }\n    return this.cache.has(key);\n  }\n\n  async delete(key: string) {\n    if (!this.cache) {\n      return;\n    }\n    return this.cache.delete(key);\n  }\n\n  async hDelete(key: string, field: string) {\n    if (!this.cache) {\n      return false;\n    }\n    try {\n      await this.cache.hDelete(key, field);\n      return true;\n    } catch (error) {\n      this.logger.error(error);\n      return false;\n    }\n  }\n\n  async deleteAll(appendCriteria?: string) {\n    if (!this.cache) {\n      return;\n    }\n    return this.cache.deleteAll(appendCriteria);\n  }\n\n  async keys(appendCriteria?: string) {\n    if (!this.cache) {\n      return;\n    }\n    return this.cache.keys(appendCriteria);\n  }\n}\n"
  },
  {
    "path": "src/api/services/channel.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ProxyDto } from '@api/dto/proxy.dto';\nimport { SettingsDto } from '@api/dto/settings.dto';\nimport { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';\nimport { ChatwootService } from '@api/integrations/chatbot/chatwoot/services/chatwoot.service';\nimport { DifyService } from '@api/integrations/chatbot/dify/services/dify.service';\nimport { OpenaiService } from '@api/integrations/chatbot/openai/services/openai.service';\nimport { TypebotService } from '@api/integrations/chatbot/typebot/services/typebot.service';\nimport { PrismaRepository, Query } from '@api/repository/repository.service';\nimport { eventManager, waMonitor } from '@api/server.module';\nimport { Events, wa } from '@api/types/wa.types';\nimport { Auth, Chatwoot, ConfigService, HttpServer, Proxy } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { NotFoundException } from '@exceptions';\nimport { Contact, Message, Prisma } from '@prisma/client';\nimport { createJid } from '@utils/createJid';\nimport { WASocket } from 'baileys';\nimport { isArray } from 'class-validator';\nimport EventEmitter2 from 'eventemitter2';\nimport { v4 } from 'uuid';\n\nimport { CacheService } from './cache.service';\n\nexport class ChannelStartupService {\n  constructor(\n    public readonly configService: ConfigService,\n    public readonly eventEmitter: EventEmitter2,\n    public readonly prismaRepository: PrismaRepository,\n    public readonly chatwootCache: CacheService,\n  ) {}\n\n  public readonly logger = new Logger('ChannelStartupService');\n\n  public client: WASocket;\n  public readonly instance: wa.Instance = {};\n  public readonly localChatwoot: wa.LocalChatwoot = {};\n  public readonly localProxy: wa.LocalProxy = {};\n  public readonly localSettings: wa.LocalSettings = {};\n  public readonly localWebhook: wa.LocalWebHook = {};\n\n  public chatwootService = new ChatwootService(\n    waMonitor,\n    this.configService,\n    this.prismaRepository,\n    this.chatwootCache,\n  );\n\n  public openaiService = new OpenaiService(waMonitor, this.prismaRepository, this.configService);\n\n  public typebotService = new TypebotService(waMonitor, this.configService, this.prismaRepository, this.openaiService);\n\n  public difyService = new DifyService(waMonitor, this.prismaRepository, this.configService, this.openaiService);\n\n  public setInstance(instance: InstanceDto) {\n    this.logger.setInstance(instance.instanceName);\n\n    this.instance.name = instance.instanceName;\n    this.instance.id = instance.instanceId;\n    this.instance.integration = instance.integration;\n    this.instance.number = instance.number;\n    this.instance.token = instance.token;\n    this.instance.businessId = instance.businessId;\n    this.instance.ownerJid = instance.ownerJid;\n\n    if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {\n      this.chatwootService.eventWhatsapp(\n        Events.STATUS_INSTANCE,\n        { instanceName: this.instance.name },\n        {\n          instance: this.instance.name,\n          status: 'created',\n        },\n      );\n    }\n  }\n\n  public set instanceName(name: string) {\n    this.logger.setInstance(name);\n\n    if (!name) {\n      this.instance.name = v4();\n      return;\n    }\n    this.instance.name = name;\n  }\n\n  public get instanceName() {\n    return this.instance.name;\n  }\n\n  public set instanceId(id: string) {\n    if (!id) {\n      this.instance.id = v4();\n      return;\n    }\n    this.instance.id = id;\n  }\n\n  public get instanceId() {\n    return this.instance.id;\n  }\n\n  public set integration(integration: string) {\n    this.instance.integration = integration;\n  }\n\n  public get integration() {\n    return this.instance.integration;\n  }\n\n  public set number(number: string) {\n    this.instance.number = number;\n  }\n\n  public get number() {\n    return this.instance.number;\n  }\n\n  public set token(token: string) {\n    this.instance.token = token;\n  }\n\n  public get token() {\n    return this.instance.token;\n  }\n\n  public get wuid() {\n    return this.instance.wuid;\n  }\n\n  public async loadWebhook() {\n    const data = await this.prismaRepository.webhook.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    this.localWebhook.enabled = data?.enabled;\n    this.localWebhook.webhookBase64 = data?.webhookBase64;\n  }\n\n  public async loadSettings() {\n    const data = await this.prismaRepository.setting.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    this.localSettings.rejectCall = data?.rejectCall;\n    this.localSettings.msgCall = data?.msgCall;\n    this.localSettings.groupsIgnore = data?.groupsIgnore;\n    this.localSettings.alwaysOnline = data?.alwaysOnline;\n    this.localSettings.readMessages = data?.readMessages;\n    this.localSettings.readStatus = data?.readStatus;\n    this.localSettings.syncFullHistory = data?.syncFullHistory;\n    this.localSettings.wavoipToken = data?.wavoipToken;\n  }\n\n  public async setSettings(data: SettingsDto) {\n    await this.prismaRepository.setting.upsert({\n      where: {\n        instanceId: this.instanceId,\n      },\n      update: {\n        rejectCall: data.rejectCall,\n        msgCall: data.msgCall,\n        groupsIgnore: data.groupsIgnore,\n        alwaysOnline: data.alwaysOnline,\n        readMessages: data.readMessages,\n        readStatus: data.readStatus,\n        syncFullHistory: data.syncFullHistory,\n        wavoipToken: data.wavoipToken,\n      },\n      create: {\n        rejectCall: data.rejectCall,\n        msgCall: data.msgCall,\n        groupsIgnore: data.groupsIgnore,\n        alwaysOnline: data.alwaysOnline,\n        readMessages: data.readMessages,\n        readStatus: data.readStatus,\n        syncFullHistory: data.syncFullHistory,\n        wavoipToken: data.wavoipToken,\n        instanceId: this.instanceId,\n      },\n    });\n\n    this.localSettings.rejectCall = data?.rejectCall;\n    this.localSettings.msgCall = data?.msgCall;\n    this.localSettings.groupsIgnore = data?.groupsIgnore;\n    this.localSettings.alwaysOnline = data?.alwaysOnline;\n    this.localSettings.readMessages = data?.readMessages;\n    this.localSettings.readStatus = data?.readStatus;\n    this.localSettings.syncFullHistory = data?.syncFullHistory;\n    this.localSettings.wavoipToken = data?.wavoipToken;\n\n    if (this.localSettings.wavoipToken && this.localSettings.wavoipToken.length > 0) {\n      this.client.ws.close();\n      this.client.ws.connect();\n    }\n  }\n\n  public async findSettings() {\n    const data = await this.prismaRepository.setting.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    if (!data) {\n      return null;\n    }\n\n    return {\n      rejectCall: data.rejectCall,\n      msgCall: data.msgCall,\n      groupsIgnore: data.groupsIgnore,\n      alwaysOnline: data.alwaysOnline,\n      readMessages: data.readMessages,\n      readStatus: data.readStatus,\n      syncFullHistory: data.syncFullHistory,\n      wavoipToken: data.wavoipToken,\n    };\n  }\n\n  public async loadChatwoot() {\n    if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n      return;\n    }\n\n    const data = await this.prismaRepository.chatwoot.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    this.localChatwoot.enabled = data?.enabled;\n    this.localChatwoot.accountId = data?.accountId;\n    this.localChatwoot.token = data?.token;\n    this.localChatwoot.url = data?.url;\n    this.localChatwoot.nameInbox = data?.nameInbox;\n    this.localChatwoot.signMsg = data?.signMsg;\n    this.localChatwoot.signDelimiter = data?.signDelimiter;\n    this.localChatwoot.number = data?.number;\n    this.localChatwoot.reopenConversation = data?.reopenConversation;\n    this.localChatwoot.conversationPending = data?.conversationPending;\n    this.localChatwoot.mergeBrazilContacts = data?.mergeBrazilContacts;\n    this.localChatwoot.importContacts = data?.importContacts;\n    this.localChatwoot.importMessages = data?.importMessages;\n    this.localChatwoot.daysLimitImportMessages = data?.daysLimitImportMessages;\n  }\n\n  public async setChatwoot(data: ChatwootDto) {\n    if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n      return;\n    }\n\n    const chatwoot = await this.prismaRepository.chatwoot.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    if (chatwoot) {\n      await this.prismaRepository.chatwoot.update({\n        where: {\n          instanceId: this.instanceId,\n        },\n        data: {\n          enabled: data?.enabled,\n          accountId: data.accountId,\n          token: data.token,\n          url: data.url,\n          nameInbox: data.nameInbox,\n          signMsg: data.signMsg,\n          signDelimiter: data.signMsg ? data.signDelimiter : null,\n          number: data.number,\n          reopenConversation: data.reopenConversation,\n          conversationPending: data.conversationPending,\n          mergeBrazilContacts: data.mergeBrazilContacts,\n          importContacts: data.importContacts,\n          importMessages: data.importMessages,\n          daysLimitImportMessages: data.daysLimitImportMessages,\n          organization: data.organization,\n          logo: data.logo,\n          ignoreJids: data.ignoreJids,\n        },\n      });\n\n      Object.assign(this.localChatwoot, { ...data, signDelimiter: data.signMsg ? data.signDelimiter : null });\n\n      this.clearCacheChatwoot();\n      return;\n    }\n\n    await this.prismaRepository.chatwoot.create({\n      data: {\n        enabled: data?.enabled,\n        accountId: data.accountId,\n        token: data.token,\n        url: data.url,\n        nameInbox: data.nameInbox,\n        signMsg: data.signMsg,\n        number: data.number,\n        reopenConversation: data.reopenConversation,\n        conversationPending: data.conversationPending,\n        mergeBrazilContacts: data.mergeBrazilContacts,\n        importContacts: data.importContacts,\n        importMessages: data.importMessages,\n        daysLimitImportMessages: data.daysLimitImportMessages,\n        organization: data.organization,\n        logo: data.logo,\n        ignoreJids: data.ignoreJids,\n        instanceId: this.instanceId,\n      },\n    });\n\n    Object.assign(this.localChatwoot, { ...data, signDelimiter: data.signMsg ? data.signDelimiter : null });\n\n    this.clearCacheChatwoot();\n  }\n\n  public async findChatwoot(): Promise<ChatwootDto | null> {\n    if (!this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n      return null;\n    }\n\n    const data = await this.prismaRepository.chatwoot.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    if (!data) {\n      return null;\n    }\n\n    const ignoreJidsArray = Array.isArray(data.ignoreJids) ? data.ignoreJids.map((event) => String(event)) : [];\n\n    return {\n      enabled: data?.enabled,\n      accountId: data.accountId,\n      token: data.token,\n      url: data.url,\n      nameInbox: data.nameInbox,\n      signMsg: data.signMsg,\n      signDelimiter: data.signDelimiter || null,\n      reopenConversation: data.reopenConversation,\n      conversationPending: data.conversationPending,\n      mergeBrazilContacts: data.mergeBrazilContacts,\n      importContacts: data.importContacts,\n      importMessages: data.importMessages,\n      daysLimitImportMessages: data.daysLimitImportMessages,\n      organization: data.organization,\n      logo: data.logo,\n      ignoreJids: ignoreJidsArray,\n    };\n  }\n\n  public clearCacheChatwoot() {\n    if (this.localChatwoot?.enabled) {\n      this.chatwootService.getCache()?.deleteAll(this.instanceName);\n    }\n  }\n\n  public async loadProxy() {\n    this.localProxy.enabled = false;\n\n    const proxyConfig = this.configService.get<Proxy>('PROXY');\n    if (proxyConfig.HOST) {\n      this.localProxy.enabled = true;\n      this.localProxy.host = proxyConfig.HOST;\n      this.localProxy.port = proxyConfig.PORT || '80';\n      this.localProxy.protocol = proxyConfig.PROTOCOL || 'http';\n      this.localProxy.username = proxyConfig.USERNAME;\n      this.localProxy.password = proxyConfig.PASSWORD;\n    }\n\n    const data = await this.prismaRepository.proxy.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    if (data?.enabled) {\n      this.localProxy.enabled = true;\n      this.localProxy.host = data?.host;\n      this.localProxy.port = data?.port;\n      this.localProxy.protocol = data?.protocol;\n      this.localProxy.username = data?.username;\n      this.localProxy.password = data?.password;\n    }\n  }\n\n  public async setProxy(data: ProxyDto) {\n    await this.prismaRepository.proxy.upsert({\n      where: {\n        instanceId: this.instanceId,\n      },\n      update: {\n        enabled: data?.enabled,\n        host: data.host,\n        port: data.port,\n        protocol: data.protocol,\n        username: data.username,\n        password: data.password,\n      },\n      create: {\n        enabled: data?.enabled,\n        host: data.host,\n        port: data.port,\n        protocol: data.protocol,\n        username: data.username,\n        password: data.password,\n        instanceId: this.instanceId,\n      },\n    });\n\n    Object.assign(this.localProxy, data);\n  }\n\n  public async findProxy() {\n    const data = await this.prismaRepository.proxy.findUnique({\n      where: {\n        instanceId: this.instanceId,\n      },\n    });\n\n    if (!data) {\n      throw new NotFoundException('Proxy not found');\n    }\n\n    return data;\n  }\n\n  public async sendDataWebhook<T extends object = any>(\n    event: Events,\n    data: T,\n    local = true,\n    integration?: string[],\n    extra?: Record<string, any>,\n  ) {\n    const serverUrl = this.configService.get<HttpServer>('SERVER').URL;\n    const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds\n    const localISOTime = new Date(Date.now() - tzoffset).toISOString();\n    const now = localISOTime;\n\n    const expose = this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES;\n\n    const instanceApikey = this.token || 'Apikey not found';\n\n    await eventManager.emit({\n      instanceName: this.instance.name,\n      origin: ChannelStartupService.name,\n      event,\n      data,\n      serverUrl,\n      dateTime: now,\n      sender: this.wuid,\n      apiKey: expose && instanceApikey ? instanceApikey : null,\n      local,\n      integration,\n      extra,\n    });\n  }\n\n  // Check if the number is MX or AR\n  public formatMXOrARNumber(jid: string): string {\n    const countryCode = jid.substring(0, 2);\n\n    if (Number(countryCode) === 52 || Number(countryCode) === 54) {\n      if (jid.length === 13) {\n        const number = countryCode + jid.substring(3);\n        return number;\n      }\n\n      return jid;\n    }\n    return jid;\n  }\n\n  // Check if the number is br\n  public formatBRNumber(jid: string) {\n    const regexp = new RegExp(/^(\\d{2})(\\d{2})\\d{1}(\\d{8})$/);\n    if (regexp.test(jid)) {\n      const match = regexp.exec(jid);\n      if (match && match[1] === '55') {\n        const joker = Number.parseInt(match[3][0]);\n        const ddd = Number.parseInt(match[2]);\n        if (joker < 7 || ddd < 31) {\n          return match[0];\n        }\n        return match[1] + match[2] + match[3];\n      }\n      return jid;\n    } else {\n      return jid;\n    }\n  }\n\n  public async fetchContacts(query: Query<Contact>) {\n    const where: any = {\n      instanceId: this.instanceId,\n    };\n\n    if (query?.where?.remoteJid) {\n      const remoteJid = query.where.remoteJid.includes('@') ? query.where.remoteJid : createJid(query.where.remoteJid);\n      where['remoteJid'] = remoteJid;\n    }\n\n    if (query?.where?.id) {\n      where['id'] = query.where.id;\n    }\n\n    if (query?.where?.pushName) {\n      where['pushName'] = query.where.pushName;\n    }\n\n    const contactFindManyArgs: Prisma.ContactFindManyArgs = {\n      where,\n    };\n\n    if (query.offset) contactFindManyArgs.take = query.offset;\n    if (query.page) {\n      const validPage = Math.max(query.page as number, 1);\n      contactFindManyArgs.skip = query.offset * (validPage - 1);\n    }\n\n    const contacts = await this.prismaRepository.contact.findMany(contactFindManyArgs);\n\n    return contacts.map((contact) => {\n      const remoteJid = contact.remoteJid;\n      const isGroup = remoteJid.endsWith('@g.us');\n      const isSaved = !!contact.pushName || !!contact.profilePicUrl;\n      const type = isGroup ? 'group' : isSaved ? 'contact' : 'group_member';\n      return {\n        ...contact,\n        isGroup,\n        isSaved,\n        type,\n      };\n    });\n  }\n\n  public cleanMessageData(message: any) {\n    if (!message) return message;\n    const cleanedMessage = { ...message };\n\n    if (cleanedMessage.message) {\n      const { mediaUrl } = cleanedMessage.message;\n      delete cleanedMessage.message.base64;\n\n      // Limpa imageMessage\n      if (cleanedMessage.message.imageMessage) {\n        cleanedMessage.message.imageMessage = {\n          caption: cleanedMessage.message.imageMessage.caption,\n        };\n      }\n\n      // Limpa videoMessage\n      if (cleanedMessage.message.videoMessage) {\n        cleanedMessage.message.videoMessage = {\n          caption: cleanedMessage.message.videoMessage.caption,\n        };\n      }\n\n      // Limpa audioMessage\n      if (cleanedMessage.message.audioMessage) {\n        cleanedMessage.message.audioMessage = {\n          seconds: cleanedMessage.message.audioMessage.seconds,\n        };\n      }\n\n      // Limpa stickerMessage\n      if (cleanedMessage.message.stickerMessage) {\n        cleanedMessage.message.stickerMessage = {};\n      }\n\n      // Limpa documentMessage\n      if (cleanedMessage.message.documentMessage) {\n        cleanedMessage.message.documentMessage = {\n          caption: cleanedMessage.message.documentMessage.caption,\n          name: cleanedMessage.message.documentMessage.name,\n        };\n      }\n\n      // Limpa documentWithCaptionMessage\n      if (cleanedMessage.message.documentWithCaptionMessage) {\n        cleanedMessage.message.documentWithCaptionMessage = {\n          caption: cleanedMessage.message.documentWithCaptionMessage.caption,\n          name: cleanedMessage.message.documentWithCaptionMessage.name,\n        };\n      }\n\n      if (mediaUrl) cleanedMessage.message.mediaUrl = mediaUrl;\n    }\n\n    return cleanedMessage;\n  }\n\n  public async fetchMessages(query: Query<Message>) {\n    const keyFilters = query?.where?.key as {\n      id?: string;\n      fromMe?: boolean;\n      remoteJid?: string;\n      participants?: string;\n    };\n\n    const timestampFilter = {};\n    if (query?.where?.messageTimestamp) {\n      if (query.where.messageTimestamp['gte'] && query.where.messageTimestamp['lte']) {\n        timestampFilter['messageTimestamp'] = {\n          gte: Math.floor(new Date(query.where.messageTimestamp['gte']).getTime() / 1000),\n          lte: Math.floor(new Date(query.where.messageTimestamp['lte']).getTime() / 1000),\n        };\n      }\n    }\n\n    const count = await this.prismaRepository.message.count({\n      where: {\n        instanceId: this.instanceId,\n        id: query?.where?.id,\n        source: query?.where?.source,\n        messageType: query?.where?.messageType,\n        ...timestampFilter,\n        AND: [\n          keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {},\n          keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {},\n          keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {},\n          keyFilters?.participants ? { key: { path: ['participants'], equals: keyFilters?.participants } } : {},\n        ],\n      },\n    });\n\n    if (!query?.offset) {\n      query.offset = 50;\n    }\n\n    if (!query?.page) {\n      query.page = 1;\n    }\n\n    const messages = await this.prismaRepository.message.findMany({\n      where: {\n        instanceId: this.instanceId,\n        id: query?.where?.id,\n        source: query?.where?.source,\n        messageType: query?.where?.messageType,\n        ...timestampFilter,\n        AND: [\n          keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {},\n          keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {},\n          keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {},\n          keyFilters?.participants ? { key: { path: ['participants'], equals: keyFilters?.participants } } : {},\n        ],\n      },\n      orderBy: {\n        messageTimestamp: 'desc',\n      },\n      skip: query.offset * (query?.page === 1 ? 0 : (query?.page as number) - 1),\n      take: query.offset,\n      select: {\n        id: true,\n        key: true,\n        pushName: true,\n        messageType: true,\n        message: true,\n        messageTimestamp: true,\n        instanceId: true,\n        source: true,\n        contextInfo: true,\n        MessageUpdate: {\n          select: {\n            status: true,\n          },\n        },\n      },\n    });\n\n    return {\n      messages: {\n        total: count,\n        pages: Math.ceil(count / query.offset),\n        currentPage: query.page,\n        records: messages,\n      },\n    };\n  }\n\n  public async fetchStatusMessage(query: any) {\n    if (!query?.offset) {\n      query.offset = 50;\n    }\n\n    if (!query?.page) {\n      query.page = 1;\n    }\n\n    return await this.prismaRepository.messageUpdate.findMany({\n      where: {\n        instanceId: this.instanceId,\n        remoteJid: query.where?.remoteJid,\n        keyId: query.where?.id,\n      },\n      skip: query.offset * (query?.page === 1 ? 0 : (query?.page as number) - 1),\n      take: query.offset,\n    });\n  }\n\n  public async findChatByRemoteJid(remoteJid: string) {\n    if (!remoteJid) return null;\n    return await this.prismaRepository.chat.findFirst({\n      where: {\n        instanceId: this.instanceId,\n        remoteJid: remoteJid,\n      },\n    });\n  }\n\n  public async fetchChats(query: any) {\n    const remoteJid = query?.where?.remoteJid\n      ? query?.where?.remoteJid.includes('@')\n        ? query.where?.remoteJid\n        : createJid(query.where?.remoteJid)\n      : null;\n\n    const where = {\n      instanceId: this.instanceId,\n    };\n\n    if (remoteJid) {\n      where['remoteJid'] = remoteJid;\n    }\n\n    const timestampFilter =\n      query?.where?.messageTimestamp?.gte && query?.where?.messageTimestamp?.lte\n        ? Prisma.sql`\n        AND \"Message\".\"messageTimestamp\" >= ${Math.floor(new Date(query.where.messageTimestamp.gte).getTime() / 1000)}\n        AND \"Message\".\"messageTimestamp\" <= ${Math.floor(new Date(query.where.messageTimestamp.lte).getTime() / 1000)}`\n        : Prisma.sql``;\n\n    const limit = query?.take ? Prisma.sql`LIMIT ${query.take}` : Prisma.sql``;\n    const offset = query?.skip ? Prisma.sql`OFFSET ${query.skip}` : Prisma.sql``;\n\n    const results = await this.prismaRepository.$queryRaw`\n      WITH rankedMessages AS (\n        SELECT DISTINCT ON (\"Message\".\"key\"->>'remoteJid') \n          \"Contact\".\"id\" as \"contactId\",\n          \"Message\".\"key\"->>'remoteJid' as \"remoteJid\",\n          CASE \n            WHEN \"Message\".\"key\"->>'remoteJid' LIKE '%@g.us' THEN COALESCE(\"Chat\".\"name\", \"Contact\".\"pushName\")\n            ELSE COALESCE(\"Contact\".\"pushName\", \"Message\".\"pushName\")\n          END as \"pushName\",\n          \"Contact\".\"profilePicUrl\",\n          COALESCE(\n            to_timestamp(\"Message\".\"messageTimestamp\"::double precision), \n            \"Contact\".\"updatedAt\"\n          ) as \"updatedAt\",\n          \"Chat\".\"name\" as \"pushName\",\n          \"Chat\".\"createdAt\" as \"windowStart\",\n          \"Chat\".\"createdAt\" + INTERVAL '24 hours' as \"windowExpires\",\n          \"Chat\".\"unreadMessages\" as \"unreadMessages\",\n          CASE WHEN \"Chat\".\"createdAt\" + INTERVAL '24 hours' > NOW() THEN true ELSE false END as \"windowActive\",\n          \"Message\".\"id\" AS \"lastMessageId\",\n          \"Message\".\"key\" AS \"lastMessage_key\",\n          CASE\n            WHEN \"Message\".\"key\"->>'fromMe' = 'true' THEN 'Você'\n            ELSE \"Message\".\"pushName\"\n          END AS \"lastMessagePushName\",\n          \"Message\".\"participant\" AS \"lastMessageParticipant\",\n          \"Message\".\"messageType\" AS \"lastMessageMessageType\",\n          \"Message\".\"message\" AS \"lastMessageMessage\",\n          \"Message\".\"contextInfo\" AS \"lastMessageContextInfo\",\n          \"Message\".\"source\" AS \"lastMessageSource\",\n          \"Message\".\"messageTimestamp\" AS \"lastMessageMessageTimestamp\",\n          \"Message\".\"instanceId\" AS \"lastMessageInstanceId\",\n          \"Message\".\"sessionId\" AS \"lastMessageSessionId\",\n          \"Message\".\"status\" AS \"lastMessageStatus\"\n        FROM \"Message\"\n        LEFT JOIN \"Contact\" ON \"Contact\".\"remoteJid\" = \"Message\".\"key\"->>'remoteJid' AND \"Contact\".\"instanceId\" = \"Message\".\"instanceId\"\n        LEFT JOIN \"Chat\" ON \"Chat\".\"remoteJid\" = \"Message\".\"key\"->>'remoteJid' AND \"Chat\".\"instanceId\" = \"Message\".\"instanceId\"\n        WHERE \"Message\".\"instanceId\" = ${this.instanceId}\n        ${remoteJid ? Prisma.sql`AND \"Message\".\"key\"->>'remoteJid' = ${remoteJid}` : Prisma.sql``}\n        ${timestampFilter}\n        ORDER BY \"Message\".\"key\"->>'remoteJid', \"Message\".\"messageTimestamp\" DESC\n      )\n      SELECT * FROM rankedMessages \n      ORDER BY \"updatedAt\" DESC NULLS LAST\n      ${limit}\n      ${offset};\n    `;\n\n    if (results && isArray(results) && results.length > 0) {\n      const mappedResults = results.map((contact) => {\n        const lastMessage = contact.lastMessageId\n          ? {\n              id: contact.lastMessageId,\n              key: contact.lastMessage_key,\n              pushName: contact.lastMessagePushName,\n              participant: contact.lastMessageParticipant,\n              messageType: contact.lastMessageMessageType,\n              message: contact.lastMessageMessage,\n              contextInfo: contact.lastMessageContextInfo,\n              source: contact.lastMessageSource,\n              messageTimestamp: contact.lastMessageMessageTimestamp,\n              instanceId: contact.lastMessageInstanceId,\n              sessionId: contact.lastMessageSessionId,\n              status: contact.lastMessageStatus,\n            }\n          : undefined;\n\n        return {\n          id: contact.contactId || null,\n          remoteJid: contact.remoteJid,\n          pushName: contact.pushName,\n          profilePicUrl: contact.profilePicUrl,\n          updatedAt: contact.updatedAt,\n          windowStart: contact.windowStart,\n          windowExpires: contact.windowExpires,\n          windowActive: contact.windowActive,\n          lastMessage: lastMessage ? this.cleanMessageData(lastMessage) : undefined,\n          unreadCount: contact.unreadMessages,\n          isSaved: !!contact.contactId,\n        };\n      });\n\n      return mappedResults;\n    }\n\n    return [];\n  }\n\n  public hasValidMediaContent(message: any): boolean {\n    if (!message?.message) return false;\n\n    const msg = message.message;\n\n    // Se só tem messageContextInfo, não é mídia válida\n    if (Object.keys(msg).length === 1 && Object.prototype.hasOwnProperty.call(msg, 'messageContextInfo')) {\n      return false;\n    }\n\n    // Verifica se tem pelo menos um tipo de mídia válido\n    const mediaTypes = [\n      'imageMessage',\n      'videoMessage',\n      'stickerMessage',\n      'documentMessage',\n      'documentWithCaptionMessage',\n      'ptvMessage',\n      'audioMessage',\n    ];\n\n    return mediaTypes.some((type) => msg[type] && Object.keys(msg[type]).length > 0);\n  }\n}\n"
  },
  {
    "path": "src/api/services/monitor.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { channelController } from '@api/server.module';\nimport { Events, Integration } from '@api/types/wa.types';\nimport { CacheConf, Chatwoot, ConfigService, Database, DelInstance, ProviderSession } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { INSTANCE_DIR, STORE_DIR } from '@config/path.config';\nimport { NotFoundException } from '@exceptions';\nimport { execFileSync } from 'child_process';\nimport EventEmitter2 from 'eventemitter2';\nimport { rmSync } from 'fs';\nimport { join } from 'path';\n\nimport { CacheService } from './cache.service';\n\nexport class WAMonitoringService {\n  constructor(\n    private readonly eventEmitter: EventEmitter2,\n    private readonly configService: ConfigService,\n    private readonly prismaRepository: PrismaRepository,\n    private readonly providerFiles: ProviderFiles,\n    private readonly cache: CacheService,\n    private readonly chatwootCache: CacheService,\n    private readonly baileysCache: CacheService,\n  ) {\n    this.removeInstance();\n    this.noConnection();\n\n    Object.assign(this.db, configService.get<Database>('DATABASE'));\n    Object.assign(this.redis, configService.get<CacheConf>('CACHE'));\n\n    (this as any).providerSession = Object.freeze(configService.get<ProviderSession>('PROVIDER'));\n  }\n\n  private readonly db: Partial<Database> = {};\n  private readonly redis: Partial<CacheConf> = {};\n\n  private readonly logger = new Logger('WAMonitoringService');\n  public readonly waInstances: Record<string, any> = {};\n  private readonly delInstanceTimeouts: Record<string, NodeJS.Timeout> = {};\n\n  private readonly providerSession: ProviderSession;\n\n  public delInstanceTime(instance: string) {\n    const time = this.configService.get<DelInstance>('DEL_INSTANCE');\n    if (typeof time === 'number' && time > 0) {\n      // Clear previous timeout if exists\n      if (this.delInstanceTimeouts[instance]) {\n        clearTimeout(this.delInstanceTimeouts[instance]);\n      }\n\n      // Set new timeout and store reference\n      this.delInstanceTimeouts[instance] = setTimeout(\n        async () => {\n          try {\n            if (this.waInstances[instance]?.connectionStatus?.state !== 'open') {\n              if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') {\n                if ((await this.waInstances[instance].integration) === Integration.WHATSAPP_BAILEYS) {\n                  await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance);\n                  this.waInstances[instance]?.client?.ws?.close();\n                  this.waInstances[instance]?.client?.end(undefined);\n                }\n                this.eventEmitter.emit('remove.instance', instance, 'inner');\n              } else {\n                this.eventEmitter.emit('remove.instance', instance, 'inner');\n              }\n            }\n          } finally {\n            // Clean up timeout reference\n            delete this.delInstanceTimeouts[instance];\n          }\n        },\n        1000 * 60 * time,\n      );\n    }\n  }\n\n  public clearDelInstanceTime(instance: string) {\n    if (this.delInstanceTimeouts[instance]) {\n      clearTimeout(this.delInstanceTimeouts[instance]);\n      delete this.delInstanceTimeouts[instance];\n    }\n  }\n\n  public async instanceInfo(instanceNames?: string[]): Promise<any> {\n    if (instanceNames && instanceNames.length > 0) {\n      const inexistentInstances = instanceNames ? instanceNames.filter((instance) => !this.waInstances[instance]) : [];\n\n      if (inexistentInstances.length > 0) {\n        throw new NotFoundException(\n          `Instance${inexistentInstances.length > 1 ? 's' : ''} \"${inexistentInstances.join(', ')}\" not found`,\n        );\n      }\n    }\n\n    const clientName = this.configService.get<Database>('DATABASE').CONNECTION.CLIENT_NAME;\n\n    const where =\n      instanceNames && instanceNames.length > 0\n        ? {\n            name: {\n              in: instanceNames,\n            },\n            clientName,\n          }\n        : { clientName };\n\n    const instances = await this.prismaRepository.instance.findMany({\n      where,\n      include: {\n        Chatwoot: true,\n        Proxy: true,\n        Rabbitmq: true,\n        Nats: true,\n        Sqs: true,\n        Websocket: true,\n        Setting: true,\n        _count: {\n          select: {\n            Message: true,\n            Contact: true,\n            Chat: true,\n          },\n        },\n      },\n    });\n\n    return instances;\n  }\n\n  public async instanceInfoById(instanceId?: string, number?: string) {\n    let instanceName: string;\n    if (instanceId) {\n      instanceName = await this.prismaRepository.instance.findFirst({ where: { id: instanceId } }).then((r) => r?.name);\n      if (!instanceName) {\n        throw new NotFoundException(`Instance \"${instanceId}\" not found`);\n      }\n    } else if (number) {\n      instanceName = await this.prismaRepository.instance.findFirst({ where: { number } }).then((r) => r?.name);\n      if (!instanceName) {\n        throw new NotFoundException(`Instance \"${number}\" not found`);\n      }\n    }\n\n    if (!instanceName) {\n      throw new NotFoundException(`Instance \"${instanceId}\" not found`);\n    }\n\n    if (instanceName && !this.waInstances[instanceName]) {\n      throw new NotFoundException(`Instance \"${instanceName}\" not found`);\n    }\n\n    const instanceNames = instanceName ? [instanceName] : null;\n\n    return this.instanceInfo(instanceNames);\n  }\n\n  public async cleaningUp(instanceName: string) {\n    let instanceDbId: string;\n    if (this.db.SAVE_DATA.INSTANCE) {\n      const findInstance = await this.prismaRepository.instance.findFirst({\n        where: { name: instanceName },\n      });\n\n      if (findInstance) {\n        const instance = await this.prismaRepository.instance.update({\n          where: { name: instanceName },\n          data: { connectionStatus: 'close' },\n        });\n\n        rmSync(join(INSTANCE_DIR, instance.id), { recursive: true, force: true });\n\n        instanceDbId = instance.id;\n        await this.prismaRepository.session.deleteMany({ where: { sessionId: instance.id } });\n      }\n    }\n\n    if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) {\n      await this.cache.delete(instanceName);\n      if (instanceDbId) {\n        await this.cache.delete(instanceDbId);\n      }\n    }\n\n    if (this.providerSession?.ENABLED) {\n      await this.providerFiles.removeSession(instanceName);\n    }\n  }\n\n  public async cleaningStoreData(instanceName: string) {\n    if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n      const instancePath = join(STORE_DIR, 'chatwoot', instanceName);\n      execFileSync('rm', ['-rf', instancePath]);\n    }\n\n    const instance = await this.prismaRepository.instance.findFirst({\n      where: { name: instanceName },\n    });\n\n    if (!instance) return;\n\n    rmSync(join(INSTANCE_DIR, instance.id), { recursive: true, force: true });\n\n    await this.prismaRepository.session.deleteMany({ where: { sessionId: instance.id } });\n\n    await this.prismaRepository.chat.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.contact.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.messageUpdate.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.message.deleteMany({ where: { instanceId: instance.id } });\n\n    await this.prismaRepository.webhook.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.chatwoot.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.proxy.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.rabbitmq.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.nats.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.sqs.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.integrationSession.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.typebot.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.websocket.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.setting.deleteMany({ where: { instanceId: instance.id } });\n    await this.prismaRepository.label.deleteMany({ where: { instanceId: instance.id } });\n\n    await this.prismaRepository.instance.delete({ where: { name: instanceName } });\n  }\n\n  public async loadInstance() {\n    try {\n      if (this.providerSession?.ENABLED) {\n        await this.loadInstancesFromProvider();\n      } else if (this.db.SAVE_DATA.INSTANCE) {\n        await this.loadInstancesFromDatabasePostgres();\n      } else if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) {\n        await this.loadInstancesFromRedis();\n      }\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public async saveInstance(data: any) {\n    try {\n      const clientName = await this.configService.get<Database>('DATABASE').CONNECTION.CLIENT_NAME;\n      await this.prismaRepository.instance.create({\n        data: {\n          id: data.instanceId,\n          name: data.instanceName,\n          ownerJid: data.ownerJid,\n          profileName: data.profileName,\n          profilePicUrl: data.profilePicUrl,\n          connectionStatus:\n            data.integration && data.integration === Integration.WHATSAPP_BAILEYS ? 'close' : (data.status ?? 'open'),\n          number: data.number,\n          integration: data.integration || Integration.WHATSAPP_BAILEYS,\n          token: data.hash,\n          clientName: clientName,\n          businessId: data.businessId,\n        },\n      });\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  public deleteInstance(instanceName: string) {\n    try {\n      this.eventEmitter.emit('remove.instance', instanceName, 'inner');\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  private async setInstance(instanceData: InstanceDto) {\n    const instance = channelController.init(instanceData, {\n      configService: this.configService,\n      eventEmitter: this.eventEmitter,\n      prismaRepository: this.prismaRepository,\n      cache: this.cache,\n      chatwootCache: this.chatwootCache,\n      baileysCache: this.baileysCache,\n      providerFiles: this.providerFiles,\n    });\n\n    if (!instance) return;\n\n    instance.setInstance({\n      instanceId: instanceData.instanceId,\n      instanceName: instanceData.instanceName,\n      integration: instanceData.integration,\n      token: instanceData.token,\n      number: instanceData.number,\n      businessId: instanceData.businessId,\n      ownerJid: instanceData.ownerJid,\n    });\n\n    if (instanceData.connectionStatus === 'open' || instanceData.connectionStatus === 'connecting') {\n      this.logger.info(\n        `Auto-connecting instance \"${instanceData.instanceName}\" (status: ${instanceData.connectionStatus})`,\n      );\n      await instance.connectToWhatsapp();\n    } else {\n      this.logger.info(\n        `Skipping auto-connect for instance \"${instanceData.instanceName}\" (status: ${instanceData.connectionStatus || 'close'})`,\n      );\n    }\n\n    this.waInstances[instanceData.instanceName] = instance;\n  }\n\n  private async loadInstancesFromRedis() {\n    const keys = await this.cache.keys();\n\n    if (keys?.length > 0) {\n      await Promise.all(\n        keys.map(async (k) => {\n          const instanceData = await this.prismaRepository.instance.findUnique({\n            where: { id: k.split(':')[1] },\n          });\n\n          if (!instanceData) {\n            return;\n          }\n\n          const instance = {\n            instanceId: k.split(':')[1],\n            instanceName: k.split(':')[2],\n            integration: instanceData.integration,\n            token: instanceData.token,\n            number: instanceData.number,\n            businessId: instanceData.businessId,\n            connectionStatus: instanceData.connectionStatus as any, // Pass connection status\n          };\n\n          this.setInstance(instance);\n        }),\n      );\n    }\n  }\n\n  private async loadInstancesFromDatabasePostgres() {\n    const clientName = await this.configService.get<Database>('DATABASE').CONNECTION.CLIENT_NAME;\n\n    const instances = await this.prismaRepository.instance.findMany({\n      where: { clientName: clientName },\n    });\n\n    if (instances.length === 0) {\n      return;\n    }\n\n    await Promise.all(\n      instances.map(async (instance) => {\n        this.setInstance({\n          instanceId: instance.id,\n          instanceName: instance.name,\n          integration: instance.integration,\n          token: instance.token,\n          number: instance.number,\n          businessId: instance.businessId,\n          ownerJid: instance.ownerJid,\n          connectionStatus: instance.connectionStatus as any, // Pass connection status\n        });\n      }),\n    );\n  }\n\n  private async loadInstancesFromProvider() {\n    const [instances] = await this.providerFiles.allInstances();\n\n    if (!instances?.data) {\n      return;\n    }\n\n    await Promise.all(\n      instances?.data?.map(async (instanceId: string) => {\n        const instance = await this.prismaRepository.instance.findUnique({\n          where: { id: instanceId },\n        });\n\n        this.setInstance({\n          instanceId: instance.id,\n          instanceName: instance.name,\n          integration: instance.integration,\n          token: instance.token,\n          businessId: instance.businessId,\n          connectionStatus: instance.connectionStatus as any, // Pass connection status\n        });\n      }),\n    );\n  }\n\n  private removeInstance() {\n    this.eventEmitter.on('remove.instance', async (instanceName: string) => {\n      try {\n        await this.waInstances[instanceName]?.sendDataWebhook(Events.REMOVE_INSTANCE, null);\n\n        this.clearDelInstanceTime(instanceName);\n\n        this.cleaningUp(instanceName);\n        this.cleaningStoreData(instanceName);\n      } finally {\n        this.logger.warn(`Instance \"${instanceName}\" - REMOVED`);\n      }\n\n      try {\n        delete this.waInstances[instanceName];\n      } catch (error) {\n        this.logger.error(error);\n      }\n    });\n    this.eventEmitter.on('logout.instance', async (instanceName: string) => {\n      try {\n        await this.waInstances[instanceName]?.sendDataWebhook(Events.LOGOUT_INSTANCE, null);\n\n        this.clearDelInstanceTime(instanceName);\n\n        if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED) {\n          this.waInstances[instanceName]?.clearCacheChatwoot();\n        }\n\n        this.cleaningUp(instanceName);\n      } finally {\n        this.logger.warn(`Instance \"${instanceName}\" - LOGOUT`);\n      }\n    });\n  }\n\n  private noConnection() {\n    this.eventEmitter.on('no.connection', async (instanceName) => {\n      try {\n        await this.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName);\n\n        this.waInstances[instanceName]?.client?.ws?.close();\n\n        this.waInstances[instanceName].instance.qrcode = { count: 0 };\n        this.waInstances[instanceName].stateConnection.state = 'close';\n      } catch (error) {\n        this.logger.error({\n          localError: 'noConnection',\n          warn: 'Error deleting instance from memory.',\n          error,\n        });\n      } finally {\n        this.logger.warn(`Instance \"${instanceName}\" - NOT CONNECTION`);\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "src/api/services/proxy.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { ProxyDto } from '@api/dto/proxy.dto';\nimport { Logger } from '@config/logger.config';\nimport { Proxy } from '@prisma/client';\n\nimport { WAMonitoringService } from './monitor.service';\n\nexport class ProxyService {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  private readonly logger = new Logger('ProxyService');\n\n  public create(instance: InstanceDto, data: ProxyDto) {\n    this.waMonitor.waInstances[instance.instanceName].setProxy(data);\n\n    return { proxy: { ...instance, proxy: data } };\n  }\n\n  public async find(instance: InstanceDto): Promise<Proxy> {\n    try {\n      const result = await this.waMonitor.waInstances[instance.instanceName].findProxy();\n\n      if (Object.keys(result).length === 0) {\n        throw new Error('Proxy not found');\n      }\n\n      return result;\n    } catch {\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/services/settings.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { SettingsDto } from '@api/dto/settings.dto';\nimport { Logger } from '@config/logger.config';\n\nimport { WAMonitoringService } from './monitor.service';\n\nexport class SettingsService {\n  constructor(private readonly waMonitor: WAMonitoringService) {}\n\n  private readonly logger = new Logger('SettingsService');\n\n  public async create(instance: InstanceDto, data: SettingsDto) {\n    await this.waMonitor.waInstances[instance.instanceName].setSettings(data);\n\n    return { settings: { ...instance, settings: data } };\n  }\n\n  public async find(instance: InstanceDto): Promise<SettingsDto> {\n    try {\n      const result = await this.waMonitor.waInstances[instance.instanceName].findSettings();\n\n      if (Object.keys(result).length === 0) {\n        throw new Error('Settings not found');\n      }\n\n      return result;\n    } catch {\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/services/template.service.ts",
    "content": "import { InstanceDto } from '@api/dto/instance.dto';\nimport { TemplateDto } from '@api/dto/template.dto';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { ConfigService, WaBusiness } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport axios from 'axios';\n\nimport { WAMonitoringService } from './monitor.service';\n\nexport class TemplateService {\n  constructor(\n    private readonly waMonitor: WAMonitoringService,\n    public readonly prismaRepository: PrismaRepository,\n    private readonly configService: ConfigService,\n  ) {}\n\n  private readonly logger = new Logger('TemplateService');\n\n  private businessId: string;\n  private token: string;\n\n  public async find(instance: InstanceDto) {\n    const getInstance = await this.waMonitor.waInstances[instance.instanceName].instance;\n\n    if (!getInstance) {\n      throw new Error('Instance not found');\n    }\n\n    this.businessId = getInstance.businessId;\n    this.token = getInstance.token;\n\n    const response = await this.requestTemplate({}, 'GET');\n\n    if (!response) {\n      throw new Error('Error to create template');\n    }\n\n    return response.data;\n  }\n\n  public async create(instance: InstanceDto, data: TemplateDto) {\n    try {\n      const getInstance = await this.waMonitor.waInstances[instance.instanceName].instance;\n\n      if (!getInstance) {\n        throw new Error('Instance not found');\n      }\n\n      this.businessId = getInstance.businessId;\n      this.token = getInstance.token;\n\n      const postData = {\n        name: data.name,\n        category: data.category,\n        allow_category_change: data.allowCategoryChange,\n        language: data.language,\n        components: data.components,\n      };\n\n      const response = await this.requestTemplate(postData, 'POST');\n\n      if (!response || response.error) {\n        // If there's an error from WhatsApp API, throw it with the real error data\n        if (response && response.error) {\n          // Create an error object that includes the template field for Meta errors\n          const metaError = new Error(response.error.message || 'WhatsApp API Error');\n          (metaError as any).template = response.error;\n          throw metaError;\n        }\n        throw new Error('Error to create template');\n      }\n\n      const template = await this.prismaRepository.template.create({\n        data: {\n          templateId: response.id,\n          name: data.name,\n          template: response,\n          webhookUrl: data.webhookUrl,\n          instanceId: getInstance.id,\n        },\n      });\n\n      return template;\n    } catch (error) {\n      this.logger.error('Error in create template: ' + error);\n      // Propagate the real error instead of \"engolindo\" it\n      throw error;\n    }\n  }\n\n  public async edit(\n    instance: InstanceDto,\n    data: { templateId: string; category?: string; components?: any; allowCategoryChange?: boolean; ttl?: number },\n  ) {\n    const getInstance = await this.waMonitor.waInstances[instance.instanceName].instance;\n    if (!getInstance) {\n      throw new Error('Instance not found');\n    }\n\n    this.businessId = getInstance.businessId;\n    this.token = getInstance.token;\n\n    const payload: Record<string, unknown> = {};\n    if (typeof data.category === 'string') payload.category = data.category;\n    if (typeof data.allowCategoryChange === 'boolean') payload.allow_category_change = data.allowCategoryChange;\n    if (typeof data.ttl === 'number') payload.time_to_live = data.ttl;\n    if (data.components) payload.components = data.components;\n\n    const response = await this.requestEditTemplate(data.templateId, payload);\n\n    if (!response || response.error) {\n      if (response && response.error) {\n        const metaError = new Error(response.error.message || 'WhatsApp API Error');\n        (metaError as any).template = response.error;\n        throw metaError;\n      }\n      throw new Error('Error to edit template');\n    }\n\n    return response;\n  }\n\n  public async delete(instance: InstanceDto, data: { name: string; hsmId?: string }) {\n    const getInstance = await this.waMonitor.waInstances[instance.instanceName].instance;\n    if (!getInstance) {\n      throw new Error('Instance not found');\n    }\n\n    this.businessId = getInstance.businessId;\n    this.token = getInstance.token;\n\n    const response = await this.requestDeleteTemplate({ name: data.name, hsm_id: data.hsmId });\n\n    if (!response || response.error) {\n      if (response && response.error) {\n        const metaError = new Error(response.error.message || 'WhatsApp API Error');\n        (metaError as any).template = response.error;\n        throw metaError;\n      }\n      throw new Error('Error to delete template');\n    }\n\n    try {\n      // Best-effort local cleanup of stored template metadata\n      await this.prismaRepository.template.deleteMany({\n        where: {\n          OR: [\n            { name: data.name, instanceId: getInstance.id },\n            data.hsmId ? { templateId: data.hsmId, instanceId: getInstance.id } : undefined,\n          ].filter(Boolean) as any,\n        },\n      });\n    } catch (err) {\n      this.logger.warn(\n        `Failed to cleanup local template records after delete: ${(err as Error)?.message || String(err)}`,\n      );\n    }\n\n    return response;\n  }\n\n  private async requestTemplate(data: any, method: string) {\n    try {\n      let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;\n      const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;\n      urlServer = `${urlServer}/${version}/${this.businessId}/message_templates`;\n      const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };\n\n      if (method === 'GET') {\n        const result = await axios.get(urlServer, { headers });\n        return result.data;\n      } else if (method === 'POST') {\n        const result = await axios.post(urlServer, data, { headers });\n        return result.data;\n      }\n    } catch (e) {\n      this.logger.error(\n        'WhatsApp API request error: ' + (e.response?.data ? JSON.stringify(e.response?.data) : e.message),\n      );\n\n      // Return the complete error response from WhatsApp API\n      if (e.response?.data) {\n        return e.response.data;\n      }\n\n      // If no response data, throw connection error\n      throw new Error(`Connection error: ${e.message}`);\n    }\n  }\n\n  private async requestEditTemplate(templateId: string, data: any) {\n    try {\n      let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;\n      const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;\n      urlServer = `${urlServer}/${version}/${templateId}`;\n      const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };\n      const result = await axios.post(urlServer, data, { headers });\n      return result.data;\n    } catch (e) {\n      this.logger.error(\n        'WhatsApp API request error: ' + (e.response?.data ? JSON.stringify(e.response?.data) : e.message),\n      );\n      if (e.response?.data) return e.response.data;\n      throw new Error(`Connection error: ${e.message}`);\n    }\n  }\n\n  private async requestDeleteTemplate(params: { name: string; hsm_id?: string }) {\n    try {\n      let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;\n      const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;\n      urlServer = `${urlServer}/${version}/${this.businessId}/message_templates`;\n      const headers = { Authorization: `Bearer ${this.token}` };\n      const result = await axios.delete(urlServer, { headers, params });\n      return result.data;\n    } catch (e) {\n      this.logger.error(\n        'WhatsApp API request error: ' + (e.response?.data ? JSON.stringify(e.response?.data) : e.message),\n      );\n      if (e.response?.data) return e.response.data;\n      throw new Error(`Connection error: ${e.message}`);\n    }\n  }\n}\n"
  },
  {
    "path": "src/api/types/wa.types.ts",
    "content": "/* eslint-disable @typescript-eslint/no-namespace */\nimport { JsonValue } from '@prisma/client/runtime/library';\nimport { AuthenticationState, WAConnectionState } from 'baileys';\n\nexport enum Events {\n  APPLICATION_STARTUP = 'application.startup',\n  INSTANCE_CREATE = 'instance.create',\n  INSTANCE_DELETE = 'instance.delete',\n  QRCODE_UPDATED = 'qrcode.updated',\n  CONNECTION_UPDATE = 'connection.update',\n  STATUS_INSTANCE = 'status.instance',\n  MESSAGES_SET = 'messages.set',\n  MESSAGES_UPSERT = 'messages.upsert',\n  MESSAGES_EDITED = 'messages.edited',\n  MESSAGES_UPDATE = 'messages.update',\n  MESSAGES_DELETE = 'messages.delete',\n  SEND_MESSAGE = 'send.message',\n  SEND_MESSAGE_UPDATE = 'send.message.update',\n  CONTACTS_SET = 'contacts.set',\n  CONTACTS_UPSERT = 'contacts.upsert',\n  CONTACTS_UPDATE = 'contacts.update',\n  PRESENCE_UPDATE = 'presence.update',\n  CHATS_SET = 'chats.set',\n  CHATS_UPDATE = 'chats.update',\n  CHATS_UPSERT = 'chats.upsert',\n  CHATS_DELETE = 'chats.delete',\n  GROUPS_UPSERT = 'groups.upsert',\n  GROUPS_UPDATE = 'groups.update',\n  GROUP_PARTICIPANTS_UPDATE = 'group-participants.update',\n  CALL = 'call',\n  TYPEBOT_START = 'typebot.start',\n  TYPEBOT_CHANGE_STATUS = 'typebot.change-status',\n  LABELS_EDIT = 'labels.edit',\n  LABELS_ASSOCIATION = 'labels.association',\n  CREDS_UPDATE = 'creds.update',\n  MESSAGING_HISTORY_SET = 'messaging-history.set',\n  REMOVE_INSTANCE = 'remove.instance',\n  LOGOUT_INSTANCE = 'logout.instance',\n}\n\nexport declare namespace wa {\n  export type QrCode = {\n    count?: number;\n    pairingCode?: string;\n    base64?: string;\n    code?: string;\n  };\n\n  export type Instance = {\n    id?: string;\n    qrcode?: QrCode;\n    pairingCode?: string;\n    authState?: { state: AuthenticationState; saveCreds: () => void };\n    name?: string;\n    ownerJid?: string;\n    wuid?: string;\n    profileName?: string;\n    profilePictureUrl?: string;\n    token?: string;\n    number?: string;\n    integration?: string;\n    businessId?: string;\n  };\n\n  export type LocalChatwoot = {\n    enabled?: boolean;\n    accountId?: string;\n    token?: string;\n    url?: string;\n    nameInbox?: string;\n    signMsg?: boolean;\n    signDelimiter?: string;\n    number?: string;\n    reopenConversation?: boolean;\n    conversationPending?: boolean;\n    mergeBrazilContacts?: boolean;\n    importContacts?: boolean;\n    importMessages?: boolean;\n    daysLimitImportMessages?: number;\n  };\n\n  export type LocalSettings = {\n    rejectCall?: boolean;\n    msgCall?: string;\n    groupsIgnore?: boolean;\n    alwaysOnline?: boolean;\n    readMessages?: boolean;\n    readStatus?: boolean;\n    syncFullHistory?: boolean;\n    wavoipToken?: string;\n  };\n\n  export type LocalEvent = {\n    enabled?: boolean;\n    events?: JsonValue;\n  };\n\n  export type LocalWebHook = LocalEvent & {\n    url?: string;\n    headers?: JsonValue;\n    webhookByEvents?: boolean;\n    webhookBase64?: boolean;\n  };\n\n  export type LocalPusher = LocalEvent & {\n    appId?: string;\n    key?: string;\n    secret?: string;\n    cluster?: string;\n    useTLS?: boolean;\n  };\n\n  type Session = {\n    remoteJid?: string;\n    sessionId?: string;\n    createdAt?: number;\n  };\n\n  export type LocalProxy = {\n    enabled?: boolean;\n    host?: string;\n    port?: string;\n    protocol?: string;\n    username?: string;\n    password?: string;\n  };\n\n  export type StateConnection = {\n    instance?: string;\n    state?: WAConnectionState | 'refused';\n    statusReason?: number;\n  };\n\n  export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED';\n}\n\nexport const TypeMediaMessage = [\n  'imageMessage',\n  'documentMessage',\n  'audioMessage',\n  'videoMessage',\n  'stickerMessage',\n  'ptvMessage',\n];\n\nexport const MessageSubtype = [\n  'ephemeralMessage',\n  'documentWithCaptionMessage',\n  'viewOnceMessage',\n  'viewOnceMessageV2',\n];\n\nexport const Integration = {\n  WHATSAPP_BUSINESS: 'WHATSAPP-BUSINESS',\n  WHATSAPP_BAILEYS: 'WHATSAPP-BAILEYS',\n  EVOLUTION: 'EVOLUTION',\n};\n"
  },
  {
    "path": "src/cache/cacheengine.ts",
    "content": "import { ICache } from '@api/abstract/abstract.cache';\nimport { CacheConf, ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\n\nimport { LocalCache } from './localcache';\nimport { RedisCache } from './rediscache';\n\nconst logger = new Logger('CacheEngine');\n\nexport class CacheEngine {\n  private engine: ICache;\n\n  constructor(\n    private readonly configService: ConfigService,\n    module: string,\n  ) {\n    const cacheConf = configService.get<CacheConf>('CACHE');\n\n    if (cacheConf?.REDIS?.ENABLED && cacheConf?.REDIS?.URI !== '') {\n      logger.verbose(`RedisCache initialized for ${module}`);\n      this.engine = new RedisCache(configService, module);\n    } else if (cacheConf?.LOCAL?.ENABLED) {\n      logger.verbose(`LocalCache initialized for ${module}`);\n      this.engine = new LocalCache(configService, module);\n    }\n  }\n\n  public getEngine() {\n    return this.engine;\n  }\n}\n"
  },
  {
    "path": "src/cache/localcache.ts",
    "content": "import { ICache } from '@api/abstract/abstract.cache';\nimport { CacheConf, CacheConfLocal, ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BufferJSON } from 'baileys';\nimport NodeCache from 'node-cache';\n\nexport class LocalCache implements ICache {\n  private readonly logger = new Logger('LocalCache');\n  private conf: CacheConfLocal;\n  static localCache = new NodeCache();\n\n  constructor(\n    private readonly configService: ConfigService,\n    private readonly module: string,\n  ) {\n    this.conf = this.configService.get<CacheConf>('CACHE')?.LOCAL;\n  }\n\n  async get(key: string): Promise<any> {\n    return LocalCache.localCache.get(this.buildKey(key));\n  }\n\n  async set(key: string, value: any, ttl?: number) {\n    return LocalCache.localCache.set(this.buildKey(key), value, ttl || this.conf.TTL);\n  }\n\n  async has(key: string) {\n    return LocalCache.localCache.has(this.buildKey(key));\n  }\n\n  async delete(key: string) {\n    return LocalCache.localCache.del(this.buildKey(key));\n  }\n\n  async deleteAll(appendCriteria?: string) {\n    const keys = await this.keys(appendCriteria);\n    if (!keys?.length) {\n      return 0;\n    }\n\n    return LocalCache.localCache.del(keys);\n  }\n\n  async keys(appendCriteria?: string) {\n    const filter = `${this.buildKey('')}${appendCriteria ? `${appendCriteria}:` : ''}`;\n\n    return LocalCache.localCache.keys().filter((key) => key.substring(0, filter.length) === filter);\n  }\n\n  buildKey(key: string) {\n    return `${this.module}:${key}`;\n  }\n\n  async hGet(key: string, field: string) {\n    try {\n      const data = LocalCache.localCache.get(this.buildKey(key)) as object;\n\n      if (data && field in data) {\n        return JSON.parse(data[field], BufferJSON.reviver);\n      }\n\n      return null;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async hSet(key: string, field: string, value: any) {\n    try {\n      const json = JSON.stringify(value, BufferJSON.replacer);\n\n      let hash = LocalCache.localCache.get(this.buildKey(key));\n\n      if (!hash) {\n        hash = {};\n      }\n\n      hash[field] = json;\n      LocalCache.localCache.set(this.buildKey(key), hash);\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async hDelete(key: string, field: string) {\n    try {\n      const data = LocalCache.localCache.get(this.buildKey(key)) as object;\n\n      if (data && field in data) {\n        delete data[field];\n        LocalCache.localCache.set(this.buildKey(key), data);\n        return 1;\n      }\n\n      return 0;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n}\n"
  },
  {
    "path": "src/cache/rediscache.client.ts",
    "content": "import { CacheConf, CacheConfRedis, configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { createClient, RedisClientType } from 'redis';\n\nclass Redis {\n  private logger = new Logger('Redis');\n  private client: RedisClientType = null;\n  private conf: CacheConfRedis;\n  private connected = false;\n\n  constructor() {\n    this.conf = configService.get<CacheConf>('CACHE')?.REDIS;\n  }\n\n  getConnection(): RedisClientType {\n    if (this.connected) {\n      return this.client;\n    } else {\n      this.client = createClient({\n        url: this.conf.URI,\n      });\n\n      this.client.on('connect', () => {\n        this.logger.verbose('redis connecting');\n      });\n\n      this.client.on('ready', () => {\n        this.logger.verbose('redis ready');\n        this.connected = true;\n      });\n\n      this.client.on('error', () => {\n        this.logger.error('redis disconnected');\n        this.connected = false;\n      });\n\n      this.client.on('end', () => {\n        this.logger.verbose('redis connection ended');\n        this.connected = false;\n      });\n\n      try {\n        this.client.connect();\n        this.connected = true;\n      } catch (e) {\n        this.connected = false;\n        this.logger.error('redis connect exception caught: ' + e);\n        return null;\n      }\n\n      return this.client;\n    }\n  }\n}\n\nexport const redisClient = new Redis();\n"
  },
  {
    "path": "src/cache/rediscache.ts",
    "content": "import { ICache } from '@api/abstract/abstract.cache';\nimport { CacheConf, CacheConfRedis, ConfigService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { BufferJSON } from 'baileys';\nimport { RedisClientType } from 'redis';\n\nimport { redisClient } from './rediscache.client';\n\nexport class RedisCache implements ICache {\n  private readonly logger = new Logger('RedisCache');\n  private client: RedisClientType;\n  private conf: CacheConfRedis;\n\n  constructor(\n    private readonly configService: ConfigService,\n    private readonly module: string,\n  ) {\n    this.conf = this.configService.get<CacheConf>('CACHE')?.REDIS;\n    this.client = redisClient.getConnection();\n  }\n  async get(key: string): Promise<any> {\n    try {\n      return JSON.parse(await this.client.get(this.buildKey(key)));\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async hGet(key: string, field: string) {\n    try {\n      const data = await this.client.hGet(this.buildKey(key), field);\n\n      if (data) {\n        return JSON.parse(data, BufferJSON.reviver);\n      }\n\n      return null;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async set(key: string, value: any, ttl?: number) {\n    try {\n      await this.client.setEx(this.buildKey(key), ttl || this.conf?.TTL, JSON.stringify(value));\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async hSet(key: string, field: string, value: any) {\n    try {\n      const json = JSON.stringify(value, BufferJSON.replacer);\n\n      await this.client.hSet(this.buildKey(key), field, json);\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async has(key: string) {\n    try {\n      return (await this.client.exists(this.buildKey(key))) > 0;\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async delete(key: string) {\n    try {\n      return await this.client.del(this.buildKey(key));\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async hDelete(key: string, field: string) {\n    try {\n      return await this.client.hDel(this.buildKey(key), field);\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async deleteAll(appendCriteria?: string) {\n    try {\n      const keys = await this.keys(appendCriteria);\n      if (!keys?.length) {\n        return 0;\n      }\n\n      return await this.client.del(keys);\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  async keys(appendCriteria?: string) {\n    try {\n      const match = `${this.buildKey('')}${appendCriteria ? `${appendCriteria}:` : ''}*`;\n      const keys = [];\n      for await (const key of this.client.scanIterator({\n        MATCH: match,\n        COUNT: 100,\n      })) {\n        keys.push(key);\n      }\n\n      return [...new Set(keys)];\n    } catch (error) {\n      this.logger.error(error);\n    }\n  }\n\n  buildKey(key: string) {\n    return `${this.conf?.PREFIX_KEY}:${this.module}:${key}`;\n  }\n}\n"
  },
  {
    "path": "src/config/env.config.ts",
    "content": "import { isBooleanString } from 'class-validator';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\nexport type HttpServer = {\n  NAME: string;\n  TYPE: 'http' | 'https';\n  PORT: number;\n  URL: string;\n  DISABLE_DOCS: boolean;\n  DISABLE_MANAGER: boolean;\n};\n\nexport type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE';\nexport type Cors = {\n  ORIGIN: string[];\n  METHODS: HttpMethods[];\n  CREDENTIALS: boolean;\n};\n\nexport type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\nexport type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS' | 'WEBSOCKET';\n\nexport type Log = {\n  LEVEL: LogLevel[];\n  COLOR: boolean;\n  BAILEYS: LogBaileys;\n};\n\nexport type ProviderSession = {\n  ENABLED: boolean;\n  HOST: string;\n  PORT: string;\n  PREFIX: string;\n};\n\nexport type SaveData = {\n  INSTANCE: boolean;\n  HISTORIC: boolean;\n  NEW_MESSAGE: boolean;\n  MESSAGE_UPDATE: boolean;\n  CONTACTS: boolean;\n  CHATS: boolean;\n  LABELS: boolean;\n  IS_ON_WHATSAPP: boolean;\n  IS_ON_WHATSAPP_DAYS: number;\n};\n\nexport type DBConnection = {\n  URI: string;\n  CLIENT_NAME: string;\n};\nexport type Database = {\n  CONNECTION: DBConnection;\n  PROVIDER: string;\n  SAVE_DATA: SaveData;\n  DELETE_DATA: DeleteData;\n};\n\nexport type DeleteData = {\n  LOGICAL_MESSAGE_DELETE: boolean;\n};\nexport type EventsRabbitmq = {\n  APPLICATION_STARTUP: boolean;\n  INSTANCE_CREATE: boolean;\n  INSTANCE_DELETE: boolean;\n  QRCODE_UPDATED: boolean;\n  MESSAGES_SET: boolean;\n  MESSAGES_UPSERT: boolean;\n  MESSAGES_EDITED: boolean;\n  MESSAGES_UPDATE: boolean;\n  MESSAGES_DELETE: boolean;\n  SEND_MESSAGE: boolean;\n  SEND_MESSAGE_UPDATE: boolean;\n  CONTACTS_SET: boolean;\n  CONTACTS_UPDATE: boolean;\n  CONTACTS_UPSERT: boolean;\n  PRESENCE_UPDATE: boolean;\n  CHATS_SET: boolean;\n  CHATS_UPDATE: boolean;\n  CHATS_DELETE: boolean;\n  CHATS_UPSERT: boolean;\n  CONNECTION_UPDATE: boolean;\n  LABELS_EDIT: boolean;\n  LABELS_ASSOCIATION: boolean;\n  GROUPS_UPSERT: boolean;\n  GROUP_UPDATE: boolean;\n  GROUP_PARTICIPANTS_UPDATE: boolean;\n  CALL: boolean;\n  TYPEBOT_START: boolean;\n  TYPEBOT_CHANGE_STATUS: boolean;\n};\n\nexport type Rabbitmq = {\n  ENABLED: boolean;\n  URI: string;\n  FRAME_MAX: number;\n  EXCHANGE_NAME: string;\n  GLOBAL_ENABLED: boolean;\n  EVENTS: EventsRabbitmq;\n  PREFIX_KEY?: string;\n};\n\nexport type Nats = {\n  ENABLED: boolean;\n  URI: string;\n  EXCHANGE_NAME: string;\n  GLOBAL_ENABLED: boolean;\n  EVENTS: EventsRabbitmq;\n  PREFIX_KEY?: string;\n};\n\nexport type Sqs = {\n  ENABLED: boolean;\n  GLOBAL_ENABLED: boolean;\n  GLOBAL_FORCE_SINGLE_QUEUE: boolean;\n  GLOBAL_PREFIX_NAME: string;\n  ACCESS_KEY_ID: string;\n  SECRET_ACCESS_KEY: string;\n  ACCOUNT_ID: string;\n  REGION: string;\n  MAX_PAYLOAD_SIZE: number;\n  EVENTS: {\n    APPLICATION_STARTUP: boolean;\n    CALL: boolean;\n    CHATS_DELETE: boolean;\n    CHATS_SET: boolean;\n    CHATS_UPDATE: boolean;\n    CHATS_UPSERT: boolean;\n    CONNECTION_UPDATE: boolean;\n    CONTACTS_SET: boolean;\n    CONTACTS_UPDATE: boolean;\n    CONTACTS_UPSERT: boolean;\n    GROUP_PARTICIPANTS_UPDATE: boolean;\n    GROUPS_UPDATE: boolean;\n    GROUPS_UPSERT: boolean;\n    LABELS_ASSOCIATION: boolean;\n    LABELS_EDIT: boolean;\n    LOGOUT_INSTANCE: boolean;\n    MESSAGES_DELETE: boolean;\n    MESSAGES_EDITED: boolean;\n    MESSAGES_SET: boolean;\n    MESSAGES_UPDATE: boolean;\n    MESSAGES_UPSERT: boolean;\n    PRESENCE_UPDATE: boolean;\n    QRCODE_UPDATED: boolean;\n    REMOVE_INSTANCE: boolean;\n    SEND_MESSAGE: boolean;\n    TYPEBOT_CHANGE_STATUS: boolean;\n    TYPEBOT_START: boolean;\n  };\n};\n\nexport type Kafka = {\n  ENABLED: boolean;\n  CLIENT_ID: string;\n  BROKERS: string[];\n  CONNECTION_TIMEOUT: number;\n  REQUEST_TIMEOUT: number;\n  GLOBAL_ENABLED: boolean;\n  CONSUMER_GROUP_ID: string;\n  TOPIC_PREFIX: string;\n  NUM_PARTITIONS: number;\n  REPLICATION_FACTOR: number;\n  AUTO_CREATE_TOPICS: boolean;\n  EVENTS: EventsRabbitmq;\n  SASL?: {\n    ENABLED: boolean;\n    MECHANISM: string;\n    USERNAME: string;\n    PASSWORD: string;\n  };\n  SSL?: {\n    ENABLED: boolean;\n    REJECT_UNAUTHORIZED: boolean;\n    CA?: string;\n    KEY?: string;\n    CERT?: string;\n  };\n};\n\nexport type Websocket = {\n  ENABLED: boolean;\n  GLOBAL_EVENTS: boolean;\n  ALLOWED_HOSTS?: string;\n};\n\nexport type WaBusiness = {\n  TOKEN_WEBHOOK: string;\n  URL: string;\n  VERSION: string;\n  LANGUAGE: string;\n};\n\nexport type EventsWebhook = {\n  APPLICATION_STARTUP: boolean;\n  INSTANCE_CREATE: boolean;\n  INSTANCE_DELETE: boolean;\n  QRCODE_UPDATED: boolean;\n  MESSAGES_SET: boolean;\n  MESSAGES_UPSERT: boolean;\n  MESSAGES_EDITED: boolean;\n  MESSAGES_UPDATE: boolean;\n  MESSAGES_DELETE: boolean;\n  SEND_MESSAGE: boolean;\n  SEND_MESSAGE_UPDATE: boolean;\n  CONTACTS_SET: boolean;\n  CONTACTS_UPDATE: boolean;\n  CONTACTS_UPSERT: boolean;\n  PRESENCE_UPDATE: boolean;\n  CHATS_SET: boolean;\n  CHATS_UPDATE: boolean;\n  CHATS_DELETE: boolean;\n  CHATS_UPSERT: boolean;\n  CONNECTION_UPDATE: boolean;\n  LABELS_EDIT: boolean;\n  LABELS_ASSOCIATION: boolean;\n  GROUPS_UPSERT: boolean;\n  GROUP_UPDATE: boolean;\n  GROUP_PARTICIPANTS_UPDATE: boolean;\n  CALL: boolean;\n  TYPEBOT_START: boolean;\n  TYPEBOT_CHANGE_STATUS: boolean;\n  ERRORS: boolean;\n  ERRORS_WEBHOOK: string;\n};\n\nexport type EventsPusher = {\n  APPLICATION_STARTUP: boolean;\n  INSTANCE_CREATE: boolean;\n  INSTANCE_DELETE: boolean;\n  QRCODE_UPDATED: boolean;\n  MESSAGES_SET: boolean;\n  MESSAGES_UPSERT: boolean;\n  MESSAGES_EDITED: boolean;\n  MESSAGES_UPDATE: boolean;\n  MESSAGES_DELETE: boolean;\n  SEND_MESSAGE: boolean;\n  SEND_MESSAGE_UPDATE: boolean;\n  CONTACTS_SET: boolean;\n  CONTACTS_UPDATE: boolean;\n  CONTACTS_UPSERT: boolean;\n  PRESENCE_UPDATE: boolean;\n  CHATS_SET: boolean;\n  CHATS_UPDATE: boolean;\n  CHATS_DELETE: boolean;\n  CHATS_UPSERT: boolean;\n  CONNECTION_UPDATE: boolean;\n  LABELS_EDIT: boolean;\n  LABELS_ASSOCIATION: boolean;\n  GROUPS_UPSERT: boolean;\n  GROUP_UPDATE: boolean;\n  GROUP_PARTICIPANTS_UPDATE: boolean;\n  CALL: boolean;\n  TYPEBOT_START: boolean;\n  TYPEBOT_CHANGE_STATUS: boolean;\n};\n\nexport type ApiKey = { KEY: string };\n\nexport type Auth = {\n  API_KEY: ApiKey;\n  EXPOSE_IN_FETCH_INSTANCES: boolean;\n};\n\nexport type DelInstance = number | boolean;\n\nexport type Language = string | 'en';\n\nexport type GlobalWebhook = {\n  URL: string;\n  ENABLED: boolean;\n  WEBHOOK_BY_EVENTS: boolean;\n};\n\nexport type GlobalPusher = {\n  ENABLED: boolean;\n  APP_ID: string;\n  KEY: string;\n  SECRET: string;\n  CLUSTER: string;\n  USE_TLS: boolean;\n};\n\nexport type CacheConfRedis = {\n  ENABLED: boolean;\n  URI: string;\n  PREFIX_KEY: string;\n  TTL: number;\n  SAVE_INSTANCES: boolean;\n};\nexport type CacheConfLocal = {\n  ENABLED: boolean;\n  TTL: number;\n};\nexport type SslConf = { PRIVKEY: string; FULLCHAIN: string };\nexport type Webhook = {\n  GLOBAL?: GlobalWebhook;\n  EVENTS: EventsWebhook;\n  REQUEST?: {\n    TIMEOUT_MS?: number;\n  };\n  RETRY?: {\n    MAX_ATTEMPTS?: number;\n    INITIAL_DELAY_SECONDS?: number;\n    USE_EXPONENTIAL_BACKOFF?: boolean;\n    MAX_DELAY_SECONDS?: number;\n    JITTER_FACTOR?: number;\n    NON_RETRYABLE_STATUS_CODES?: number[];\n  };\n};\nexport type Pusher = { ENABLED: boolean; GLOBAL?: GlobalPusher; EVENTS: EventsPusher };\nexport type ConfigSessionPhone = { CLIENT: string; NAME: string };\nexport type QrCode = { LIMIT: number; COLOR: string };\nexport type Typebot = { ENABLED: boolean; API_VERSION: string; SEND_MEDIA_BASE64: boolean };\nexport type Chatwoot = {\n  ENABLED: boolean;\n  MESSAGE_DELETE: boolean;\n  MESSAGE_READ: boolean;\n  BOT_CONTACT: boolean;\n  IMPORT: {\n    DATABASE: {\n      CONNECTION: {\n        URI: string;\n      };\n    };\n    PLACEHOLDER_MEDIA_MESSAGE: boolean;\n  };\n};\nexport type Openai = { ENABLED: boolean; API_KEY_GLOBAL?: string };\nexport type Dify = { ENABLED: boolean };\nexport type N8n = { ENABLED: boolean };\nexport type Evoai = { ENABLED: boolean };\nexport type Flowise = { ENABLED: boolean };\n\nexport type S3 = {\n  ACCESS_KEY: string;\n  SECRET_KEY: string;\n  ENDPOINT: string;\n  BUCKET_NAME: string;\n  ENABLE: boolean;\n  PORT?: number;\n  USE_SSL?: boolean;\n  REGION?: string;\n  SKIP_POLICY?: boolean;\n  SAVE_VIDEO?: boolean;\n};\n\nexport type CacheConf = { REDIS: CacheConfRedis; LOCAL: CacheConfLocal };\nexport type Metrics = {\n  ENABLED: boolean;\n  AUTH_REQUIRED: boolean;\n  USER?: string;\n  PASSWORD?: string;\n  ALLOWED_IPS?: string;\n};\n\nexport type Telemetry = {\n  ENABLED: boolean;\n  URL?: string;\n};\n\nexport type Proxy = {\n  HOST?: string;\n  PORT?: string;\n  PROTOCOL?: string;\n  USERNAME?: string;\n  PASSWORD?: string;\n};\n\nexport type AudioConverter = {\n  API_URL?: string;\n  API_KEY?: string;\n};\n\nexport type Facebook = {\n  APP_ID?: string;\n  CONFIG_ID?: string;\n  USER_TOKEN?: string;\n};\n\nexport type Sentry = {\n  DSN?: string;\n};\n\nexport type EventEmitter = {\n  MAX_LISTENERS: number;\n};\n\nexport type Production = boolean;\n\nexport interface Env {\n  SERVER: HttpServer;\n  CORS: Cors;\n  SSL_CONF: SslConf;\n  PROVIDER: ProviderSession;\n  DATABASE: Database;\n  RABBITMQ: Rabbitmq;\n  NATS: Nats;\n  SQS: Sqs;\n  KAFKA: Kafka;\n  WEBSOCKET: Websocket;\n  WA_BUSINESS: WaBusiness;\n  LOG: Log;\n  DEL_INSTANCE: DelInstance;\n  DEL_TEMP_INSTANCES: boolean;\n  LANGUAGE: Language;\n  WEBHOOK: Webhook;\n  PUSHER: Pusher;\n  CONFIG_SESSION_PHONE: ConfigSessionPhone;\n  QRCODE: QrCode;\n  TYPEBOT: Typebot;\n  CHATWOOT: Chatwoot;\n  OPENAI: Openai;\n  DIFY: Dify;\n  N8N: N8n;\n  EVOAI: Evoai;\n  FLOWISE: Flowise;\n  CACHE: CacheConf;\n  S3?: S3;\n  AUTHENTICATION: Auth;\n  METRICS: Metrics;\n  TELEMETRY: Telemetry;\n  PROXY: Proxy;\n  AUDIO_CONVERTER: AudioConverter;\n  FACEBOOK: Facebook;\n  SENTRY: Sentry;\n  EVENT_EMITTER: EventEmitter;\n  PRODUCTION?: Production;\n}\n\nexport type Key = keyof Env;\n\nexport class ConfigService {\n  constructor() {\n    this.loadEnv();\n  }\n\n  private env: Env;\n\n  public get<T = any>(key: Key) {\n    return this.env[key] as T;\n  }\n\n  private loadEnv() {\n    this.env = this.envProcess();\n    this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD';\n    if (process.env?.DOCKER_ENV === 'true') {\n      this.env.SERVER.TYPE = process.env.SERVER_TYPE as 'http' | 'http';\n      this.env.SERVER.PORT = Number.parseInt(process.env.SERVER_PORT) || 8080;\n    }\n  }\n\n  private envProcess(): Env {\n    return {\n      SERVER: {\n        NAME: process.env?.SERVER_NAME || 'evolution',\n        TYPE: (process.env.SERVER_TYPE as 'http' | 'https') || 'http',\n        PORT: Number.parseInt(process.env.SERVER_PORT) || 8080,\n        URL: process.env.SERVER_URL,\n        DISABLE_DOCS: process.env?.SERVER_DISABLE_DOCS === 'true',\n        DISABLE_MANAGER: process.env?.SERVER_DISABLE_MANAGER === 'true',\n      },\n      CORS: {\n        ORIGIN: process.env.CORS_ORIGIN?.split(',') || ['*'],\n        METHODS:\n          (process.env.CORS_METHODS?.split(',') as HttpMethods[]) ||\n          (['POST', 'GET', 'PUT', 'DELETE'] as HttpMethods[]),\n        CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true',\n      },\n      SSL_CONF: {\n        PRIVKEY: process.env?.SSL_CONF_PRIVKEY || '',\n        FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN || '',\n      },\n      PROVIDER: {\n        ENABLED: process.env?.PROVIDER_ENABLED === 'true',\n        HOST: process.env.PROVIDER_HOST,\n        PORT: process.env?.PROVIDER_PORT || '5656',\n        PREFIX: process.env?.PROVIDER_PREFIX || 'evolution',\n      },\n      DATABASE: {\n        CONNECTION: {\n          URI: process.env.DATABASE_CONNECTION_URI || '',\n          CLIENT_NAME: process.env.DATABASE_CONNECTION_CLIENT_NAME || 'evolution',\n        },\n        PROVIDER: process.env.DATABASE_PROVIDER || 'postgresql',\n        SAVE_DATA: {\n          INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',\n          NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',\n          MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true',\n          CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true',\n          CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true',\n          HISTORIC: process.env?.DATABASE_SAVE_DATA_HISTORIC === 'true',\n          LABELS: process.env?.DATABASE_SAVE_DATA_LABELS === 'true',\n          IS_ON_WHATSAPP: process.env?.DATABASE_SAVE_IS_ON_WHATSAPP === 'true',\n          IS_ON_WHATSAPP_DAYS: Number.parseInt(process.env?.DATABASE_SAVE_IS_ON_WHATSAPP_DAYS ?? '7'),\n        },\n        DELETE_DATA: {\n          LOGICAL_MESSAGE_DELETE: process.env?.DATABASE_DELETE_MESSAGE === 'true',\n        },\n      },\n      RABBITMQ: {\n        ENABLED: process.env?.RABBITMQ_ENABLED === 'true',\n        GLOBAL_ENABLED: process.env?.RABBITMQ_GLOBAL_ENABLED === 'true',\n        PREFIX_KEY: process.env?.RABBITMQ_PREFIX_KEY,\n        EXCHANGE_NAME: process.env?.RABBITMQ_EXCHANGE_NAME || 'evolution_exchange',\n        URI: process.env.RABBITMQ_URI || '',\n        FRAME_MAX: Number.parseInt(process.env.RABBITMQ_FRAME_MAX) || 8192,\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.RABBITMQ_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.RABBITMQ_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.RABBITMQ_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.RABBITMQ_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.RABBITMQ_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.RABBITMQ_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.RABBITMQ_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.RABBITMQ_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.RABBITMQ_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.RABBITMQ_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.RABBITMQ_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.RABBITMQ_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.RABBITMQ_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.RABBITMQ_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.RABBITMQ_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.RABBITMQ_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.RABBITMQ_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.RABBITMQ_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.RABBITMQ_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.RABBITMQ_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.RABBITMQ_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.RABBITMQ_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.RABBITMQ_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.RABBITMQ_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.RABBITMQ_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.RABBITMQ_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n      },\n      NATS: {\n        ENABLED: process.env?.NATS_ENABLED === 'true',\n        GLOBAL_ENABLED: process.env?.NATS_GLOBAL_ENABLED === 'true',\n        PREFIX_KEY: process.env?.NATS_PREFIX_KEY,\n        EXCHANGE_NAME: process.env?.NATS_EXCHANGE_NAME || 'evolution_exchange',\n        URI: process.env.NATS_URI || '',\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.NATS_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.NATS_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.NATS_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.NATS_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.NATS_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.NATS_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.NATS_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.NATS_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.NATS_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.NATS_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.NATS_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.NATS_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.NATS_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.NATS_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.NATS_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.NATS_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.NATS_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.NATS_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.NATS_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.NATS_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.NATS_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.NATS_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.NATS_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.NATS_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.NATS_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.NATS_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.NATS_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.NATS_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n      },\n      SQS: {\n        ENABLED: process.env?.SQS_ENABLED === 'true',\n        GLOBAL_ENABLED: process.env?.SQS_GLOBAL_ENABLED === 'true',\n        GLOBAL_FORCE_SINGLE_QUEUE: process.env?.SQS_GLOBAL_FORCE_SINGLE_QUEUE === 'true',\n        GLOBAL_PREFIX_NAME: process.env?.SQS_GLOBAL_PREFIX_NAME || 'global',\n        ACCESS_KEY_ID: process.env.SQS_ACCESS_KEY_ID || '',\n        SECRET_ACCESS_KEY: process.env.SQS_SECRET_ACCESS_KEY || '',\n        ACCOUNT_ID: process.env.SQS_ACCOUNT_ID || '',\n        REGION: process.env.SQS_REGION || '',\n        MAX_PAYLOAD_SIZE: Number.parseInt(process.env.SQS_MAX_PAYLOAD_SIZE ?? '1048576'),\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.SQS_GLOBAL_APPLICATION_STARTUP === 'true',\n          CALL: process.env?.SQS_GLOBAL_CALL === 'true',\n          CHATS_DELETE: process.env?.SQS_GLOBAL_CHATS_DELETE === 'true',\n          CHATS_SET: process.env?.SQS_GLOBAL_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.SQS_GLOBAL_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.SQS_GLOBAL_CHATS_UPSERT === 'true',\n          CONNECTION_UPDATE: process.env?.SQS_GLOBAL_CONNECTION_UPDATE === 'true',\n          CONTACTS_SET: process.env?.SQS_GLOBAL_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.SQS_GLOBAL_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.SQS_GLOBAL_CONTACTS_UPSERT === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.SQS_GLOBAL_GROUP_PARTICIPANTS_UPDATE === 'true',\n          GROUPS_UPDATE: process.env?.SQS_GLOBAL_GROUPS_UPDATE === 'true',\n          GROUPS_UPSERT: process.env?.SQS_GLOBAL_GROUPS_UPSERT === 'true',\n          LABELS_ASSOCIATION: process.env?.SQS_GLOBAL_LABELS_ASSOCIATION === 'true',\n          LABELS_EDIT: process.env?.SQS_GLOBAL_LABELS_EDIT === 'true',\n          LOGOUT_INSTANCE: process.env?.SQS_GLOBAL_LOGOUT_INSTANCE === 'true',\n          MESSAGES_DELETE: process.env?.SQS_GLOBAL_MESSAGES_DELETE === 'true',\n          MESSAGES_EDITED: process.env?.SQS_GLOBAL_MESSAGES_EDITED === 'true',\n          MESSAGES_SET: process.env?.SQS_GLOBAL_MESSAGES_SET === 'true',\n          MESSAGES_UPDATE: process.env?.SQS_GLOBAL_MESSAGES_UPDATE === 'true',\n          MESSAGES_UPSERT: process.env?.SQS_GLOBAL_MESSAGES_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.SQS_GLOBAL_PRESENCE_UPDATE === 'true',\n          QRCODE_UPDATED: process.env?.SQS_GLOBAL_QRCODE_UPDATED === 'true',\n          REMOVE_INSTANCE: process.env?.SQS_GLOBAL_REMOVE_INSTANCE === 'true',\n          SEND_MESSAGE: process.env?.SQS_GLOBAL_SEND_MESSAGE === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.SQS_GLOBAL_TYPEBOT_CHANGE_STATUS === 'true',\n          TYPEBOT_START: process.env?.SQS_GLOBAL_TYPEBOT_START === 'true',\n        },\n      },\n      KAFKA: {\n        ENABLED: process.env?.KAFKA_ENABLED === 'true',\n        CLIENT_ID: process.env?.KAFKA_CLIENT_ID || 'evolution-api',\n        BROKERS: process.env?.KAFKA_BROKERS?.split(',') || ['localhost:9092'],\n        CONNECTION_TIMEOUT: Number.parseInt(process.env?.KAFKA_CONNECTION_TIMEOUT || '3000'),\n        REQUEST_TIMEOUT: Number.parseInt(process.env?.KAFKA_REQUEST_TIMEOUT || '30000'),\n        GLOBAL_ENABLED: process.env?.KAFKA_GLOBAL_ENABLED === 'true',\n        CONSUMER_GROUP_ID: process.env?.KAFKA_CONSUMER_GROUP_ID || 'evolution-api-consumers',\n        TOPIC_PREFIX: process.env?.KAFKA_TOPIC_PREFIX || 'evolution',\n        NUM_PARTITIONS: Number.parseInt(process.env?.KAFKA_NUM_PARTITIONS || '1'),\n        REPLICATION_FACTOR: Number.parseInt(process.env?.KAFKA_REPLICATION_FACTOR || '1'),\n        AUTO_CREATE_TOPICS: process.env?.KAFKA_AUTO_CREATE_TOPICS === 'true',\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.KAFKA_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.KAFKA_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.KAFKA_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.KAFKA_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.KAFKA_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.KAFKA_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.KAFKA_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.KAFKA_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.KAFKA_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.KAFKA_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.KAFKA_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.KAFKA_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPSERT: process.env?.KAFKA_EVENTS_CONTACTS_UPSERT === 'true',\n          CONTACTS_UPDATE: process.env?.KAFKA_EVENTS_CONTACTS_UPDATE === 'true',\n          PRESENCE_UPDATE: process.env?.KAFKA_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.KAFKA_EVENTS_CHATS_SET === 'true',\n          CHATS_UPSERT: process.env?.KAFKA_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_UPDATE: process.env?.KAFKA_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_DELETE: process.env?.KAFKA_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.KAFKA_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.KAFKA_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.KAFKA_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.KAFKA_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.KAFKA_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.KAFKA_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.KAFKA_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.KAFKA_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.KAFKA_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n        SASL:\n          process.env?.KAFKA_SASL_ENABLED === 'true'\n            ? {\n                ENABLED: true,\n                MECHANISM: process.env?.KAFKA_SASL_MECHANISM || 'plain',\n                USERNAME: process.env?.KAFKA_SASL_USERNAME || '',\n                PASSWORD: process.env?.KAFKA_SASL_PASSWORD || '',\n              }\n            : undefined,\n        SSL:\n          process.env?.KAFKA_SSL_ENABLED === 'true'\n            ? {\n                ENABLED: true,\n                REJECT_UNAUTHORIZED: process.env?.KAFKA_SSL_REJECT_UNAUTHORIZED !== 'false',\n                CA: process.env?.KAFKA_SSL_CA,\n                KEY: process.env?.KAFKA_SSL_KEY,\n                CERT: process.env?.KAFKA_SSL_CERT,\n              }\n            : undefined,\n      },\n      WEBSOCKET: {\n        ENABLED: process.env?.WEBSOCKET_ENABLED === 'true',\n        GLOBAL_EVENTS: process.env?.WEBSOCKET_GLOBAL_EVENTS === 'true',\n        ALLOWED_HOSTS: process.env?.WEBSOCKET_ALLOWED_HOSTS,\n      },\n      PUSHER: {\n        ENABLED: process.env?.PUSHER_ENABLED === 'true',\n        GLOBAL: {\n          ENABLED: process.env?.PUSHER_GLOBAL_ENABLED === 'true',\n          APP_ID: process.env?.PUSHER_GLOBAL_APP_ID || '',\n          KEY: process.env?.PUSHER_GLOBAL_KEY || '',\n          SECRET: process.env?.PUSHER_GLOBAL_SECRET || '',\n          CLUSTER: process.env?.PUSHER_GLOBAL_CLUSTER || '',\n          USE_TLS: process.env?.PUSHER_GLOBAL_USE_TLS === 'true',\n        },\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.PUSHER_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.PUSHER_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.PUSHER_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.PUSHER_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.PUSHER_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.PUSHER_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.PUSHER_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.PUSHER_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.PUSHER_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.PUSHER_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.PUSHER_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.PUSHER_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.PUSHER_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.PUSHER_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.PUSHER_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.PUSHER_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.PUSHER_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.PUSHER_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.PUSHER_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.PUSHER_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.PUSHER_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.PUSHER_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.PUSHER_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.PUSHER_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.PUSHER_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.PUSHER_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.PUSHER_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.PUSHER_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n        },\n      },\n      WA_BUSINESS: {\n        TOKEN_WEBHOOK: process.env.WA_BUSINESS_TOKEN_WEBHOOK || 'evolution',\n        URL: process.env.WA_BUSINESS_URL || 'https://graph.facebook.com',\n        VERSION: process.env.WA_BUSINESS_VERSION || 'v18.0',\n        LANGUAGE: process.env.WA_BUSINESS_LANGUAGE || 'en',\n      },\n      LOG: {\n        LEVEL:\n          (process.env?.LOG_LEVEL?.split(',') as LogLevel[]) ||\n          (['ERROR', 'WARN', 'DEBUG', 'INFO', 'LOG', 'VERBOSE', 'DARK', 'WEBHOOKS', 'WEBSOCKET'] as LogLevel[]),\n        COLOR: process.env?.LOG_COLOR === 'true',\n        BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error',\n      },\n      DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE)\n        ? process.env.DEL_INSTANCE === 'true'\n        : Number.parseInt(process.env.DEL_INSTANCE) || false,\n      DEL_TEMP_INSTANCES: isBooleanString(process.env?.DEL_TEMP_INSTANCES)\n        ? process.env.DEL_TEMP_INSTANCES === 'true'\n        : true,\n      LANGUAGE: process.env?.LANGUAGE || 'en',\n      WEBHOOK: {\n        GLOBAL: {\n          URL: process.env?.WEBHOOK_GLOBAL_URL || '',\n          ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true',\n          WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true',\n        },\n        EVENTS: {\n          APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true',\n          INSTANCE_CREATE: process.env?.WEBHOOK_EVENTS_INSTANCE_CREATE === 'true',\n          INSTANCE_DELETE: process.env?.WEBHOOK_EVENTS_INSTANCE_DELETE === 'true',\n          QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true',\n          MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true',\n          MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true',\n          MESSAGES_EDITED: process.env?.WEBHOOK_EVENTS_MESSAGES_EDITED === 'true',\n          MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true',\n          MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true',\n          SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true',\n          SEND_MESSAGE_UPDATE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE_UPDATE === 'true',\n          CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true',\n          CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true',\n          CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true',\n          PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true',\n          CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true',\n          CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true',\n          CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true',\n          CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true',\n          CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true',\n          LABELS_EDIT: process.env?.WEBHOOK_EVENTS_LABELS_EDIT === 'true',\n          LABELS_ASSOCIATION: process.env?.WEBHOOK_EVENTS_LABELS_ASSOCIATION === 'true',\n          GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true',\n          GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true',\n          GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true',\n          CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true',\n          TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true',\n          TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',\n          ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',\n          ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',\n        },\n        REQUEST: {\n          TIMEOUT_MS: Number.parseInt(process.env?.WEBHOOK_REQUEST_TIMEOUT_MS) || 30000,\n        },\n        RETRY: {\n          MAX_ATTEMPTS: Number.parseInt(process.env?.WEBHOOK_RETRY_MAX_ATTEMPTS) || 10,\n          INITIAL_DELAY_SECONDS: Number.parseInt(process.env?.WEBHOOK_RETRY_INITIAL_DELAY_SECONDS) || 5,\n          USE_EXPONENTIAL_BACKOFF: process.env?.WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF !== 'false',\n          MAX_DELAY_SECONDS: Number.parseInt(process.env?.WEBHOOK_RETRY_MAX_DELAY_SECONDS) || 300,\n          JITTER_FACTOR: Number.parseFloat(process.env?.WEBHOOK_RETRY_JITTER_FACTOR) || 0.2,\n          NON_RETRYABLE_STATUS_CODES: process.env?.WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES?.split(',').map(Number) || [\n            400, 401, 403, 404, 422,\n          ],\n        },\n      },\n      CONFIG_SESSION_PHONE: {\n        CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API',\n        NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'Chrome',\n      },\n      QRCODE: {\n        LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30,\n        COLOR: process.env.QRCODE_COLOR || '#198754',\n      },\n      TYPEBOT: {\n        ENABLED: process.env?.TYPEBOT_ENABLED === 'true',\n        API_VERSION: process.env?.TYPEBOT_API_VERSION || 'old',\n        SEND_MEDIA_BASE64: process.env?.TYPEBOT_SEND_MEDIA_BASE64 === 'true',\n      },\n      CHATWOOT: {\n        ENABLED: process.env?.CHATWOOT_ENABLED === 'true',\n        MESSAGE_DELETE: process.env.CHATWOOT_MESSAGE_DELETE === 'true',\n        MESSAGE_READ: process.env.CHATWOOT_MESSAGE_READ === 'true',\n        BOT_CONTACT: !process.env.CHATWOOT_BOT_CONTACT || process.env.CHATWOOT_BOT_CONTACT === 'true',\n        IMPORT: {\n          DATABASE: {\n            CONNECTION: {\n              URI: process.env.CHATWOOT_IMPORT_DATABASE_CONNECTION_URI || '',\n            },\n          },\n          PLACEHOLDER_MEDIA_MESSAGE: process.env?.CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE === 'true',\n        },\n      },\n      OPENAI: {\n        ENABLED: process.env?.OPENAI_ENABLED === 'true',\n        API_KEY_GLOBAL: process.env?.OPENAI_API_KEY_GLOBAL || null,\n      },\n      DIFY: {\n        ENABLED: process.env?.DIFY_ENABLED === 'true',\n      },\n      N8N: {\n        ENABLED: process.env?.N8N_ENABLED === 'true',\n      },\n      EVOAI: {\n        ENABLED: process.env?.EVOAI_ENABLED === 'true',\n      },\n      FLOWISE: {\n        ENABLED: process.env?.FLOWISE_ENABLED === 'true',\n      },\n      CACHE: {\n        REDIS: {\n          ENABLED: process.env?.CACHE_REDIS_ENABLED === 'true',\n          URI: process.env?.CACHE_REDIS_URI || '',\n          PREFIX_KEY: process.env?.CACHE_REDIS_PREFIX_KEY || 'evolution-cache',\n          TTL: Number.parseInt(process.env?.CACHE_REDIS_TTL) || 604800,\n          SAVE_INSTANCES: process.env?.CACHE_REDIS_SAVE_INSTANCES === 'true',\n        },\n        LOCAL: {\n          ENABLED: process.env?.CACHE_LOCAL_ENABLED === 'true',\n          TTL: Number.parseInt(process.env?.CACHE_REDIS_TTL) || 86400,\n        },\n      },\n      S3: {\n        ACCESS_KEY: process.env?.S3_ACCESS_KEY,\n        SECRET_KEY: process.env?.S3_SECRET_KEY,\n        ENDPOINT: process.env?.S3_ENDPOINT,\n        BUCKET_NAME: process.env?.S3_BUCKET,\n        ENABLE: process.env?.S3_ENABLED === 'true',\n        PORT: Number.parseInt(process.env?.S3_PORT || '9000'),\n        USE_SSL: process.env?.S3_USE_SSL === 'true',\n        REGION: process.env?.S3_REGION,\n        SKIP_POLICY: process.env?.S3_SKIP_POLICY === 'true',\n        SAVE_VIDEO: process.env?.S3_SAVE_VIDEO === 'true',\n      },\n      AUTHENTICATION: {\n        API_KEY: {\n          KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ',\n        },\n        EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true',\n      },\n      METRICS: {\n        ENABLED: process.env?.PROMETHEUS_METRICS === 'true',\n        AUTH_REQUIRED: process.env?.METRICS_AUTH_REQUIRED === 'true',\n        USER: process.env?.METRICS_USER,\n        PASSWORD: process.env?.METRICS_PASSWORD,\n        ALLOWED_IPS: process.env?.METRICS_ALLOWED_IPS,\n      },\n      TELEMETRY: {\n        ENABLED: process.env?.TELEMETRY_ENABLED === undefined || process.env?.TELEMETRY_ENABLED === 'true',\n        URL: process.env?.TELEMETRY_URL,\n      },\n      PROXY: {\n        HOST: process.env?.PROXY_HOST,\n        PORT: process.env?.PROXY_PORT,\n        PROTOCOL: process.env?.PROXY_PROTOCOL,\n        USERNAME: process.env?.PROXY_USERNAME,\n        PASSWORD: process.env?.PROXY_PASSWORD,\n      },\n      AUDIO_CONVERTER: {\n        API_URL: process.env?.API_AUDIO_CONVERTER,\n        API_KEY: process.env?.API_AUDIO_CONVERTER_KEY,\n      },\n      FACEBOOK: {\n        APP_ID: process.env?.FACEBOOK_APP_ID,\n        CONFIG_ID: process.env?.FACEBOOK_CONFIG_ID,\n        USER_TOKEN: process.env?.FACEBOOK_USER_TOKEN,\n      },\n      SENTRY: {\n        DSN: process.env?.SENTRY_DSN,\n      },\n      EVENT_EMITTER: {\n        MAX_LISTENERS: Number.parseInt(process.env?.EVENT_EMITTER_MAX_LISTENERS) || 50,\n      },\n    };\n  }\n}\n\nexport const configService = new ConfigService();\n"
  },
  {
    "path": "src/config/error.config.ts",
    "content": "import { Logger } from './logger.config';\n\nexport function onUnexpectedError() {\n  process.on('uncaughtException', (error, origin) => {\n    const logger = new Logger('uncaughtException');\n    logger.error({\n      origin,\n      stderr: process.stderr.fd,\n      error,\n    });\n  });\n\n  process.on('unhandledRejection', (error, origin) => {\n    const logger = new Logger('unhandledRejection');\n    logger.error({\n      origin,\n      stderr: process.stderr.fd,\n    });\n    logger.error(error);\n  });\n}\n"
  },
  {
    "path": "src/config/event.config.ts",
    "content": "import { configService, EventEmitter as EventEmitterConfig } from '@config/env.config';\nimport EventEmitter2 from 'eventemitter2';\n\nconst eventEmitterConfig = configService.get<EventEmitterConfig>('EVENT_EMITTER');\n\nexport const eventEmitter = new EventEmitter2({\n  delimiter: '.',\n  newListener: false,\n  ignoreErrors: false,\n  maxListeners: eventEmitterConfig.MAX_LISTENERS,\n});\n"
  },
  {
    "path": "src/config/logger.config.ts",
    "content": "import dayjs from 'dayjs';\nimport fs from 'fs';\n\nimport { configService, Log } from './env.config';\nconst packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));\n\nconst formatDateLog = (timestamp: number) =>\n  dayjs(timestamp)\n    .toDate()\n    .toString()\n    .replace(/\\sGMT.+/, '');\n\nenum Color {\n  LOG = '\\x1b[32m',\n  INFO = '\\x1b[34m',\n  WARN = '\\x1b[33m',\n  ERROR = '\\x1b[31m',\n  DEBUG = '\\x1b[36m',\n  VERBOSE = '\\x1b[37m',\n  DARK = '\\x1b[30m',\n}\n\nenum Command {\n  RESET = '\\x1b[0m',\n  BRIGHT = '\\x1b[1m',\n  UNDERSCORE = '\\x1b[4m',\n}\n\nenum Level {\n  LOG = Color.LOG + '%s' + Command.RESET,\n  DARK = Color.DARK + '%s' + Command.RESET,\n  INFO = Color.INFO + '%s' + Command.RESET,\n  WARN = Color.WARN + '%s' + Command.RESET,\n  ERROR = Color.ERROR + '%s' + Command.RESET,\n  DEBUG = Color.DEBUG + '%s' + Command.RESET,\n  VERBOSE = Color.VERBOSE + '%s' + Command.RESET,\n}\n\nenum Type {\n  LOG = 'LOG',\n  WARN = 'WARN',\n  INFO = 'INFO',\n  DARK = 'DARK',\n  ERROR = 'ERROR',\n  DEBUG = 'DEBUG',\n  VERBOSE = 'VERBOSE',\n}\n\nenum Background {\n  LOG = '\\x1b[42m',\n  INFO = '\\x1b[44m',\n  WARN = '\\x1b[43m',\n  DARK = '\\x1b[40m',\n  ERROR = '\\x1b[41m',\n  DEBUG = '\\x1b[46m',\n  VERBOSE = '\\x1b[47m',\n}\n\nexport class Logger {\n  private readonly configService = configService;\n  private context: string;\n\n  constructor(context = 'Logger') {\n    this.context = context;\n  }\n\n  private instance = null;\n\n  public setContext(value: string) {\n    this.context = value;\n  }\n\n  public setInstance(value: string) {\n    this.instance = value;\n  }\n\n  private console(value: any, type: Type) {\n    const types: Type[] = [];\n\n    this.configService.get<Log>('LOG').LEVEL.forEach((level) => types.push(Type[level]));\n\n    const typeValue = typeof value;\n    if (types.includes(type)) {\n      if (configService.get<Log>('LOG').COLOR) {\n        console.log(\n          /*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type],\n          '[Evolution API]',\n          Command.BRIGHT + Color[type],\n          this.instance ? `[${this.instance}]` : '',\n          Command.BRIGHT + Color[type],\n          `v${packageJson.version}`,\n          Command.BRIGHT + Color[type],\n          process.pid.toString(),\n          Command.RESET,\n          Command.BRIGHT + Color[type],\n          '-',\n          Command.BRIGHT + Color.VERBOSE,\n          `${formatDateLog(Date.now())}  `,\n          Command.RESET,\n          Color[type] + Background[type] + Command.BRIGHT,\n          `${type} ` + Command.RESET,\n          Color.WARN + Command.BRIGHT,\n          `[${this.context}]` + Command.RESET,\n          Color[type] + Command.BRIGHT,\n          `[${typeValue}]` + Command.RESET,\n          Color[type],\n          typeValue !== 'object' ? value : '',\n          Command.RESET,\n        );\n        typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\\n') : '';\n      } else {\n        console.log(\n          '[Evolution API]',\n          this.instance ? `[${this.instance}]` : '',\n          process.pid.toString(),\n          '-',\n          `${formatDateLog(Date.now())}  `,\n          `${type} `,\n          `[${this.context}]`,\n          `[${typeValue}]`,\n          value,\n        );\n      }\n    }\n  }\n\n  public log(value: any) {\n    this.console(value, Type.LOG);\n  }\n\n  public info(value: any) {\n    this.console(value, Type.INFO);\n  }\n\n  public warn(value: any) {\n    this.console(value, Type.WARN);\n  }\n\n  public error(value: any) {\n    this.console(value, Type.ERROR);\n  }\n\n  public verbose(value: any) {\n    this.console(value, Type.VERBOSE);\n  }\n\n  public debug(value: any) {\n    this.console(value, Type.DEBUG);\n  }\n\n  public dark(value: any) {\n    this.console(value, Type.DARK);\n  }\n}\n"
  },
  {
    "path": "src/config/path.config.ts",
    "content": "import { join } from 'path';\n\nexport const ROOT_DIR = process.cwd();\nexport const INSTANCE_DIR = join(ROOT_DIR, 'instances');\nexport const SRC_DIR = join(ROOT_DIR, 'src');\nexport const AUTH_DIR = join(ROOT_DIR, 'store', 'auth');\nexport const STORE_DIR = join(ROOT_DIR, 'store');\n"
  },
  {
    "path": "src/exceptions/400.exception.ts",
    "content": "import { HttpStatus } from '@api/routes/index.router';\n\nexport class BadRequestException {\n  constructor(...objectError: any[]) {\n    throw {\n      status: HttpStatus.BAD_REQUEST,\n      error: 'Bad Request',\n      message: objectError.length > 0 ? objectError : undefined,\n    };\n  }\n}\n"
  },
  {
    "path": "src/exceptions/401.exception.ts",
    "content": "import { HttpStatus } from '@api/routes/index.router';\n\nexport class UnauthorizedException {\n  constructor(...objectError: any[]) {\n    throw {\n      status: HttpStatus.UNAUTHORIZED,\n      error: 'Unauthorized',\n      message: objectError.length > 0 ? objectError : 'Unauthorized',\n    };\n  }\n}\n"
  },
  {
    "path": "src/exceptions/403.exception.ts",
    "content": "import { HttpStatus } from '@api/routes/index.router';\n\nexport class ForbiddenException {\n  constructor(...objectError: any[]) {\n    throw {\n      status: HttpStatus.FORBIDDEN,\n      error: 'Forbidden',\n      message: objectError.length > 0 ? objectError : undefined,\n    };\n  }\n}\n"
  },
  {
    "path": "src/exceptions/404.exception.ts",
    "content": "import { HttpStatus } from '@api/routes/index.router';\n\nexport class NotFoundException {\n  constructor(...objectError: any[]) {\n    throw {\n      status: HttpStatus.NOT_FOUND,\n      error: 'Not Found',\n      message: objectError.length > 0 ? objectError : undefined,\n    };\n  }\n}\n"
  },
  {
    "path": "src/exceptions/500.exception.ts",
    "content": "import { HttpStatus } from '@api/routes/index.router';\n\nexport class InternalServerErrorException {\n  constructor(...objectError: any[]) {\n    throw {\n      status: HttpStatus.INTERNAL_SERVER_ERROR,\n      error: 'Internal Server Error',\n      message: objectError.length > 0 ? objectError : undefined,\n    };\n  }\n}\n"
  },
  {
    "path": "src/exceptions/index.ts",
    "content": "export * from './400.exception';\nexport * from './401.exception';\nexport * from './403.exception';\nexport * from './404.exception';\nexport * from './500.exception';\n"
  },
  {
    "path": "src/main.ts",
    "content": "// Import this first from sentry instrument!\nimport '@utils/instrumentSentry';\n\n// Now import other modules\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { PrismaRepository } from '@api/repository/repository.service';\nimport { HttpStatus, router } from '@api/routes/index.router';\nimport { eventManager, waMonitor } from '@api/server.module';\nimport {\n  Auth,\n  configService,\n  Cors,\n  HttpServer,\n  ProviderSession,\n  Sentry as SentryConfig,\n  Webhook,\n} from '@config/env.config';\nimport { onUnexpectedError } from '@config/error.config';\nimport { Logger } from '@config/logger.config';\nimport { ROOT_DIR } from '@config/path.config';\nimport * as Sentry from '@sentry/node';\nimport { ServerUP } from '@utils/server-up';\nimport axios from 'axios';\nimport compression from 'compression';\nimport cors from 'cors';\nimport express, { json, NextFunction, Request, Response, urlencoded } from 'express';\nimport { join } from 'path';\n\nasync function initWA() {\n  await waMonitor.loadInstance();\n}\n\nasync function bootstrap() {\n  const logger = new Logger('SERVER');\n  const app = express();\n\n  let providerFiles: ProviderFiles = null;\n  if (configService.get<ProviderSession>('PROVIDER').ENABLED) {\n    providerFiles = new ProviderFiles(configService);\n    await providerFiles.onModuleInit();\n    logger.info('Provider:Files - ON');\n  }\n\n  const prismaRepository = new PrismaRepository(configService);\n  await prismaRepository.onModuleInit();\n\n  app.use(\n    cors({\n      origin(requestOrigin, callback) {\n        const { ORIGIN } = configService.get<Cors>('CORS');\n        if (ORIGIN.includes('*')) {\n          return callback(null, true);\n        }\n        if (ORIGIN.indexOf(requestOrigin) !== -1) {\n          return callback(null, true);\n        }\n        return callback(new Error('Not allowed by CORS'));\n      },\n      methods: [...configService.get<Cors>('CORS').METHODS],\n      credentials: configService.get<Cors>('CORS').CREDENTIALS,\n    }),\n    urlencoded({ extended: true, limit: '136mb' }),\n    json({ limit: '136mb' }),\n    compression(),\n  );\n\n  app.set('view engine', 'hbs');\n  app.set('views', join(ROOT_DIR, 'views'));\n  app.use(express.static(join(ROOT_DIR, 'public')));\n\n  app.use('/store', express.static(join(ROOT_DIR, 'store')));\n\n  app.use('/', router);\n\n  app.use(\n    (err: Error, req: Request, res: Response, next: NextFunction) => {\n      if (err) {\n        const webhook = configService.get<Webhook>('WEBHOOK');\n\n        if (webhook.EVENTS.ERRORS_WEBHOOK && webhook.EVENTS.ERRORS_WEBHOOK != '' && webhook.EVENTS.ERRORS) {\n          const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds\n          const localISOTime = new Date(Date.now() - tzoffset).toISOString();\n          const now = localISOTime;\n          const globalApiKey = configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;\n          const serverUrl = configService.get<HttpServer>('SERVER').URL;\n\n          const errorData = {\n            event: 'error',\n            data: {\n              error: err['error'] || 'Internal Server Error',\n              message: err['message'] || 'Internal Server Error',\n              status: err['status'] || 500,\n              response: {\n                message: err['message'] || 'Internal Server Error',\n              },\n            },\n            date_time: now,\n            api_key: globalApiKey,\n            server_url: serverUrl,\n          };\n\n          logger.error(errorData);\n\n          const baseURL = webhook.EVENTS.ERRORS_WEBHOOK;\n          const httpService = axios.create({ baseURL });\n\n          httpService.post('', errorData);\n        }\n\n        return res.status(err['status'] || 500).json({\n          status: err['status'] || 500,\n          error: err['error'] || 'Internal Server Error',\n          response: {\n            message: err['message'] || 'Internal Server Error',\n          },\n        });\n      }\n\n      next();\n    },\n    (req: Request, res: Response, next: NextFunction) => {\n      const { method, url } = req;\n\n      res.status(HttpStatus.NOT_FOUND).json({\n        status: HttpStatus.NOT_FOUND,\n        error: 'Not Found',\n        response: {\n          message: [`Cannot ${method.toUpperCase()} ${url}`],\n        },\n      });\n\n      next();\n    },\n  );\n\n  const httpServer = configService.get<HttpServer>('SERVER');\n\n  ServerUP.app = app;\n  let server = ServerUP[httpServer.TYPE];\n\n  if (server === null) {\n    logger.warn('SSL cert load failed — falling back to HTTP.');\n    logger.info(\"Ensure 'SSL_CONF_PRIVKEY' and 'SSL_CONF_FULLCHAIN' env vars point to valid certificate files.\");\n\n    httpServer.TYPE = 'http';\n    server = ServerUP[httpServer.TYPE];\n  }\n\n  eventManager.init(server);\n\n  const sentryConfig = configService.get<SentryConfig>('SENTRY');\n  if (sentryConfig.DSN) {\n    logger.info('Sentry - ON');\n\n    // Add this after all routes,\n    // but before any and other error-handling middlewares are defined\n    Sentry.setupExpressErrorHandler(app);\n  }\n\n  server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT));\n\n  initWA().catch((error) => {\n    logger.error('Error loading instances: ' + error);\n  });\n\n  onUnexpectedError();\n}\n\nbootstrap();\n"
  },
  {
    "path": "src/railway.json",
    "content": "{\n  \"$schema\": \"https://railway.com/railway.schema.json\",\n  \"build\": {\n    \"builder\": \"DOCKERFILE\",\n    \"dockerfilePath\": \"Dockerfile\"\n  },\n  \"deploy\": {\n    \"runtime\": \"V2\",\n    \"numReplicas\": 1,\n    \"sleepApplication\": false,\n    \"multiRegionConfig\": {\n      \"us-east4-eqdc4a\": {\n        \"numReplicas\": 1\n      }\n    },\n    \"restartPolicyType\": \"ON_FAILURE\",\n    \"restartPolicyMaxRetries\": 10\n  }\n}\n"
  },
  {
    "path": "src/utils/advancedOperatorsSearch.ts",
    "content": "function normalizeString(str: string): string {\n  return str\n    .normalize('NFD')\n    .replace(/[\\u0300-\\u036f]/g, '')\n    .toLowerCase();\n}\n\nexport function advancedOperatorsSearch(data: string, query: string): boolean {\n  const filters = query.split(' ').reduce((acc: Record<string, string[]>, filter) => {\n    const [operator, ...values] = filter.split(':');\n    const value = values.join(':');\n\n    if (!acc[operator]) {\n      acc[operator] = [];\n    }\n    acc[operator].push(value);\n    return acc;\n  }, {});\n\n  const normalizedItem = normalizeString(data);\n\n  return Object.entries(filters).every(([operator, values]) => {\n    return values.some((val) => {\n      const subValues = val.split(',');\n      return subValues.every((subVal) => {\n        const normalizedSubVal = normalizeString(subVal);\n\n        switch (operator.toLowerCase()) {\n          case 'contains':\n            return normalizedItem.includes(normalizedSubVal);\n          case 'notcontains':\n            return !normalizedItem.includes(normalizedSubVal);\n          case 'startswith':\n            return normalizedItem.startsWith(normalizedSubVal);\n          case 'endswith':\n            return normalizedItem.endsWith(normalizedSubVal);\n          case 'exact':\n            return normalizedItem === normalizedSubVal;\n          default:\n            return false;\n        }\n      });\n    });\n  });\n}\n"
  },
  {
    "path": "src/utils/createJid.ts",
    "content": "// Check if the number is MX or AR\nfunction formatMXOrARNumber(jid: string): string {\n  const countryCode = jid.substring(0, 2);\n\n  if (Number(countryCode) === 52 || Number(countryCode) === 54) {\n    if (jid.length === 13) {\n      const number = countryCode + jid.substring(3);\n      return number;\n    }\n\n    return jid;\n  }\n  return jid;\n}\n\n// Check if the number is br\nfunction formatBRNumber(jid: string) {\n  const regexp = new RegExp(/^(\\d{2})(\\d{2})\\d{1}(\\d{8})$/);\n  if (regexp.test(jid)) {\n    const match = regexp.exec(jid);\n    if (match && match[1] === '55') {\n      const joker = Number.parseInt(match[3][0]);\n      const ddd = Number.parseInt(match[2]);\n      if (joker < 7 || ddd < 31) {\n        return match[0];\n      }\n      return match[1] + match[2] + match[3];\n    }\n    return jid;\n  } else {\n    return jid;\n  }\n}\n\nexport function createJid(number: string): string {\n  number = number.replace(/:\\d+/, '');\n\n  if (number.includes('@g.us') || number.includes('@s.whatsapp.net') || number.includes('@lid')) {\n    return number;\n  }\n\n  if (number.includes('@broadcast')) {\n    return number;\n  }\n\n  number = number\n    ?.replace(/\\s/g, '')\n    .replace(/\\+/g, '')\n    .replace(/\\(/g, '')\n    .replace(/\\)/g, '')\n    .split(':')[0]\n    .split('@')[0];\n\n  if (number.includes('-') && number.length >= 24) {\n    number = number.replace(/[^\\d-]/g, '');\n    return `${number}@g.us`;\n  }\n\n  number = number.replace(/\\D/g, '');\n\n  if (number.length >= 18) {\n    number = number.replace(/[^\\d-]/g, '');\n    return `${number}@g.us`;\n  }\n\n  number = formatMXOrARNumber(number);\n\n  number = formatBRNumber(number);\n\n  return `${number}@s.whatsapp.net`;\n}\n"
  },
  {
    "path": "src/utils/errorResponse.ts",
    "content": "import { HttpStatus } from '@api/routes/index.router';\n\nexport interface MetaErrorResponse {\n  status: number;\n  error: string;\n  message: string;\n  details: {\n    whatsapp_error: string;\n    whatsapp_code: string | number;\n    error_user_title: string;\n    error_user_msg: string;\n    error_type: string;\n    error_subcode: number | null;\n    fbtrace_id: string | null;\n    context: string;\n    type: string;\n  };\n  timestamp: string;\n}\n\n/**\n * Creates standardized error response for Meta/WhatsApp API errors\n */\nexport function createMetaErrorResponse(error: any, context: string): MetaErrorResponse {\n  // Extract Meta/WhatsApp specific error fields\n  const metaError = error.template || error;\n  const errorUserTitle = metaError.error_user_title || metaError.message || 'Unknown error';\n  const errorUserMsg = metaError.error_user_msg || metaError.message || 'Unknown error';\n\n  return {\n    status: HttpStatus.BAD_REQUEST,\n    error: 'Bad Request',\n    message: errorUserTitle,\n    details: {\n      whatsapp_error: errorUserMsg,\n      whatsapp_code: metaError.code || 'UNKNOWN_ERROR',\n      error_user_title: errorUserTitle,\n      error_user_msg: errorUserMsg,\n      error_type: metaError.type || 'UNKNOWN',\n      error_subcode: metaError.error_subcode || null,\n      fbtrace_id: metaError.fbtrace_id || null,\n      context,\n      type: 'whatsapp_api_error',\n    },\n    timestamp: new Date().toISOString(),\n  };\n}\n"
  },
  {
    "path": "src/utils/fetchLatestWaWebVersion.ts",
    "content": "import axios, { AxiosRequestConfig } from 'axios';\nimport { fetchLatestBaileysVersion, WAVersion } from 'baileys';\n\nexport const fetchLatestWaWebVersion = async (options: AxiosRequestConfig<{}>) => {\n  try {\n    const { data } = await axios.get('https://web.whatsapp.com/sw.js', {\n      ...options,\n      responseType: 'json',\n    });\n\n    const regex = /\\\\?\"client_revision\\\\?\":\\s*(\\d+)/;\n    const match = data.match(regex);\n\n    if (!match?.[1]) {\n      return {\n        version: (await fetchLatestBaileysVersion()).version as WAVersion,\n        isLatest: false,\n        error: {\n          message: 'Could not find client revision in the fetched content',\n        },\n      };\n    }\n\n    const clientRevision = match[1];\n\n    return {\n      version: [2, 3000, +clientRevision] as WAVersion,\n      isLatest: true,\n    };\n  } catch (error) {\n    return {\n      version: (await fetchLatestBaileysVersion()).version as WAVersion,\n      isLatest: false,\n      error,\n    };\n  }\n};\n"
  },
  {
    "path": "src/utils/findBotByTrigger.ts",
    "content": "import { advancedOperatorsSearch } from './advancedOperatorsSearch';\n\nexport const findBotByTrigger = async (botRepository: any, content: string, instanceId: string) => {\n  // Check for triggerType 'all' or 'none' (both should match any message)\n  const findTriggerAllOrNone = await botRepository.findFirst({\n    where: {\n      enabled: true,\n      triggerType: {\n        in: ['all', 'none'],\n      },\n      instanceId: instanceId,\n    },\n  });\n\n  if (findTriggerAllOrNone) {\n    return findTriggerAllOrNone;\n  }\n\n  const findTriggerAdvanced = await botRepository.findMany({\n    where: {\n      enabled: true,\n      triggerType: 'advanced',\n      instanceId: instanceId,\n    },\n  });\n  for (const advanced of findTriggerAdvanced) {\n    if (advancedOperatorsSearch(content, advanced.triggerValue)) {\n      return advanced;\n    }\n  }\n\n  // Check for exact match\n  const findTriggerEquals = await botRepository.findFirst({\n    where: {\n      enabled: true,\n      triggerType: 'keyword',\n      triggerOperator: 'equals',\n      triggerValue: content,\n      instanceId: instanceId,\n    },\n  });\n\n  if (findTriggerEquals) {\n    return findTriggerEquals;\n  }\n\n  // Check for regex match\n  const findRegex = await botRepository.findMany({\n    where: {\n      enabled: true,\n      triggerType: 'keyword',\n      triggerOperator: 'regex',\n      instanceId: instanceId,\n    },\n  });\n\n  let findTriggerRegex = null;\n\n  for (const regex of findRegex) {\n    const regexValue = new RegExp(regex.triggerValue);\n\n    if (regexValue.test(content)) {\n      findTriggerRegex = regex;\n      break;\n    }\n  }\n\n  if (findTriggerRegex) return findTriggerRegex;\n\n  // Check for startsWith match\n  const findStartsWith = await botRepository.findMany({\n    where: {\n      enabled: true,\n      triggerType: 'keyword',\n      triggerOperator: 'startsWith',\n      instanceId: instanceId,\n    },\n  });\n\n  let findTriggerStartsWith = null;\n\n  for (const startsWith of findStartsWith) {\n    if (content.startsWith(startsWith.triggerValue)) {\n      findTriggerStartsWith = startsWith;\n      break;\n    }\n  }\n\n  if (findTriggerStartsWith) return findTriggerStartsWith;\n\n  // Check for endsWith match\n  const findEndsWith = await botRepository.findMany({\n    where: {\n      enabled: true,\n      triggerType: 'keyword',\n      triggerOperator: 'endsWith',\n      instanceId: instanceId,\n    },\n  });\n\n  let findTriggerEndsWith = null;\n\n  for (const endsWith of findEndsWith) {\n    if (content.endsWith(endsWith.triggerValue)) {\n      findTriggerEndsWith = endsWith;\n      break;\n    }\n  }\n\n  if (findTriggerEndsWith) return findTriggerEndsWith;\n\n  // Check for contains match\n  const findContains = await botRepository.findMany({\n    where: {\n      enabled: true,\n      triggerType: 'keyword',\n      triggerOperator: 'contains',\n      instanceId: instanceId,\n    },\n  });\n\n  let findTriggerContains = null;\n\n  for (const contains of findContains) {\n    if (content.includes(contains.triggerValue)) {\n      findTriggerContains = contains;\n      break;\n    }\n  }\n\n  if (findTriggerContains) return findTriggerContains;\n\n  return null;\n};\n"
  },
  {
    "path": "src/utils/getConversationMessage.ts",
    "content": "import { configService, S3 } from '@config/env.config';\n\nconst getTypeMessage = (msg: any) => {\n  let mediaId: string;\n\n  if (\n    configService.get<S3>('S3').ENABLE &&\n    (configService.get<S3>('S3').SAVE_VIDEO ||\n      (msg?.message?.videoMessage === undefined &&\n        msg?.message?.viewOnceMessageV2?.message?.videoMessage === undefined))\n  )\n    mediaId = msg.message?.mediaUrl;\n  else mediaId = msg.key?.id;\n\n  const types = {\n    conversation: msg?.message?.conversation,\n    extendedTextMessage: msg?.message?.extendedTextMessage?.text,\n    contactMessage: msg?.message?.contactMessage?.displayName,\n    locationMessage: msg?.message?.locationMessage?.degreesLatitude.toString(),\n    viewOnceMessageV2:\n      msg?.message?.viewOnceMessageV2?.message?.imageMessage?.url ||\n      msg?.message?.viewOnceMessageV2?.message?.videoMessage?.url ||\n      msg?.message?.viewOnceMessageV2?.message?.audioMessage?.url,\n    listResponseMessage: msg?.message?.listResponseMessage?.title || msg?.listResponseMessage?.title,\n    responseRowId: msg?.message?.listResponseMessage?.singleSelectReply?.selectedRowId,\n    templateButtonReplyMessage:\n      msg?.message?.templateButtonReplyMessage?.selectedId || msg?.message?.buttonsResponseMessage?.selectedButtonId,\n    // Medias\n    audioMessage: msg?.message?.speechToText\n      ? msg?.message?.speechToText\n      : msg?.message?.audioMessage\n        ? `audioMessage|${mediaId}`\n        : undefined,\n    imageMessage: msg?.message?.imageMessage\n      ? `imageMessage|${mediaId}${msg?.message?.imageMessage?.caption ? `|${msg?.message?.imageMessage?.caption}` : ''}`\n      : undefined,\n    videoMessage: msg?.message?.videoMessage\n      ? `videoMessage|${mediaId}${msg?.message?.videoMessage?.caption ? `|${msg?.message?.videoMessage?.caption}` : ''}`\n      : undefined,\n    documentMessage: msg?.message?.documentMessage\n      ? `documentMessage|${mediaId}${\n          msg?.message?.documentMessage?.caption ? `|${msg?.message?.documentMessage?.caption}` : ''\n        }`\n      : undefined,\n    documentWithCaptionMessage: msg?.message?.documentWithCaptionMessage?.message?.documentMessage\n      ? `documentWithCaptionMessage|${mediaId}${\n          msg?.message?.documentWithCaptionMessage?.message?.documentMessage?.caption\n            ? `|${msg?.message?.documentWithCaptionMessage?.message?.documentMessage?.caption}`\n            : ''\n        }`\n      : undefined,\n    externalAdReplyBody: msg?.contextInfo?.externalAdReply?.body\n      ? `externalAdReplyBody|${msg.contextInfo.externalAdReply.body}`\n      : undefined,\n  };\n\n  const messageType = Object.keys(types).find((key) => types[key] !== undefined) || 'unknown';\n\n  return { ...types, messageType };\n};\n\nconst getMessageContent = (types: any) => {\n  const typeKey = Object.keys(types).find((key) => key !== 'externalAdReplyBody' && types[key] !== undefined);\n\n  let result = typeKey ? types[typeKey] : undefined;\n\n  if (types.externalAdReplyBody) {\n    result = result ? `${result}\\n${types.externalAdReplyBody}` : types.externalAdReplyBody;\n  }\n\n  return result;\n};\n\nexport const getConversationMessage = (msg: any) => {\n  const types = getTypeMessage(msg);\n\n  const messageContent = getMessageContent(types);\n\n  return messageContent;\n};\n"
  },
  {
    "path": "src/utils/i18n.ts",
    "content": "import { ConfigService, Language } from '@config/env.config';\nimport fs from 'fs';\nimport i18next from 'i18next';\nimport path from 'path';\n\nconst languages = ['en', 'pt-BR', 'es'];\nconst translationsPath = path.join(__dirname, 'translations');\nconst configService: ConfigService = new ConfigService();\n\nconst resources: any = {};\n\nlanguages.forEach((language) => {\n  const languagePath = path.join(translationsPath, `${language}.json`);\n  if (fs.existsSync(languagePath)) {\n    const translationContent = fs.readFileSync(languagePath, 'utf8');\n    resources[language] = {\n      translation: JSON.parse(translationContent),\n    };\n  }\n});\n\ni18next.init({\n  resources,\n  fallbackLng: 'en',\n  lng: configService.get<Language>('LANGUAGE'),\n  debug: false,\n\n  interpolation: {\n    escapeValue: false,\n  },\n});\nexport default i18next;\n"
  },
  {
    "path": "src/utils/instrumentSentry.ts",
    "content": "import { configService, Sentry as SentryConfig } from '@config/env.config';\r\nimport * as Sentry from '@sentry/node';\r\n\r\nconst sentryConfig = configService.get<SentryConfig>('SENTRY');\r\n\r\nif (sentryConfig.DSN) {\r\n  Sentry.init({\r\n    dsn: sentryConfig.DSN,\r\n    environment: process.env.NODE_ENV || 'development',\r\n    tracesSampleRate: 1.0,\r\n    profilesSampleRate: 1.0,\r\n  });\r\n}\r\n"
  },
  {
    "path": "src/utils/makeProxyAgent.ts",
    "content": "import { socksDispatcher } from 'fetch-socks';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { SocksProxyAgent } from 'socks-proxy-agent';\nimport { ProxyAgent } from 'undici';\n\ntype Proxy = {\n  host: string;\n  password?: string;\n  port: string;\n  protocol: string;\n  username?: string;\n};\n\nfunction selectProxyAgent(proxyUrl: string): HttpsProxyAgent<string> | SocksProxyAgent {\n  const url = new URL(proxyUrl);\n\n  // NOTE: The following constants are not used in the function but are defined for clarity.\n  // When a proxy URL is used to build the URL object, the protocol returned by procotol's property contains a `:` at\n  // the end so, we add the protocol constants without the `:` to avoid confusion.\n  const PROXY_HTTP_PROTOCOL = 'http:';\n  const PROXY_SOCKS_PROTOCOL = 'socks:';\n  const PROXY_SOCKS5_PROTOCOL = 'socks5:';\n\n  switch (url.protocol) {\n    case PROXY_HTTP_PROTOCOL:\n      return new HttpsProxyAgent(url);\n    case PROXY_SOCKS_PROTOCOL:\n    case PROXY_SOCKS5_PROTOCOL: {\n      let urlSocks = '';\n\n      if (url.username && url.password) {\n        urlSocks = `socks://${url.username}:${url.password}@${url.hostname}:${url.port}`;\n      } else {\n        urlSocks = `socks://${url.hostname}:${url.port}`;\n      }\n\n      return new SocksProxyAgent(urlSocks);\n    }\n    default:\n      throw new Error(`Unsupported proxy protocol: ${url.protocol}`);\n  }\n}\n\nexport function makeProxyAgent(proxy: Proxy | string): HttpsProxyAgent<string> | SocksProxyAgent {\n  if (typeof proxy === 'string') {\n    return selectProxyAgent(proxy);\n  }\n\n  const { host, password, port, protocol, username } = proxy;\n  let proxyUrl = `${protocol}://${host}:${port}`;\n\n  if (username && password) {\n    proxyUrl = `${protocol}://${username}:${password}@${host}:${port}`;\n  }\n\n  return selectProxyAgent(proxyUrl);\n}\n\nexport function makeProxyAgentUndici(proxy: Proxy | string): ProxyAgent {\n  let proxyUrl: string;\n  let protocol: string;\n\n  if (typeof proxy === 'string') {\n    const url = new URL(proxy);\n    protocol = url.protocol.replace(':', '');\n    proxyUrl = proxy;\n  } else {\n    const { host, password, port, protocol: proto, username } = proxy;\n    protocol = (proto || 'http').replace(':', '');\n\n    if (protocol === 'socks') {\n      protocol = 'socks5';\n    }\n\n    const auth = username && password ? `${username}:${password}@` : '';\n    proxyUrl = `${protocol}://${auth}${host}:${port}`;\n  }\n\n  protocol = protocol.toLowerCase();\n\n  const PROXY_HTTP_PROTOCOL = 'http';\n  const PROXY_HTTPS_PROTOCOL = 'https';\n  const PROXY_SOCKS4_PROTOCOL = 'socks4';\n  const PROXY_SOCKS5_PROTOCOL = 'socks5';\n\n  switch (protocol) {\n    case PROXY_HTTP_PROTOCOL:\n    case PROXY_HTTPS_PROTOCOL:\n      return new ProxyAgent(proxyUrl);\n\n    case PROXY_SOCKS4_PROTOCOL:\n    case PROXY_SOCKS5_PROTOCOL: {\n      let type: 4 | 5 = 5;\n\n      if (PROXY_SOCKS4_PROTOCOL === protocol) type = 4;\n\n      const url = new URL(proxyUrl);\n\n      return socksDispatcher({\n        type: type,\n        host: url.hostname,\n        port: Number(url.port),\n        userId: url.username || undefined,\n        password: url.password || undefined,\n      });\n    }\n\n    default:\n      throw new Error(`Unsupported proxy protocol: ${protocol}`);\n  }\n}\n"
  },
  {
    "path": "src/utils/onWhatsappCache.ts",
    "content": "import { prismaRepository } from '@api/server.module';\nimport { configService, Database } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport dayjs from 'dayjs';\n\nconst logger = new Logger('OnWhatsappCache');\n\nfunction getAvailableNumbers(remoteJid: string) {\n  const numbersAvailable: string[] = [];\n\n  if (remoteJid.startsWith('+')) {\n    remoteJid = remoteJid.slice(1);\n  }\n\n  const [number, domain] = remoteJid.split('@');\n\n  // TODO: Se já for @lid, retornar apenas ele mesmo SEM adicionar @domain novamente\n  if (domain === 'lid' || domain === 'g.us') {\n    return [remoteJid]; // Retorna direto para @lid e @g.us\n  }\n\n  // Brazilian numbers\n  if (remoteJid.startsWith('55')) {\n    const numberWithDigit =\n      number.slice(4, 5) === '9' && number.length === 13 ? number : `${number.slice(0, 4)}9${number.slice(4)}`;\n    const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 4) + number.slice(5);\n\n    numbersAvailable.push(numberWithDigit);\n    numbersAvailable.push(numberWithoutDigit);\n  }\n\n  // Mexican/Argentina numbers\n  // Ref: https://faq.whatsapp.com/1294841057948784\n  else if (number.startsWith('52') || number.startsWith('54')) {\n    let prefix = '';\n    if (number.startsWith('52')) {\n      prefix = '1';\n    }\n    if (number.startsWith('54')) {\n      prefix = '9';\n    }\n\n    const numberWithDigit =\n      number.slice(2, 3) === prefix && number.length === 13\n        ? number\n        : `${number.slice(0, 2)}${prefix}${number.slice(2)}`;\n    const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 2) + number.slice(3);\n\n    numbersAvailable.push(numberWithDigit);\n    numbersAvailable.push(numberWithoutDigit);\n  }\n\n  // Other countries\n  else {\n    numbersAvailable.push(remoteJid);\n  }\n\n  // TODO: Adiciona @domain apenas para números que não são @lid\n  return numbersAvailable.map((number) => `${number}@${domain}`);\n}\n\ninterface ISaveOnWhatsappCacheParams {\n  remoteJid: string;\n  remoteJidAlt?: string;\n  lid?: 'lid' | undefined;\n}\n\nfunction normalizeJid(jid: string | null | undefined): string | null {\n  if (!jid) return null;\n  return jid.startsWith('+') ? jid.slice(1) : jid;\n}\n\nexport async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) {\n  if (!configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {\n    return;\n  }\n\n  // Processa todos os itens em paralelo para melhor performance\n  const processingPromises = data.map(async (item) => {\n    try {\n      const remoteJid = normalizeJid(item.remoteJid);\n      if (!remoteJid) {\n        logger.warn('[saveOnWhatsappCache] Item skipped, missing remoteJid.');\n        return;\n      }\n\n      const altJidNormalized = normalizeJid(item.remoteJidAlt);\n      const lidAltJid = altJidNormalized && altJidNormalized.includes('@lid') ? altJidNormalized : null;\n\n      const baseJids = [remoteJid]; // Garante que o remoteJid esteja na lista inicial\n      if (lidAltJid) {\n        baseJids.push(lidAltJid);\n      }\n\n      const expandedJids = baseJids.flatMap((jid) => getAvailableNumbers(jid));\n\n      // 1. Busca entrada por jidOptions e também remoteJid\n      // Às vezes acontece do remoteJid atual NÃO ESTAR no jidOptions ainda, ocasionando o erro:\n      // 'Unique constraint failed on the fields: (`remoteJid`)'\n      // Isso acontece principalmente em grupos que possuem o número do criador no ID (ex.: '559911223345-1234567890@g.us')\n      const existingRecord = await prismaRepository.isOnWhatsapp.findFirst({\n        where: {\n          OR: [\n            ...expandedJids.map((jid) => ({ jidOptions: { contains: jid } })),\n            { remoteJid: remoteJid }, // TODO: Descobrir o motivo que causa o remoteJid não estar (às vezes) incluso na lista de jidOptions\n          ],\n        },\n      });\n\n      logger.verbose(\n        `[saveOnWhatsappCache] Register exists for [${expandedJids.join(',')}]? => ${existingRecord ? existingRecord.remoteJid : 'Not found'}`,\n      );\n\n      // 2. Unifica todos os JIDs usando um Set para garantir valores únicos\n      const finalJidOptions = new Set(expandedJids);\n\n      if (lidAltJid) {\n        finalJidOptions.add(lidAltJid);\n      }\n\n      if (existingRecord?.jidOptions) {\n        existingRecord.jidOptions.split(',').forEach((jid) => finalJidOptions.add(jid));\n      }\n\n      // 3. Prepara o payload final\n      // Ordena os JIDs para garantir consistência na string final\n      const sortedJidOptions = [...finalJidOptions].sort();\n      const newJidOptionsString = sortedJidOptions.join(',');\n      const newLid = item.lid === 'lid' || item.remoteJid?.includes('@lid') ? 'lid' : null;\n\n      const dataPayload = {\n        remoteJid: remoteJid,\n        jidOptions: newJidOptionsString,\n        lid: newLid,\n      };\n\n      // 4. Decide entre Criar ou Atualizar\n      if (existingRecord) {\n        // Compara a string de JIDs ordenada existente com a nova\n        const existingJidOptionsString = existingRecord.jidOptions\n          ? existingRecord.jidOptions.split(',').sort().join(',')\n          : '';\n\n        const isDataSame =\n          existingRecord.remoteJid === dataPayload.remoteJid &&\n          existingJidOptionsString === dataPayload.jidOptions &&\n          existingRecord.lid === dataPayload.lid;\n\n        if (isDataSame) {\n          logger.verbose(`[saveOnWhatsappCache] Data for ${remoteJid} is already up-to-date. Skipping update.`);\n          return; // Pula para o próximo item\n        }\n\n        // Os dados são diferentes, então atualiza\n        logger.verbose(\n          `[saveOnWhatsappCache] Register exists, updating: remoteJid=${remoteJid}, jidOptions=${dataPayload.jidOptions}, lid=${dataPayload.lid}`,\n        );\n        await prismaRepository.isOnWhatsapp.update({\n          where: { id: existingRecord.id },\n          data: dataPayload,\n        });\n      } else {\n        // Cria nova entrada\n        logger.verbose(\n          `[saveOnWhatsappCache] Register does not exist, creating: remoteJid=${remoteJid}, jidOptions=${dataPayload.jidOptions}, lid=${dataPayload.lid}`,\n        );\n        await prismaRepository.isOnWhatsapp.create({\n          data: dataPayload,\n        });\n      }\n    } catch (e) {\n      // Loga o erro mas não para a execução dos outros promises\n      logger.error(`[saveOnWhatsappCache] Error processing item for ${item.remoteJid}: `);\n      logger.error(e);\n    }\n  });\n\n  // Espera todas as operações paralelas terminarem\n  await Promise.allSettled(processingPromises);\n}\n\nexport async function getOnWhatsappCache(remoteJids: string[]) {\n  let results: {\n    remoteJid: string;\n    number: string;\n    jidOptions: string[];\n    lid?: string;\n  }[] = [];\n\n  if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {\n    const remoteJidsWithoutPlus = remoteJids.map((remoteJid) => getAvailableNumbers(remoteJid)).flat();\n\n    const onWhatsappCache = await prismaRepository.isOnWhatsapp.findMany({\n      where: {\n        OR: remoteJidsWithoutPlus.map((remoteJid) => ({ jidOptions: { contains: remoteJid } })),\n        updatedAt: {\n          gte: dayjs().subtract(configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP_DAYS, 'days').toDate(),\n        },\n      },\n    });\n\n    results = onWhatsappCache.map((item) => ({\n      remoteJid: item.remoteJid,\n      number: item.remoteJid.split('@')[0],\n      jidOptions: item.jidOptions.split(','),\n      lid: item.lid,\n    }));\n  }\n\n  return results;\n}\n"
  },
  {
    "path": "src/utils/renderStatus.ts",
    "content": "import { wa } from '@api/types/wa.types';\n\nexport const status: Record<number, wa.StatusMessage> = {\n  0: 'ERROR',\n  1: 'PENDING',\n  2: 'SERVER_ACK',\n  3: 'DELIVERY_ACK',\n  4: 'READ',\n  5: 'PLAYED',\n};\n"
  },
  {
    "path": "src/utils/sendTelemetry.ts",
    "content": "import { configService, Telemetry } from '@config/env.config';\nimport axios from 'axios';\nimport fs from 'fs';\n\nconst packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));\n\nexport interface TelemetryData {\n  route: string;\n  apiVersion: string;\n  timestamp: Date;\n}\n\nexport const sendTelemetry = async (route: string): Promise<void> => {\n  const telemetryConfig = configService.get<Telemetry>('TELEMETRY');\n\n  if (!telemetryConfig.ENABLED) {\n    return;\n  }\n\n  if (route === '/') {\n    return;\n  }\n\n  const telemetry: TelemetryData = {\n    route,\n    apiVersion: `${packageJson.version}`,\n    timestamp: new Date(),\n  };\n\n  const url =\n    telemetryConfig.URL && telemetryConfig.URL !== '' ? telemetryConfig.URL : 'https://log.evolution-api.com/telemetry';\n\n  axios\n    .post(url, telemetry)\n    .then(() => {})\n    .catch(() => {});\n};\n"
  },
  {
    "path": "src/utils/server-up.ts",
    "content": "import { configService, SslConf } from '@config/env.config';\nimport { Express } from 'express';\nimport { readFileSync } from 'fs';\nimport * as http from 'http';\nimport * as https from 'https';\n\nexport class ServerUP {\n  static #app: Express;\n\n  static set app(e: Express) {\n    this.#app = e;\n  }\n\n  static get https() {\n    const { FULLCHAIN, PRIVKEY } = configService.get<SslConf>('SSL_CONF');\n    return https.createServer(\n      {\n        cert: readFileSync(FULLCHAIN),\n        key: readFileSync(PRIVKEY),\n      },\n      ServerUP.#app,\n    );\n  }\n\n  static get http() {\n    return http.createServer(ServerUP.#app);\n  }\n}\n"
  },
  {
    "path": "src/utils/translations/en.json",
    "content": "{\n  \"qrgeneratedsuccesfully\": \"QRCode successfully generated!\",\n  \"scanqr\": \"Scan this QR code within the next 40 seconds.\",\n  \"qrlimitreached\": \"QRCode generation limit reached, to generate a new QRCode, send the 'init' message again.\",\n  \"cw.inbox.connected\": \"🚀 Connection successfully established!\",\n  \"cw.inbox.disconnect\": \"🚨 Disconnecting WhatsApp from inbox *{{inboxName}}*.\",\n  \"cw.inbox.alreadyConnected\": \"🚨 {{inboxName}} instance is connected.\",\n  \"cw.inbox.clearCache\": \"✅ {{inboxName}} instance cache cleared.\",\n  \"cw.inbox.notFound\": \"⚠️ {{inboxName}} instance not found.\",\n  \"cw.inbox.status\": \"⚠️ {{inboxName}} instance status: *{{state}}*.\",\n  \"cw.import.startImport\": \"💬 Starting to import messages. Please wait...\",\n  \"cw.import.importingMessages\": \"💬 Importing messages. More one moment...\",\n  \"cw.import.messagesImported\": \"💬 {{totalMessagesImported}} messages imported. Refresh page to see the new messages.\",\n  \"cw.import.messagesException\": \"💬 Something went wrong in importing messages.\",\n  \"cw.locationMessage.location\": \"Location\",\n  \"cw.locationMessage.latitude\": \"Latitude\",\n  \"cw.locationMessage.longitude\": \"Longitude\",\n  \"cw.locationMessage.locationName\": \"Name\",\n  \"cw.locationMessage.locationAddress\": \"Address\",\n  \"cw.locationMessage.locationUrl\": \"URL\",\n  \"cw.contactMessage.contact\": \"Contact\",\n  \"cw.contactMessage.name\": \"Name\",\n  \"cw.contactMessage.number\": \"Number\",\n  \"cw.message.notsent\": \"🚨 The message could not be sent. Please check your connection. {{error}}\",\n  \"cw.message.numbernotinwhatsapp\": \"🚨 The message was not sent as the contact is not a valid Whatsapp number.\",\n  \"cw.message.edited\": \"Edited Message\"\n}"
  },
  {
    "path": "src/utils/translations/es.json",
    "content": "{\n  \"qrgeneratedsuccesfully\": \"Código QR generado exitosamente!\",\n  \"scanqr\": \"Escanea este código QR en los próximos 40 segundos.\",\n  \"qrlimitreached\": \"🚨 Se alcanzó el límite de generación de QRCode. Para generar un nuevo QRCode, envíe el mensaje 'init' nuevamente.\",\n  \"cw.inbox.connected\": \"🚀 ¡Conexión establecida exitosamente!\",\n  \"cw.inbox.disconnect\": \"🚨 Instancia *{{inboxName}}* desconectado de Whatsapp.\",\n  \"cw.inbox.alreadyConnected\": \"🚨 La instancia {{inboxName}} está conectada.\",\n  \"cw.inbox.clearCache\": \"✅ Caché de la instancia {{inboxName}} borrada.\",\n  \"cw.inbox.notFound\": \"⚠️ Instancia {{inboxName}} no encontrada.\",\n  \"cw.inbox.status\": \"⚠️ Estado de la instancia {{inboxName}}: *{{state}}*.\",\n  \"cw.import.startImport\": \"💬 Empezando a importar mensajes. Espere por favor...\",\n  \"cw.import.importingMessages\": \"💬 Importando mensajes. mas un momento...\",\n  \"cw.import.messagesImported\": \"💬 {{totalMessagesImported}} mensajes importados. Actualiza la página para ver los nuevos mensajes..\",\n  \"cw.import.messagesException\": \"⚠️ Algo salió mal al importar mensajes..\",\n  \"cw.locationMessage.location\": \"Ubicación\",\n  \"cw.locationMessage.latitude\": \"Latitude\",\n  \"cw.locationMessage.longitude\": \"Longitude\",\n  \"cw.locationMessage.locationName\": \"Nombre\",\n  \"cw.locationMessage.locationAddress\": \"Direccion\",\n  \"cw.locationMessage.locationUrl\": \"URL\",\n  \"cw.contactMessage.contact\": \"Contacto\",\n  \"cw.contactMessage.name\": \"Nombre\",\n  \"cw.contactMessage.number\": \"Numero\",\n  \"cw.message.notsent\": \"🚨 El mensaje no se pudo enviar. Comprueba tu conexión. {{error}}\",\n  \"cw.message.numbernotinwhatsapp\": \"🚨 El mensaje no fue enviado porque el contacto no es un número de Whatsapp válido.\",\n  \"cw.message.edited\": \"Mensaje editado\"\n}"
  },
  {
    "path": "src/utils/translations/pt-BR.json",
    "content": "{\n  \"qrgeneratedsuccesfully\": \"QRCode gerado com sucesso!\",\n  \"scanqr\": \"Escaneie o QRCode com o WhatsApp nos próximos 40 segundos.\",\n  \"qrlimitreached\": \"Limite de geração de QRCode atingido! Para gerar um novo QRCode, envie o texto 'init' nesta conversa.\",\n  \"cw.inbox.connected\": \"🚀 Conectado com sucesso!\",\n  \"cw.inbox.disconnect\": \"🚨 Instância *{{inboxName}}* desconectada do WhatsApp.\",\n  \"cw.inbox.alreadyConnected\": \"🚨 Instância *{{inboxName}}* já está conectada.\",\n  \"cw.inbox.clearCache\": \"✅ Instância *{{inboxName}}* cache removido.\",\n  \"cw.inbox.notFound\": \"⚠️ Instância *{{inboxName}}* não encontrada.\",\n  \"cw.inbox.status\": \"⚠️ Status da instância {{inboxName}}: *{{state}}*.\",\n  \"cw.import.startImport\": \"💬 Iniciando importação de mensagens. Por favor, aguarde...\",\n  \"cw.import.importingMessages\": \"💬 Importando mensagens. Mais um momento...\",\n  \"cw.import.messagesImported\": \"💬 {{totalMessagesImported}} mensagens importadas. Atualize a página para ver as novas mensagens.\",\n  \"cw.import.messagesException\": \"💬 Não foi possível importar as mensagens.\",\n  \"cw.locationMessage.location\": \"Localização\",\n  \"cw.locationMessage.latitude\": \"Latitude\",\n  \"cw.locationMessage.longitude\": \"Longitude\",\n  \"cw.locationMessage.locationName\": \"Nome\",\n  \"cw.locationMessage.locationAddress\": \"Endereço\",\n  \"cw.locationMessage.locationUrl\": \"URL\",\n  \"cw.contactMessage.contact\": \"Contato\",\n  \"cw.contactMessage.name\": \"Nome\",\n  \"cw.contactMessage.number\": \"Número\",\n  \"cw.message.notsent\": \"🚨 Não foi possível enviar a mensagem. Verifique sua conexão. {{error}}\",\n  \"cw.message.numbernotinwhatsapp\": \"🚨 A mensagem não foi enviada, pois o contato não é um número válido do WhatsApp.\",\n  \"cw.message.edited\": \"Mensagem editada\"\n}"
  },
  {
    "path": "src/utils/use-multi-file-auth-state-prisma.ts",
    "content": "import { prismaRepository } from '@api/server.module';\nimport { CacheService } from '@api/services/cache.service';\nimport { CacheConf, configService } from '@config/env.config';\nimport { Logger } from '@config/logger.config';\nimport { INSTANCE_DIR } from '@config/path.config';\nimport { AuthenticationState, BufferJSON, initAuthCreds, WAProto as proto } from 'baileys';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nconst fixFileName = (file: string): string | undefined => {\n  if (!file) {\n    return undefined;\n  }\n  const replacedSlash = file.replace(/\\//g, '__');\n  const replacedColon = replacedSlash.replace(/:/g, '-');\n  return replacedColon;\n};\n\nexport async function keyExists(sessionId: string): Promise<any> {\n  try {\n    const key = await prismaRepository.session.findUnique({ where: { sessionId: sessionId } });\n    return !!key;\n  } catch {\n    return false;\n  }\n}\n\nexport async function saveKey(sessionId: string, keyJson: any): Promise<any> {\n  const exists = await keyExists(sessionId);\n  try {\n    if (!exists)\n      return await prismaRepository.session.create({\n        data: {\n          sessionId: sessionId,\n          creds: JSON.stringify(keyJson),\n        },\n      });\n    await prismaRepository.session.update({\n      where: { sessionId: sessionId },\n      data: { creds: JSON.stringify(keyJson) },\n    });\n  } catch {\n    return null;\n  }\n}\n\nexport async function getAuthKey(sessionId: string): Promise<any> {\n  try {\n    const register = await keyExists(sessionId);\n    if (!register) return null;\n    const auth = await prismaRepository.session.findUnique({ where: { sessionId: sessionId } });\n    return JSON.parse(auth?.creds);\n  } catch {\n    return null;\n  }\n}\n\nasync function deleteAuthKey(sessionId: string): Promise<any> {\n  try {\n    const register = await keyExists(sessionId);\n    if (!register) return;\n    await prismaRepository.session.delete({ where: { sessionId: sessionId } });\n  } catch {\n    return;\n  }\n}\n\nasync function fileExists(file: string): Promise<any> {\n  try {\n    const stat = await fs.stat(file);\n    if (stat.isFile()) return true;\n  } catch {\n    return;\n  }\n}\n\nconst logger = new Logger('useMultiFileAuthStatePrisma');\n\nexport default async function useMultiFileAuthStatePrisma(\n  sessionId: string,\n  cache: CacheService,\n): Promise<{\n  state: AuthenticationState;\n  saveCreds: () => Promise<void>;\n  removeCreds: () => Promise<void>;\n}> {\n  const localFolder = path.join(INSTANCE_DIR, sessionId);\n  const localFile = (key: string) => path.join(localFolder, fixFileName(key) + '.json');\n  await fs.mkdir(localFolder, { recursive: true });\n\n  async function writeData(data: any, key: string): Promise<any> {\n    const dataString = JSON.stringify(data, BufferJSON.replacer);\n    const cacheConfig = configService.get<CacheConf>('CACHE');\n\n    if (key != 'creds') {\n      if (cacheConfig.REDIS.ENABLED) {\n        return await cache.hSet(sessionId, key, data);\n      } else {\n        await fs.writeFile(localFile(key), dataString);\n        return;\n      }\n    }\n    await saveKey(sessionId, dataString);\n    return;\n  }\n\n  async function readData(key: string): Promise<any> {\n    try {\n      let rawData;\n      const cacheConfig = configService.get<CacheConf>('CACHE');\n\n      if (key != 'creds') {\n        if (cacheConfig.REDIS.ENABLED) {\n          return await cache.hGet(sessionId, key);\n        } else {\n          if (!(await fileExists(localFile(key)))) return null;\n          rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' });\n          return JSON.parse(rawData, BufferJSON.reviver);\n        }\n      } else {\n        rawData = await getAuthKey(sessionId);\n      }\n\n      const parsedData = JSON.parse(rawData, BufferJSON.reviver);\n      return parsedData;\n    } catch {\n      return null;\n    }\n  }\n\n  async function removeData(key: string): Promise<any> {\n    try {\n      const cacheConfig = configService.get<CacheConf>('CACHE');\n\n      if (key != 'creds') {\n        if (cacheConfig.REDIS.ENABLED) {\n          return await cache.hDelete(sessionId, key);\n        } else {\n          await fs.unlink(localFile(key));\n        }\n      } else {\n        await deleteAuthKey(sessionId);\n      }\n    } catch {\n      return;\n    }\n  }\n\n  async function removeCreds(): Promise<any> {\n    const cacheConfig = configService.get<CacheConf>('CACHE');\n\n    // Redis\n    try {\n      if (cacheConfig.REDIS.ENABLED) {\n        await cache.delete(sessionId);\n        logger.info({ action: 'redis.delete', sessionId });\n\n        return;\n      }\n    } catch (err) {\n      logger.warn({ action: 'redis.delete', sessionId, err });\n    }\n\n    logger.info({ action: 'auth.key.delete', sessionId });\n\n    await deleteAuthKey(sessionId);\n  }\n\n  let creds = await readData('creds');\n  if (!creds) {\n    creds = initAuthCreds();\n    await writeData(creds, 'creds');\n  }\n\n  return {\n    state: {\n      creds,\n      keys: {\n        get: async (type, ids) => {\n          const data = {};\n          await Promise.all(\n            ids.map(async (id) => {\n              let value = await readData(`${type}-${id}`);\n              if (type === 'app-state-sync-key' && value) {\n                value = proto.Message.AppStateSyncKeyData.create(value);\n              }\n\n              data[id] = value;\n            }),\n          );\n          return data;\n        },\n        set: async (data) => {\n          const tasks = [];\n          for (const category in data) {\n            for (const id in data[category]) {\n              const value = data[category][id];\n              const key = `${category}-${id}`;\n\n              tasks.push(value ? writeData(value, key) : removeData(key));\n            }\n          }\n          await Promise.all(tasks);\n        },\n      },\n    },\n    saveCreds: () => {\n      return writeData(creds, 'creds');\n    },\n\n    removeCreds,\n  };\n}\n"
  },
  {
    "path": "src/utils/use-multi-file-auth-state-provider-files.ts",
    "content": "/**\n * ┌──────────────────────────────────────────────────────────────────────────────┐\n * │ @author jrCleber                                                             │\n * │ @filename use-multi-file-auth-state-provider-files.ts                              │\n * │ Developed by: Cleber Wilson                                                  │\n * │ Creation date: May 31, 2024                                                 │\n * │ Contact: contato@codechat.dev                                                │\n * ├──────────────────────────────────────────────────────────────────────────────┤\n * │ @copyright © Cleber Wilson 2023. All rights reserved.                        │\n * │ Licensed under the Apache License, Version 2.0                               │\n * │                                                                              │\n * │  @license \"https://github.com/code-chat-br/whatsapp-api/blob/main/LICENSE\"   │\n * │                                                                              │\n * │ You may not use this file except in compliance with the License.             │\n * │ You may obtain a copy of the License at                                      │\n * │                                                                              │\n * │    http://www.apache.org/licenses/LICENSE-2.0                                │\n * │                                                                              │\n * │ Unless required by applicable law or agreed to in writing, software          │\n * │ distributed under the License is distributed on an \"AS IS\" BASIS,            │\n * │ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.     │\n * │                                                                              │\n * │ See the License for the specific language governing permissions and          │\n * │ limitations under the License.                                               │\n * │                                                                              │\n * │ @type {AuthState}                                                            │\n * │ @function useMultiFileAuthStateRedisDb                                       │\n * │ @returns {Promise<AuthState>}                                                │\n * ├──────────────────────────────────────────────────────────────────────────────┤\n * │ @important                                                                   │\n * │ For any future changes to the code in this file, it is recommended to        │\n * │ contain, together with the modification, the information of the developer    │\n * │ who changed it and the date of modification.                                 │\n * └──────────────────────────────────────────────────────────────────────────────┘\n */\n\nimport { ProviderFiles } from '@api/provider/sessions';\nimport { Logger } from '@config/logger.config';\nimport { AuthenticationCreds, AuthenticationState, BufferJSON, initAuthCreds, proto, SignalDataTypeMap } from 'baileys';\nimport { isNotEmpty } from 'class-validator';\n\nexport type AuthState = {\n  state: AuthenticationState;\n  saveCreds: () => Promise<void>;\n  removeCreds: () => Promise<void>;\n};\n\nexport class AuthStateProvider {\n  constructor(private readonly providerFiles: ProviderFiles) {}\n\n  private readonly logger = new Logger('AuthStateProvider');\n\n  public async authStateProvider(instance: string): Promise<AuthState> {\n    const [, error] = await this.providerFiles.create(instance);\n    if (error) {\n      this.logger.error(['Failed to create folder on file server', error?.message, error?.stack]);\n      return;\n    }\n\n    const writeData = async (data: any, key: string): Promise<any> => {\n      const json = JSON.stringify(data, BufferJSON.replacer);\n      const [response, error] = await this.providerFiles.write(instance, key, {\n        data: json,\n      });\n      if (error) {\n        // this.logger.error(['writeData', error?.message, error?.stack]);\n        return;\n      }\n      return response;\n    };\n\n    const readData = async (key: string): Promise<any> => {\n      const [response, error] = await this.providerFiles.read(instance, key);\n      if (error) {\n        // this.logger.error(['readData', error?.message, error?.stack]);\n        return;\n      }\n      if (isNotEmpty(response?.data)) {\n        return JSON.parse(JSON.stringify(response.data), BufferJSON.reviver);\n      }\n    };\n\n    const removeData = async (key: string) => {\n      const [response, error] = await this.providerFiles.delete(instance, key);\n      if (error) {\n        // this.logger.error(['removeData', error?.message, error?.stack]);\n        return;\n      }\n\n      return response;\n    };\n\n    const removeCreds = async () => {\n      const [response, error] = await this.providerFiles.removeSession(instance);\n      if (error) {\n        // this.logger.error(['removeData', error?.message, error?.stack]);\n        return;\n      }\n\n      logger.info({ action: 'remove.session', instance, response });\n\n      return;\n    };\n\n    const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();\n\n    return {\n      state: {\n        creds,\n        keys: {\n          get: async (type, ids: string[]) => {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            const data: { [_: string]: SignalDataTypeMap[type] } = {};\n            await Promise.all(\n              ids.map(async (id) => {\n                let value = await readData(`${type}-${id}`);\n                if (type === 'app-state-sync-key' && value) {\n                  value = proto.Message.AppStateSyncKeyData.create(value);\n                }\n\n                data[id] = value;\n              }),\n            );\n\n            return data;\n          },\n          set: async (data: any) => {\n            const tasks: Promise<void>[] = [];\n            for (const category in data) {\n              for (const id in data[category]) {\n                const value = data[category][id];\n                const key = `${category}-${id}`;\n                tasks.push(value ? await writeData(value, key) : await removeData(key));\n              }\n            }\n\n            await Promise.all(tasks);\n          },\n        },\n      },\n      saveCreds: async () => {\n        return await writeData(creds, 'creds');\n      },\n\n      removeCreds,\n    };\n  }\n}\n\nconst logger = new Logger('useMultiFileAuthStatePrisma');\n"
  },
  {
    "path": "src/utils/use-multi-file-auth-state-redis-db.ts",
    "content": "import { CacheService } from '@api/services/cache.service';\nimport { Logger } from '@config/logger.config';\nimport { AuthenticationCreds, AuthenticationState, initAuthCreds, proto, SignalDataTypeMap } from 'baileys';\n\nexport async function useMultiFileAuthStateRedisDb(\n  instanceName: string,\n  cache: CacheService,\n): Promise<{\n  state: AuthenticationState;\n  saveCreds: () => Promise<void>;\n  removeCreds: () => Promise<void>;\n}> {\n  const logger = new Logger('useMultiFileAuthStateRedisDb');\n\n  const writeData = async (data: any, key: string): Promise<any> => {\n    try {\n      return await cache.hSet(instanceName, key, data);\n    } catch (error) {\n      return logger.error({ localError: 'writeData', error });\n    }\n  };\n\n  const readData = async (key: string): Promise<any> => {\n    try {\n      return await cache.hGet(instanceName, key);\n    } catch (error) {\n      logger.error({ localError: 'readData', error });\n      return;\n    }\n  };\n\n  const removeData = async (key: string) => {\n    try {\n      return await cache.hDelete(instanceName, key);\n    } catch (error) {\n      logger.error({ readData: 'removeData', error });\n    }\n  };\n\n  async function removeCreds(): Promise<any> {\n    try {\n      logger.warn({ action: 'redis.delete', instanceName });\n\n      return await cache.delete(instanceName);\n    } catch {\n      return;\n    }\n  }\n\n  const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();\n\n  return {\n    state: {\n      creds,\n      keys: {\n        get: async (type, ids: string[]) => {\n          // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n          // @ts-ignore\n          const data: { [_: string]: SignalDataTypeMap[type] } = {};\n          await Promise.all(\n            ids.map(async (id) => {\n              let value = await readData(`${type}-${id}`);\n              if (type === 'app-state-sync-key' && value) {\n                value = proto.Message.AppStateSyncKeyData.create(value);\n              }\n\n              data[id] = value;\n            }),\n          );\n\n          return data;\n        },\n        set: async (data: any) => {\n          const tasks: Promise<void>[] = [];\n          for (const category in data) {\n            for (const id in data[category]) {\n              const value = data[category][id];\n              const key = `${category}-${id}`;\n              tasks.push(value ? await writeData(value, key) : await removeData(key));\n            }\n          }\n\n          await Promise.all(tasks);\n        },\n      },\n    },\n    saveCreds: async () => {\n      return await writeData(creds, 'creds');\n    },\n\n    removeCreds,\n  };\n}\n"
  },
  {
    "path": "src/validate/business.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\n\nexport const catalogSchema: JSONSchema7 = {\n  type: 'object',\n  properties: {\n    number: { type: 'string' },\n    limit: { type: 'number' },\n  },\n};\n\nexport const collectionsSchema: JSONSchema7 = {\n  type: 'object',\n  properties: {\n    number: { type: 'string' },\n    limit: { type: 'number' },\n  },\n};\n"
  },
  {
    "path": "src/validate/chat.schema.ts",
    "content": "import { JSONSchema7, JSONSchema7Definition } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nconst numberDefinition: JSONSchema7Definition = {\n  type: 'string',\n  description: 'Invalid format',\n};\n\nexport const whatsappNumberSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    numbers: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        description: '\"numbers\" must be an array of numeric strings',\n      },\n    },\n  },\n};\n\nexport const readMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    readMessages: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        properties: {\n          id: { type: 'string' },\n          fromMe: { type: 'boolean', enum: [true, false] },\n          remoteJid: { type: 'string' },\n        },\n        required: ['id', 'fromMe', 'remoteJid'],\n        ...isNotEmpty('id', 'remoteJid'),\n      },\n    },\n  },\n  required: ['readMessages'],\n};\n\nexport const archiveChatSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    chat: { type: 'string' },\n    lastMessage: {\n      type: 'object',\n      properties: {\n        key: {\n          type: 'object',\n          properties: {\n            id: { type: 'string' },\n            remoteJid: { type: 'string' },\n            fromMe: { type: 'boolean', enum: [true, false] },\n          },\n          required: ['id', 'fromMe', 'remoteJid'],\n          ...isNotEmpty('id', 'remoteJid'),\n        },\n        messageTimestamp: { type: 'integer', minLength: 1 },\n      },\n      required: ['key'],\n      ...isNotEmpty('messageTimestamp'),\n    },\n    archive: { type: 'boolean', enum: [true, false] },\n  },\n  required: ['archive'],\n};\n\nexport const markChatUnreadSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    chat: { type: 'string' },\n    lastMessage: {\n      type: 'object',\n      properties: {\n        key: {\n          type: 'object',\n          properties: {\n            id: { type: 'string' },\n            remoteJid: { type: 'string' },\n            fromMe: { type: 'boolean', enum: [true, false] },\n          },\n          required: ['id', 'fromMe', 'remoteJid'],\n          ...isNotEmpty('id', 'remoteJid'),\n        },\n        messageTimestamp: { type: 'integer', minLength: 1 },\n      },\n      required: ['key'],\n      ...isNotEmpty('messageTimestamp'),\n    },\n  },\n  required: ['lastMessage'],\n};\n\nexport const deleteMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    id: { type: 'string' },\n    fromMe: { type: 'boolean', enum: [true, false] },\n    remoteJid: { type: 'string' },\n    participant: { type: 'string' },\n  },\n  required: ['id', 'fromMe', 'remoteJid'],\n  ...isNotEmpty('id', 'remoteJid', 'participant'),\n};\n\nexport const profilePictureSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { type: 'string' },\n    picture: { type: 'string' },\n  },\n};\n\nexport const updateMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { type: 'string' },\n    text: { type: 'string' },\n    key: {\n      type: 'object',\n      properties: {\n        id: { type: 'string' },\n        remoteJid: { type: 'string' },\n        fromMe: { type: 'boolean', enum: [true, false] },\n      },\n      required: ['id', 'fromMe', 'remoteJid'],\n      ...isNotEmpty('id', 'remoteJid'),\n    },\n  },\n  ...isNotEmpty('number', 'text', 'key'),\n};\n\nexport const presenceSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    delay: { type: 'number' },\n    presence: {\n      type: 'string',\n      enum: ['unavailable', 'available', 'composing', 'recording', 'paused'],\n    },\n  },\n  required: ['number', 'presence', 'delay'],\n};\n\nexport const blockUserSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { type: 'string' },\n    status: { type: 'string', enum: ['block', 'unblock'] },\n  },\n  required: ['number', 'status'],\n  ...isNotEmpty('number', 'status'),\n};\n\nexport const contactValidateSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    where: {\n      type: 'object',\n      properties: {\n        _id: { type: 'string', minLength: 1 },\n        pushName: { type: 'string', minLength: 1 },\n        id: { type: 'string', minLength: 1 },\n        remoteJid: { type: 'string', minLength: 1 },\n      },\n      ...isNotEmpty('_id', 'id', 'pushName', 'remoteJid'),\n    },\n  },\n};\n\nexport const messageValidateSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    where: {\n      type: 'object',\n      properties: {\n        _id: { type: 'string', minLength: 1 },\n        key: {\n          type: 'object',\n          if: {\n            propertyNames: {\n              enum: ['fromMe', 'remoteJid', 'id'],\n            },\n          },\n          then: {\n            properties: {\n              remoteJid: {\n                type: 'string',\n                minLength: 1,\n                description: 'The property cannot be empty',\n              },\n              id: {\n                type: 'string',\n                minLength: 1,\n                description: 'The property cannot be empty',\n              },\n              fromMe: { type: 'boolean', enum: [true, false] },\n            },\n          },\n        },\n        message: { type: 'object' },\n      },\n      ...isNotEmpty('_id'),\n    },\n    limit: { type: 'integer' },\n  },\n};\n\nexport const messageUpSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    where: {\n      type: 'object',\n      properties: {\n        _id: { type: 'string' },\n        remoteJid: { type: 'string' },\n        id: { type: 'string' },\n        fromMe: { type: 'boolean', enum: [true, false] },\n        participant: { type: 'string' },\n        status: {\n          type: 'string',\n          enum: ['ERROR', 'PENDING', 'SERVER_ACK', 'DELIVERY_ACK', 'READ', 'PLAYED'],\n        },\n      },\n      ...isNotEmpty('_id', 'remoteJid', 'id', 'status'),\n    },\n    limit: { type: 'integer' },\n  },\n};\n\nexport const privacySettingsSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    readreceipts: { type: 'string', enum: ['all', 'none'] },\n    profile: {\n      type: 'string',\n      enum: ['all', 'contacts', 'contact_blacklist', 'none'],\n    },\n    status: {\n      type: 'string',\n      enum: ['all', 'contacts', 'contact_blacklist', 'none'],\n    },\n    online: { type: 'string', enum: ['all', 'match_last_seen'] },\n    last: { type: 'string', enum: ['all', 'contacts', 'contact_blacklist', 'none'] },\n    groupadd: {\n      type: 'string',\n      enum: ['all', 'contacts', 'contact_blacklist', 'none'],\n    },\n  },\n  required: ['readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'],\n  ...isNotEmpty('readreceipts', 'profile', 'status', 'online', 'last', 'groupadd'),\n};\n\nexport const profileNameSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    name: { type: 'string' },\n  },\n  ...isNotEmpty('name'),\n};\n\nexport const profileStatusSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    status: { type: 'string' },\n  },\n  ...isNotEmpty('status'),\n};\n\nexport const profileSchema: JSONSchema7 = {\n  type: 'object',\n  properties: {\n    wuid: { type: 'string' },\n    name: { type: 'string' },\n    picture: { type: 'string' },\n    status: { type: 'string' },\n    isBusiness: { type: 'boolean' },\n  },\n};\n"
  },
  {
    "path": "src/validate/group.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const createGroupSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    subject: { type: 'string' },\n    description: { type: 'string' },\n    profilePicture: { type: 'string' },\n    promoteParticipants: { type: 'boolean', enum: [true, false] },\n    participants: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        minLength: 10,\n        pattern: '\\\\d+',\n        description: '\"participants\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['subject', 'participants'],\n  ...isNotEmpty('subject', 'description', 'profilePicture'),\n};\n\nexport const groupJidSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string', pattern: '^[\\\\d-]+@g.us$' },\n  },\n  required: ['groupJid'],\n  ...isNotEmpty('groupJid'),\n};\n\nexport const getParticipantsSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    getParticipants: { type: 'string', enum: ['true', 'false'] },\n  },\n  required: ['getParticipants'],\n  ...isNotEmpty('getParticipants'),\n};\n\nexport const groupSendInviteSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    description: { type: 'string' },\n    numbers: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        minLength: 10,\n        pattern: '\\\\d+',\n        description: '\"numbers\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['groupJid', 'description', 'numbers'],\n  ...isNotEmpty('groupJid', 'description', 'numbers'),\n};\n\nexport const groupInviteSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' },\n  },\n  required: ['inviteCode'],\n  ...isNotEmpty('inviteCode'),\n};\n\nexport const AcceptGroupInviteSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    inviteCode: { type: 'string', pattern: '^[a-zA-Z0-9]{22}$' },\n  },\n  required: ['inviteCode'],\n  ...isNotEmpty('inviteCode'),\n};\n\nexport const updateParticipantsSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    action: {\n      type: 'string',\n      enum: ['add', 'remove', 'promote', 'demote'],\n    },\n    participants: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        minLength: 10,\n        pattern: '\\\\d+',\n        description: '\"participants\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['groupJid', 'action', 'participants'],\n  ...isNotEmpty('groupJid', 'action'),\n};\n\nexport const updateSettingsSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    action: {\n      type: 'string',\n      enum: ['announcement', 'not_announcement', 'locked', 'unlocked'],\n    },\n  },\n  required: ['groupJid', 'action'],\n  ...isNotEmpty('groupJid', 'action'),\n};\n\nexport const toggleEphemeralSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    expiration: {\n      type: 'number',\n      enum: [0, 86400, 604800, 7776000],\n    },\n  },\n  required: ['groupJid', 'expiration'],\n  ...isNotEmpty('groupJid', 'expiration'),\n};\n\nexport const updateGroupPictureSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    image: { type: 'string' },\n  },\n  required: ['groupJid', 'image'],\n  ...isNotEmpty('groupJid', 'image'),\n};\n\nexport const updateGroupSubjectSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    subject: { type: 'string' },\n  },\n  required: ['groupJid', 'subject'],\n  ...isNotEmpty('groupJid', 'subject'),\n};\n\nexport const updateGroupDescriptionSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    groupJid: { type: 'string' },\n    description: { type: 'string' },\n  },\n  required: ['groupJid', 'description'],\n  ...isNotEmpty('groupJid', 'description'),\n};\n"
  },
  {
    "path": "src/validate/instance.schema.ts",
    "content": "import { Integration } from '@api/types/wa.types';\nimport { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const instanceSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    // Instance\n    instanceName: { type: 'string' },\n    token: { type: 'string' },\n    number: { type: 'string', pattern: '^\\\\d+[\\\\.@\\\\w-]+' },\n    businessId: { type: 'string' },\n    qrcode: { type: 'boolean' },\n    Integration: {\n      type: 'string',\n      enum: Object.values(Integration),\n    },\n    // Settings\n    rejectCall: { type: 'boolean' },\n    msgCall: { type: 'string' },\n    groupsIgnore: { type: 'boolean' },\n    alwaysOnline: { type: 'boolean' },\n    readMessages: { type: 'boolean' },\n    readStatus: { type: 'boolean' },\n    syncFullHistory: { type: 'boolean' },\n    wavoipToken: { type: 'string' },\n    // Proxy\n    proxyHost: { type: 'string' },\n    proxyPort: { type: 'string' },\n    proxyProtocol: { type: 'string' },\n    proxyUsername: { type: 'string' },\n    proxyPassword: { type: 'string' },\n    // Webhook\n    webhookUrl: { type: 'string' },\n    webhookByEvents: { type: 'boolean' },\n    webhookBase64: { type: 'boolean' },\n    webhookEvents: {\n      type: 'array',\n      minItems: 0,\n      items: {\n        type: 'string',\n        enum: [\n          'APPLICATION_STARTUP',\n          'QRCODE_UPDATED',\n          'MESSAGES_SET',\n          'MESSAGES_UPSERT',\n          'MESSAGES_EDITED',\n          'MESSAGES_UPDATE',\n          'MESSAGES_DELETE',\n          'SEND_MESSAGE',\n          'SEND_MESSAGE_UPDATE',\n          'CONTACTS_SET',\n          'CONTACTS_UPSERT',\n          'CONTACTS_UPDATE',\n          'PRESENCE_UPDATE',\n          'CHATS_SET',\n          'CHATS_UPSERT',\n          'CHATS_UPDATE',\n          'CHATS_DELETE',\n          'GROUPS_UPSERT',\n          'GROUP_UPDATE',\n          'GROUP_PARTICIPANTS_UPDATE',\n          'CONNECTION_UPDATE',\n          'LABELS_EDIT',\n          'LABELS_ASSOCIATION',\n          'CALL',\n          'TYPEBOT_START',\n          'TYPEBOT_CHANGE_STATUS',\n        ],\n      },\n    },\n    // RabbitMQ\n    rabbitmqEnabled: { type: 'boolean' },\n    rabbitmqEvents: {\n      type: 'array',\n      minItems: 0,\n      items: {\n        type: 'string',\n        enum: [\n          'APPLICATION_STARTUP',\n          'QRCODE_UPDATED',\n          'MESSAGES_SET',\n          'MESSAGES_UPSERT',\n          'MESSAGES_EDITED',\n          'MESSAGES_UPDATE',\n          'MESSAGES_DELETE',\n          'SEND_MESSAGE',\n          'SEND_MESSAGE_UPDATE',\n          'CONTACTS_SET',\n          'CONTACTS_UPSERT',\n          'CONTACTS_UPDATE',\n          'PRESENCE_UPDATE',\n          'CHATS_SET',\n          'CHATS_UPSERT',\n          'CHATS_UPDATE',\n          'CHATS_DELETE',\n          'GROUPS_UPSERT',\n          'GROUP_UPDATE',\n          'GROUP_PARTICIPANTS_UPDATE',\n          'CONNECTION_UPDATE',\n          'LABELS_EDIT',\n          'LABELS_ASSOCIATION',\n          'CALL',\n          'TYPEBOT_START',\n          'TYPEBOT_CHANGE_STATUS',\n        ],\n      },\n    },\n    // NATS\n    natsEnabled: { type: 'boolean' },\n    natsEvents: {\n      type: 'array',\n      minItems: 0,\n      items: {\n        type: 'string',\n        enum: [\n          'APPLICATION_STARTUP',\n          'QRCODE_UPDATED',\n          'MESSAGES_SET',\n          'MESSAGES_UPSERT',\n          'MESSAGES_EDITED',\n          'MESSAGES_UPDATE',\n          'MESSAGES_DELETE',\n          'SEND_MESSAGE',\n          'SEND_MESSAGE_UPDATE',\n          'CONTACTS_SET',\n          'CONTACTS_UPSERT',\n          'CONTACTS_UPDATE',\n          'PRESENCE_UPDATE',\n          'CHATS_SET',\n          'CHATS_UPSERT',\n          'CHATS_UPDATE',\n          'CHATS_DELETE',\n          'GROUPS_UPSERT',\n          'GROUP_UPDATE',\n          'GROUP_PARTICIPANTS_UPDATE',\n          'CONNECTION_UPDATE',\n          'LABELS_EDIT',\n          'LABELS_ASSOCIATION',\n          'CALL',\n          'TYPEBOT_START',\n          'TYPEBOT_CHANGE_STATUS',\n        ],\n      },\n    },\n    // SQS\n    sqsEnabled: { type: 'boolean' },\n    sqsEvents: {\n      type: 'array',\n      minItems: 0,\n      items: {\n        type: 'string',\n        enum: [\n          'APPLICATION_STARTUP',\n          'QRCODE_UPDATED',\n          'MESSAGES_SET',\n          'MESSAGES_UPSERT',\n          'MESSAGES_EDITED',\n          'MESSAGES_UPDATE',\n          'MESSAGES_DELETE',\n          'SEND_MESSAGE',\n          'SEND_MESSAGE_UPDATE',\n          'CONTACTS_SET',\n          'CONTACTS_UPSERT',\n          'CONTACTS_UPDATE',\n          'PRESENCE_UPDATE',\n          'CHATS_SET',\n          'CHATS_UPSERT',\n          'CHATS_UPDATE',\n          'CHATS_DELETE',\n          'GROUPS_UPSERT',\n          'GROUP_UPDATE',\n          'GROUP_PARTICIPANTS_UPDATE',\n          'CONNECTION_UPDATE',\n          'LABELS_EDIT',\n          'LABELS_ASSOCIATION',\n          'CALL',\n          'TYPEBOT_START',\n          'TYPEBOT_CHANGE_STATUS',\n        ],\n      },\n    },\n    // Chatwoot\n    chatwootAccountId: { type: 'string' },\n    chatwootToken: { type: 'string' },\n    chatwootUrl: { type: 'string' },\n    chatwootSignMsg: { type: 'boolean' },\n    chatwootReopenConversation: { type: 'boolean' },\n    chatwootConversationPending: { type: 'boolean' },\n    chatwootImportContacts: { type: 'boolean' },\n    chatwootNameInbox: { type: 'string' },\n    chatwootMergeBrazilContacts: { type: 'boolean' },\n    chatwootImportMessages: { type: 'boolean' },\n    chatwootDaysLimitImportMessages: { type: 'number' },\n  },\n  ...isNotEmpty('instanceName'),\n};\n\nexport const presenceOnlySchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    presence: {\n      type: 'string',\n      enum: ['unavailable', 'available', 'composing', 'recording', 'paused'],\n    },\n  },\n  required: ['presence'],\n};\n"
  },
  {
    "path": "src/validate/label.schema.ts",
    "content": "import { JSONSchema7, JSONSchema7Definition } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nconst numberDefinition: JSONSchema7Definition = {\n  type: 'string',\n  description: 'Invalid format',\n};\n\nexport const handleLabelSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    labelId: { type: 'string' },\n    action: { type: 'string', enum: ['add', 'remove'] },\n  },\n  required: ['number', 'labelId', 'action'],\n  ...isNotEmpty('number', 'labelId', 'action'),\n};\n"
  },
  {
    "path": "src/validate/message.schema.ts",
    "content": "import { JSONSchema7, JSONSchema7Definition } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nconst numberDefinition: JSONSchema7Definition = {\n  type: 'string',\n  description: 'Invalid format',\n};\n\nexport const templateMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    name: { type: 'string' },\n    language: { type: 'string' },\n    components: { type: 'array' },\n    webhookUrl: { type: 'string' },\n  },\n  required: ['name', 'language'],\n};\n\nconst quotedOptionsSchema: JSONSchema7 = {\n  properties: {\n    key: {\n      type: 'object',\n      properties: {\n        id: { type: 'string' },\n        remoteJid: { type: 'string' },\n        fromMe: { type: 'boolean', enum: [true, false] },\n      },\n      required: ['id'],\n      ...isNotEmpty('id'),\n    },\n    message: { type: 'object' },\n  },\n};\n\nexport const offerCallSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    isVideo: { type: 'boolean', enum: [true, false] },\n    callDuration: { type: 'integer', minimum: 1, maximum: 15 },\n  },\n  required: ['number', 'callDuration'],\n};\n\nexport const textMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    text: { type: 'string' },\n    linkPreview: { type: 'boolean' },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number', 'text'],\n};\n\nexport const mediaMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    mediatype: { type: 'string', enum: ['image', 'document', 'video', 'audio'] },\n    mimetype: { type: 'string' },\n    media: { type: 'string' },\n    fileName: { type: 'string' },\n    caption: { type: 'string' },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number', 'mediatype'],\n};\n\nexport const ptvMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    video: { type: 'string' },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number'],\n};\n\nexport const audioMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    audio: { type: 'string' },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number'],\n};\n\nexport const statusMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    type: { type: 'string', enum: ['text', 'image', 'audio', 'video'] },\n    content: { type: 'string' },\n    caption: { type: 'string' },\n    backgroundColor: { type: 'string' },\n    font: { type: 'integer', minimum: 0, maximum: 5 },\n    statusJidList: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"statusJidList\" must be an array of numeric strings',\n      },\n    },\n    allContacts: { type: 'boolean', enum: [true, false] },\n  },\n  required: ['type'],\n};\n\nexport const stickerMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    sticker: { type: 'string' },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number'],\n};\n\nexport const locationMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    latitude: { type: 'number' },\n    longitude: { type: 'number' },\n    name: { type: 'string' },\n    address: { type: 'string' },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number', 'latitude', 'longitude', 'name', 'address'],\n};\n\nexport const contactMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    contact: {\n      type: 'array',\n      items: {\n        type: 'object',\n        properties: {\n          fullName: { type: 'string' },\n          wuid: {\n            type: 'string',\n            minLength: 10,\n            pattern: '\\\\d+',\n            description: '\"wuid\" must be a numeric string',\n          },\n          phoneNumber: { type: 'string', minLength: 10 },\n          organization: { type: 'string' },\n          email: { type: 'string' },\n          url: { type: 'string' },\n        },\n        required: ['fullName', 'phoneNumber'],\n        ...isNotEmpty('fullName'),\n      },\n      minItems: 1,\n      uniqueItems: true,\n    },\n  },\n  required: ['number', 'contact'],\n};\n\nexport const reactionMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    key: {\n      type: 'object',\n      properties: {\n        id: { type: 'string' },\n        remoteJid: { type: 'string' },\n        fromMe: { type: 'boolean', enum: [true, false] },\n      },\n      required: ['id', 'remoteJid', 'fromMe'],\n      ...isNotEmpty('id', 'remoteJid'),\n    },\n    reaction: { type: 'string' },\n  },\n  required: ['key', 'reaction'],\n};\n\nexport const pollMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    name: { type: 'string' },\n    selectableCount: { type: 'integer', minimum: 0, maximum: 10 },\n    values: {\n      type: 'array',\n      minItems: 2,\n      maxItems: 10,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n      },\n    },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number', 'name', 'selectableCount', 'values'],\n};\n\nexport const listMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    title: { type: 'string' },\n    description: { type: 'string' },\n    footerText: { type: 'string' },\n    buttonText: { type: 'string' },\n    sections: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'object',\n        properties: {\n          title: { type: 'string' },\n          rows: {\n            type: 'array',\n            minItems: 1,\n            uniqueItems: true,\n            items: {\n              type: 'object',\n              properties: {\n                title: { type: 'string' },\n                description: { type: 'string' },\n                rowId: { type: 'string' },\n              },\n              required: ['title', 'rowId'],\n              ...isNotEmpty('title', 'description', 'rowId'),\n            },\n          },\n        },\n        required: ['title', 'rows'],\n        ...isNotEmpty('title'),\n      },\n    },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number', 'title', 'footerText', 'buttonText', 'sections'],\n};\n\nexport const buttonsMessageSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    number: { ...numberDefinition },\n    thumbnailUrl: { type: 'string' },\n    title: { type: 'string' },\n    description: { type: 'string' },\n    footer: { type: 'string' },\n    buttons: {\n      type: 'array',\n      items: {\n        type: 'object',\n        properties: {\n          type: {\n            type: 'string',\n            enum: ['reply', 'copy', 'url', 'call', 'pix'],\n          },\n          displayText: { type: 'string' },\n          id: { type: 'string' },\n          url: { type: 'string' },\n          phoneNumber: { type: 'string' },\n          currency: { type: 'string' },\n          name: { type: 'string' },\n          keyType: { type: 'string', enum: ['phone', 'email', 'cpf', 'cnpj', 'random'] },\n          key: { type: 'string' },\n        },\n        required: ['type'],\n        ...isNotEmpty('id', 'url', 'phoneNumber'),\n      },\n    },\n    delay: {\n      type: 'integer',\n      description: 'Enter a value in milliseconds',\n    },\n    quoted: { ...quotedOptionsSchema },\n    everyOne: { type: 'boolean', enum: [true, false] },\n    mentioned: {\n      type: 'array',\n      minItems: 1,\n      uniqueItems: true,\n      items: {\n        type: 'string',\n        pattern: '^\\\\d+',\n        description: '\"mentioned\" must be an array of numeric strings',\n      },\n    },\n  },\n  required: ['number'],\n};\n"
  },
  {
    "path": "src/validate/proxy.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const proxySchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    enabled: { type: 'boolean', enum: [true, false] },\n    host: { type: 'string' },\n    port: { type: 'string' },\n    protocol: { type: 'string' },\n    username: { type: 'string' },\n    password: { type: 'string' },\n  },\n  required: ['enabled', 'host', 'port', 'protocol'],\n  ...isNotEmpty('enabled', 'host', 'port', 'protocol'),\n};\n"
  },
  {
    "path": "src/validate/settings.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const settingsSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    rejectCall: { type: 'boolean' },\n    msgCall: { type: 'string' },\n    groupsIgnore: { type: 'boolean' },\n    alwaysOnline: { type: 'boolean' },\n    readMessages: { type: 'boolean' },\n    readStatus: { type: 'boolean' },\n    syncFullHistory: { type: 'boolean' },\n    wavoipToken: { type: 'string' },\n  },\n  required: ['rejectCall', 'groupsIgnore', 'alwaysOnline', 'readMessages', 'readStatus', 'syncFullHistory'],\n  ...isNotEmpty('rejectCall', 'groupsIgnore', 'alwaysOnline', 'readMessages', 'readStatus', 'syncFullHistory'),\n};\n"
  },
  {
    "path": "src/validate/template.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  };\n};\n\nexport const templateSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    name: { type: 'string' },\n    category: { type: 'string', enum: ['AUTHENTICATION', 'MARKETING', 'UTILITY'] },\n    allowCategoryChange: { type: 'boolean' },\n    language: { type: 'string' },\n    components: { type: 'array' },\n    webhookUrl: { type: 'string' },\n  },\n  required: ['name', 'category', 'language', 'components'],\n  ...isNotEmpty('name', 'category', 'language', 'components'),\n};\n"
  },
  {
    "path": "src/validate/templateDelete.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties: Record<string, unknown> = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  } as JSONSchema7;\n};\n\nexport const templateDeleteSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    name: { type: 'string' },\n    hsmId: { type: 'string' },\n  },\n  required: ['name'],\n  ...isNotEmpty('name'),\n};\n"
  },
  {
    "path": "src/validate/templateEdit.schema.ts",
    "content": "import { JSONSchema7 } from 'json-schema';\nimport { v4 } from 'uuid';\n\nconst isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {\n  const properties: Record<string, unknown> = {};\n  propertyNames.forEach(\n    (property) =>\n      (properties[property] = {\n        minLength: 1,\n        description: `The \"${property}\" cannot be empty`,\n      }),\n  );\n  return {\n    if: {\n      propertyNames: {\n        enum: [...propertyNames],\n      },\n    },\n    then: { properties },\n  } as JSONSchema7;\n};\n\nexport const templateEditSchema: JSONSchema7 = {\n  $id: v4(),\n  type: 'object',\n  properties: {\n    templateId: { type: 'string' },\n    category: { type: 'string', enum: ['AUTHENTICATION', 'MARKETING', 'UTILITY'] },\n    allowCategoryChange: { type: 'boolean' },\n    ttl: { type: 'number' },\n    components: { type: 'array' },\n  },\n  required: ['templateId'],\n  ...isNotEmpty('templateId'),\n};\n"
  },
  {
    "path": "src/validate/validate.schema.ts",
    "content": "// Integrations Schema\nexport * from './business.schema';\nexport * from './chat.schema';\nexport * from './group.schema';\nexport * from './instance.schema';\nexport * from './label.schema';\nexport * from './message.schema';\nexport * from './proxy.schema';\nexport * from './settings.schema';\nexport * from './template.schema';\nexport * from './templateDelete.schema';\nexport * from './templateEdit.schema';\nexport * from '@api/integrations/chatbot/chatbot.schema';\nexport * from '@api/integrations/event/event.schema';\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"declaration\": true,\n    \"target\": \"es2020\",\n    \"module\": \"CommonJS\",\n    \"rootDir\": \"./\",\n    \"resolveJsonModule\": true,\n    \"removeComments\": true,\n    \"outDir\": \"./dist\",\n    \"noEmitOnError\": true,\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": false,\n    \"skipLibCheck\": true,\n    \"strictNullChecks\": false,\n    \"incremental\": true,\n    \"noImplicitAny\": false,\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@api/*\": [\"./src/api/*\"],\n      \"@cache/*\": [\"./src/cache/*\"],\n      \"@config/*\": [\"./src/config/*\"],\n      \"@exceptions\": [\"./src/exceptions\"],\n      \"@libs/*\": [\"./src/libs/*\"],\n      \"@utils/*\": [\"./src/utils/*\"],\n      \"@validate/*\": [\"./src/validate/*\"]\n    },\n    \"moduleResolution\": \"Node\"\n  },\n  \"exclude\": [\"node_modules\", \"./test\", \"./dist\", \"./prisma\"],\n  \"include\": [\n    \"src/**/*\",\n    \"src/**/*.json\"\n  ]\n}"
  },
  {
    "path": "tsup.config.ts",
    "content": "import { cpSync } from 'node:fs';\n\nimport { defineConfig } from 'tsup';\n\nexport default defineConfig({\n  entry: ['src'],\n  outDir: 'dist',\n  splitting: false,\n  sourcemap: true,\n  clean: true,\n  minify: true,\n  format: ['cjs', 'esm'],\n  onSuccess: async () => {\n    cpSync('src/utils/translations', 'dist/translations', { recursive: true });\n  },\n  loader: {\n    '.json': 'file',\n    '.yml': 'file',\n  },\n});\n"
  }
]