diff --git a/.env.hostinger.template b/.env.hostinger.template new file mode 100644 index 0000000..a07389c --- /dev/null +++ b/.env.hostinger.template @@ -0,0 +1,29 @@ +# LittleShop + TeleBot Hostinger Deployment Configuration +# Copy this to .env and fill in your values + +# BTCPay Server Configuration (Hostinger deployment) +BTCPAY_API_KEY=994589c8b514531f867dd24c83a02b6381a5f4a2 +BTCPAY_STORE_ID=AoxXjM9NJT6P9C1MErkaawXaSchz8sFPYdQ9FyhmQz33 +BTCPAY_WEBHOOK_SECRET=generate-a-secure-webhook-secret-here + +# Telegram Bot Configuration +TELEGRAM_BOT_TOKEN=your-telegram-bot-token +TELEGRAM_ADMIN_CHAT_ID=your-telegram-admin-chat-id + +# LittleShop Admin Credentials +LITTLESHOP_USERNAME=admin +LITTLESHOP_PASSWORD=admin + +# Brand Name +BRAND_NAME=Little Shop + +# Security Keys +JWT_SECRET_KEY=YourSuperSecretKeyThatIsAtLeast32CharactersLong! +DATABASE_ENCRYPTION_KEY=CHANGE_THIS_KEY_IN_PRODUCTION_32CHAR + +# Redis Configuration +REDIS_ENABLED=false +REDIS_PASSWORD=RedisPassword123 + +# Hangfire Configuration +HANGFIRE_ENABLED=false \ No newline at end of file diff --git a/BTCPAY_EXTERNAL_NODES_STATUS.md b/BTCPAY_EXTERNAL_NODES_STATUS.md new file mode 100644 index 0000000..4ebcb17 --- /dev/null +++ b/BTCPAY_EXTERNAL_NODES_STATUS.md @@ -0,0 +1,113 @@ +# BTCPay External Nodes Configuration Status + +## ✅ Configuration Completed + +### Infrastructure Setup +1. **Tor Container**: ✅ Running and connected (port 9050) +2. **Bitcoin Node**: ✅ Running but only 60% synced (continuing in background) +3. **Monero Remote Wallet**: ✅ Running with Tor onion node connection +4. **BTCPay Server**: ✅ Running and accessible + +### Current Configuration + +#### Tor Network +- **Status**: Fully operational +- **SOCKS Port**: 9050 +- **Container**: tor (running) +- **Bootstrap**: 100% complete + +#### Bitcoin Setup +- **Local Node**: Running (60% synced, July 2022) +- **Container**: btcpayserver_bitcoind +- **Pruned Mode**: 10GB max storage +- **Will sync in background**: ~2-3 weeks to complete + +#### Monero Setup +- **Remote Node Used**: `zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:18089` +- **Connection**: Via Tor SOCKS proxy +- **Container**: monero_wallet_remote +- **RPC Port**: 18082 +- **Credentials**: btcpay:btcpay + +## ⚠️ Manual Steps Required in BTCPay Admin + +To complete the setup and start accepting payments, you need to configure wallets through the BTCPay web interface: + +### For Bitcoin (Immediate Setup - No Sync Required) + +1. **Login to BTCPay**: https://thebankofdebbie.giize.com +2. **Navigate to**: Store Settings → Wallets → Bitcoin +3. **Choose Setup Method**: + - Click "Connect an existing wallet" + - Select "Enter extended public key" +4. **Enter Your xpub/zpub**: + - For testing: `xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB` + - For production: Generate from your hardware wallet or Bitcoin Core +5. **Configure Derivation**: + - Account Key Path: `m/84'/0'/0'` (for native segwit) + - Or use Legacy: `m/44'/0'/0'` +6. **Save Configuration** + +### For Monero (Requires View Key) + +1. **Navigate to**: Store Settings → Wallets → Monero +2. **Configure Wallet**: + - Primary Address: Your Monero address + - View Key: Your private view key (for incoming payment detection) +3. **Save Configuration** + +## Alternative: Use External Services (Fastest) + +If you need immediate operation without any node syncing: + +### Option 1: BTCPay Server Demo (Immediate) +1. Use BTCPay's demo server: https://testnet.demo.btcpayserver.org +2. Create account and store +3. Update LittleShop configuration with new credentials + +### Option 2: Third-Party BTCPay Host +- Voltage: https://voltage.cloud +- LunaNode: https://www.lunanode.com +- BTCPayJungle: https://btcpayjungle.com + +### Option 3: Electrum Personal Server +1. Install Electrum Personal Server locally +2. Connect it to public Electrum servers via Tor +3. Configure BTCPay to use your EPS instance + +## Current Payment Status + +- **Bitcoin**: ❌ Requires wallet configuration (xpub/zpub) +- **Monero**: ❌ Requires wallet configuration (address + view key) +- **API Connection**: ✅ Working +- **Invoice Creation**: Will work after wallet setup + +## Monitoring Commands + +```bash +# Check Bitcoin sync progress +ssh -i /silverlabs/src/LittleShop/Hostinger/vps_hardening_key -p 2255 sysadmin@thebankofdebbie.giize.com \ + "docker logs btcpayserver_bitcoind --tail 5 | grep progress" + +# Check Tor status +ssh -i /silverlabs/src/LittleShop/Hostinger/vps_hardening_key -p 2255 sysadmin@thebankofdebbie.giize.com \ + "docker logs tor --tail 5" + +# Check Monero wallet +ssh -i /silverlabs/src/LittleShop/Hostinger/vps_hardening_key -p 2255 sysadmin@thebankofdebbie.giize.com \ + "docker logs monero_wallet_remote --tail 5" + +# Test BTCPay connection +curl https://thebankofdebbie.giize.com/api/v1/stores \ + -H "Authorization: token db920209c0101efdbd1c6b6d1c99a48e3ba9d0de" +``` + +## Summary + +The infrastructure is ready with external node connectivity via Tor. However, BTCPay requires wallet configuration through its web interface to start accepting payments. You can either: + +1. **Configure watch-only wallets** (xpub for Bitcoin, view key for Monero) - Immediate +2. **Wait for local Bitcoin sync** to complete (~2-3 weeks) - Most private +3. **Use external BTCPay service** temporarily - Fastest + +The system is designed for privacy with all external connections routed through Tor. \ No newline at end of file diff --git a/HOSTINGER-DEPLOYMENT.md b/HOSTINGER-DEPLOYMENT.md new file mode 100644 index 0000000..df03895 --- /dev/null +++ b/HOSTINGER-DEPLOYMENT.md @@ -0,0 +1,220 @@ +# Hostinger Deployment Guide for LittleShop + TeleBot + +## Overview +This guide explains how to deploy LittleShop and TeleBot to Hostinger VPS with BTCPay Server integration. + +## Current BTCPay Server Setup +- **URL**: https://thebankofdebbie.giize.com +- **Host**: srv1002428.hstgr.cloud +- **Cryptocurrencies**: BTC, DOGE, XMR, ETH, ZEC +- **API Key**: 994589c8b514531f867dd24c83a02b6381a5f4a2 +- **Store ID**: AoxXjM9NJT6P9C1MErkaawXaSchz8sFPYdQ9FyhmQz33 + +## Deployment Files Created + +### 1. `appsettings.Hostinger.json` +- Production configuration for LittleShop +- Points to Hostinger BTCPay Server +- Uses local SQLite database + +### 2. `docker-compose.hostinger.yml` +- Combined deployment for LittleShop + TeleBot +- Network configuration for container communication +- Volume persistence for data + +### 3. `.env.hostinger.template` +- Environment variables template +- Copy to `.env` and configure + +### 4. `deploy-to-hostinger.sh` +- Automated deployment script +- Builds and starts all services +- Health checks included + +## Step-by-Step Deployment + +### 1. Connect to Hostinger VPS +```bash +ssh root@srv1002428.hstgr.cloud -p 2255 +``` + +### 2. Clone/Update Repository +```bash +cd /root +git clone https://git.silverlabs.uk/SilverLABS/LittleShop.git +# OR if already exists +cd LittleShop +git pull +``` + +### 3. Configure Environment +```bash +cp .env.hostinger.template .env +nano .env +``` + +Required configurations: +- `TELEGRAM_BOT_TOKEN` - Your Telegram bot token +- `TELEGRAM_ADMIN_CHAT_ID` - Your Telegram chat ID for admin messages +- `BTCPAY_WEBHOOK_SECRET` - Generate a secure random string (32+ chars) + +### 4. Run Deployment Script +```bash +./deploy-to-hostinger.sh +``` + +## BTCPay Webhook Configuration + +After deployment, configure the webhook in BTCPay Server: + +1. Log into BTCPay: https://thebankofdebbie.giize.com +2. Go to Store Settings → Webhooks +3. Add new webhook: + - **URL**: `http://srv1002428.hstgr.cloud:8080/api/orders/payments/webhook` + - **Secret**: Use the same value as `BTCPAY_WEBHOOK_SECRET` in `.env` + - **Events**: Select all payment-related events + +## Troubleshooting + +### Problem: TeleBot can't create orders +**Solution**: Check BTCPay connection +```bash +# Check LittleShop logs +docker logs littleshop | grep -i btcpay + +# Test BTCPay connectivity from container +docker exec littleshop curl https://thebankofdebbie.giize.com/api/v1/health +``` + +### Problem: Payment creation fails +**Possible causes**: +1. Wrong BTCPay API key or Store ID +2. Currency not configured in BTCPay +3. Network connectivity issues + +**Debug steps**: +```bash +# Check detailed error logs +docker logs littleshop | grep -i error + +# Verify environment variables +docker exec littleshop env | grep BTCPAY + +# Test API directly +curl -X GET https://thebankofdebbie.giize.com/api/v1/stores \ + -H "Authorization: token 994589c8b514531f867dd24c83a02b6381a5f4a2" +``` + +### Problem: TeleBot not responding +**Solution**: Check bot registration +```bash +# Check TeleBot logs +docker logs littleshop-telebot + +# Verify bot token +docker exec littleshop-telebot env | grep TELEGRAM + +# Restart bot +docker restart littleshop-telebot +``` + +### Problem: Orders stuck in "PendingPayment" +**Solution**: Check webhook configuration +```bash +# Monitor webhook delivery +docker logs littleshop | grep webhook + +# Test webhook manually +curl -X POST http://localhost:8080/api/orders/payments/webhook \ + -H "Content-Type: application/json" \ + -H "BTCPay-Sig: sha256=test" \ + -d '{"test": true}' +``` + +## Service URLs + +### External Access +- **BTCPay Server**: https://thebankofdebbie.giize.com +- **LittleShop API**: http://srv1002428.hstgr.cloud:8080 +- **Telegram Bot**: Search for your bot on Telegram + +### Internal Container Network +- **LittleShop**: http://littleshop:8080 +- **Redis**: redis:6379 + +## Monitoring + +### View Real-time Logs +```bash +# All services +docker-compose -f docker-compose.hostinger.yml logs -f + +# Specific service +docker logs -f littleshop +docker logs -f littleshop-telebot +``` + +### Check Service Status +```bash +docker-compose -f docker-compose.hostinger.yml ps +``` + +### Resource Usage +```bash +docker stats +``` + +## Backup + +### Database Backup +```bash +# Backup LittleShop database +docker exec littleshop sqlite3 /app/data/littleshop.db ".backup /app/data/backup.db" +docker cp littleshop:/app/data/backup.db ./littleshop-backup-$(date +%Y%m%d).db + +# Backup TeleBot database +docker exec littleshop-telebot sqlite3 /app/data/telebot.db ".backup /app/data/backup.db" +docker cp littleshop-telebot:/app/data/backup.db ./telebot-backup-$(date +%Y%m%d).db +``` + +### Full Volume Backup +```bash +# Stop services +docker-compose -f docker-compose.hostinger.yml down + +# Backup volumes +docker run --rm -v littleshop_data:/data -v $(pwd):/backup alpine tar czf /backup/littleshop-data-$(date +%Y%m%d).tar.gz -C /data . + +# Restart services +docker-compose -f docker-compose.hostinger.yml up -d +``` + +## Update Deployment + +To update to latest version: +```bash +# Pull latest code +git pull + +# Rebuild and restart +./deploy-to-hostinger.sh +``` + +## Security Considerations + +1. **Change default passwords** in production +2. **Use strong webhook secret** (32+ random characters) +3. **Enable firewall** for port 8080 if exposing externally +4. **Regular backups** of databases +5. **Monitor logs** for suspicious activity + +## Support Currencies + +Currently configured in BTCPay: +- BTC (Bitcoin) +- DOGE (Dogecoin) +- XMR (Monero) +- ETH (Ethereum) +- ZEC (Zcash) + +To add more currencies, configure them in BTCPay Server first. \ No newline at end of file diff --git a/LittleShop.Client/Models/Product.cs b/LittleShop.Client/Models/Product.cs index a5db35d..dd41182 100644 --- a/LittleShop.Client/Models/Product.cs +++ b/LittleShop.Client/Models/Product.cs @@ -12,6 +12,7 @@ public class Product public string? CategoryName { get; set; } public bool IsActive { get; set; } public List Photos { get; set; } = new(); + public List Variations { get; set; } = new(); public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } @@ -22,4 +23,17 @@ public class ProductPhoto public string Url { get; set; } = string.Empty; public string? AltText { get; set; } public int SortOrder { get; set; } +} + +public class ProductVariation +{ + public Guid Id { get; set; } + public Guid ProductId { get; set; } + public string Name { get; set; } = string.Empty; + public string? Description { get; set; } + public int Quantity { get; set; } + public decimal Price { get; set; } + public decimal PricePerUnit { get; set; } + public int SortOrder { get; set; } + public bool IsActive { get; set; } } \ No newline at end of file diff --git a/LittleShop/Areas/Admin/Controllers/BotRecoveryController.cs b/LittleShop/Areas/Admin/Controllers/BotRecoveryController.cs new file mode 100644 index 0000000..07a132d --- /dev/null +++ b/LittleShop/Areas/Admin/Controllers/BotRecoveryController.cs @@ -0,0 +1,165 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using LittleShop.Services; + +namespace LittleShop.Areas.Admin.Controllers; + +[Area("Admin")] +[Authorize(Policy = "AdminOnly")] +public class BotRecoveryController : Controller +{ + private readonly IBotContactService _contactService; + private readonly IBotService _botService; + private readonly ILogger _logger; + + public BotRecoveryController( + IBotContactService contactService, + IBotService botService, + ILogger logger) + { + _contactService = contactService; + _botService = botService; + _logger = logger; + } + + // GET: Admin/BotRecovery + public async Task Index() + { + var allBots = await _botService.GetAllBotsAsync(); + var botsWithStatus = allBots.Select(bot => new + { + Bot = bot, + Contacts = _contactService.GetBotContactsAsync(bot.Id).Result, + IsHealthy = bot.Status == Enums.BotStatus.Active && + bot.LastSeenAt > DateTime.UtcNow.AddMinutes(-5) + }).ToList(); + + ViewData["BotsWithStatus"] = botsWithStatus; + return View(); + } + + // GET: Admin/BotRecovery/PrepareRecovery/{botId} + public async Task PrepareRecovery(Guid botId) + { + var recoveryData = await _contactService.PrepareContactRecoveryAsync(botId); + return View(recoveryData); + } + + // POST: Admin/BotRecovery/ExecuteRecovery + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ExecuteRecovery(Guid fromBotId, Guid toBotId, bool notifyUsers = false) + { + try + { + // Migrate contacts + var success = await _contactService.MigrateContactsAsync(fromBotId, toBotId); + + if (!success) + { + TempData["Error"] = "Failed to migrate contacts. Check logs for details."; + return RedirectToAction(nameof(PrepareRecovery), new { botId = fromBotId }); + } + + // Get the new bot info for notifications + if (notifyUsers) + { + var toBot = await _botService.GetBotByIdAsync(toBotId); + var orphanedContacts = await _contactService.GetOrphanedContactsAsync(fromBotId); + + foreach (var contact in orphanedContacts) + { + await _contactService.NotifyContactOfBotChangeAsync( + contact.TelegramUserId, + toBot.PlatformUsername); + } + } + + // Update bot statuses + await _botService.UpdateBotStatusAsync(fromBotId, Enums.BotStatus.Retired); + + TempData["Success"] = $"Successfully migrated contacts from bot {fromBotId} to {toBotId}"; + return RedirectToAction(nameof(Index)); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to execute bot recovery"); + TempData["Error"] = "An error occurred during recovery. Please try again."; + return RedirectToAction(nameof(PrepareRecovery), new { botId = fromBotId }); + } + } + + // GET: Admin/BotRecovery/Backup/{botId} + public async Task Backup(Guid botId) + { + var backup = await _contactService.CreateContactBackupAsync(botId); + + // Return as downloadable JSON file + var json = System.Text.Json.JsonSerializer.Serialize(backup, new System.Text.Json.JsonSerializerOptions + { + WriteIndented = true + }); + + var bytes = System.Text.Encoding.UTF8.GetBytes(json); + return File(bytes, "application/json", $"bot-contacts-{botId}-{DateTime.UtcNow:yyyyMMdd}.json"); + } + + // POST: Admin/BotRecovery/RestoreBackup + [HttpPost] + [ValidateAntiForgeryToken] + public async Task RestoreBackup(Guid toBotId, IFormFile backupFile) + { + if (backupFile == null || backupFile.Length == 0) + { + TempData["Error"] = "Please select a backup file to restore"; + return RedirectToAction(nameof(Index)); + } + + try + { + using var stream = backupFile.OpenReadStream(); + using var reader = new System.IO.StreamReader(stream); + var json = await reader.ReadToEndAsync(); + + var backup = System.Text.Json.JsonSerializer.Deserialize(json); + + if (backup == null) + { + TempData["Error"] = "Invalid backup file format"; + return RedirectToAction(nameof(Index)); + } + + var success = await _contactService.RestoreContactsFromBackupAsync(toBotId, backup); + + if (success) + { + TempData["Success"] = $"Successfully restored {backup.ContactCount} contacts to bot"; + } + else + { + TempData["Error"] = "Failed to restore contacts from backup"; + } + + return RedirectToAction(nameof(Index)); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to restore backup"); + TempData["Error"] = "An error occurred while restoring the backup"; + return RedirectToAction(nameof(Index)); + } + } + + // GET: Admin/BotRecovery/ContactHistory/{telegramUserId} + public async Task ContactHistory(long telegramUserId) + { + // Show all bot interactions for a specific user + ViewData["UserId"] = telegramUserId; + // Implementation would query all BotContacts for this user across all bots + return View(); + } +} \ No newline at end of file diff --git a/LittleShop/Areas/Admin/Views/Bots/Edit.cshtml b/LittleShop/Areas/Admin/Views/Bots/Edit.cshtml index 15fc947..5718b7b 100644 --- a/LittleShop/Areas/Admin/Views/Bots/Edit.cshtml +++ b/LittleShop/Areas/Admin/Views/Bots/Edit.cshtml @@ -18,6 +18,7 @@ }
+ @Html.AntiForgeryToken()
diff --git a/LittleShop/Models/BotContact.cs b/LittleShop/Models/BotContact.cs new file mode 100644 index 0000000..cda005a --- /dev/null +++ b/LittleShop/Models/BotContact.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace LittleShop.Models; + +/// +/// Tracks all contacts for each bot, enabling contact recovery and migration +/// +public class BotContact +{ + [Key] + public Guid Id { get; set; } + + // Bot Association + [Required] + public Guid BotId { get; set; } + public virtual Bot Bot { get; set; } = null!; + + // Telegram User Information + [Required] + public long TelegramUserId { get; set; } + + [StringLength(100)] + public string TelegramUsername { get; set; } = string.Empty; + + [Required] + [StringLength(200)] + public string DisplayName { get; set; } = string.Empty; + + [StringLength(50)] + public string FirstName { get; set; } = string.Empty; + + [StringLength(50)] + public string LastName { get; set; } = string.Empty; + + // Contact Metadata + public DateTime FirstContactDate { get; set; } + public DateTime LastContactDate { get; set; } + public int TotalInteractions { get; set; } + public string LastKnownLanguage { get; set; } = "en"; + + // Relationship Status + public ContactStatus Status { get; set; } = ContactStatus.Active; + public string? StatusReason { get; set; } + + // Customer Link (if they've made purchases) + public Guid? CustomerId { get; set; } + public virtual Customer? Customer { get; set; } + + // Recovery Information + public bool IsRecovered { get; set; } = false; + public Guid? RecoveredFromBotId { get; set; } + public DateTime? RecoveredAt { get; set; } + + // Backup Metadata + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public bool IsActive { get; set; } = true; + + // Additional Contact Info (encrypted/hashed) + [StringLength(500)] + public string? EncryptedContactData { get; set; } // For storing additional contact methods + + // Preferences and Notes + [StringLength(500)] + public string? Preferences { get; set; } // JSON string of user preferences + + [StringLength(1000)] + public string? Notes { get; set; } // Admin notes about this contact +} + +public enum ContactStatus +{ + Active, + Inactive, + Blocked, + Migrated, + Lost, + Recovered +} \ No newline at end of file diff --git a/LittleShop/Services/BotContactService.cs b/LittleShop/Services/BotContactService.cs new file mode 100644 index 0000000..39a2b28 --- /dev/null +++ b/LittleShop/Services/BotContactService.cs @@ -0,0 +1,386 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using LittleShop.Data; +using LittleShop.Models; +using LittleShop.DTOs; + +namespace LittleShop.Services; + +public interface IMessageDeliveryService +{ + // Placeholder interface for compilation +} + +public interface IBotContactService +{ + Task RecordContactAsync(Guid botId, TelegramUserDto user); + Task> GetBotContactsAsync(Guid botId, bool activeOnly = true); + Task> GetOrphanedContactsAsync(Guid failedBotId); + Task MigrateContactsAsync(Guid fromBotId, Guid toBotId); + Task PrepareContactRecoveryAsync(Guid failedBotId); + Task NotifyContactOfBotChangeAsync(long telegramUserId, string newBotUsername); + Task CreateContactBackupAsync(Guid botId); + Task RestoreContactsFromBackupAsync(Guid toBotId, ContactBackupDto backup); +} + +public class BotContactService : IBotContactService +{ + private readonly LittleShopContext _context; + private readonly ILogger _logger; + private readonly IMessageDeliveryService _messageService; + + public BotContactService( + LittleShopContext context, + ILogger logger, + IMessageDeliveryService messageService) + { + _context = context; + _logger = logger; + _messageService = messageService; + } + + public async Task RecordContactAsync(Guid botId, TelegramUserDto user) + { + var existingContact = await _context.BotContacts + .FirstOrDefaultAsync(c => c.BotId == botId && c.TelegramUserId == user.Id); + + if (existingContact != null) + { + // Update existing contact + existingContact.TelegramUsername = user.Username ?? string.Empty; + existingContact.DisplayName = $"{user.FirstName} {user.LastName}".Trim(); + existingContact.FirstName = user.FirstName ?? string.Empty; + existingContact.LastName = user.LastName ?? string.Empty; + existingContact.LastContactDate = DateTime.UtcNow; + existingContact.TotalInteractions++; + existingContact.UpdatedAt = DateTime.UtcNow; + + _context.BotContacts.Update(existingContact); + } + else + { + // Create new contact record + existingContact = new BotContact + { + Id = Guid.NewGuid(), + BotId = botId, + TelegramUserId = user.Id, + TelegramUsername = user.Username ?? string.Empty, + DisplayName = $"{user.FirstName} {user.LastName}".Trim(), + FirstName = user.FirstName ?? string.Empty, + LastName = user.LastName ?? string.Empty, + FirstContactDate = DateTime.UtcNow, + LastContactDate = DateTime.UtcNow, + TotalInteractions = 1, + LastKnownLanguage = user.LanguageCode ?? "en", + Status = ContactStatus.Active, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + IsActive = true + }; + + await _context.BotContacts.AddAsync(existingContact); + } + + await _context.SaveChangesAsync(); + _logger.LogInformation("Recorded contact {UserId} for bot {BotId}", user.Id, botId); + + return existingContact; + } + + public async Task> GetBotContactsAsync(Guid botId, bool activeOnly = true) + { + var query = _context.BotContacts.Where(c => c.BotId == botId); + + if (activeOnly) + query = query.Where(c => c.IsActive && c.Status == ContactStatus.Active); + + return await query + .OrderByDescending(c => c.LastContactDate) + .ToListAsync(); + } + + public async Task> GetOrphanedContactsAsync(Guid failedBotId) + { + // Get contacts from failed bot that haven't been recovered yet + return await _context.BotContacts + .Where(c => c.BotId == failedBotId && + c.Status == ContactStatus.Active && + !c.IsRecovered) + .OrderByDescending(c => c.TotalInteractions) // Prioritize most active users + .ToListAsync(); + } + + public async Task MigrateContactsAsync(Guid fromBotId, Guid toBotId) + { + try + { + var contactsToMigrate = await GetOrphanedContactsAsync(fromBotId); + var toBot = await _context.Bots.FindAsync(toBotId); + + if (toBot == null) + { + _logger.LogError("Target bot {BotId} not found", toBotId); + return false; + } + + foreach (var contact in contactsToMigrate) + { + // Create new contact record for new bot + var newContact = new BotContact + { + Id = Guid.NewGuid(), + BotId = toBotId, + TelegramUserId = contact.TelegramUserId, + TelegramUsername = contact.TelegramUsername, + DisplayName = contact.DisplayName, + FirstName = contact.FirstName, + LastName = contact.LastName, + FirstContactDate = DateTime.UtcNow, + LastContactDate = DateTime.UtcNow, + TotalInteractions = 0, // Reset for new bot + LastKnownLanguage = contact.LastKnownLanguage, + Status = ContactStatus.Recovered, + CustomerId = contact.CustomerId, + IsRecovered = true, + RecoveredFromBotId = fromBotId, + RecoveredAt = DateTime.UtcNow, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + IsActive = true, + Preferences = contact.Preferences, + Notes = $"Migrated from bot {fromBotId} on {DateTime.UtcNow:yyyy-MM-dd}" + }; + + await _context.BotContacts.AddAsync(newContact); + + // Mark original contact as migrated + contact.Status = ContactStatus.Migrated; + contact.IsRecovered = true; + contact.UpdatedAt = DateTime.UtcNow; + _context.BotContacts.Update(contact); + + _logger.LogInformation("Migrated contact {UserId} from bot {FromBot} to {ToBot}", + contact.TelegramUserId, fromBotId, toBotId); + } + + await _context.SaveChangesAsync(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to migrate contacts from {FromBot} to {ToBot}", fromBotId, toBotId); + return false; + } + } + + public async Task PrepareContactRecoveryAsync(Guid failedBotId) + { + var orphanedContacts = await GetOrphanedContactsAsync(failedBotId); + var failedBot = await _context.Bots.FindAsync(failedBotId); + var availableBots = await _context.Bots + .Where(b => b.Id != failedBotId && b.Status == BotStatus.Active) + .ToListAsync(); + + return new BotContactRecoveryDto + { + FailedBotId = failedBotId, + FailedBotName = failedBot?.Name ?? "Unknown", + OrphanedContactCount = orphanedContacts.Count(), + HighValueContacts = orphanedContacts + .Where(c => c.TotalInteractions > 10 || c.CustomerId != null) + .Count(), + AvailableRecoveryBots = availableBots.Select(b => new BotInfoDto + { + Id = b.Id, + Name = b.Name, + Status = b.Status.ToString(), + CurrentContactCount = _context.BotContacts.Count(c => c.BotId == b.Id && c.IsActive) + }).ToList(), + ContactDetails = orphanedContacts.Select(c => new ContactSummaryDto + { + TelegramUserId = c.TelegramUserId, + Username = c.TelegramUsername, + DisplayName = c.DisplayName, + TotalInteractions = c.TotalInteractions, + LastContactDate = c.LastContactDate, + IsCustomer = c.CustomerId != null + }).ToList() + }; + } + + public async Task NotifyContactOfBotChangeAsync(long telegramUserId, string newBotUsername) + { + try + { + // This would integrate with the message delivery service + var message = $"Hello! Your previous bot is temporarily unavailable. " + + $"Please continue your conversation with our new bot: @{newBotUsername} " + + $"All your order history and preferences have been preserved."; + + // Queue message for delivery when user contacts new bot + await _messageService.QueueRecoveryMessageAsync(telegramUserId, message); + + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to notify user {UserId} of bot change", telegramUserId); + return false; + } + } + + public async Task CreateContactBackupAsync(Guid botId) + { + var contacts = await GetBotContactsAsync(botId, activeOnly: false); + var bot = await _context.Bots.FindAsync(botId); + + return new ContactBackupDto + { + BackupId = Guid.NewGuid(), + BotId = botId, + BotName = bot?.Name ?? "Unknown", + BackupDate = DateTime.UtcNow, + ContactCount = contacts.Count(), + Contacts = contacts.Select(c => new ContactExportDto + { + TelegramUserId = c.TelegramUserId, + TelegramUsername = c.TelegramUsername, + DisplayName = c.DisplayName, + FirstName = c.FirstName, + LastName = c.LastName, + FirstContactDate = c.FirstContactDate, + LastContactDate = c.LastContactDate, + TotalInteractions = c.TotalInteractions, + LastKnownLanguage = c.LastKnownLanguage, + Status = c.Status.ToString(), + CustomerId = c.CustomerId, + Preferences = c.Preferences, + Notes = c.Notes + }).ToList() + }; + } + + public async Task RestoreContactsFromBackupAsync(Guid toBotId, ContactBackupDto backup) + { + try + { + foreach (var contactData in backup.Contacts) + { + // Check if contact already exists for this bot + var existingContact = await _context.BotContacts + .FirstOrDefaultAsync(c => c.BotId == toBotId && + c.TelegramUserId == contactData.TelegramUserId); + + if (existingContact == null) + { + var newContact = new BotContact + { + Id = Guid.NewGuid(), + BotId = toBotId, + TelegramUserId = contactData.TelegramUserId, + TelegramUsername = contactData.TelegramUsername, + DisplayName = contactData.DisplayName, + FirstName = contactData.FirstName, + LastName = contactData.LastName, + FirstContactDate = contactData.FirstContactDate, + LastContactDate = contactData.LastContactDate, + TotalInteractions = contactData.TotalInteractions, + LastKnownLanguage = contactData.LastKnownLanguage, + Status = Enum.Parse(contactData.Status), + CustomerId = contactData.CustomerId, + IsRecovered = true, + RecoveredFromBotId = backup.BotId, + RecoveredAt = DateTime.UtcNow, + CreatedAt = DateTime.UtcNow, + UpdatedAt = DateTime.UtcNow, + IsActive = true, + Preferences = contactData.Preferences, + Notes = $"Restored from backup {backup.BackupId} on {DateTime.UtcNow:yyyy-MM-dd}" + }; + + await _context.BotContacts.AddAsync(newContact); + } + } + + await _context.SaveChangesAsync(); + _logger.LogInformation("Restored {Count} contacts from backup to bot {BotId}", + backup.Contacts.Count, toBotId); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to restore contacts from backup"); + return false; + } + } +} + +// DTOs for contact management +public class TelegramUserDto +{ + public long Id { get; set; } + public string? Username { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? LanguageCode { get; set; } +} + +public class BotContactRecoveryDto +{ + public Guid FailedBotId { get; set; } + public string FailedBotName { get; set; } = string.Empty; + public int OrphanedContactCount { get; set; } + public int HighValueContacts { get; set; } + public List AvailableRecoveryBots { get; set; } = new(); + public List ContactDetails { get; set; } = new(); +} + +public class BotInfoDto +{ + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public string Status { get; set; } = string.Empty; + public int CurrentContactCount { get; set; } +} + +public class ContactSummaryDto +{ + public long TelegramUserId { get; set; } + public string Username { get; set; } = string.Empty; + public string DisplayName { get; set; } = string.Empty; + public int TotalInteractions { get; set; } + public DateTime LastContactDate { get; set; } + public bool IsCustomer { get; set; } +} + +public class ContactBackupDto +{ + public Guid BackupId { get; set; } + public Guid BotId { get; set; } + public string BotName { get; set; } = string.Empty; + public DateTime BackupDate { get; set; } + public int ContactCount { get; set; } + public List Contacts { get; set; } = new(); +} + +public class ContactExportDto +{ + public long TelegramUserId { get; set; } + public string TelegramUsername { get; set; } = string.Empty; + public string DisplayName { get; set; } = string.Empty; + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public DateTime FirstContactDate { get; set; } + public DateTime LastContactDate { get; set; } + public int TotalInteractions { get; set; } + public string LastKnownLanguage { get; set; } = string.Empty; + public string Status { get; set; } = string.Empty; + public Guid? CustomerId { get; set; } + public string? Preferences { get; set; } + public string? Notes { get; set; } +} \ No newline at end of file diff --git a/TeleBot/.env.multi.example b/TeleBot/.env.multi.example new file mode 100644 index 0000000..a7b8d6e --- /dev/null +++ b/TeleBot/.env.multi.example @@ -0,0 +1,131 @@ +# LittleShop Multi-Bot Environment Configuration Template +# Copy this file to .env.multi and configure your values + +# ======================================== +# SHARED CONFIGURATION (All Bots) +# ======================================== + +# LittleShop API Configuration +LITTLESHOP_API_URL=http://localhost:8080 +# For remote API: https://api.yourdomain.com +# For Docker host: http://host.docker.internal:8080 +# For same network: http://littleshop-api:8080 + +LITTLESHOP_USERNAME=admin +LITTLESHOP_PASSWORD=admin + +# Redis Configuration (Optional - for shared caching) +REDIS_ENABLED=false +REDIS_PASSWORD=your_secure_redis_password_here + +# ======================================== +# SUPPORT BOT CONFIGURATION +# ======================================== + +# Telegram Bot Token from @BotFather +SUPPORT_BOT_TOKEN= + +# Admin Chat ID for notifications (get from @userinfobot) +SUPPORT_ADMIN_CHAT_ID= + +# Bot API Key from LittleShop Admin Panel +SUPPORT_BOT_API_KEY= + +# 32-character encryption key for database +SUPPORT_DB_ENCRYPTION_KEY=change_this_to_32_char_secure_key + +# ======================================== +# SALES & MARKETING BOT CONFIGURATION +# ======================================== + +# Telegram Bot Token from @BotFather +SALES_BOT_TOKEN= + +# Admin Chat ID for notifications +SALES_ADMIN_CHAT_ID= + +# Bot API Key from LittleShop Admin Panel +SALES_BOT_API_KEY= + +# 32-character encryption key for database +SALES_DB_ENCRYPTION_KEY=change_this_to_32_char_secure_key + +# ======================================== +# VIP/PREMIUM BOT CONFIGURATION +# ======================================== + +# Telegram Bot Token from @BotFather +VIP_BOT_TOKEN= + +# Admin Chat ID for notifications +VIP_ADMIN_CHAT_ID= + +# Bot API Key from LittleShop Admin Panel +VIP_BOT_API_KEY= + +# 32-character encryption key for database +VIP_DB_ENCRYPTION_KEY=change_this_to_32_char_secure_key + +# Enhanced privacy for VIP customers +VIP_ENABLE_TOR=false + +# ======================================== +# EU REGION BOT CONFIGURATION (Optional) +# ======================================== + +# Telegram Bot Token from @BotFather +EU_BOT_TOKEN= + +# Admin Chat ID for notifications +EU_ADMIN_CHAT_ID= + +# Bot API Key from LittleShop Admin Panel +EU_BOT_API_KEY= + +# 32-character encryption key for database +EU_DB_ENCRYPTION_KEY=change_this_to_32_char_secure_key + +# Optional: Different API endpoint for EU region +EU_API_URL=${LITTLESHOP_API_URL} + +# ======================================== +# DEPLOYMENT NOTES +# ======================================== + +# To generate secure encryption keys: +# openssl rand -hex 16 # Generates 32-character hex string +# or +# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1 + +# To get your Telegram Chat ID: +# 1. Message @userinfobot on Telegram +# 2. It will reply with your user info including chat ID + +# To create bot tokens: +# 1. Message @BotFather on Telegram +# 2. Send /newbot and follow instructions +# 3. Copy the token provided + +# To get Bot API Keys: +# 1. Login to LittleShop Admin Panel +# 2. Go to /Admin/Bots/Wizard +# 3. Create bot and copy the API key + +# ======================================== +# DOCKER DEPLOYMENT COMMANDS +# ======================================== + +# Deploy all bots: +# docker-compose -f docker-compose.multi.yml --env-file .env.multi up -d + +# Deploy specific bot: +# docker-compose -f docker-compose.multi.yml --env-file .env.multi up -d bot-support + +# View logs: +# docker-compose -f docker-compose.multi.yml logs -f bot-support + +# Stop all bots: +# docker-compose -f docker-compose.multi.yml down + +# Remove all data (CAUTION): +# docker-compose -f docker-compose.multi.yml down -v \ No newline at end of file diff --git a/TeleBot/MULTI-HOST-DEPLOYMENT.md b/TeleBot/MULTI-HOST-DEPLOYMENT.md new file mode 100644 index 0000000..beedd09 --- /dev/null +++ b/TeleBot/MULTI-HOST-DEPLOYMENT.md @@ -0,0 +1,504 @@ +# 🚀 Multi-Host Docker Bot Deployment Guide + +Deploy multiple LittleShop TeleBots across different Docker hosts for scalability, redundancy, and geographic distribution. + +## 📋 Table of Contents + +- [Overview](#overview) +- [Architecture](#architecture) +- [Quick Start](#quick-start) +- [Deployment Methods](#deployment-methods) +- [Configuration](#configuration) +- [Management](#management) +- [Security](#security) +- [Troubleshooting](#troubleshooting) + +## Overview + +The LittleShop TeleBot system supports deploying multiple bot instances across different Docker hosts. Each bot: +- Runs independently in its own container +- Connects to the central LittleShop API +- Has its own Telegram bot token and personality +- Can serve different customer segments or regions + +## Architecture + +``` +┌─────────────────────────────────────────────────┐ +│ Central LittleShop API │ +│ (http://api.littleshop.com) │ +└─────────────┬─────────┬─────────┬───────────────┘ + │ │ │ + ┌────▼───┐ ┌──▼───┐ ┌──▼───┐ + │Docker │ │Docker│ │Docker│ + │Host A │ │Host B│ │Host C│ + └────────┘ └──────┘ └──────┘ + Support Sales VIP Bots + Bot Bot +``` + +## Quick Start + +### 1. Build Docker Image + +```bash +# Build the image locally +cd /silverlabs/src/LittleShop +docker build -f TeleBot/TeleBot/Dockerfile -t littleshop/telebot:latest . + +# Push to registry (Docker Hub, GitLab, or private) +docker push littleshop/telebot:latest +``` + +### 2. Create Bot in Admin Panel + +1. Navigate to `http://localhost:8080/Admin/Bots/Wizard` +2. Follow the wizard to create a bot with @BotFather +3. Save the bot token and API key + +### 3. Deploy Bot + +```bash +# Using the deployment script +./TeleBot/deploy-bot.sh \ + -n my-bot \ + -t "YOUR_BOT_TOKEN" \ + -k "YOUR_API_KEY" \ + -a "https://api.littleshop.com" + +# Or using Docker directly +docker run -d \ + --name littleshop-bot-sales \ + -e Telegram__BotToken=YOUR_TOKEN \ + -e LittleShop__ApiUrl=https://api.shop.com \ + littleshop/telebot:latest +``` + +## Deployment Methods + +### Method 1: Deployment Script + +The `deploy-bot.sh` script provides an easy way to deploy bots: + +```bash +# Deploy to local Docker +./deploy-bot.sh -n support-bot -t "TOKEN" -k "API_KEY" + +# Deploy to remote host +./deploy-bot.sh -n sales-bot -t "TOKEN" -h ssh://user@server.com + +# Deploy with all options +./deploy-bot.sh \ + -n vip-bot \ + -t "BOT_TOKEN" \ + -k "API_KEY" \ + -a https://api.shop.com \ + -c "ADMIN_CHAT_ID" \ + -e "32_CHAR_ENCRYPTION_KEY" \ + -p "Sarah" \ + -m strict \ + --pull --rm +``` + +### Method 2: Docker Compose (Multiple Bots) + +Deploy multiple bots on the same host: + +```bash +# Copy and configure environment file +cp .env.multi.example .env.multi +# Edit .env.multi with your values + +# Deploy all bots +docker-compose -f docker-compose.multi.yml --env-file .env.multi up -d + +# Deploy specific bot +docker-compose -f docker-compose.multi.yml --env-file .env.multi up -d bot-support + +# View logs +docker-compose -f docker-compose.multi.yml logs -f +``` + +### Method 3: Portainer Stack + +1. **Add Template to Portainer**: + - Go to **App Templates** → **Custom Templates** + - Add the content from `portainer-template.json` + +2. **Deploy from Template**: + - Go to **App Templates** + - Select "LittleShop TeleBot" + - Fill in environment variables + - Deploy + +3. **Or Deploy Stack Directly**: + ```bash + curl -X POST \ + http://portainer:9000/api/stacks \ + -H "X-API-Key: YOUR_PORTAINER_KEY" \ + -F "Name=littleshop-bot" \ + -F "StackFileContent=@docker-compose.yml" \ + -F "Env=@.env" + ``` + +### Method 4: Docker Swarm + +Deploy across a Docker Swarm cluster: + +```bash +# Initialize swarm (if not already) +docker swarm init + +# Create secrets +echo "YOUR_TOKEN" | docker secret create bot_token - +echo "YOUR_API_KEY" | docker secret create bot_api_key - + +# Deploy service +docker service create \ + --name littleshop-bot \ + --secret bot_token \ + --secret bot_api_key \ + --replicas 3 \ + --env Telegram__BotToken_FILE=/run/secrets/bot_token \ + --env BotManager__ApiKey_FILE=/run/secrets/bot_api_key \ + littleshop/telebot:latest +``` + +## Configuration + +### Environment Variables + +| Variable | Description | Required | +|----------|-------------|----------| +| `Telegram__BotToken` | Bot token from @BotFather | ✅ | +| `LittleShop__ApiUrl` | LittleShop API endpoint | ✅ | +| `BotManager__ApiKey` | API key from admin panel | ⭕ | +| `Telegram__AdminChatId` | Admin notifications chat | ⭕ | +| `Database__EncryptionKey` | 32-char encryption key | ⭕ | +| `Privacy__Mode` | strict/moderate/relaxed | ⭕ | + +### Bot Personalities + +Configure different personalities for different bots: + +```yaml +# Support Bot - Helpful and professional +Bot__PersonalityName: "Alan" +Bot__Tone: "professional" + +# Sales Bot - Enthusiastic and engaging +Bot__PersonalityName: "Sarah" +Bot__Tone: "friendly" + +# VIP Bot - Discrete and sophisticated +Bot__PersonalityName: "Emma" +Bot__Tone: "formal" +``` + +### Network Configuration + +#### Same Network as API +```yaml +LittleShop__ApiUrl: http://littleshop-api:8080 +``` + +#### Docker Host Network +```yaml +LittleShop__ApiUrl: http://host.docker.internal:8080 +``` + +#### External API +```yaml +LittleShop__ApiUrl: https://api.littleshop.com +``` + +## Management + +### Monitor Bots + +```bash +# List all bot containers +docker ps --filter "label=com.littleshop.bot=true" + +# Check bot health +docker inspect littleshop-bot-support --format='{{.State.Health.Status}}' + +# View logs +docker logs -f littleshop-bot-support --tail 100 + +# Get metrics +docker stats littleshop-bot-support +``` + +### Update Bots + +```bash +# Pull latest image +docker pull littleshop/telebot:latest + +# Recreate container with new image +docker-compose -f docker-compose.multi.yml pull +docker-compose -f docker-compose.multi.yml up -d + +# Or using deployment script +./deploy-bot.sh -n my-bot -t "TOKEN" --pull --rm +``` + +### Backup & Restore + +```bash +# Backup bot data +docker run --rm \ + -v littleshop-bot-support-data:/data \ + -v $(pwd):/backup \ + alpine tar czf /backup/bot-backup.tar.gz /data + +# Restore bot data +docker run --rm \ + -v littleshop-bot-support-data:/data \ + -v $(pwd):/backup \ + alpine tar xzf /backup/bot-backup.tar.gz -C / +``` + +## Deployment Scenarios + +### Scenario 1: Geographic Distribution + +Deploy bots closer to users for better latency: + +```bash +# EU Bot on European server +ssh eu-server "docker run -d --name bot-eu \ + -e Telegram__BotToken=$EU_TOKEN \ + -e LittleShop__ApiUrl=https://api.shop.com \ + -e TZ=Europe/London \ + littleshop/telebot:latest" + +# US Bot on US server +ssh us-server "docker run -d --name bot-us \ + -e Telegram__BotToken=$US_TOKEN \ + -e LittleShop__ApiUrl=https://api.shop.com \ + -e TZ=America/New_York \ + littleshop/telebot:latest" + +# Asia Bot on Singapore server +ssh asia-server "docker run -d --name bot-asia \ + -e Telegram__BotToken=$ASIA_TOKEN \ + -e LittleShop__ApiUrl=https://api.shop.com \ + -e TZ=Asia/Singapore \ + littleshop/telebot:latest" +``` + +### Scenario 2: Customer Segmentation + +Different bots for different customer types: + +```yaml +# docker-compose.segments.yml +services: + bot-public: + image: littleshop/telebot:latest + environment: + - Privacy__Mode=moderate + - Features__EnableAnalytics=true + + bot-vip: + image: littleshop/telebot:latest + environment: + - Privacy__Mode=strict + - Privacy__EnableTor=true + - Features__EnableOrderMixing=true + + bot-wholesale: + image: littleshop/telebot:latest + environment: + - Features__BulkOrdering=true + - Features__B2BPricing=true +``` + +### Scenario 3: A/B Testing + +Deploy multiple versions for testing: + +```bash +# Version A - Standard features +docker run -d --name bot-version-a \ + -e EXPERIMENT_VERSION=A \ + littleshop/telebot:latest + +# Version B - New features +docker run -d --name bot-version-b \ + -e EXPERIMENT_VERSION=B \ + -e Features__NewCheckout=true \ + littleshop/telebot:v2-beta +``` + +## Security + +### Best Practices + +1. **Use Docker Secrets** for sensitive data: + ```bash + echo "TOKEN" | docker secret create bot_token - + docker service create --secret bot_token ... + ``` + +2. **Network Isolation**: + ```yaml + networks: + frontend: + driver: overlay + encrypted: true + backend: + driver: overlay + internal: true + ``` + +3. **Resource Limits**: + ```yaml + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M + ``` + +4. **Health Checks**: + ```yaml + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/health"] + interval: 30s + timeout: 10s + retries: 3 + ``` + +### TLS/SSL Configuration + +For production deployments with TLS: + +```bash +docker run -d \ + -v /path/to/certs:/certs:ro \ + -e ASPNETCORE_Kestrel__Certificates__Default__Path=/certs/cert.pfx \ + -e ASPNETCORE_Kestrel__Certificates__Default__Password=CERT_PASSWORD \ + -e ASPNETCORE_URLS="https://+:443" \ + littleshop/telebot:latest +``` + +## Troubleshooting + +### Common Issues + +#### Bot Won't Start +```bash +# Check logs +docker logs littleshop-bot --tail 50 + +# Common causes: +# - Invalid bot token +# - Can't reach API +# - Port already in use +``` + +#### Can't Connect to API +```bash +# Test connectivity from container +docker exec littleshop-bot curl http://api-url/health + +# Check DNS resolution +docker exec littleshop-bot nslookup api.shop.com +``` + +#### High Memory Usage +```bash +# Check memory stats +docker stats littleshop-bot + +# Limit memory +docker update --memory 512m littleshop-bot +``` + +### Debug Mode + +Enable debug logging: + +```bash +docker run -d \ + -e Logging__LogLevel__Default=Debug \ + -e Logging__LogLevel__TeleBot=Trace \ + littleshop/telebot:latest +``` + +### Performance Monitoring + +```bash +# CPU and Memory usage +docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" + +# Network I/O +docker exec littleshop-bot netstat -i + +# Disk usage +docker system df -v +``` + +## Advanced Topics + +### Custom Docker Networks + +Create isolated networks for different bot groups: + +```bash +# Create networks +docker network create bots-support --driver overlay +docker network create bots-sales --driver overlay +docker network create bots-vip --driver overlay --opt encrypted + +# Deploy with specific network +docker run -d --network bots-vip ... +``` + +### Load Balancing + +Use multiple bot instances with same token: + +```bash +# Note: Requires webhook mode and load balancer +docker service create \ + --name bot-pool \ + --replicas 5 \ + --publish 8443:8443 \ + -e Telegram__UseWebhook=true \ + littleshop/telebot:latest +``` + +### Monitoring with Prometheus + +```yaml +# Add to docker-compose +prometheus: + image: prom/prometheus + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml + command: + - '--config.file=/etc/prometheus/prometheus.yml' + ports: + - '9090:9090' +``` + +## Support + +For issues or questions: +1. Check container logs: `docker logs ` +2. Verify environment variables +3. Test API connectivity +4. Review admin panel bot status +5. Check the [main deployment guide](DEPLOYMENT.md) + +## Next Steps + +1. **Set up monitoring** - Add Prometheus/Grafana +2. **Implement CI/CD** - Automate deployments +3. **Add backup strategy** - Regular data backups +4. **Scale horizontally** - Add more hosts as needed +5. **Implement geo-routing** - Route users to nearest bot \ No newline at end of file diff --git a/TeleBot/TeleBot/BotConfig.cs b/TeleBot/TeleBot/BotConfig.cs new file mode 100644 index 0000000..d19c3ee --- /dev/null +++ b/TeleBot/TeleBot/BotConfig.cs @@ -0,0 +1,7 @@ +namespace TeleBot +{ + public static class BotConfig + { + public static string BrandName { get; set; } = "Little Shop"; + } +} \ No newline at end of file diff --git a/TeleBot/TeleBot/Controllers/WebhookController.cs b/TeleBot/TeleBot/Controllers/WebhookController.cs new file mode 100644 index 0000000..c887d18 --- /dev/null +++ b/TeleBot/TeleBot/Controllers/WebhookController.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using TeleBot.Services; + +namespace TeleBot.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class WebhookController : ControllerBase + { + private readonly ILogger _logger; + private readonly TelegramBotService _telegramBotService; + private readonly BotManagerService _botManagerService; + private readonly IConfiguration _configuration; + + public WebhookController( + ILogger logger, + TelegramBotService telegramBotService, + BotManagerService botManagerService, + IConfiguration configuration) + { + _logger = logger; + _telegramBotService = telegramBotService; + _botManagerService = botManagerService; + _configuration = configuration; + } + + /// + /// Webhook endpoint for configuration updates from admin panel + /// + [HttpPost("config-update")] + public async Task ConfigurationUpdate([FromBody] ConfigUpdateDto dto) + { + try + { + // Verify the request is authorized (you might want to add API key validation) + var apiKey = Request.Headers["X-Webhook-Key"].ToString(); + var expectedKey = _configuration["Webhook:Secret"]; + + if (!string.IsNullOrEmpty(expectedKey) && apiKey != expectedKey) + { + _logger.LogWarning("Unauthorized webhook request"); + return Unauthorized(); + } + + _logger.LogInformation("Received configuration update via webhook"); + + // Handle different types of updates + if (dto.UpdateType == "bot_token" && !string.IsNullOrEmpty(dto.BotToken)) + { + _logger.LogInformation("Updating bot token via webhook"); + await _telegramBotService.UpdateBotTokenAsync(dto.BotToken); + return Ok(new { success = true, message = "Bot token updated successfully" }); + } + else if (dto.UpdateType == "settings") + { + _logger.LogInformation("Triggering settings sync via webhook"); + // Force a settings sync + var settings = await _botManagerService.GetSettingsAsync(); + if (settings != null) + { + _logger.LogInformation("Settings synced successfully via webhook"); + } + return Ok(new { success = true, message = "Settings synced successfully" }); + } + + return BadRequest(new { success = false, message = "Unknown update type" }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error processing webhook update"); + return StatusCode(500, new { success = false, message = "Internal server error" }); + } + } + + /// + /// Health check endpoint + /// + [HttpGet("health")] + public IActionResult Health() + { + return Ok(new + { + status = "healthy", + timestamp = DateTime.UtcNow, + botKey = !string.IsNullOrEmpty(_configuration["BotManager:ApiKey"]) + }); + } + } + + public class ConfigUpdateDto + { + public string UpdateType { get; set; } = string.Empty; + public string? BotToken { get; set; } + public Dictionary? Settings { get; set; } + } +} \ No newline at end of file diff --git a/TeleBot/TeleBot/Handlers/CallbackHandler.cs b/TeleBot/TeleBot/Handlers/CallbackHandler.cs index b6211b7..c923e9f 100644 --- a/TeleBot/TeleBot/Handlers/CallbackHandler.cs +++ b/TeleBot/TeleBot/Handlers/CallbackHandler.cs @@ -11,6 +11,7 @@ using Telegram.Bot.Types.ReplyMarkups; using TeleBot.Models; using TeleBot.Services; using TeleBot.UI; +using LittleShop.Client.Models; namespace TeleBot.Handlers { @@ -97,7 +98,15 @@ namespace TeleBot.Handlers case "add": await HandleAddToCart(bot, callbackQuery, session, data); break; - + + case "quickbuy": + await HandleQuickBuy(bot, callbackQuery, session, data); + break; + + case "quickbuyvar": + await HandleQuickBuyWithVariation(bot, callbackQuery, session, data); + break; + case "cart": await HandleViewCart(bot, callbackQuery.Message, session); break; @@ -281,7 +290,7 @@ namespace TeleBot.Handlers // Use carousel service to send products with images await _carouselService.SendProductCarouselAsync(bot, message.Chat.Id, products, categoryName, page); - session.State = SessionState.BrowsingProducts; + session.State = SessionState.ViewingProducts; } private async Task HandleProductsPage(ITelegramBotClient bot, Message message, UserSession session, string[] data) @@ -294,7 +303,7 @@ namespace TeleBot.Handlers // Use carousel service to send products with images await _carouselService.SendProductCarouselAsync(bot, message.Chat.Id, products, "All Categories", page); - session.State = SessionState.BrowsingProducts; + session.State = SessionState.ViewingProducts; } private async Task HandleProductDetail(ITelegramBotClient bot, Message message, UserSession session, Guid productId) @@ -336,27 +345,49 @@ namespace TeleBot.Handlers private async Task HandleAddToCart(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session, string[] data) { - // Format: add:productId:quantity + // Format: add:productId:quantity or add:productId:quantity:variationId var productId = Guid.Parse(data[1]); var quantity = int.Parse(data[2]); - + Guid? variationId = data.Length > 3 ? Guid.Parse(data[3]) : null; + var product = await _shopService.GetProductAsync(productId); if (product == null) { await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Product not found", showAlert: true); return; } - - session.Cart.AddItem(productId, product.Name, product.Price, quantity); - + + // If variations exist but none selected, show variation selection + if (variationId == null && product.Variations?.Any() == true) + { + await ShowVariationSelection(bot, callbackQuery.Message!, session, product, quantity); + return; + } + + // Get price based on variation or base product + decimal price = product.Price; + string itemName = product.Name; + if (variationId.HasValue && product.Variations != null) + { + var variation = product.Variations.FirstOrDefault(v => v.Id == variationId); + if (variation != null) + { + price = variation.Price; + itemName = $"{product.Name} ({variation.Name})"; + quantity = variation.Quantity; // Use variation's quantity + } + } + + session.Cart.AddItem(productId, itemName, price, quantity, variationId); + await bot.AnswerCallbackQueryAsync( callbackQuery.Id, - $"✅ Added {quantity}x {product.Name} to cart", + $"✅ Added {quantity}x {itemName} to cart", showAlert: false ); - - // Show cart - await HandleViewCart(bot, callbackQuery.Message!, session); + + // Send new cart message instead of editing + await SendNewCartMessage(bot, callbackQuery.Message!.Chat.Id, session); } private async Task HandleViewCart(ITelegramBotClient bot, Message message, UserSession session) @@ -370,6 +401,149 @@ namespace TeleBot.Handlers ); session.State = SessionState.ViewingCart; } + + private async Task SendNewCartMessage(ITelegramBotClient bot, long chatId, UserSession session) + { + await bot.SendTextMessageAsync( + chatId, + MessageFormatter.FormatCart(session.Cart), + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.CartMenu(session.Cart) + ); + session.State = SessionState.ViewingCart; + } + + private async Task ShowVariationSelection(ITelegramBotClient bot, Message message, UserSession session, Product product, int defaultQuantity) + { + var text = MessageFormatter.FormatProductWithVariations(product); + await bot.SendTextMessageAsync( + message.Chat.Id, + text, + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.ProductVariationsMenu(product, defaultQuantity) + ); + } + + private async Task HandleQuickBuy(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session, string[] data) + { + // Format: quickbuy:productId:quantity + var productId = Guid.Parse(data[1]); + var quantity = int.Parse(data[2]); + + var product = await _shopService.GetProductAsync(productId); + if (product == null) + { + await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Product not found", showAlert: true); + return; + } + + // If variations exist, show variation selection with quickbuy flow + if (product.Variations?.Any() == true) + { + await ShowVariationSelectionForQuickBuy(bot, callbackQuery.Message!, session, product); + return; + } + + // Add to cart with base product + session.Cart.AddItem(productId, product.Name, product.Price, quantity, null); + + await bot.AnswerCallbackQueryAsync( + callbackQuery.Id, + $"✅ Added {quantity}x {product.Name} to cart", + showAlert: false + ); + + // Send cart summary in new message + await bot.SendTextMessageAsync( + callbackQuery.Message!.Chat.Id, + MessageFormatter.FormatCart(session.Cart), + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.CartMenu(session.Cart) + ); + + // Immediately proceed to checkout + await Task.Delay(500); // Small delay for better UX + await HandleCheckout(bot, callbackQuery.Message, session); + } + + private async Task ShowVariationSelectionForQuickBuy(ITelegramBotClient bot, Message message, UserSession session, Product product) + { + var text = MessageFormatter.FormatProductWithVariations(product); + var buttons = new List(); + + if (product.Variations?.Any() == true) + { + // Add buttons for each variation with quickbuy flow + foreach (var variation in product.Variations.OrderBy(v => v.Quantity)) + { + var label = variation.Quantity > 1 + ? $"{variation.Name} - ${variation.Price:F2} (${variation.PricePerUnit:F2}/ea)" + : $"{variation.Name} - ${variation.Price:F2}"; + + buttons.Add(new[] + { + InlineKeyboardButton.WithCallbackData(label, $"quickbuyvar:{product.Id}:{variation.Quantity}:{variation.Id}") + }); + } + } + + // Add back button + buttons.Add(new[] + { + InlineKeyboardButton.WithCallbackData("⬅️ Back", "menu") + }); + + await bot.SendTextMessageAsync( + message.Chat.Id, + text + "\n\n*Select an option for quick checkout:*", + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: new InlineKeyboardMarkup(buttons) + ); + } + + private async Task HandleQuickBuyWithVariation(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session, string[] data) + { + // Format: quickbuyvar:productId:quantity:variationId + var productId = Guid.Parse(data[1]); + var quantity = int.Parse(data[2]); + var variationId = Guid.Parse(data[3]); + + var product = await _shopService.GetProductAsync(productId); + if (product == null) + { + await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Product not found", showAlert: true); + return; + } + + var variation = product.Variations?.FirstOrDefault(v => v.Id == variationId); + if (variation == null) + { + await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Variation not found", showAlert: true); + return; + } + + // Add to cart with variation + var itemName = $"{product.Name} ({variation.Name})"; + session.Cart.AddItem(productId, itemName, variation.Price, variation.Quantity, variationId); + + await bot.AnswerCallbackQueryAsync( + callbackQuery.Id, + $"✅ Added {variation.Quantity}x {itemName} to cart", + showAlert: false + ); + + // Send cart summary in new message + await bot.SendTextMessageAsync( + callbackQuery.Message!.Chat.Id, + MessageFormatter.FormatCart(session.Cart), + parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown, + replyMarkup: MenuBuilder.CartMenu(session.Cart) + ); + + // Immediately proceed to checkout + await Task.Delay(500); // Small delay for better UX + await HandleCheckout(bot, callbackQuery.Message, session); + } private async Task HandleRemoveFromCart(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session, Guid productId) { @@ -406,18 +580,18 @@ namespace TeleBot.Handlers await bot.AnswerCallbackQueryAsync("", "Your cart is empty", showAlert: true); return; } - + // Initialize order flow session.OrderFlow = new OrderFlowData { UsePGPEncryption = session.Privacy.RequirePGP }; - + session.State = SessionState.CheckoutFlow; - - await bot.EditMessageTextAsync( + + // Send new message for checkout instead of editing + await bot.SendTextMessageAsync( message.Chat.Id, - message.MessageId, "📦 *Checkout - Step 1/5*\n\n" + "Please enter your shipping name:\n\n" + "_Reply to this message with your name_", @@ -459,9 +633,9 @@ namespace TeleBot.Handlers // Store order ID for payment session.TempData["current_order_id"] = order.Id; - // Show payment options - var currencies = _configuration.GetSection("Cryptocurrencies").Get>() - ?? new List { "BTC", "XMR", "USDT", "LTC" }; + // Show payment options - only safe currencies with BTCPay Server support + var currencies = _configuration.GetSection("Cryptocurrencies").Get>() + ?? new List { "BTC", "XMR", "LTC", "DASH" }; await bot.EditMessageTextAsync( message.Chat.Id, diff --git a/TeleBot/TeleBot/Handlers/CommandHandler.cs b/TeleBot/TeleBot/Handlers/CommandHandler.cs index 2b1d41d..2e7489d 100644 --- a/TeleBot/TeleBot/Handlers/CommandHandler.cs +++ b/TeleBot/TeleBot/Handlers/CommandHandler.cs @@ -189,7 +189,7 @@ namespace TeleBot.Handlers // Send products as carousel with images await _carouselService.SendProductCarouselAsync(bot, message.Chat.Id, products, categoryName, 1); - session.State = Models.SessionState.BrowsingProducts; + session.State = Models.SessionState.ViewingProducts; } catch (Exception ex) { diff --git a/TeleBot/TeleBot/Models/ShoppingCart.cs b/TeleBot/TeleBot/Models/ShoppingCart.cs index 487e70d..c5a65a3 100644 --- a/TeleBot/TeleBot/Models/ShoppingCart.cs +++ b/TeleBot/TeleBot/Models/ShoppingCart.cs @@ -11,10 +11,11 @@ namespace TeleBot.Models public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; - public void AddItem(Guid productId, string productName, decimal price, int quantity = 1) + public void AddItem(Guid productId, string productName, decimal price, int quantity = 1, Guid? variationId = null) { - var existingItem = Items.FirstOrDefault(i => i.ProductId == productId); - + var existingItem = Items.FirstOrDefault(i => + i.ProductId == productId && i.VariationId == variationId); + if (existingItem != null) { existingItem.Quantity += quantity; @@ -25,6 +26,7 @@ namespace TeleBot.Models var newItem = new CartItem { ProductId = productId, + VariationId = variationId, ProductName = productName, UnitPrice = price, Quantity = quantity @@ -32,7 +34,7 @@ namespace TeleBot.Models newItem.UpdateTotalPrice(); // Ensure total is calculated after all properties are set Items.Add(newItem); } - + UpdatedAt = DateTime.UtcNow; } @@ -85,6 +87,7 @@ namespace TeleBot.Models public class CartItem { public Guid ProductId { get; set; } + public Guid? VariationId { get; set; } public string ProductName { get; set; } = string.Empty; public int Quantity { get; set; } public decimal UnitPrice { get; set; } diff --git a/TeleBot/TeleBot/Program.cs b/TeleBot/TeleBot/Program.cs index 29643d9..c3e6146 100644 --- a/TeleBot/TeleBot/Program.cs +++ b/TeleBot/TeleBot/Program.cs @@ -4,6 +4,8 @@ using System.Threading.Tasks; using Hangfire; using Hangfire.LiteDB; using LittleShop.Client.Extensions; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -14,8 +16,7 @@ using TeleBot; using TeleBot.Handlers; using TeleBot.Services; -var builder = Host.CreateApplicationBuilder(args); -public static string BrandName ?? "Little Shop"; +var builder = WebApplication.CreateBuilder(args); // Configuration builder.Configuration .SetBasePath(Directory.GetCurrentDirectory()) @@ -23,6 +24,9 @@ builder.Configuration .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); +// Add MVC Controllers for webhook endpoints +builder.Services.AddControllers(); + // Serilog Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() @@ -49,7 +53,8 @@ builder.Services.AddLittleShopClient(options => options.TimeoutSeconds = 30; options.MaxRetryAttempts = 3; - BrandName = config["LittleShop.BrandName"] ?? "Little Shop"; + // Set the brand name globally + BotConfig.BrandName = config["LittleShop:BrandName"] ?? "Little Shop"; }); builder.Services.AddSingleton(); @@ -80,10 +85,10 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -// Bot Manager Service (for registration and metrics) +// Bot Manager Service (for registration and metrics) - Single instance builder.Services.AddHttpClient(); builder.Services.AddSingleton(); -builder.Services.AddHostedService(); +builder.Services.AddHostedService(provider => provider.GetRequiredService()); // Message Delivery Service - Single instance builder.Services.AddSingleton(); @@ -94,11 +99,26 @@ builder.Services.AddHostedService(sp => sp.GetRequiredSe builder.Services.AddHttpClient(); builder.Services.AddSingleton(); -// Bot Service -builder.Services.AddHostedService(); +// Bot Service - Single instance +builder.Services.AddSingleton(); +builder.Services.AddHostedService(provider => provider.GetRequiredService()); -// Build and run -var host = builder.Build(); +// Build the application +var app = builder.Build(); + +// Connect the services +var botManagerService = app.Services.GetRequiredService(); +var telegramBotService = app.Services.GetRequiredService(); +botManagerService.SetTelegramBotService(telegramBotService); + +// Configure the HTTP request pipeline +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +} + +app.UseRouting(); +app.MapControllers(); try { @@ -106,8 +126,9 @@ try Log.Information("Privacy Mode: {PrivacyMode}", builder.Configuration["Privacy:Mode"]); Log.Information("Ephemeral by Default: {Ephemeral}", builder.Configuration["Privacy:EphemeralByDefault"]); Log.Information("Tor Enabled: {Tor}", builder.Configuration["Privacy:EnableTor"]); - - await host.RunAsync(); + Log.Information("Webhook endpoints available at /api/webhook"); + + await app.RunAsync(); } catch (Exception ex) { diff --git a/TeleBot/TeleBot/Services/BotManagerService.cs b/TeleBot/TeleBot/Services/BotManagerService.cs index c6b10e2..8c06eab 100644 --- a/TeleBot/TeleBot/Services/BotManagerService.cs +++ b/TeleBot/TeleBot/Services/BotManagerService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -20,9 +21,12 @@ namespace TeleBot.Services private readonly SessionManager _sessionManager; private Timer? _heartbeatTimer; private Timer? _metricsTimer; + private Timer? _settingsSyncTimer; private string? _botKey; private Guid? _botId; private readonly Dictionary _metricsBuffer; + private TelegramBotService? _telegramBotService; + private string? _lastKnownBotToken; public BotManagerService( IConfiguration configuration, @@ -37,6 +41,11 @@ namespace TeleBot.Services _metricsBuffer = new Dictionary(); } + public void SetTelegramBotService(TelegramBotService telegramBotService) + { + _telegramBotService = telegramBotService; + } + public async Task StartAsync(CancellationToken cancellationToken) { try @@ -64,6 +73,9 @@ namespace TeleBot.Services // Start metrics timer (every 60 seconds) _metricsTimer = new Timer(SendMetrics, null, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60)); + // Start settings sync timer (every 5 minutes) + _settingsSyncTimer = new Timer(SyncSettingsWithBotUpdate, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(5)); + _logger.LogInformation("Bot manager service started successfully"); } catch (Exception ex) @@ -76,10 +88,11 @@ namespace TeleBot.Services { _heartbeatTimer?.Change(Timeout.Infinite, 0); _metricsTimer?.Change(Timeout.Infinite, 0); - + _settingsSyncTimer?.Change(Timeout.Infinite, 0); + // Send final metrics before stopping SendMetrics(null); - + _logger.LogInformation("Bot manager service stopped"); return Task.CompletedTask; } @@ -161,23 +174,42 @@ namespace TeleBot.Services { if (string.IsNullOrEmpty(_botKey)) return; - var apiUrl = _configuration["LittleShop:ApiUrl"]; - _httpClient.DefaultRequestHeaders.Clear(); - _httpClient.DefaultRequestHeaders.Add("X-Bot-Key", _botKey); - - var response = await _httpClient.GetAsync($"{apiUrl}/api/bots/settings"); - - if (response.IsSuccessStatusCode) + var settings = await GetSettingsAsync(); + if (settings != null) { - var settingsJson = await response.Content.ReadAsStringAsync(); - var settings = JsonSerializer.Deserialize>(settingsJson); - // Apply settings to configuration // This would update the running configuration with server settings _logger.LogInformation("Settings synced from server"); } } + public async Task?> GetSettingsAsync() + { + if (string.IsNullOrEmpty(_botKey)) return null; + + try + { + var apiUrl = _configuration["LittleShop:ApiUrl"]; + _httpClient.DefaultRequestHeaders.Clear(); + _httpClient.DefaultRequestHeaders.Add("X-Bot-Key", _botKey); + + var response = await _httpClient.GetAsync($"{apiUrl}/api/bots/settings"); + + if (response.IsSuccessStatusCode) + { + var settingsJson = await response.Content.ReadAsStringAsync(); + var settings = JsonSerializer.Deserialize>(settingsJson); + return settings; + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to fetch settings from API"); + } + + return null; + } + private async void SendHeartbeat(object? state) { if (string.IsNullOrEmpty(_botKey)) return; @@ -350,10 +382,45 @@ namespace TeleBot.Services }; } + private async void SyncSettingsWithBotUpdate(object? state) + { + try + { + var settings = await GetSettingsAsync(); + if (settings != null && settings.ContainsKey("telegram")) + { + if (settings["telegram"] is JsonElement telegramElement) + { + var telegramSettings = telegramElement.EnumerateObject().ToDictionary(p => p.Name, p => p.Value.ToString()); + if (telegramSettings.TryGetValue("botToken", out var token)) + { + // Check if token has changed + if (!string.IsNullOrEmpty(token) && token != _lastKnownBotToken) + { + _logger.LogInformation("Bot token has changed. Updating bot..."); + _lastKnownBotToken = token; + + // Update the TelegramBotService if available + if (_telegramBotService != null) + { + await _telegramBotService.UpdateBotTokenAsync(token); + } + } + } + } + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to sync settings with bot update"); + } + } + public void Dispose() { _heartbeatTimer?.Dispose(); _metricsTimer?.Dispose(); + _settingsSyncTimer?.Dispose(); } // DTOs for API responses diff --git a/TeleBot/TeleBot/Services/ProductCarouselService.cs b/TeleBot/TeleBot/Services/ProductCarouselService.cs index 34d36f1..d475a77 100644 --- a/TeleBot/TeleBot/Services/ProductCarouselService.cs +++ b/TeleBot/TeleBot/Services/ProductCarouselService.cs @@ -9,8 +9,10 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Telegram.Bot; using Telegram.Bot.Types; -using Telegram.Bot.Types.InputFiles; +// InputFiles namespace no longer exists in newer Telegram.Bot versions +// using Telegram.Bot.Types.InputFiles; using Telegram.Bot.Types.ReplyMarkups; +using TeleBot.UI; namespace TeleBot.Services { @@ -18,7 +20,7 @@ namespace TeleBot.Services { Task SendProductCarouselAsync(ITelegramBotClient botClient, long chatId, PagedResult products, string? categoryName = null, int currentPage = 1); Task SendSingleProductWithImageAsync(ITelegramBotClient botClient, long chatId, Product product); - Task GetProductImageAsync(Product product); + Task GetProductImageAsync(Product product); Task IsImageUrlValidAsync(string imageUrl); } @@ -234,7 +236,7 @@ namespace TeleBot.Services } } - public async Task GetProductImageAsync(Product product) + public async Task GetProductImageAsync(Product product) { try { @@ -256,16 +258,16 @@ namespace TeleBot.Services var cacheKey = $"{product.Id}_{photo.Id}"; var cachedPath = Path.Combine(_imageCachePath, $"{cacheKey}.jpg"); - if (File.Exists(cachedPath)) + if (System.IO.File.Exists(cachedPath)) { - return new InputOnlineFile(File.OpenRead(cachedPath), $"{product.Name}.jpg"); + return InputFile.FromStream(System.IO.File.OpenRead(cachedPath), $"{product.Name}.jpg"); } // Download and cache the image var imageBytes = await _httpClient.GetByteArrayAsync(imageUrl); - await File.WriteAllBytesAsync(cachedPath, imageBytes); + await System.IO.File.WriteAllBytesAsync(cachedPath, imageBytes); - return new InputOnlineFile(File.OpenRead(cachedPath), $"{product.Name}.jpg"); + return InputFile.FromStream(System.IO.File.OpenRead(cachedPath), $"{product.Name}.jpg"); } catch (Exception ex) { @@ -281,7 +283,8 @@ namespace TeleBot.Services if (string.IsNullOrEmpty(imageUrl)) return false; - var response = await _httpClient.HeadAsync(imageUrl); + using var request = new HttpRequestMessage(HttpMethod.Head, imageUrl); + var response = await _httpClient.SendAsync(request); return response.IsSuccessStatusCode && response.Content.Headers.ContentType?.MediaType?.StartsWith("image/") == true; } diff --git a/TeleBot/TeleBot/TelegramBotService.cs b/TeleBot/TeleBot/TelegramBotService.cs index 4218e26..c4385ac 100644 --- a/TeleBot/TeleBot/TelegramBotService.cs +++ b/TeleBot/TeleBot/TelegramBotService.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; @@ -24,9 +26,11 @@ namespace TeleBot private readonly ICallbackHandler _callbackHandler; private readonly IMessageHandler _messageHandler; private readonly IMessageDeliveryService _messageDeliveryService; + private readonly BotManagerService _botManagerService; private ITelegramBotClient? _botClient; private CancellationTokenSource? _cancellationTokenSource; - + private string? _currentBotToken; + public TelegramBotService( IConfiguration configuration, ILogger logger, @@ -34,7 +38,8 @@ namespace TeleBot ICommandHandler commandHandler, ICallbackHandler callbackHandler, IMessageHandler messageHandler, - IMessageDeliveryService messageDeliveryService) + IMessageDeliveryService messageDeliveryService, + BotManagerService botManagerService) { _configuration = configuration; _logger = logger; @@ -43,16 +48,27 @@ namespace TeleBot _callbackHandler = callbackHandler; _messageHandler = messageHandler; _messageDeliveryService = messageDeliveryService; + _botManagerService = botManagerService; } - + public async Task StartAsync(CancellationToken cancellationToken) { - var botToken = _configuration["Telegram:BotToken"]; + // Try to get bot token from API first via BotManagerService + var botToken = await GetBotTokenAsync(); + + // Fallback to configuration if API doesn't provide token + if (string.IsNullOrEmpty(botToken)) + { + botToken = _configuration["Telegram:BotToken"]; + } + if (string.IsNullOrEmpty(botToken) || botToken == "YOUR_BOT_TOKEN_HERE") { - _logger.LogError("Bot token not configured. Please set Telegram:BotToken in appsettings.json"); + _logger.LogError("Bot token not configured. Please either register via admin panel or set Telegram:BotToken in appsettings.json"); return; } + + _currentBotToken = botToken; _botClient = new TelegramBotClient(botToken); _cancellationTokenSource = new CancellationTokenSource(); @@ -128,9 +144,82 @@ namespace TeleBot ApiRequestException apiException => $"Telegram API Error: [{apiException.ErrorCode}] {apiException.Message}", _ => exception.ToString() }; - + _logger.LogError(exception, "Bot error: {ErrorMessage}", errorMessage); return Task.CompletedTask; } + + private async Task GetBotTokenAsync() + { + try + { + // Check if we have a bot key stored + var botKey = _configuration["BotManager:ApiKey"]; + if (string.IsNullOrEmpty(botKey)) + { + _logger.LogInformation("No bot key configured. Bot will need to register first or use local token."); + return null; + } + + // Fetch settings from API + var settings = await _botManagerService.GetSettingsAsync(); + if (settings != null && settings.ContainsKey("telegram")) + { + if (settings["telegram"] is JsonElement telegramElement) + { + var telegramSettings = telegramElement.EnumerateObject().ToDictionary(p => p.Name, p => p.Value.ToString()); + if (telegramSettings.TryGetValue("botToken", out var token)) + { + _logger.LogInformation("Bot token fetched from admin panel successfully"); + return token; + } + } + } + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to fetch bot token from API. Will use local configuration."); + } + + return null; + } + + public async Task UpdateBotTokenAsync(string newToken) + { + if (_botClient != null && _currentBotToken != newToken) + { + _logger.LogInformation("Updating bot token and restarting bot..."); + + // Stop current bot + _cancellationTokenSource?.Cancel(); + + // Create new bot client with new token + _currentBotToken = newToken; + _botClient = new TelegramBotClient(newToken); + _cancellationTokenSource = new CancellationTokenSource(); + + var receiverOptions = new ReceiverOptions + { + AllowedUpdates = Array.Empty(), + ThrowPendingUpdates = true + }; + + _botClient.StartReceiving( + HandleUpdateAsync, + HandleErrorAsync, + receiverOptions, + cancellationToken: _cancellationTokenSource.Token + ); + + var me = await _botClient.GetMeAsync(); + _logger.LogInformation("Bot restarted with new token: @{Username} ({Id})", me.Username, me.Id); + + // Update message delivery service + if (_messageDeliveryService is MessageDeliveryService deliveryService) + { + deliveryService.SetBotClient(_botClient); + } + } + } } } \ No newline at end of file diff --git a/TeleBot/TeleBot/TestCarousel.cs b/TeleBot/TeleBot/TestCarousel.cs index 36d0fdf..0684434 100644 --- a/TeleBot/TeleBot/TestCarousel.cs +++ b/TeleBot/TeleBot/TestCarousel.cs @@ -59,7 +59,7 @@ namespace TeleBot { Id = Guid.NewGuid(), Url = "https://via.placeholder.com/300x200.jpg", - IsMain = true + SortOrder = 0 // Use SortOrder = 0 to indicate main photo } } }; diff --git a/TeleBot/TeleBot/UI/MenuBuilder.cs b/TeleBot/TeleBot/UI/MenuBuilder.cs index eb74f5c..575d09f 100644 --- a/TeleBot/TeleBot/UI/MenuBuilder.cs +++ b/TeleBot/TeleBot/UI/MenuBuilder.cs @@ -328,13 +328,50 @@ namespace TeleBot.UI { return new InlineKeyboardMarkup(new[] { - new[] { - InlineKeyboardButton.WithCallbackData("🛒 Buy Now", $"add:{productId}:1"), + new[] { + InlineKeyboardButton.WithCallbackData("🛒 Quick Buy", $"quickbuy:{productId}:1"), InlineKeyboardButton.WithCallbackData("📄 Details", $"product:{productId}") } }); } + public static InlineKeyboardMarkup ProductVariationsMenu(Product product, int defaultQuantity = 1) + { + var buttons = new List(); + + if (product.Variations?.Any() == true) + { + // Add a button for each variation + foreach (var variation in product.Variations.OrderBy(v => v.Quantity)) + { + var label = variation.Quantity > 1 + ? $"{variation.Name} - ${variation.Price:F2} (${variation.PricePerUnit:F2}/ea)" + : $"{variation.Name} - ${variation.Price:F2}"; + + buttons.Add(new[] + { + InlineKeyboardButton.WithCallbackData(label, $"add:{product.Id}:{variation.Quantity}:{variation.Id}") + }); + } + } + else + { + // No variations, just show regular add to cart + buttons.Add(new[] + { + InlineKeyboardButton.WithCallbackData($"Add to Cart - ${product.Price:F2}", $"add:{product.Id}:{defaultQuantity}") + }); + } + + // Add back button + buttons.Add(new[] + { + InlineKeyboardButton.WithCallbackData("⬅️ Back", "menu") + }); + + return new InlineKeyboardMarkup(buttons); + } + public static InlineKeyboardMarkup CategoryNavigationMenu(Guid? categoryId) { return new InlineKeyboardMarkup(new[] diff --git a/TeleBot/TeleBot/UI/MessageFormatter.cs b/TeleBot/TeleBot/UI/MessageFormatter.cs index 205293f..c3646bf 100644 --- a/TeleBot/TeleBot/UI/MessageFormatter.cs +++ b/TeleBot/TeleBot/UI/MessageFormatter.cs @@ -12,13 +12,13 @@ namespace TeleBot.UI { if (isReturning) { - return $"🔒 *Welcome back to {Program.BrandName}*\n\n" + + return $"🔒 *Welcome back to {BotConfig.BrandName}*\n\n" + "Your privacy is our priority. All sessions are ephemeral by default.\n\n" + "🖼️ *New Feature:* Browse products with beautiful image carousels!\n\n" + "How can I help you today?"; } - return $"🔒 *Welcome to {Program.BrandName}*\n\n" + + return $"🔒 *Welcome to {BotConfig.BrandName}*\n\n" + "🛡️ *Your Privacy Matters:*\n" + "• No account required\n" + "• Ephemeral sessions by default\n" + @@ -83,43 +83,93 @@ namespace TeleBot.UI public static string FormatSingleProduct(Product product) { var sb = new StringBuilder(); - + sb.AppendLine($"🛍️ *{product.Name}*"); - sb.AppendLine($"💰 £{product.Price:F2}"); - + + // Show variations if available + if (product.Variations?.Any() == true) + { + var lowestPrice = product.Variations.Min(v => v.PricePerUnit); + sb.AppendLine($"💰 From £{lowestPrice:F2}"); + sb.AppendLine($"📦 _{product.Variations.Count} options available_"); + } + else + { + sb.AppendLine($"💰 £{product.Price:F2}"); + } + if (!string.IsNullOrEmpty(product.Description)) { // Truncate description for bubble format - var desc = product.Description.Length > 100 + var desc = product.Description.Length > 100 ? product.Description.Substring(0, 100) + "..." : product.Description; sb.AppendLine($"\n_{desc}_"); } - + return sb.ToString(); } public static string FormatProductDetail(Product product) { var sb = new StringBuilder(); - + sb.AppendLine($"🛍️ *{product.Name}*\n"); sb.AppendLine($"💰 *Price:* ${product.Price:F2}"); sb.AppendLine($"⚖️ *Weight:* {product.Weight} {product.WeightUnit}"); sb.AppendLine($"📁 *Category:* {product.CategoryName ?? "Uncategorized"}"); - + if (!string.IsNullOrEmpty(product.Description)) { sb.AppendLine($"\n📝 *Description:*\n{product.Description}"); } - + if (product.Photos.Any()) { sb.AppendLine($"\n🖼️ _{product.Photos.Count} photo(s) available_"); } - + sb.AppendLine("\nSelect quantity and add to cart:"); - + + return sb.ToString(); + } + + public static string FormatProductWithVariations(Product product) + { + var sb = new StringBuilder(); + + sb.AppendLine($"🛍️ *{product.Name}*\n"); + + if (product.Variations?.Any() == true) + { + sb.AppendLine("📦 *Available Options:*\n"); + foreach (var variation in product.Variations.OrderBy(v => v.Quantity)) + { + var savings = variation.Quantity > 1 + ? $" (${variation.PricePerUnit:F2} each)" + : ""; + sb.AppendLine($"• *{variation.Name}*: ${variation.Price:F2}{savings}"); + if (!string.IsNullOrEmpty(variation.Description)) + { + sb.AppendLine($" _{variation.Description}_"); + } + } + } + else + { + sb.AppendLine($"💰 *Price:* ${product.Price:F2}"); + } + + sb.AppendLine($"\n⚖️ *Weight:* {product.Weight} {product.WeightUnit}"); + sb.AppendLine($"📁 *Category:* {product.CategoryName ?? "Uncategorized"}"); + + if (!string.IsNullOrEmpty(product.Description)) + { + sb.AppendLine($"\n📝 *Description:*\n{product.Description}"); + } + + sb.AppendLine("\n*Select an option to add to cart:*"); + return sb.ToString(); } @@ -275,7 +325,7 @@ namespace TeleBot.UI "/cancel - Cancel current operation\n" + "/delete - Delete all your data\n" + "/tor - Get Tor onion address\n" + - "/help - Show this help message\n\n" + "/help - Show this help message\n\n"; } public static string FormatPrivacyPolicy() diff --git a/TeleBot/TeleBot/appsettings.json b/TeleBot/TeleBot/appsettings.json index 12069b2..ffeb04b 100644 --- a/TeleBot/TeleBot/appsettings.json +++ b/TeleBot/TeleBot/appsettings.json @@ -6,16 +6,21 @@ }, "BotManager": { "ApiKey": "", - "Comment": "This will be populated after first registration" + "Comment": "This will be populated after first registration with admin panel" }, "Telegram": { - "BotToken": "7880403661:AAGma1wAyoHsmG45iO6VvHCqzimhJX1pp14", + "BotToken": "", "AdminChatId": "", "WebhookUrl": "", - "UseWebhook": false + "UseWebhook": false, + "Comment": "Bot token will be fetched from admin panel API if BotManager:ApiKey is set" + }, + "Webhook": { + "Secret": "", + "Comment": "Optional secret key for webhook authentication" }, "LittleShop": { - "ApiUrl": "https://localhost:5001", + "ApiUrl": "http://localhost:8080", "OnionUrl": "", "Username": "admin", "Password": "admin", @@ -66,11 +71,14 @@ "Cryptocurrencies": [ "BTC", "XMR", - "USDT", "LTC", - "ETH", - "ZEC", - "DASH", - "DOGE" - ] + "DASH" + ], + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://localhost:5010" + } + } + } } \ No newline at end of file diff --git a/TeleBot/deploy-bot.sh b/TeleBot/deploy-bot.sh new file mode 100755 index 0000000..4704e0e --- /dev/null +++ b/TeleBot/deploy-bot.sh @@ -0,0 +1,253 @@ +#!/bin/bash + +# LittleShop TeleBot Docker Deployment Script +# Usage: ./deploy-bot.sh [OPTIONS] +# +# This script helps deploy TeleBot instances to local or remote Docker hosts + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Default values +DOCKER_IMAGE="littleshop/telebot:latest" +CONTAINER_PREFIX="littleshop-bot" +API_URL="${LITTLESHOP_API_URL:-http://localhost:8080}" +RESTART_POLICY="unless-stopped" +DOCKER_HOST="" + +# Function to print colored output +print_message() { + local color=$1 + local message=$2 + echo -e "${color}${message}${NC}" +} + +# Function to show usage +show_usage() { + cat << EOF +Usage: $0 [OPTIONS] + +Deploy LittleShop TeleBot to Docker hosts + +OPTIONS: + -n, --name NAME Bot container name (required) + -t, --token TOKEN Telegram bot token (required) + -k, --api-key KEY Bot API key from admin panel + -a, --api-url URL LittleShop API URL (default: $API_URL) + -h, --host HOST Docker host (e.g., ssh://user@host or tcp://host:2376) + -c, --chat-id ID Admin chat ID for notifications + -e, --encryption-key KEY Database encryption key + -p, --personality NAME Bot personality name + -m, --mode MODE Privacy mode (strict|moderate|relaxed) + -i, --image IMAGE Docker image (default: $DOCKER_IMAGE) + -r, --restart POLICY Restart policy (default: $RESTART_POLICY) + -d, --detach Run in detached mode (default) + -l, --logs Follow logs after deployment + --pull Pull latest image before deployment + --rm Remove existing container before deployment + --help Show this help message + +EXAMPLES: + # Deploy to local Docker + $0 -n support-bot -t "TOKEN" -k "API_KEY" + + # Deploy to remote host via SSH + $0 -n sales-bot -t "TOKEN" -k "API_KEY" -h ssh://user@server.com + + # Deploy with all options + $0 -n vip-bot -t "TOKEN" -k "API_KEY" -a https://api.shop.com \\ + -c "123456789" -e "32_char_encryption_key_here" \\ + -p "Sarah" -m strict --pull --rm + + # Deploy multiple bots using environment file + source .env.bot1 && $0 -n bot1 -t "\$BOT_TOKEN" -k "\$API_KEY" + source .env.bot2 && $0 -n bot2 -t "\$BOT_TOKEN" -k "\$API_KEY" + +EOF +} + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + -n|--name) + BOT_NAME="$2" + shift 2 + ;; + -t|--token) + BOT_TOKEN="$2" + shift 2 + ;; + -k|--api-key) + API_KEY="$2" + shift 2 + ;; + -a|--api-url) + API_URL="$2" + shift 2 + ;; + -h|--host) + DOCKER_HOST="$2" + shift 2 + ;; + -c|--chat-id) + ADMIN_CHAT_ID="$2" + shift 2 + ;; + -e|--encryption-key) + ENCRYPTION_KEY="$2" + shift 2 + ;; + -p|--personality) + PERSONALITY="$2" + shift 2 + ;; + -m|--mode) + PRIVACY_MODE="$2" + shift 2 + ;; + -i|--image) + DOCKER_IMAGE="$2" + shift 2 + ;; + -r|--restart) + RESTART_POLICY="$2" + shift 2 + ;; + -l|--logs) + FOLLOW_LOGS=true + shift + ;; + --pull) + PULL_IMAGE=true + shift + ;; + --rm) + REMOVE_EXISTING=true + shift + ;; + --help) + show_usage + exit 0 + ;; + *) + print_message "$RED" "Unknown option: $1" + show_usage + exit 1 + ;; + esac +done + +# Validate required parameters +if [ -z "$BOT_NAME" ]; then + print_message "$RED" "Error: Bot name is required (-n/--name)" + exit 1 +fi + +if [ -z "$BOT_TOKEN" ]; then + print_message "$RED" "Error: Bot token is required (-t/--token)" + exit 1 +fi + +# Set container name +CONTAINER_NAME="${CONTAINER_PREFIX}-${BOT_NAME}" + +# Build Docker command +DOCKER_CMD="docker" +if [ -n "$DOCKER_HOST" ]; then + export DOCKER_HOST="$DOCKER_HOST" + print_message "$YELLOW" "Deploying to remote host: $DOCKER_HOST" +fi + +# Pull latest image if requested +if [ "$PULL_IMAGE" = true ]; then + print_message "$YELLOW" "Pulling latest image: $DOCKER_IMAGE" + $DOCKER_CMD pull "$DOCKER_IMAGE" +fi + +# Remove existing container if requested +if [ "$REMOVE_EXISTING" = true ]; then + if $DOCKER_CMD ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + print_message "$YELLOW" "Removing existing container: $CONTAINER_NAME" + $DOCKER_CMD rm -f "$CONTAINER_NAME" + fi +fi + +# Build environment variables +ENV_VARS=( + "-e DOTNET_ENVIRONMENT=Production" + "-e TZ=UTC" + "-e Telegram__BotToken=$BOT_TOKEN" + "-e LittleShop__ApiUrl=$API_URL" + "-e Database__ConnectionString=Filename=/app/data/telebot.db;Password=;" +) + +# Add optional environment variables +[ -n "$API_KEY" ] && ENV_VARS+=("-e BotManager__ApiKey=$API_KEY") +[ -n "$ADMIN_CHAT_ID" ] && ENV_VARS+=("-e Telegram__AdminChatId=$ADMIN_CHAT_ID") +[ -n "$ENCRYPTION_KEY" ] && ENV_VARS+=("-e Database__EncryptionKey=$ENCRYPTION_KEY") +[ -n "$PERSONALITY" ] && ENV_VARS+=("-e Bot__PersonalityName=$PERSONALITY") +[ -n "$PRIVACY_MODE" ] && ENV_VARS+=("-e Privacy__Mode=$PRIVACY_MODE") + +# Default privacy settings +ENV_VARS+=( + "-e Privacy__DataRetentionHours=24" + "-e Privacy__SessionTimeoutMinutes=30" + "-e Privacy__EphemeralByDefault=true" + "-e Features__EnableQRCodes=true" + "-e Features__EnablePGPEncryption=true" + "-e Features__EnableDisappearingMessages=true" +) + +# Build volumes +VOLUMES=( + "-v ${CONTAINER_NAME}-data:/app/data" + "-v ${CONTAINER_NAME}-logs:/app/logs" +) + +# Deploy the container +print_message "$GREEN" "Deploying bot: $CONTAINER_NAME" +print_message "$YELLOW" "API URL: $API_URL" + +$DOCKER_CMD run -d \ + --name "$CONTAINER_NAME" \ + --restart "$RESTART_POLICY" \ + "${ENV_VARS[@]}" \ + "${VOLUMES[@]}" \ + "$DOCKER_IMAGE" + +# Check if deployment was successful +if [ $? -eq 0 ]; then + print_message "$GREEN" "✅ Bot deployed successfully: $CONTAINER_NAME" + + # Get container info + CONTAINER_ID=$($DOCKER_CMD ps -q -f name="$CONTAINER_NAME") + print_message "$YELLOW" "Container ID: $CONTAINER_ID" + + # Show container status + $DOCKER_CMD ps -f name="$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" + + # Follow logs if requested + if [ "$FOLLOW_LOGS" = true ]; then + print_message "$YELLOW" "Following logs (Ctrl+C to exit)..." + $DOCKER_CMD logs -f "$CONTAINER_NAME" + else + print_message "$YELLOW" "View logs with: docker logs -f $CONTAINER_NAME" + fi +else + print_message "$RED" "❌ Deployment failed" + exit 1 +fi + +# Print next steps +echo "" +print_message "$GREEN" "Next steps:" +echo "1. Check bot status: docker ps -f name=$CONTAINER_NAME" +echo "2. View logs: docker logs $CONTAINER_NAME" +echo "3. Stop bot: docker stop $CONTAINER_NAME" +echo "4. Remove bot: docker rm -f $CONTAINER_NAME" +echo "5. Access admin panel to manage bot settings" \ No newline at end of file diff --git a/TeleBot/docker-compose.multi.yml b/TeleBot/docker-compose.multi.yml new file mode 100644 index 0000000..da4d00f --- /dev/null +++ b/TeleBot/docker-compose.multi.yml @@ -0,0 +1,284 @@ +version: '3.8' + +services: + # Customer Support Bot + bot-support: + image: littleshop/telebot:latest + container_name: littleshop-bot-support + restart: unless-stopped + + environment: + - DOTNET_ENVIRONMENT=Production + - TZ=UTC + + # Telegram Configuration + - Telegram__BotToken=${SUPPORT_BOT_TOKEN} + - Telegram__AdminChatId=${SUPPORT_ADMIN_CHAT_ID} + - Telegram__UseWebhook=false + + # LittleShop API Configuration + - LittleShop__ApiUrl=${LITTLESHOP_API_URL:-http://host.docker.internal:8080} + - LittleShop__Username=${LITTLESHOP_USERNAME:-admin} + - LittleShop__Password=${LITTLESHOP_PASSWORD:-admin} + - BotManager__ApiKey=${SUPPORT_BOT_API_KEY} + + # Privacy Settings + - Privacy__Mode=strict + - Privacy__DataRetentionHours=24 + - Privacy__SessionTimeoutMinutes=30 + + # Database Configuration + - Database__ConnectionString=Filename=/app/data/telebot.db;Password=; + - Database__EncryptionKey=${SUPPORT_DB_ENCRYPTION_KEY} + + # Features + - Features__EnableQRCodes=true + - Features__EnablePGPEncryption=true + - Features__EnableDisappearingMessages=true + + volumes: + - support-bot-data:/app/data + - support-bot-logs:/app/logs + + networks: + - littleshop-network + + healthcheck: + test: ["CMD", "pgrep", "-f", "dotnet.*TeleBot"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + # Sales & Marketing Bot + bot-sales: + image: littleshop/telebot:latest + container_name: littleshop-bot-sales + restart: unless-stopped + + environment: + - DOTNET_ENVIRONMENT=Production + - TZ=UTC + + # Telegram Configuration + - Telegram__BotToken=${SALES_BOT_TOKEN} + - Telegram__AdminChatId=${SALES_ADMIN_CHAT_ID} + - Telegram__UseWebhook=false + + # LittleShop API Configuration + - LittleShop__ApiUrl=${LITTLESHOP_API_URL:-http://host.docker.internal:8080} + - LittleShop__Username=${LITTLESHOP_USERNAME:-admin} + - LittleShop__Password=${LITTLESHOP_PASSWORD:-admin} + - BotManager__ApiKey=${SALES_BOT_API_KEY} + + # Privacy Settings + - Privacy__Mode=moderate + - Privacy__DataRetentionHours=72 + - Privacy__SessionTimeoutMinutes=60 + - Privacy__EnableAnalytics=true + + # Database Configuration + - Database__ConnectionString=Filename=/app/data/telebot.db;Password=; + - Database__EncryptionKey=${SALES_DB_ENCRYPTION_KEY} + + # Features + - Features__EnableQRCodes=true + - Features__EnablePGPEncryption=false + - Features__EnableDisappearingMessages=false + + volumes: + - sales-bot-data:/app/data + - sales-bot-logs:/app/logs + + networks: + - littleshop-network + + healthcheck: + test: ["CMD", "pgrep", "-f", "dotnet.*TeleBot"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + # VIP/Premium Customer Bot + bot-vip: + image: littleshop/telebot:latest + container_name: littleshop-bot-vip + restart: unless-stopped + + environment: + - DOTNET_ENVIRONMENT=Production + - TZ=UTC + + # Telegram Configuration + - Telegram__BotToken=${VIP_BOT_TOKEN} + - Telegram__AdminChatId=${VIP_ADMIN_CHAT_ID} + - Telegram__UseWebhook=false + + # LittleShop API Configuration + - LittleShop__ApiUrl=${LITTLESHOP_API_URL:-http://host.docker.internal:8080} + - LittleShop__Username=${LITTLESHOP_USERNAME:-admin} + - LittleShop__Password=${LITTLESHOP_PASSWORD:-admin} + - BotManager__ApiKey=${VIP_BOT_API_KEY} + + # Privacy Settings (Enhanced for VIP) + - Privacy__Mode=strict + - Privacy__DataRetentionHours=1 + - Privacy__SessionTimeoutMinutes=15 + - Privacy__EnableAnalytics=false + - Privacy__RequirePGPForShipping=true + - Privacy__EphemeralByDefault=true + - Privacy__EnableTor=${VIP_ENABLE_TOR:-false} + + # Database Configuration + - Database__ConnectionString=Filename=/app/data/telebot.db;Password=; + - Database__EncryptionKey=${VIP_DB_ENCRYPTION_KEY} + + # Features (All features for VIP) + - Features__EnableVoiceSearch=true + - Features__EnableQRCodes=true + - Features__EnablePGPEncryption=true + - Features__EnableDisappearingMessages=true + - Features__EnableOrderMixing=true + - Features__MixingDelayMinSeconds=60 + - Features__MixingDelayMaxSeconds=300 + + volumes: + - vip-bot-data:/app/data + - vip-bot-logs:/app/logs + + networks: + - littleshop-network + + healthcheck: + test: ["CMD", "pgrep", "-f", "dotnet.*TeleBot"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + # Regional Bot Example (EU) + bot-eu: + image: littleshop/telebot:latest + container_name: littleshop-bot-eu + restart: unless-stopped + + environment: + - DOTNET_ENVIRONMENT=Production + - TZ=Europe/London + + # Telegram Configuration + - Telegram__BotToken=${EU_BOT_TOKEN} + - Telegram__AdminChatId=${EU_ADMIN_CHAT_ID} + - Telegram__UseWebhook=false + + # LittleShop API Configuration + - LittleShop__ApiUrl=${EU_API_URL:-http://host.docker.internal:8080} + - LittleShop__Username=${LITTLESHOP_USERNAME:-admin} + - LittleShop__Password=${LITTLESHOP_PASSWORD:-admin} + - BotManager__ApiKey=${EU_BOT_API_KEY} + + # Privacy Settings (GDPR Compliant) + - Privacy__Mode=strict + - Privacy__DataRetentionHours=24 + - Privacy__SessionTimeoutMinutes=30 + - Privacy__EnableAnalytics=false + - Privacy__EphemeralByDefault=true + + # Database Configuration + - Database__ConnectionString=Filename=/app/data/telebot.db;Password=; + - Database__EncryptionKey=${EU_DB_ENCRYPTION_KEY} + + # Features + - Features__EnableQRCodes=true + - Features__EnablePGPEncryption=true + - Features__EnableDisappearingMessages=true + + volumes: + - eu-bot-data:/app/data + - eu-bot-logs:/app/logs + + networks: + - littleshop-network + + healthcheck: + test: ["CMD", "pgrep", "-f", "dotnet.*TeleBot"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + # Optional: Shared Redis for all bots + redis: + image: redis:7-alpine + container_name: littleshop-redis-shared + restart: unless-stopped + + command: redis-server --requirepass ${REDIS_PASSWORD} + + volumes: + - redis-data:/data + + networks: + - littleshop-network + + healthcheck: + test: ["CMD", "redis-cli", "--raw", "incr", "ping"] + interval: 30s + timeout: 3s + retries: 5 + + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + +volumes: + support-bot-data: + name: littleshop-bot-support-data + support-bot-logs: + name: littleshop-bot-support-logs + sales-bot-data: + name: littleshop-bot-sales-data + sales-bot-logs: + name: littleshop-bot-sales-logs + vip-bot-data: + name: littleshop-bot-vip-data + vip-bot-logs: + name: littleshop-bot-vip-logs + eu-bot-data: + name: littleshop-bot-eu-data + eu-bot-logs: + name: littleshop-bot-eu-logs + redis-data: + name: littleshop-redis-shared-data + +networks: + littleshop-network: + name: littleshop-network + driver: bridge \ No newline at end of file diff --git a/TeleBot/portainer-template.json b/TeleBot/portainer-template.json new file mode 100644 index 0000000..efd3ca5 --- /dev/null +++ b/TeleBot/portainer-template.json @@ -0,0 +1,295 @@ +{ + "version": "2", + "templates": [ + { + "type": 1, + "title": "LittleShop TeleBot", + "name": "littleshop-telebot", + "description": "Deploy a Telegram bot for LittleShop e-commerce platform", + "note": "Requires a Telegram bot token from @BotFather and API key from LittleShop admin panel", + "categories": ["bots", "ecommerce", "telegram"], + "platform": "linux", + "logo": "https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/telegram.png", + "image": "littleshop/telebot:latest", + "restart_policy": "unless-stopped", + "network_mode": "bridge", + "hostname": "", + "privileged": false, + "interactive": false, + "env": [ + { + "name": "DOTNET_ENVIRONMENT", + "label": "Environment", + "default": "Production", + "preset": true + }, + { + "name": "TZ", + "label": "Timezone", + "default": "UTC", + "description": "Container timezone (e.g., Europe/London, America/New_York)" + }, + { + "name": "Telegram__BotToken", + "label": "Telegram Bot Token", + "description": "Token from @BotFather (required)" + }, + { + "name": "Telegram__AdminChatId", + "label": "Admin Chat ID", + "description": "Telegram chat ID for admin notifications (optional)" + }, + { + "name": "LittleShop__ApiUrl", + "label": "LittleShop API URL", + "default": "http://host.docker.internal:8080", + "description": "URL to LittleShop API (e.g., https://api.shop.com)" + }, + { + "name": "LittleShop__Username", + "label": "API Username", + "default": "admin", + "description": "LittleShop API username" + }, + { + "name": "LittleShop__Password", + "label": "API Password", + "default": "admin", + "description": "LittleShop API password" + }, + { + "name": "BotManager__ApiKey", + "label": "Bot API Key", + "description": "API key from LittleShop admin panel (optional)" + }, + { + "name": "Database__EncryptionKey", + "label": "Database Encryption Key", + "description": "32-character key for database encryption (auto-generated if not provided)" + }, + { + "name": "Privacy__Mode", + "label": "Privacy Mode", + "default": "strict", + "select": [ + { + "text": "Strict (Maximum Privacy)", + "value": "strict" + }, + { + "text": "Moderate (Balanced)", + "value": "moderate" + }, + { + "text": "Relaxed (More Features)", + "value": "relaxed" + } + ], + "description": "Privacy level for user data handling" + }, + { + "name": "Privacy__DataRetentionHours", + "label": "Data Retention Hours", + "default": "24", + "description": "Hours to retain user data (1-168)" + }, + { + "name": "Privacy__SessionTimeoutMinutes", + "label": "Session Timeout Minutes", + "default": "30", + "description": "Minutes before session expires (5-1440)" + }, + { + "name": "Privacy__EphemeralByDefault", + "label": "Ephemeral Messages", + "default": "true", + "select": [ + { + "text": "Enabled", + "value": "true" + }, + { + "text": "Disabled", + "value": "false" + } + ], + "description": "Enable ephemeral messages by default" + }, + { + "name": "Features__EnableQRCodes", + "label": "Enable QR Codes", + "default": "true", + "select": [ + { + "text": "Enabled", + "value": "true" + }, + { + "text": "Disabled", + "value": "false" + } + ] + }, + { + "name": "Features__EnablePGPEncryption", + "label": "Enable PGP Encryption", + "default": "true", + "select": [ + { + "text": "Enabled", + "value": "true" + }, + { + "text": "Disabled", + "value": "false" + } + ] + }, + { + "name": "Features__EnableDisappearingMessages", + "label": "Enable Disappearing Messages", + "default": "true", + "select": [ + { + "text": "Enabled", + "value": "true" + }, + { + "text": "Disabled", + "value": "false" + } + ] + } + ], + "volumes": [ + { + "container": "/app/data", + "bind": "!telebot-data" + }, + { + "container": "/app/logs", + "bind": "!telebot-logs" + } + ], + "labels": [ + { + "name": "traefik.enable", + "value": "false" + }, + { + "name": "com.littleshop.bot", + "value": "true" + } + ] + }, + { + "type": 3, + "title": "LittleShop Multi-Bot Stack", + "name": "littleshop-multibot", + "description": "Deploy multiple LittleShop TeleBots (Support, Sales, VIP)", + "note": "Requires multiple bot tokens and configuration. Edit the stack after creation to add environment variables.", + "categories": ["bots", "ecommerce", "telegram"], + "platform": "linux", + "logo": "https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/telegram.png", + "repository": { + "url": "https://github.com/yourusername/littleshop", + "stackfile": "TeleBot/docker-compose.multi.yml" + }, + "env": [ + { + "name": "LITTLESHOP_API_URL", + "label": "LittleShop API URL", + "default": "http://host.docker.internal:8080", + "description": "Shared API URL for all bots" + }, + { + "name": "LITTLESHOP_USERNAME", + "label": "API Username", + "default": "admin" + }, + { + "name": "LITTLESHOP_PASSWORD", + "label": "API Password", + "default": "admin" + }, + { + "name": "SUPPORT_BOT_TOKEN", + "label": "Support Bot Token", + "description": "Token for customer support bot" + }, + { + "name": "SUPPORT_BOT_API_KEY", + "label": "Support Bot API Key", + "description": "API key for support bot" + }, + { + "name": "SUPPORT_ADMIN_CHAT_ID", + "label": "Support Admin Chat ID" + }, + { + "name": "SUPPORT_DB_ENCRYPTION_KEY", + "label": "Support DB Encryption Key", + "description": "32-char key for support bot database" + }, + { + "name": "SALES_BOT_TOKEN", + "label": "Sales Bot Token", + "description": "Token for sales/marketing bot" + }, + { + "name": "SALES_BOT_API_KEY", + "label": "Sales Bot API Key", + "description": "API key for sales bot" + }, + { + "name": "SALES_ADMIN_CHAT_ID", + "label": "Sales Admin Chat ID" + }, + { + "name": "SALES_DB_ENCRYPTION_KEY", + "label": "Sales DB Encryption Key", + "description": "32-char key for sales bot database" + }, + { + "name": "VIP_BOT_TOKEN", + "label": "VIP Bot Token", + "description": "Token for VIP customer bot" + }, + { + "name": "VIP_BOT_API_KEY", + "label": "VIP Bot API Key", + "description": "API key for VIP bot" + }, + { + "name": "VIP_ADMIN_CHAT_ID", + "label": "VIP Admin Chat ID" + }, + { + "name": "VIP_DB_ENCRYPTION_KEY", + "label": "VIP DB Encryption Key", + "description": "32-char key for VIP bot database" + }, + { + "name": "VIP_ENABLE_TOR", + "label": "Enable Tor for VIP Bot", + "default": "false", + "select": [ + { + "text": "Enabled", + "value": "true" + }, + { + "text": "Disabled", + "value": "false" + } + ] + }, + { + "name": "REDIS_PASSWORD", + "label": "Redis Password", + "description": "Password for shared Redis cache" + } + ] + } + ] +} \ No newline at end of file diff --git a/cookies.txt b/cookies.txt index 82cf950..c494927 100644 --- a/cookies.txt +++ b/cookies.txt @@ -2,4 +2,4 @@ # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. -#HttpOnly_localhost FALSE / TRUE 0 .AspNetCore.Cookies CfDJ8OZGzJDh-FtIgYN_FUICYtt5LS1JOam2mW2wri916e5XsmYDR_lQkRtYVVTC7r0wkdSNTM8aSMPBRFIGmuAwBTHadPXGRSuBshsviOnShSrsgxfj-8nrfMT0ojW-P2J3rWqHwzct7iXniiFhz006O76w75ToS7hAGwBt_EuReTazhch0dviMBpKsT1AxxudabJaa4VO5wwg9iSEFuII1ZYpKqDF8gNOTlPtAeMO3LcFCyTri02dJ_NTRlGtaqPtn4PIAjoiMS_hAHI9rdkQzAecc2gM2EU12dBy_HFE7xHF1e7y4aeVgSEsDw_er50wc5QgAbJ2oqdOay41vkZssCfMbU8cMKTQjyEbOQODiMJm_Wz4m_K326RtYqJNnRjF2Pls7VMzK9se38qh1gOEdvUDoe4JRHAYJ0lt0s_7Npith2Ck9zcaVP5PfdeQsf_yhYnTCXUQq7um0FesumdhmEPJ_sOoZx-WsJF5o5xDa_ja5lklgm0UY3Q4snSMI_FMHDceT1quZKUX3g9U61Nl1wy329N0510vAH93qMmLvD4Ar +#HttpOnly_31.97.57.205 FALSE / FALSE 0 .AspNetCore.Cookies CfDJ8Hh_A9Sh3WBNi-S2OCZkQFY4WFyPqGN28cMhN1p1RyAh6E1a91SYc9cQbCOcfyQ06MrqOLNHfJbU9ghwTWAqZ_hzT4ujPSA3QgRWYJMqQBdE-YaxX7b27W9MTn9_DE9ANqPT1EzPD5ySOQq5exxqRvoca3ZH4ZmNOKC_ZXoQtU5_l-vmBHYg4_Ng94j-uShqC_Nu7OiHvRWaNwe29TNQmcDVJrJ6zEEKp-1eKNWz6yq62hvbXpjB0SH9REbNx_HOTaqSA9B81OFS6rsfKcLnSc2ermWGbVYgOoxCzg-Za-EMI--WktTqlNjaUUCzrNU2xgs9JFpH3ygoKGXRHWBKn6Qp5RQ4lXyNZCOfFQIsSSfN1YkC7doAikdvhAjTRg7UBhKdFhWWvYhP0aa1mfYkRqC1FMZ1LTPkJMPZsyrkajljKRONmA2iVvz9cEYVFljs1PaGJtgGBUH54ZTvCrZkMcKzzp12Q6pKCpFi_0zBnRCIROiChswR-eGyYKXRJ4JfpY93cXW08kJRZdnL6T_n4XIU7cJ6THMW-hqxioVQFkjh diff --git a/deploy-to-hostinger.sh b/deploy-to-hostinger.sh index 4192358..d2c2612 100755 --- a/deploy-to-hostinger.sh +++ b/deploy-to-hostinger.sh @@ -1,17 +1,10 @@ #!/bin/bash -# LittleShop Deployment Script for Hostinger VPS -# Usage: ./deploy-to-hostinger.sh +# LittleShop + TeleBot Deployment Script for Hostinger +# This script deploys both LittleShop and TeleBot to a Hostinger VPS +# with BTCPay Server integration -set -e # Exit on any error - -# Configuration -HOSTINGER_HOST="31.97.57.205" -HOSTINGER_PORT="2255" -HOSTINGER_USER="sysadmin" -SSH_KEY="./Hostinger/vps_hardening_key" -REMOTE_DIR="/opt/littleshop" -SERVICE_NAME="littleshop" +set -e # Colors for output RED='\033[0;31m' @@ -19,118 +12,105 @@ GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color -# Logging function -log() { - echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" -} +echo -e "${GREEN}======================================${NC}" +echo -e "${GREEN}LittleShop + TeleBot Hostinger Deploy${NC}" +echo -e "${GREEN}======================================${NC}" -warn() { - echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" -} +# Check if .env file exists +if [ ! -f .env ]; then + echo -e "${YELLOW}Warning: .env file not found!${NC}" + echo "Creating .env from template..." + cp .env.hostinger.template .env + echo -e "${RED}Please edit .env file with your configuration before continuing!${NC}" + echo "Required configurations:" + echo " - TELEGRAM_BOT_TOKEN" + echo " - TELEGRAM_ADMIN_CHAT_ID" + echo " - BTCPAY_WEBHOOK_SECRET (generate a secure random string)" + echo "" + read -p "Press enter after editing .env file to continue..." +fi -error() { - echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" +# Load environment variables +source .env + +# Validate required environment variables +if [ -z "$TELEGRAM_BOT_TOKEN" ]; then + echo -e "${RED}Error: TELEGRAM_BOT_TOKEN not set in .env file${NC}" exit 1 -} - -# Check if SSH key exists -if [ ! -f "$SSH_KEY" ]; then - error "SSH key not found at $SSH_KEY" fi -# Check if required files exist -if [ ! -f "hostinger-docker-compose.yml" ]; then - error "hostinger-docker-compose.yml not found" +if [ -z "$TELEGRAM_ADMIN_CHAT_ID" ]; then + echo -e "${RED}Error: TELEGRAM_ADMIN_CHAT_ID not set in .env file${NC}" + exit 1 fi -if [ ! -f "env.hostinger" ]; then - warn "env.hostinger not found - you'll need to configure environment variables manually" -fi +echo -e "${GREEN}Configuration validated successfully${NC}" -log "Starting deployment to Hostinger VPS..." +# Build Docker images +echo -e "${YELLOW}Building Docker images...${NC}" +docker-compose -f docker-compose.hostinger.yml build -# Test SSH connection -log "Testing SSH connection..." -ssh -i "$SSH_KEY" -p "$HOSTINGER_PORT" -o ConnectTimeout=10 "$HOSTINGER_USER@$HOSTINGER_HOST" "echo 'SSH connection successful'" || error "SSH connection failed" +# Stop existing containers (if any) +echo -e "${YELLOW}Stopping existing containers...${NC}" +docker-compose -f docker-compose.hostinger.yml down -# Create remote directory -log "Creating remote directory structure..." -ssh -i "$SSH_KEY" -p "$HOSTINGER_PORT" "$HOSTINGER_USER@$HOSTINGER_HOST" "echo 'Phenom12#.' | sudo -S mkdir -p $REMOTE_DIR && echo 'Phenom12#.' | sudo -S chown $HOSTINGER_USER:$HOSTINGER_USER $REMOTE_DIR" +# Start services +echo -e "${YELLOW}Starting services...${NC}" +docker-compose -f docker-compose.hostinger.yml up -d -# Copy files to server -log "Copying application files..." -scp -i "$SSH_KEY" -P "$HOSTINGER_PORT" -r LittleShop/ "$HOSTINGER_USER@$HOSTINGER_HOST:$REMOTE_DIR/" -scp -i "$SSH_KEY" -P "$HOSTINGER_PORT" hostinger-docker-compose.yml "$HOSTINGER_USER@$HOSTINGER_HOST:$REMOTE_DIR/docker-compose.yml" -scp -i "$SSH_KEY" -P "$HOSTINGER_PORT" nginx.conf "$HOSTINGER_USER@$HOSTINGER_HOST:$REMOTE_DIR/" - -# Copy environment file if it exists -if [ -f "env.hostinger" ]; then - log "Copying environment configuration..." - scp -i "$SSH_KEY" -P "$HOSTINGER_PORT" env.hostinger "$HOSTINGER_USER@$HOSTINGER_HOST:$REMOTE_DIR/.env" -fi - -# Deploy on remote server -log "Building and starting containers on remote server..." -ssh -i "$SSH_KEY" -p "$HOSTINGER_PORT" "$HOSTINGER_USER@$HOSTINGER_HOST" << 'EOF' -cd /opt/littleshop - -# Stop existing containers if running -if docker-compose ps | grep -q "littleshop"; then - echo "Stopping existing containers..." - docker-compose down -fi - -# Build and start new containers -echo "Building Docker image..." -docker-compose build - -echo "Starting containers..." -docker-compose up -d - -# Wait for container to be ready -echo "Waiting for application to start..." +# Wait for services to be ready +echo -e "${YELLOW}Waiting for services to start...${NC}" sleep 10 -# Check if container is running -if docker-compose ps | grep -q "Up"; then - echo "✅ Deployment successful!" - echo "Container status:" - docker-compose ps - echo "" - echo "Checking application health..." +# Check service health +echo -e "${YELLOW}Checking service health...${NC}" - # Try to curl the health endpoint - if curl -f http://localhost:8081/api/test > /dev/null 2>&1; then - echo "✅ Application is responding on port 8081" - else - echo "⚠️ Application may still be starting up" - fi - - echo "" - echo "📝 Next steps:" - echo "1. Configure your domain to point to this server" - echo "2. Set up SSL certificates if needed" - echo "3. Configure BTCPay Server integration" - echo "4. Test the application at http://31.97.57.205:8081" +# Check LittleShop +if curl -f -s http://localhost:8080/health > /dev/null; then + echo -e "${GREEN}✓ LittleShop is running${NC}" else - echo "❌ Deployment failed - containers not running" - docker-compose logs - exit 1 + echo -e "${RED}✗ LittleShop health check failed${NC}" fi -EOF -if [ $? -eq 0 ]; then - log "🎉 Deployment completed successfully!" - log "Application should be available at:" - log " - http://$HOSTINGER_HOST:8081 (direct access)" - log " - http://shop.thebankofdebbie.giize.com (if DNS is configured)" - log "" - log "📋 Post-deployment checklist:" - log "1. Update DNS records to point shop.thebankofdebbie.giize.com to $HOSTINGER_HOST" - log "2. Configure SSL certificates" - log "3. Update BTCPay Server settings in .env file" - log "4. Test all application functionality" - log "5. Set up monitoring and backups" +# Check TeleBot logs +if docker logs littleshop-telebot 2>&1 | grep -q "Starting TeleBot"; then + echo -e "${GREEN}✓ TeleBot is running${NC}" else - error "Deployment failed!" -fi \ No newline at end of file + echo -e "${RED}✗ TeleBot may not be running correctly${NC}" +fi + +# Show container status +echo "" +echo -e "${GREEN}Container Status:${NC}" +docker-compose -f docker-compose.hostinger.yml ps + +# Show logs +echo "" +echo -e "${GREEN}Recent logs:${NC}" +echo -e "${YELLOW}LittleShop:${NC}" +docker logs --tail 10 littleshop + +echo "" +echo -e "${YELLOW}TeleBot:${NC}" +docker logs --tail 10 littleshop-telebot + +echo "" +echo -e "${GREEN}======================================${NC}" +echo -e "${GREEN}Deployment Complete!${NC}" +echo -e "${GREEN}======================================${NC}" +echo "" +echo "Services are running:" +echo " - LittleShop API: http://localhost:8080" +echo " - TeleBot: Check your Telegram bot" +echo "" +echo "BTCPay Server:" +echo " - URL: https://thebankofdebbie.giize.com" +echo " - Make sure to configure webhook in BTCPay:" +echo " Webhook URL: http://your-server-ip:8080/api/orders/payments/webhook" +echo "" +echo "To view logs:" +echo " docker logs -f littleshop" +echo " docker logs -f littleshop-telebot" +echo "" +echo "To stop services:" +echo " docker-compose -f docker-compose.hostinger.yml down" \ No newline at end of file diff --git a/docker-compose.hostinger.yml b/docker-compose.hostinger.yml new file mode 100644 index 0000000..045a147 --- /dev/null +++ b/docker-compose.hostinger.yml @@ -0,0 +1,123 @@ +version: '3.8' + +services: + # LittleShop Main Application + littleshop: + build: . + image: littleshop:latest + container_name: littleshop + restart: unless-stopped + environment: + - ASPNETCORE_ENVIRONMENT=Hostinger + - ASPNETCORE_URLS=http://+:8080 + # BTCPay Configuration - pointing to Hostinger BTCPay + - BTCPayServer__BaseUrl=https://thebankofdebbie.giize.com + - BTCPayServer__ApiKey=${BTCPAY_API_KEY:-994589c8b514531f867dd24c83a02b6381a5f4a2} + - BTCPayServer__StoreId=${BTCPAY_STORE_ID:-AoxXjM9NJT6P9C1MErkaawXaSchz8sFPYdQ9FyhmQz33} + - BTCPayServer__WebhookSecret=${BTCPAY_WEBHOOK_SECRET} + # Database + - ConnectionStrings__DefaultConnection=Data Source=/app/data/littleshop.db + # JWT + - Jwt__Key=${JWT_SECRET_KEY:-YourSuperSecretKeyThatIsAtLeast32CharactersLong!} + volumes: + - littleshop_data:/app/data + - littleshop_uploads:/app/wwwroot/uploads + - littleshop_logs:/app/logs + ports: + - "8080:8080" + networks: + - littleshop-network + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + # TeleBot Telegram Bot + telebot: + build: + context: . + dockerfile: TeleBot/TeleBot/Dockerfile + container_name: littleshop-telebot + restart: unless-stopped + environment: + - DOTNET_ENVIRONMENT=Production + - TZ=UTC + # Telegram Bot Configuration + - Telegram__BotToken=${TELEGRAM_BOT_TOKEN} + - Telegram__AdminChatId=${TELEGRAM_ADMIN_CHAT_ID} + - Telegram__UseWebhook=false + # LittleShop API Configuration - pointing to local container + - LittleShop__ApiUrl=http://littleshop:8080 + - LittleShop__Username=${LITTLESHOP_USERNAME:-admin} + - LittleShop__Password=${LITTLESHOP_PASSWORD:-admin} + - LittleShop__UseTor=false + - LittleShop__BrandName=${BRAND_NAME:-Little Shop} + # Privacy Settings + - Privacy__Mode=strict + - Privacy__DataRetentionHours=24 + - Privacy__SessionTimeoutMinutes=30 + - Privacy__EnableAnalytics=false + - Privacy__EphemeralByDefault=true + - Privacy__EnableTor=false + # Database Configuration + - Database__ConnectionString=Filename=/app/data/telebot.db;Password=; + - Database__EncryptionKey=${DATABASE_ENCRYPTION_KEY:-CHANGE_THIS_KEY_IN_PRODUCTION} + # Features + - Features__EnableQRCodes=true + - Features__EnablePGPEncryption=true + - Features__EnableDisappearingMessages=true + # Redis (optional) + - Redis__Enabled=${REDIS_ENABLED:-false} + - Redis__ConnectionString=redis:6379 + # Hangfire (optional) + - Hangfire__Enabled=${HANGFIRE_ENABLED:-false} + volumes: + - telebot_data:/app/data + - telebot_logs:/app/logs + networks: + - littleshop-network + depends_on: + - littleshop + - redis + healthcheck: + test: ["CMD", "pgrep", "-f", "dotnet.*TeleBot"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + # Redis Cache (Optional) + redis: + image: redis:7-alpine + container_name: littleshop-redis + restart: unless-stopped + command: redis-server --requirepass ${REDIS_PASSWORD:-RedisPassword123} + volumes: + - redis_data:/data + networks: + - littleshop-network + healthcheck: + test: ["CMD", "redis-cli", "--raw", "incr", "ping"] + interval: 30s + timeout: 3s + retries: 5 + +volumes: + littleshop_data: + driver: local + littleshop_uploads: + driver: local + littleshop_logs: + driver: local + telebot_data: + driver: local + telebot_logs: + driver: local + redis_data: + driver: local + +networks: + littleshop-network: + driver: bridge \ No newline at end of file diff --git a/hostinger-deployment.tar.gz b/hostinger-deployment.tar.gz new file mode 100644 index 0000000..66fbadb Binary files /dev/null and b/hostinger-deployment.tar.gz differ diff --git a/littleshop-btcpay-fix.tar.gz b/littleshop-btcpay-fix.tar.gz new file mode 100644 index 0000000..25572cc Binary files /dev/null and b/littleshop-btcpay-fix.tar.gz differ diff --git a/littleshop-complete.tar.gz b/littleshop-complete.tar.gz new file mode 100644 index 0000000..6526fa7 Binary files /dev/null and b/littleshop-complete.tar.gz differ diff --git a/littleshop-src.tar.gz b/littleshop-src.tar.gz new file mode 100644 index 0000000..10d86c0 Binary files /dev/null and b/littleshop-src.tar.gz differ diff --git a/publish/AutoMapper.dll b/publish/AutoMapper.dll new file mode 100755 index 0000000..b8e01b0 Binary files /dev/null and b/publish/AutoMapper.dll differ diff --git a/publish/BTCPayServer.Client.dll b/publish/BTCPayServer.Client.dll new file mode 100755 index 0000000..1aaabc6 Binary files /dev/null and b/publish/BTCPayServer.Client.dll differ diff --git a/publish/BTCPayServer.Lightning.Common.dll b/publish/BTCPayServer.Lightning.Common.dll new file mode 100755 index 0000000..548c25d Binary files /dev/null and b/publish/BTCPayServer.Lightning.Common.dll differ diff --git a/publish/BouncyCastle.Crypto.dll b/publish/BouncyCastle.Crypto.dll new file mode 100755 index 0000000..80fa901 Binary files /dev/null and b/publish/BouncyCastle.Crypto.dll differ diff --git a/publish/FluentValidation.AspNetCore.dll b/publish/FluentValidation.AspNetCore.dll new file mode 100755 index 0000000..91b4e0b Binary files /dev/null and b/publish/FluentValidation.AspNetCore.dll differ diff --git a/publish/FluentValidation.DependencyInjectionExtensions.dll b/publish/FluentValidation.DependencyInjectionExtensions.dll new file mode 100755 index 0000000..3f94755 Binary files /dev/null and b/publish/FluentValidation.DependencyInjectionExtensions.dll differ diff --git a/publish/FluentValidation.dll b/publish/FluentValidation.dll new file mode 100755 index 0000000..01eb485 Binary files /dev/null and b/publish/FluentValidation.dll differ diff --git a/publish/LittleShop b/publish/LittleShop new file mode 100755 index 0000000..7dd8a56 Binary files /dev/null and b/publish/LittleShop differ diff --git a/publish/LittleShop.deps.json b/publish/LittleShop.deps.json new file mode 100644 index 0000000..dc86856 --- /dev/null +++ b/publish/LittleShop.deps.json @@ -0,0 +1,1531 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v9.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v9.0": { + "LittleShop/1.0.0": { + "dependencies": { + "AutoMapper": "13.0.1", + "BTCPayServer.Client": "2.0.0", + "FluentValidation": "11.11.0", + "FluentValidation.AspNetCore": "11.3.0", + "Microsoft.AspNetCore.Authentication.JwtBearer": "9.0.0", + "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "9.0.0", + "Microsoft.EntityFrameworkCore.Design": "9.0.0", + "Microsoft.EntityFrameworkCore.InMemory": "9.0.8", + "Microsoft.EntityFrameworkCore.Sqlite": "9.0.0", + "NBitcoin": "7.0.37", + "Newtonsoft.Json": "13.0.3", + "Serilog.AspNetCore": "8.0.3", + "Serilog.Sinks.File": "6.0.0", + "Swashbuckle.AspNetCore": "7.0.0", + "System.IdentityModel.Tokens.Jwt": "8.3.0", + "WebPush": "1.0.12" + }, + "runtime": { + "LittleShop.dll": {} + } + }, + "AutoMapper/13.0.1": { + "dependencies": { + "Microsoft.Extensions.Options": "9.0.8" + }, + "runtime": { + "lib/net6.0/AutoMapper.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.0" + } + } + }, + "BTCPayServer.Client/2.0.0": { + "dependencies": { + "BTCPayServer.Lightning.Common": "1.5.1", + "NBitcoin": "7.0.37", + "Newtonsoft.Json": "13.0.3" + }, + "runtime": { + "lib/netstandard2.1/BTCPayServer.Client.dll": { + "assemblyVersion": "2.0.0.0", + "fileVersion": "2.0.0.0" + } + } + }, + "BTCPayServer.Lightning.Common/1.5.1": { + "dependencies": { + "NBitcoin": "7.0.37", + "Newtonsoft.Json": "13.0.3" + }, + "runtime": { + "lib/net6.0/BTCPayServer.Lightning.Common.dll": { + "assemblyVersion": "1.5.1.0", + "fileVersion": "1.5.1.0" + } + } + }, + "FluentValidation/11.11.0": { + "runtime": { + "lib/net8.0/FluentValidation.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.11.0.0" + } + } + }, + "FluentValidation.AspNetCore/11.3.0": { + "dependencies": { + "FluentValidation": "11.11.0", + "FluentValidation.DependencyInjectionExtensions": "11.5.1" + }, + "runtime": { + "lib/net6.0/FluentValidation.AspNetCore.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.3.0.0" + } + } + }, + "FluentValidation.DependencyInjectionExtensions/11.5.1": { + "dependencies": { + "FluentValidation": "11.11.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" + }, + "runtime": { + "lib/netstandard2.1/FluentValidation.DependencyInjectionExtensions.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.5.1.0" + } + } + }, + "Humanizer.Core/2.14.1": {}, + "Microsoft.AspNetCore.Authentication.JwtBearer/9.0.0": { + "dependencies": { + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.0.1" + }, + "runtime": { + "lib/net9.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52903" + } + } + }, + "Microsoft.AspNetCore.Cryptography.Internal/9.0.0": {}, + "Microsoft.AspNetCore.Cryptography.KeyDerivation/9.0.0": { + "dependencies": { + "Microsoft.AspNetCore.Cryptography.Internal": "9.0.0" + } + }, + "Microsoft.AspNetCore.Identity.EntityFrameworkCore/9.0.0": { + "dependencies": { + "Microsoft.EntityFrameworkCore.Relational": "9.0.0", + "Microsoft.Extensions.Identity.Stores": "9.0.0" + }, + "runtime": { + "lib/net9.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52903" + } + } + }, + "Microsoft.Bcl.AsyncInterfaces/7.0.0": {}, + "Microsoft.Build.Framework/17.8.3": {}, + "Microsoft.Build.Locator/1.7.8": {}, + "Microsoft.CodeAnalysis.Analyzers/3.3.4": {}, + "Microsoft.CodeAnalysis.Common/4.8.0": { + "dependencies": { + "Microsoft.CodeAnalysis.Analyzers": "3.3.4", + "System.Collections.Immutable": "7.0.0", + "System.Reflection.Metadata": "7.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "Microsoft.CodeAnalysis.CSharp/4.8.0": { + "dependencies": { + "Microsoft.CodeAnalysis.Common": "4.8.0" + } + }, + "Microsoft.CodeAnalysis.CSharp.Workspaces/4.8.0": { + "dependencies": { + "Humanizer.Core": "2.14.1", + "Microsoft.CodeAnalysis.CSharp": "4.8.0", + "Microsoft.CodeAnalysis.Common": "4.8.0", + "Microsoft.CodeAnalysis.Workspaces.Common": "4.8.0" + } + }, + "Microsoft.CodeAnalysis.Workspaces.Common/4.8.0": { + "dependencies": { + "Humanizer.Core": "2.14.1", + "Microsoft.Bcl.AsyncInterfaces": "7.0.0", + "Microsoft.CodeAnalysis.Common": "4.8.0", + "System.Composition": "7.0.0", + "System.IO.Pipelines": "7.0.0", + "System.Threading.Channels": "7.0.0" + } + }, + "Microsoft.CodeAnalysis.Workspaces.MSBuild/4.8.0": { + "dependencies": { + "Microsoft.Build.Framework": "17.8.3", + "Microsoft.CodeAnalysis.Common": "4.8.0", + "Microsoft.CodeAnalysis.Workspaces.Common": "4.8.0", + "System.Text.Json": "9.0.0" + } + }, + "Microsoft.Data.Sqlite.Core/9.0.0": { + "dependencies": { + "SQLitePCLRaw.core": "2.1.10" + }, + "runtime": { + "lib/net8.0/Microsoft.Data.Sqlite.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52902" + } + } + }, + "Microsoft.EntityFrameworkCore/9.0.8": { + "dependencies": { + "Microsoft.EntityFrameworkCore.Abstractions": "9.0.8", + "Microsoft.EntityFrameworkCore.Analyzers": "9.0.8", + "Microsoft.Extensions.Caching.Memory": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8" + }, + "runtime": { + "lib/net8.0/Microsoft.EntityFrameworkCore.dll": { + "assemblyVersion": "9.0.8.0", + "fileVersion": "9.0.825.36802" + } + } + }, + "Microsoft.EntityFrameworkCore.Abstractions/9.0.8": { + "runtime": { + "lib/net8.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { + "assemblyVersion": "9.0.8.0", + "fileVersion": "9.0.825.36802" + } + } + }, + "Microsoft.EntityFrameworkCore.Analyzers/9.0.8": {}, + "Microsoft.EntityFrameworkCore.Design/9.0.0": { + "dependencies": { + "Humanizer.Core": "2.14.1", + "Microsoft.Build.Framework": "17.8.3", + "Microsoft.Build.Locator": "1.7.8", + "Microsoft.CodeAnalysis.CSharp": "4.8.0", + "Microsoft.CodeAnalysis.CSharp.Workspaces": "4.8.0", + "Microsoft.CodeAnalysis.Workspaces.MSBuild": "4.8.0", + "Microsoft.EntityFrameworkCore.Relational": "9.0.0", + "Microsoft.Extensions.Caching.Memory": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", + "Microsoft.Extensions.DependencyModel": "9.0.0", + "Microsoft.Extensions.Logging": "9.0.8", + "Mono.TextTemplating": "3.0.0", + "System.Text.Json": "9.0.0" + } + }, + "Microsoft.EntityFrameworkCore.InMemory/9.0.8": { + "dependencies": { + "Microsoft.EntityFrameworkCore": "9.0.8", + "Microsoft.Extensions.Caching.Memory": "9.0.8", + "Microsoft.Extensions.Logging": "9.0.8" + }, + "runtime": { + "lib/net8.0/Microsoft.EntityFrameworkCore.InMemory.dll": { + "assemblyVersion": "9.0.8.0", + "fileVersion": "9.0.825.36802" + } + } + }, + "Microsoft.EntityFrameworkCore.Relational/9.0.0": { + "dependencies": { + "Microsoft.EntityFrameworkCore": "9.0.8", + "Microsoft.Extensions.Caching.Memory": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", + "Microsoft.Extensions.Logging": "9.0.8" + }, + "runtime": { + "lib/net8.0/Microsoft.EntityFrameworkCore.Relational.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52902" + } + } + }, + "Microsoft.EntityFrameworkCore.Sqlite/9.0.0": { + "dependencies": { + "Microsoft.EntityFrameworkCore.Sqlite.Core": "9.0.0", + "Microsoft.Extensions.Caching.Memory": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", + "Microsoft.Extensions.DependencyModel": "9.0.0", + "Microsoft.Extensions.Logging": "9.0.8", + "SQLitePCLRaw.bundle_e_sqlite3": "2.1.10", + "SQLitePCLRaw.core": "2.1.10", + "System.Text.Json": "9.0.0" + } + }, + "Microsoft.EntityFrameworkCore.Sqlite.Core/9.0.0": { + "dependencies": { + "Microsoft.Data.Sqlite.Core": "9.0.0", + "Microsoft.EntityFrameworkCore.Relational": "9.0.0", + "Microsoft.Extensions.Caching.Memory": "9.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", + "Microsoft.Extensions.DependencyModel": "9.0.0", + "Microsoft.Extensions.Logging": "9.0.8", + "SQLitePCLRaw.core": "2.1.10", + "System.Text.Json": "9.0.0" + }, + "runtime": { + "lib/net8.0/Microsoft.EntityFrameworkCore.Sqlite.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52902" + } + } + }, + "Microsoft.Extensions.ApiDescription.Server/6.0.5": {}, + "Microsoft.Extensions.Caching.Abstractions/9.0.8": { + "dependencies": { + "Microsoft.Extensions.Primitives": "9.0.8" + }, + "runtime": { + "lib/net9.0/Microsoft.Extensions.Caching.Abstractions.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.Caching.Memory/9.0.8": { + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "9.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" + }, + "runtime": { + "lib/net9.0/Microsoft.Extensions.Caching.Memory.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.Configuration.Abstractions/9.0.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "9.0.8" + } + }, + "Microsoft.Extensions.Configuration.Binder/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "9.0.0" + } + }, + "Microsoft.Extensions.DependencyInjection/9.0.8": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" + }, + "runtime": { + "lib/net9.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/9.0.8": { + "runtime": { + "lib/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.DependencyModel/9.0.0": { + "runtime": { + "lib/net9.0/Microsoft.Extensions.DependencyModel.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.24.52809" + } + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8", + "System.Diagnostics.DiagnosticSource": "8.0.0" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Primitives": "9.0.8" + } + }, + "Microsoft.Extensions.Hosting.Abstractions/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "9.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "8.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8" + } + }, + "Microsoft.Extensions.Identity.Core/9.0.0": { + "dependencies": { + "Microsoft.AspNetCore.Cryptography.KeyDerivation": "9.0.0", + "Microsoft.Extensions.Logging": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8" + } + }, + "Microsoft.Extensions.Identity.Stores/9.0.0": { + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "9.0.8", + "Microsoft.Extensions.Identity.Core": "9.0.0", + "Microsoft.Extensions.Logging": "9.0.8" + } + }, + "Microsoft.Extensions.Logging/9.0.8": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "9.0.8", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Microsoft.Extensions.Options": "9.0.8" + }, + "runtime": { + "lib/net9.0/Microsoft.Extensions.Logging.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.Logging.Abstractions/9.0.8": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8" + }, + "runtime": { + "lib/net9.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.Options/9.0.8": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Primitives": "9.0.8" + }, + "runtime": { + "lib/net9.0/Microsoft.Extensions.Options.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.Extensions.Primitives/9.0.8": { + "runtime": { + "lib/net9.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "9.0.0.0", + "fileVersion": "9.0.825.36511" + } + } + }, + "Microsoft.IdentityModel.Abstractions/8.3.0": { + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Abstractions.dll": { + "assemblyVersion": "8.3.0.0", + "fileVersion": "8.3.0.51204" + } + } + }, + "Microsoft.IdentityModel.JsonWebTokens/8.3.0": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.3.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll": { + "assemblyVersion": "8.3.0.0", + "fileVersion": "8.3.0.51204" + } + } + }, + "Microsoft.IdentityModel.Logging/8.3.0": { + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "8.3.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Logging.dll": { + "assemblyVersion": "8.3.0.0", + "fileVersion": "8.3.0.51204" + } + } + }, + "Microsoft.IdentityModel.Protocols/8.0.1": { + "dependencies": { + "Microsoft.IdentityModel.Tokens": "8.3.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.dll": { + "assemblyVersion": "8.0.1.0", + "fileVersion": "8.0.1.50722" + } + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect/8.0.1": { + "dependencies": { + "Microsoft.IdentityModel.Protocols": "8.0.1", + "System.IdentityModel.Tokens.Jwt": "8.3.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": { + "assemblyVersion": "8.0.1.0", + "fileVersion": "8.0.1.50722" + } + } + }, + "Microsoft.IdentityModel.Tokens/8.3.0": { + "dependencies": { + "Microsoft.IdentityModel.Logging": "8.3.0" + }, + "runtime": { + "lib/net9.0/Microsoft.IdentityModel.Tokens.dll": { + "assemblyVersion": "8.3.0.0", + "fileVersion": "8.3.0.51204" + } + } + }, + "Microsoft.OpenApi/1.6.22": { + "runtime": { + "lib/netstandard2.0/Microsoft.OpenApi.dll": { + "assemblyVersion": "1.6.22.0", + "fileVersion": "1.6.22.0" + } + } + }, + "Mono.TextTemplating/3.0.0": { + "dependencies": { + "System.CodeDom": "6.0.0" + } + }, + "NBitcoin/7.0.37": { + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Newtonsoft.Json": "13.0.3" + }, + "runtime": { + "lib/net6.0/NBitcoin.dll": { + "assemblyVersion": "7.0.37.0", + "fileVersion": "7.0.37.0" + } + } + }, + "Newtonsoft.Json/13.0.3": { + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.3.27908" + } + } + }, + "Portable.BouncyCastle/1.8.1.3": { + "runtime": { + "lib/netstandard2.0/BouncyCastle.Crypto.dll": { + "assemblyVersion": "1.8.1.0", + "fileVersion": "1.8.1.146" + } + } + }, + "Serilog/4.0.0": { + "runtime": { + "lib/net8.0/Serilog.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "4.0.0.0" + } + } + }, + "Serilog.AspNetCore/8.0.3": { + "dependencies": { + "Microsoft.Extensions.Logging": "9.0.8", + "Serilog": "4.0.0", + "Serilog.Extensions.Hosting": "8.0.0", + "Serilog.Formatting.Compact": "2.0.0", + "Serilog.Settings.Configuration": "8.0.4", + "Serilog.Sinks.Console": "5.0.0", + "Serilog.Sinks.Debug": "2.0.0", + "Serilog.Sinks.File": "6.0.0" + }, + "runtime": { + "lib/net8.0/Serilog.AspNetCore.dll": { + "assemblyVersion": "8.0.3.0", + "fileVersion": "8.0.3.0" + } + } + }, + "Serilog.Extensions.Hosting/8.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "8.0.0", + "Microsoft.Extensions.Logging.Abstractions": "9.0.8", + "Serilog": "4.0.0", + "Serilog.Extensions.Logging": "8.0.0" + }, + "runtime": { + "lib/net8.0/Serilog.Extensions.Hosting.dll": { + "assemblyVersion": "7.0.0.0", + "fileVersion": "8.0.0.0" + } + } + }, + "Serilog.Extensions.Logging/8.0.0": { + "dependencies": { + "Microsoft.Extensions.Logging": "9.0.8", + "Serilog": "4.0.0" + }, + "runtime": { + "lib/net8.0/Serilog.Extensions.Logging.dll": { + "assemblyVersion": "7.0.0.0", + "fileVersion": "8.0.0.0" + } + } + }, + "Serilog.Formatting.Compact/2.0.0": { + "dependencies": { + "Serilog": "4.0.0" + }, + "runtime": { + "lib/net7.0/Serilog.Formatting.Compact.dll": { + "assemblyVersion": "2.0.0.0", + "fileVersion": "2.0.0.0" + } + } + }, + "Serilog.Settings.Configuration/8.0.4": { + "dependencies": { + "Microsoft.Extensions.Configuration.Binder": "8.0.0", + "Microsoft.Extensions.DependencyModel": "9.0.0", + "Serilog": "4.0.0" + }, + "runtime": { + "lib/net8.0/Serilog.Settings.Configuration.dll": { + "assemblyVersion": "8.0.4.0", + "fileVersion": "8.0.4.0" + } + } + }, + "Serilog.Sinks.Console/5.0.0": { + "dependencies": { + "Serilog": "4.0.0" + }, + "runtime": { + "lib/net7.0/Serilog.Sinks.Console.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.0" + } + } + }, + "Serilog.Sinks.Debug/2.0.0": { + "dependencies": { + "Serilog": "4.0.0" + }, + "runtime": { + "lib/netstandard2.1/Serilog.Sinks.Debug.dll": { + "assemblyVersion": "2.0.0.0", + "fileVersion": "2.0.0.0" + } + } + }, + "Serilog.Sinks.File/6.0.0": { + "dependencies": { + "Serilog": "4.0.0" + }, + "runtime": { + "lib/net8.0/Serilog.Sinks.File.dll": { + "assemblyVersion": "6.0.0.0", + "fileVersion": "6.0.0.0" + } + } + }, + "SQLitePCLRaw.bundle_e_sqlite3/2.1.10": { + "dependencies": { + "SQLitePCLRaw.lib.e_sqlite3": "2.1.10", + "SQLitePCLRaw.provider.e_sqlite3": "2.1.10" + }, + "runtime": { + "lib/netstandard2.0/SQLitePCLRaw.batteries_v2.dll": { + "assemblyVersion": "2.1.10.2445", + "fileVersion": "2.1.10.2445" + } + } + }, + "SQLitePCLRaw.core/2.1.10": { + "dependencies": { + "System.Memory": "4.5.3" + }, + "runtime": { + "lib/netstandard2.0/SQLitePCLRaw.core.dll": { + "assemblyVersion": "2.1.10.2445", + "fileVersion": "2.1.10.2445" + } + } + }, + "SQLitePCLRaw.lib.e_sqlite3/2.1.10": { + "runtimeTargets": { + "runtimes/browser-wasm/nativeassets/net9.0/e_sqlite3.a": { + "rid": "browser-wasm", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-arm/native/libe_sqlite3.so": { + "rid": "linux-arm", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-arm64/native/libe_sqlite3.so": { + "rid": "linux-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-armel/native/libe_sqlite3.so": { + "rid": "linux-armel", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-mips64/native/libe_sqlite3.so": { + "rid": "linux-mips64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-musl-arm/native/libe_sqlite3.so": { + "rid": "linux-musl-arm", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-musl-arm64/native/libe_sqlite3.so": { + "rid": "linux-musl-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-musl-s390x/native/libe_sqlite3.so": { + "rid": "linux-musl-s390x", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-musl-x64/native/libe_sqlite3.so": { + "rid": "linux-musl-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-ppc64le/native/libe_sqlite3.so": { + "rid": "linux-ppc64le", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-s390x/native/libe_sqlite3.so": { + "rid": "linux-s390x", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-x64/native/libe_sqlite3.so": { + "rid": "linux-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/linux-x86/native/libe_sqlite3.so": { + "rid": "linux-x86", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/maccatalyst-arm64/native/libe_sqlite3.dylib": { + "rid": "maccatalyst-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/maccatalyst-x64/native/libe_sqlite3.dylib": { + "rid": "maccatalyst-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/osx-arm64/native/libe_sqlite3.dylib": { + "rid": "osx-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/osx-x64/native/libe_sqlite3.dylib": { + "rid": "osx-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm/native/e_sqlite3.dll": { + "rid": "win-arm", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-arm64/native/e_sqlite3.dll": { + "rid": "win-arm64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x64/native/e_sqlite3.dll": { + "rid": "win-x64", + "assetType": "native", + "fileVersion": "0.0.0.0" + }, + "runtimes/win-x86/native/e_sqlite3.dll": { + "rid": "win-x86", + "assetType": "native", + "fileVersion": "0.0.0.0" + } + } + }, + "SQLitePCLRaw.provider.e_sqlite3/2.1.10": { + "dependencies": { + "SQLitePCLRaw.core": "2.1.10" + }, + "runtime": { + "lib/net6.0/SQLitePCLRaw.provider.e_sqlite3.dll": { + "assemblyVersion": "2.1.10.2445", + "fileVersion": "2.1.10.2445" + } + } + }, + "Swashbuckle.AspNetCore/7.0.0": { + "dependencies": { + "Microsoft.Extensions.ApiDescription.Server": "6.0.5", + "Swashbuckle.AspNetCore.Swagger": "7.0.0", + "Swashbuckle.AspNetCore.SwaggerGen": "7.0.0", + "Swashbuckle.AspNetCore.SwaggerUI": "7.0.0" + } + }, + "Swashbuckle.AspNetCore.Swagger/7.0.0": { + "dependencies": { + "Microsoft.OpenApi": "1.6.22" + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.Swagger.dll": { + "assemblyVersion": "7.0.0.0", + "fileVersion": "7.0.0.854" + } + } + }, + "Swashbuckle.AspNetCore.SwaggerGen/7.0.0": { + "dependencies": { + "Swashbuckle.AspNetCore.Swagger": "7.0.0" + }, + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll": { + "assemblyVersion": "7.0.0.0", + "fileVersion": "7.0.0.854" + } + } + }, + "Swashbuckle.AspNetCore.SwaggerUI/7.0.0": { + "runtime": { + "lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll": { + "assemblyVersion": "7.0.0.0", + "fileVersion": "7.0.0.854" + } + } + }, + "System.CodeDom/6.0.0": {}, + "System.Collections.Immutable/7.0.0": {}, + "System.Composition/7.0.0": { + "dependencies": { + "System.Composition.AttributedModel": "7.0.0", + "System.Composition.Convention": "7.0.0", + "System.Composition.Hosting": "7.0.0", + "System.Composition.Runtime": "7.0.0", + "System.Composition.TypedParts": "7.0.0" + } + }, + "System.Composition.AttributedModel/7.0.0": {}, + "System.Composition.Convention/7.0.0": { + "dependencies": { + "System.Composition.AttributedModel": "7.0.0" + } + }, + "System.Composition.Hosting/7.0.0": { + "dependencies": { + "System.Composition.Runtime": "7.0.0" + } + }, + "System.Composition.Runtime/7.0.0": {}, + "System.Composition.TypedParts/7.0.0": { + "dependencies": { + "System.Composition.AttributedModel": "7.0.0", + "System.Composition.Hosting": "7.0.0", + "System.Composition.Runtime": "7.0.0" + } + }, + "System.Diagnostics.DiagnosticSource/8.0.0": {}, + "System.IdentityModel.Tokens.Jwt/8.3.0": { + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "8.3.0", + "Microsoft.IdentityModel.Tokens": "8.3.0" + }, + "runtime": { + "lib/net9.0/System.IdentityModel.Tokens.Jwt.dll": { + "assemblyVersion": "8.3.0.0", + "fileVersion": "8.3.0.51204" + } + } + }, + "System.IO.Pipelines/7.0.0": {}, + "System.Memory/4.5.3": {}, + "System.Reflection.Metadata/7.0.0": { + "dependencies": { + "System.Collections.Immutable": "7.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe/6.0.0": {}, + "System.Text.Json/9.0.0": {}, + "System.Threading.Channels/7.0.0": {}, + "WebPush/1.0.12": { + "dependencies": { + "Newtonsoft.Json": "13.0.3", + "Portable.BouncyCastle": "1.8.1.3" + }, + "runtime": { + "lib/net5.0/WebPush.dll": { + "assemblyVersion": "1.0.11.0", + "fileVersion": "1.0.11.0" + } + } + } + } + }, + "libraries": { + "LittleShop/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "AutoMapper/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/Fx1SbJ16qS7dU4i604Sle+U9VLX+WSNVJggk6MupKVkYvvBm4XqYaeFuf67diHefHKHs50uQIS2YEDFhPCakQ==", + "path": "automapper/13.0.1", + "hashPath": "automapper.13.0.1.nupkg.sha512" + }, + "BTCPayServer.Client/2.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1tFbw2z6Nj/b+wr3Ht3G1Ux3Vsnlk7mYVMGxZeimVGHkPkRzbjTKXzSDsMDFOR7b9/W5Jwe8ibSQqssxFqlnXw==", + "path": "btcpayserver.client/2.0.0", + "hashPath": "btcpayserver.client.2.0.0.nupkg.sha512" + }, + "BTCPayServer.Lightning.Common/1.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1LlWIsx0KcuCUzdZb2Ta+gF4sfLmNYtQnnOSzXQ7kafs7VbEohyzntjX/aASpBLt7cQ7k1jlrumh3sLClRcuGg==", + "path": "btcpayserver.lightning.common/1.5.1", + "hashPath": "btcpayserver.lightning.common.1.5.1.nupkg.sha512" + }, + "FluentValidation/11.11.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cyIVdQBwSipxWG8MA3Rqox7iNbUNUTK5bfJi9tIdm4CAfH71Oo5ABLP4/QyrUwuakqpUEPGtE43BDddvEehuYw==", + "path": "fluentvalidation/11.11.0", + "hashPath": "fluentvalidation.11.11.0.nupkg.sha512" + }, + "FluentValidation.AspNetCore/11.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jtFVgKnDFySyBlPS8bZbTKEEwJZnn11rXXJ2SQnjDhZ56rQqybBg9Joq4crRLz3y0QR8WoOq4iE4piV81w/Djg==", + "path": "fluentvalidation.aspnetcore/11.3.0", + "hashPath": "fluentvalidation.aspnetcore.11.3.0.nupkg.sha512" + }, + "FluentValidation.DependencyInjectionExtensions/11.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iWM0LS1MDYX06pcjMEQKqHirl2zkjHlNV23mEJSoR1IZI7KQmTa0RcTtGEJpj5+iHvBCfrzP2mYKM4FtRKVb+A==", + "path": "fluentvalidation.dependencyinjectionextensions/11.5.1", + "hashPath": "fluentvalidation.dependencyinjectionextensions.11.5.1.nupkg.sha512" + }, + "Humanizer.Core/2.14.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lQKvtaTDOXnoVJ20ibTuSIOf2i0uO0MPbDhd1jm238I+U/2ZnRENj0cktKZhtchBMtCUSRQ5v4xBCUbKNmyVMw==", + "path": "humanizer.core/2.14.1", + "hashPath": "humanizer.core.2.14.1.nupkg.sha512" + }, + "Microsoft.AspNetCore.Authentication.JwtBearer/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bs+1Pq3vQdS2lTyxNUd9fEhtMsq3eLUpK36k2t56iDMVrk6OrAoFtvrQrTK0Y0OetTcJrUkGU7hBlf+ORzHLqQ==", + "path": "microsoft.aspnetcore.authentication.jwtbearer/9.0.0", + "hashPath": "microsoft.aspnetcore.authentication.jwtbearer.9.0.0.nupkg.sha512" + }, + "Microsoft.AspNetCore.Cryptography.Internal/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-M1dzTEl+2+RqT4vWcqEpWasPXHd58wC93U7QMlmPSmx+qixyVxCQjZ183wr7Wa68b4pF7wC501MU9rdA0ZNhMg==", + "path": "microsoft.aspnetcore.cryptography.internal/9.0.0", + "hashPath": "microsoft.aspnetcore.cryptography.internal.9.0.0.nupkg.sha512" + }, + "Microsoft.AspNetCore.Cryptography.KeyDerivation/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-9X4cx2IHNpYb9ka984BjDpJnKkindW17Z2kR/RI5pbTcbVUVMJjiAKnBhAqH24KtAEf1AU64LD60byzCn0/n8w==", + "path": "microsoft.aspnetcore.cryptography.keyderivation/9.0.0", + "hashPath": "microsoft.aspnetcore.cryptography.keyderivation.9.0.0.nupkg.sha512" + }, + "Microsoft.AspNetCore.Identity.EntityFrameworkCore/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-fwQkBQGaiRKDQWBc7PXxDiDXtsUsRPL88Jp0CqjqoDhd9p5uHSyuv6g3ALq2EbCvKcWk/7pOKsJiDomPvp/ptA==", + "path": "microsoft.aspnetcore.identity.entityframeworkcore/9.0.0", + "hashPath": "microsoft.aspnetcore.identity.entityframeworkcore.9.0.0.nupkg.sha512" + }, + "Microsoft.Bcl.AsyncInterfaces/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3aeMZ1N0lJoSyzqiP03hqemtb1BijhsJADdobn/4nsMJ8V1H+CrpuduUe4hlRdx+ikBQju1VGjMD1GJ3Sk05Eg==", + "path": "microsoft.bcl.asyncinterfaces/7.0.0", + "hashPath": "microsoft.bcl.asyncinterfaces.7.0.0.nupkg.sha512" + }, + "Microsoft.Build.Framework/17.8.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-NrQZJW8TlKVPx72yltGb8SVz3P5mNRk9fNiD/ao8jRSk48WqIIdCn99q4IjlVmPcruuQ+yLdjNQLL8Rb4c916g==", + "path": "microsoft.build.framework/17.8.3", + "hashPath": "microsoft.build.framework.17.8.3.nupkg.sha512" + }, + "Microsoft.Build.Locator/1.7.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-sPy10x527Ph16S2u0yGME4S6ohBKJ69WfjeGG/bvELYeZVmJdKjxgnlL8cJJJLGV/cZIRqSfB12UDB8ICakOog==", + "path": "microsoft.build.locator/1.7.8", + "hashPath": "microsoft.build.locator.1.7.8.nupkg.sha512" + }, + "Microsoft.CodeAnalysis.Analyzers/3.3.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AxkxcPR+rheX0SmvpLVIGLhOUXAKG56a64kV9VQZ4y9gR9ZmPXnqZvHJnmwLSwzrEP6junUF11vuc+aqo5r68g==", + "path": "microsoft.codeanalysis.analyzers/3.3.4", + "hashPath": "microsoft.codeanalysis.analyzers.3.3.4.nupkg.sha512" + }, + "Microsoft.CodeAnalysis.Common/4.8.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/jR+e/9aT+BApoQJABlVCKnnggGQbvGh7BKq2/wI1LamxC+LbzhcLj4Vj7gXCofl1n4E521YfF9w0WcASGg/KA==", + "path": "microsoft.codeanalysis.common/4.8.0", + "hashPath": "microsoft.codeanalysis.common.4.8.0.nupkg.sha512" + }, + "Microsoft.CodeAnalysis.CSharp/4.8.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-+3+qfdb/aaGD8PZRCrsdobbzGs1m9u119SkkJt8e/mk3xLJz/udLtS2T6nY27OTXxBBw10HzAbC8Z9w08VyP/g==", + "path": "microsoft.codeanalysis.csharp/4.8.0", + "hashPath": "microsoft.codeanalysis.csharp.4.8.0.nupkg.sha512" + }, + "Microsoft.CodeAnalysis.CSharp.Workspaces/4.8.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3amm4tq4Lo8/BGvg9p3BJh3S9nKq2wqCXfS7138i69TUpo/bD+XvD0hNurpEBtcNZhi1FyutiomKJqVF39ugYA==", + "path": "microsoft.codeanalysis.csharp.workspaces/4.8.0", + "hashPath": "microsoft.codeanalysis.csharp.workspaces.4.8.0.nupkg.sha512" + }, + "Microsoft.CodeAnalysis.Workspaces.Common/4.8.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-LXyV+MJKsKRu3FGJA3OmSk40OUIa/dQCFLOnm5X8MNcujx7hzGu8o+zjXlb/cy5xUdZK2UKYb9YaQ2E8m9QehQ==", + "path": "microsoft.codeanalysis.workspaces.common/4.8.0", + "hashPath": "microsoft.codeanalysis.workspaces.common.4.8.0.nupkg.sha512" + }, + "Microsoft.CodeAnalysis.Workspaces.MSBuild/4.8.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IEYreI82QZKklp54yPHxZNG9EKSK6nHEkeuf+0Asie9llgS1gp0V1hw7ODG+QyoB7MuAnNQHmeV1Per/ECpv6A==", + "path": "microsoft.codeanalysis.workspaces.msbuild/4.8.0", + "hashPath": "microsoft.codeanalysis.workspaces.msbuild.4.8.0.nupkg.sha512" + }, + "Microsoft.Data.Sqlite.Core/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cFfZjFL+tqzGYw9lB31EkV1IWF5xRQNk2k+MQd+Cf86Gl6zTeAoiZIFw5sRB1Z8OxpEC7nu+nTDsLSjieBAPTw==", + "path": "microsoft.data.sqlite.core/9.0.0", + "hashPath": "microsoft.data.sqlite.core.9.0.0.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-bNGdPhN762+BIIO5MFYLjafRqkSS1MqLOc/erd55InvLnFxt9H3N5JNsuag1ZHyBor1VtD42U0CHpgqkWeAYgQ==", + "path": "microsoft.entityframeworkcore/9.0.8", + "hashPath": "microsoft.entityframeworkcore.9.0.8.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.Abstractions/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-B2yfAIQRRAQ4zvvWqh+HudD+juV3YoLlpXnrog3tU0PM9AFpuq6xo0+mEglN1P43WgdcUiF+65CWBcZe35s15Q==", + "path": "microsoft.entityframeworkcore.abstractions/9.0.8", + "hashPath": "microsoft.entityframeworkcore.abstractions.9.0.8.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.Analyzers/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2EYStCXt4Hi9p3J3EYMQbItJDtASJd064Kcs8C8hj8Jt5srILrR9qlaL0Ryvk8NrWQoCQvIELsmiuqLEZMLvGA==", + "path": "microsoft.entityframeworkcore.analyzers/9.0.8", + "hashPath": "microsoft.entityframeworkcore.analyzers.9.0.8.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.Design/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Pqo8I+yHJ3VQrAoY0hiSncf+5P7gN/RkNilK5e+/K/yKh+yAWxdUAI6t0TG26a9VPlCa9FhyklzyFvRyj3YG9A==", + "path": "microsoft.entityframeworkcore.design/9.0.0", + "hashPath": "microsoft.entityframeworkcore.design.9.0.0.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.InMemory/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-F5+lo74OJH9iik/WtMae9ySeew1pxiYSmODkTmHo7n7JsCM5flW1WlUCjACoe7XM9Gng2ndUwXjIizhzx3Os5w==", + "path": "microsoft.entityframeworkcore.inmemory/9.0.8", + "hashPath": "microsoft.entityframeworkcore.inmemory.9.0.8.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.Relational/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-j+msw6fWgAE9M3Q/5B9Uhv7pdAdAQUvFPJAiBJmoy+OXvehVbfbCE8ftMAa51Uo2ZeiqVnHShhnv4Y4UJJmUzA==", + "path": "microsoft.entityframeworkcore.relational/9.0.0", + "hashPath": "microsoft.entityframeworkcore.relational.9.0.0.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.Sqlite/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-xu6dlgBO9I1WA1WdT+rUvv+ZGQ9aGRn3c246ykyuFzBX02oNYd1lk7LEVGhjBN1T49N3C9yBUHFQY8vY4JZQrw==", + "path": "microsoft.entityframeworkcore.sqlite/9.0.0", + "hashPath": "microsoft.entityframeworkcore.sqlite.9.0.0.nupkg.sha512" + }, + "Microsoft.EntityFrameworkCore.Sqlite.Core/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4gmIZli/Na39mck6s/gO2n1NdOHHwNQfSWucpA+bAU5UAEMYFGMXpCR1AHoo/VJuyMkfpBxuHzkj1/xczy2vFg==", + "path": "microsoft.entityframeworkcore.sqlite.core/9.0.0", + "hashPath": "microsoft.entityframeworkcore.sqlite.core.9.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.ApiDescription.Server/6.0.5": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Ckb5EDBUNJdFWyajfXzUIMRkhf52fHZOQuuZg/oiu8y7zDCVwD0iHhew6MnThjHmevanpxL3f5ci2TtHQEN6bw==", + "path": "microsoft.extensions.apidescription.server/6.0.5", + "hashPath": "microsoft.extensions.apidescription.server.6.0.5.nupkg.sha512" + }, + "Microsoft.Extensions.Caching.Abstractions/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4h7bsVoKoiK+SlPM+euX/ayGnKZhl47pPCidLTiio9xyG+vgVVfcYxcYQgjm0SCrdSxjG0EGIAKF8EFr3G8Ifw==", + "path": "microsoft.extensions.caching.abstractions/9.0.8", + "hashPath": "microsoft.extensions.caching.abstractions.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.Caching.Memory/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-grR+oPyj8HVn4DT8CFUUdSw2pZZKS13KjytFe4txpHQliGM1GEDotohmjgvyl3hm7RFB3FRqvbouEX3/1ewp5A==", + "path": "microsoft.extensions.caching.memory/9.0.8", + "hashPath": "microsoft.extensions.caching.memory.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Abstractions/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lqvd7W3FGKUO1+ZoUEMaZ5XDJeWvjpy2/M/ptCGz3tXLD4HWVaSzjufsAsjemasBEg+2SxXVtYVvGt5r2nKDlg==", + "path": "microsoft.extensions.configuration.abstractions/9.0.0", + "hashPath": "microsoft.extensions.configuration.abstractions.9.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Configuration.Binder/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-mBMoXLsr5s1y2zOHWmKsE9veDcx8h1x/c3rz4baEdQKTeDcmQAPNbB54Pi/lhFO3K431eEq6PFbMgLaa6PHFfA==", + "path": "microsoft.extensions.configuration.binder/8.0.0", + "hashPath": "microsoft.extensions.configuration.binder.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JJjI2Fa+QtZcUyuNjbKn04OjIUX5IgFGFu/Xc+qvzh1rXdZHLcnqqVXhR4093bGirTwacRlHiVg1XYI9xum6QQ==", + "path": "microsoft.extensions.dependencyinjection/9.0.8", + "hashPath": "microsoft.extensions.dependencyinjection.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-xY3lTjj4+ZYmiKIkyWitddrp1uL5uYiweQjqo4BKBw01ZC4HhcfgLghDpPZcUlppgWAFqFy9SgkiYWOMx365pw==", + "path": "microsoft.extensions.dependencyinjection.abstractions/9.0.8", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyModel/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-saxr2XzwgDU77LaQfYFXmddEDRUKHF4DaGMZkNB3qjdVSZlax3//dGJagJkKrGMIPNZs2jVFXITyCCR6UHJNdA==", + "path": "microsoft.extensions.dependencymodel/9.0.0", + "hashPath": "microsoft.extensions.dependencymodel.9.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Diagnostics.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JHYCQG7HmugNYUhOl368g+NMxYE/N/AiclCYRNlgCY9eVyiBkOHMwK4x60RYMxv9EL3+rmj1mqHvdCiPpC+D4Q==", + "path": "microsoft.extensions.diagnostics.abstractions/8.0.0", + "hashPath": "microsoft.extensions.diagnostics.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.FileProviders.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==", + "path": "microsoft.extensions.fileproviders.abstractions/8.0.0", + "hashPath": "microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Hosting.Abstractions/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AG7HWwVRdCHlaA++1oKDxLsXIBxmDpMPb3VoyOoAghEWnkUvEAdYQUwnV4jJbAaa/nMYNiEh5ByoLauZBEiovg==", + "path": "microsoft.extensions.hosting.abstractions/8.0.0", + "hashPath": "microsoft.extensions.hosting.abstractions.8.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Identity.Core/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-+cQjUs8PIheIMALzrf/e4gW6A/yOK8XYBxeEmAfLvVIaV9lsBGvVT0zjEZ1KPQDJ9nUeQ9uAw077J7LPUwv8wA==", + "path": "microsoft.extensions.identity.core/9.0.0", + "hashPath": "microsoft.extensions.identity.core.9.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Identity.Stores/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XG3opf0KgWoYAUdLRhrIvI46W+/E45Ov8rzgwr0omrq5u06MCrsuMm0nPmd+pIWjMXRxbBk1uL47zGyW1lI5Hw==", + "path": "microsoft.extensions.identity.stores/9.0.0", + "hashPath": "microsoft.extensions.identity.stores.9.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Logging/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Z/7ze+0iheT7FJeZPqJKARYvyC2bmwu3whbm/48BJjdlGVvgDguoCqJIkI/67NkroTYobd5geai1WheNQvWrgA==", + "path": "microsoft.extensions.logging/9.0.8", + "hashPath": "microsoft.extensions.logging.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pYnAffJL7ARD/HCnnPvnFKSIHnTSmWz84WIlT9tPeQ4lHNiu0Az7N/8itihWvcF8sT+VVD5lq8V+ckMzu4SbOw==", + "path": "microsoft.extensions.logging.abstractions/9.0.8", + "hashPath": "microsoft.extensions.logging.abstractions.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.Options/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-OmTaQ0v4gxGQkehpwWIqPoEiwsPuG/u4HUsbOFoWGx4DKET2AXzopnFe/fE608FIhzc/kcg2p8JdyMRCCUzitQ==", + "path": "microsoft.extensions.options/9.0.8", + "hashPath": "microsoft.extensions.options.9.0.8.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/9.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tizSIOEsIgSNSSh+hKeUVPK7xmTIjR8s+mJWOu1KXV3htvNQiPMFRMO17OdI1y/4ZApdBVk49u/08QGC9yvLug==", + "path": "microsoft.extensions.primitives/9.0.8", + "hashPath": "microsoft.extensions.primitives.9.0.8.nupkg.sha512" + }, + "Microsoft.IdentityModel.Abstractions/8.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jNin7yvWZu+K3U24q+6kD+LmGSRfbkHl9Px8hN1XrGwq6ZHgKGi/zuTm5m08G27fwqKfVXIWuIcUeq4Y1VQUOg==", + "path": "microsoft.identitymodel.abstractions/8.3.0", + "hashPath": "microsoft.identitymodel.abstractions.8.3.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.JsonWebTokens/8.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4SVXLT8sDG7CrHiszEBrsDYi+aDW0W9d+fuWUGdZPBdan56aM6fGXJDjbI0TVGEDjJhXbACQd8F/BnC7a+m2RQ==", + "path": "microsoft.identitymodel.jsonwebtokens/8.3.0", + "hashPath": "microsoft.identitymodel.jsonwebtokens.8.3.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Logging/8.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-4w4pSIGHhCCLTHqtVNR2Cc/zbDIUWIBHTZCu/9ZHm2SVwrXY3RJMcZ7EFGiKqmKZMQZJzA0bpwCZ6R8Yb7i5VQ==", + "path": "microsoft.identitymodel.logging/8.3.0", + "hashPath": "microsoft.identitymodel.logging.8.3.0.nupkg.sha512" + }, + "Microsoft.IdentityModel.Protocols/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uA2vpKqU3I2mBBEaeJAWPTjT9v1TZrGWKdgK6G5qJd03CLx83kdiqO9cmiK8/n1erkHzFBwU/RphP83aAe3i3g==", + "path": "microsoft.identitymodel.protocols/8.0.1", + "hashPath": "microsoft.identitymodel.protocols.8.0.1.nupkg.sha512" + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect/8.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-AQDbfpL+yzuuGhO/mQhKNsp44pm5Jv8/BI4KiFXR7beVGZoSH35zMV3PrmcfvSTsyI6qrcR898NzUauD6SRigg==", + "path": "microsoft.identitymodel.protocols.openidconnect/8.0.1", + "hashPath": "microsoft.identitymodel.protocols.openidconnect.8.0.1.nupkg.sha512" + }, + "Microsoft.IdentityModel.Tokens/8.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-yGzqmk+kInH50zeSEH/L1/J0G4/yqTQNq4YmdzOhpE7s/86tz37NS2YbbY2ievbyGjmeBI1mq26QH+yBR6AK3Q==", + "path": "microsoft.identitymodel.tokens/8.3.0", + "hashPath": "microsoft.identitymodel.tokens.8.3.0.nupkg.sha512" + }, + "Microsoft.OpenApi/1.6.22": { + "type": "package", + "serviceable": true, + "sha512": "sha512-aBvunmrdu/x+4CaA/UP1Jx4xWGwk4kymhoIRnn2Vp+zi5/KOPQJ9EkSXHRUr01WcGKtYl3Au7XfkPJbU1G2sjQ==", + "path": "microsoft.openapi/1.6.22", + "hashPath": "microsoft.openapi.1.6.22.nupkg.sha512" + }, + "Mono.TextTemplating/3.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YqueG52R/Xej4VVbKuRIodjiAhV0HR/XVbLbNrJhCZnzjnSjgMJ/dCdV0akQQxavX6hp/LC6rqLGLcXeQYU7XA==", + "path": "mono.texttemplating/3.0.0", + "hashPath": "mono.texttemplating.3.0.0.nupkg.sha512" + }, + "NBitcoin/7.0.37": { + "type": "package", + "serviceable": true, + "sha512": "sha512-JTdX01upC8DDTWJE2Q9Qno/v1zMdVYJXdMyiDORBfAvJ9G9wdMQ549Ki2ChisVtKn+TmxPiFJYPzHUGlBb4DRg==", + "path": "nbitcoin/7.0.37", + "hashPath": "nbitcoin.7.0.37.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "path": "newtonsoft.json/13.0.3", + "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512" + }, + "Portable.BouncyCastle/1.8.1.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1jUpszv0ETm+hl78HKnYgY3wPzt6qRtjxaPENNrGCuB8nondbR/j75WAKdd6sxXzOzBcX07WMZhZEYc4s5jVWg==", + "path": "portable.bouncycastle/1.8.1.3", + "hashPath": "portable.bouncycastle.1.8.1.3.nupkg.sha512" + }, + "Serilog/4.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2jDkUrSh5EofOp7Lx5Zgy0EB+7hXjjxE2ktTb1WVQmU00lDACR2TdROGKU0K1pDTBSJBN1PqgYpgOZF8mL7NJw==", + "path": "serilog/4.0.0", + "hashPath": "serilog.4.0.0.nupkg.sha512" + }, + "Serilog.AspNetCore/8.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Y5at41mc0OV982DEJslBKHd6uzcWO6POwR3QceJ6gtpMPxCzm4+FElGPF0RdaTD7MGsP6XXE05LMbSi0NO+sXg==", + "path": "serilog.aspnetcore/8.0.3", + "hashPath": "serilog.aspnetcore.8.0.3.nupkg.sha512" + }, + "Serilog.Extensions.Hosting/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-db0OcbWeSCvYQkHWu6n0v40N4kKaTAXNjlM3BKvcbwvNzYphQFcBR+36eQ/7hMMwOkJvAyLC2a9/jNdUL5NjtQ==", + "path": "serilog.extensions.hosting/8.0.0", + "hashPath": "serilog.extensions.hosting.8.0.0.nupkg.sha512" + }, + "Serilog.Extensions.Logging/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-YEAMWu1UnWgf1c1KP85l1SgXGfiVo0Rz6x08pCiPOIBt2Qe18tcZLvdBUuV5o1QHvrs8FAry9wTIhgBRtjIlEg==", + "path": "serilog.extensions.logging/8.0.0", + "hashPath": "serilog.extensions.logging.8.0.0.nupkg.sha512" + }, + "Serilog.Formatting.Compact/2.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ob6z3ikzFM3D1xalhFuBIK1IOWf+XrQq+H4KeH4VqBcPpNcmUgZlRQ2h3Q7wvthpdZBBoY86qZOI2LCXNaLlNA==", + "path": "serilog.formatting.compact/2.0.0", + "hashPath": "serilog.formatting.compact.2.0.0.nupkg.sha512" + }, + "Serilog.Settings.Configuration/8.0.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pkxvq0umBKK8IKFJc1aV5S/HGRG/NIxJ6FV42KaTPLfDmBOAbBUB1m5gqqlGxzEa1MgDDWtQlWJdHTSxVWNx+Q==", + "path": "serilog.settings.configuration/8.0.4", + "hashPath": "serilog.settings.configuration.8.0.4.nupkg.sha512" + }, + "Serilog.Sinks.Console/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IZ6bn79k+3SRXOBpwSOClUHikSkp2toGPCZ0teUkscv4dpDg9E2R2xVsNkLmwddE4OpNVO3N0xiYsAH556vN8Q==", + "path": "serilog.sinks.console/5.0.0", + "hashPath": "serilog.sinks.console.5.0.0.nupkg.sha512" + }, + "Serilog.Sinks.Debug/2.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Y6g3OBJ4JzTyyw16fDqtFcQ41qQAydnEvEqmXjhwhgjsnG/FaJ8GUqF5ldsC/bVkK8KYmqrPhDO+tm4dF6xx4A==", + "path": "serilog.sinks.debug/2.0.0", + "hashPath": "serilog.sinks.debug.2.0.0.nupkg.sha512" + }, + "Serilog.Sinks.File/6.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-lxjg89Y8gJMmFxVkbZ+qDgjl+T4yC5F7WSLTvA+5q0R04tfKVLRL/EHpYoJ/MEQd2EeCKDuylBIVnAYMotmh2A==", + "path": "serilog.sinks.file/6.0.0", + "hashPath": "serilog.sinks.file.6.0.0.nupkg.sha512" + }, + "SQLitePCLRaw.bundle_e_sqlite3/2.1.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UxWuisvZ3uVcVOLJQv7urM/JiQH+v3TmaJc1BLKl5Dxfm/nTzTUrqswCqg/INiYLi61AXnHo1M1JPmPqqLnAdg==", + "path": "sqlitepclraw.bundle_e_sqlite3/2.1.10", + "hashPath": "sqlitepclraw.bundle_e_sqlite3.2.1.10.nupkg.sha512" + }, + "SQLitePCLRaw.core/2.1.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Ii8JCbC7oiVclaE/mbDEK000EFIJ+ShRPwAvvV89GOZhQ+ZLtlnSWl6ksCNMKu/VGXA4Nfi2B7LhN/QFN9oBcw==", + "path": "sqlitepclraw.core/2.1.10", + "hashPath": "sqlitepclraw.core.2.1.10.nupkg.sha512" + }, + "SQLitePCLRaw.lib.e_sqlite3/2.1.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-mAr69tDbnf3QJpRy2nJz8Qdpebdil00fvycyByR58Cn9eARvR+UiG2Vzsp+4q1tV3ikwiYIjlXCQFc12GfebbA==", + "path": "sqlitepclraw.lib.e_sqlite3/2.1.10", + "hashPath": "sqlitepclraw.lib.e_sqlite3.2.1.10.nupkg.sha512" + }, + "SQLitePCLRaw.provider.e_sqlite3/2.1.10": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uZVTi02C1SxqzgT0HqTWatIbWGb40iIkfc3FpFCpE/r7g6K0PqzDUeefL6P6HPhDtc6BacN3yQysfzP7ks+wSQ==", + "path": "sqlitepclraw.provider.e_sqlite3/2.1.10", + "hashPath": "sqlitepclraw.provider.e_sqlite3.2.1.10.nupkg.sha512" + }, + "Swashbuckle.AspNetCore/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-aF6oCgMy8CC17cSbILAw9J4UVhqOE+0Z11V8JstA+pIrXcY8ZbNL3ayHOWKZm0NdHMS6RI1k5sFVfMkpZOobvw==", + "path": "swashbuckle.aspnetcore/7.0.0", + "hashPath": "swashbuckle.aspnetcore.7.0.0.nupkg.sha512" + }, + "Swashbuckle.AspNetCore.Swagger/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Y2QnwZkuszoIYpz069xqDU0h/rklVedE4a0NOdb8HSDTcXCmsi7Zm2RGdJccde5MojHmEhDmZggCO1wgpfZ2IA==", + "path": "swashbuckle.aspnetcore.swagger/7.0.0", + "hashPath": "swashbuckle.aspnetcore.swagger.7.0.0.nupkg.sha512" + }, + "Swashbuckle.AspNetCore.SwaggerGen/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-f/urqk9zkb5ZXc3ljLNP++JgYe2HTlA4WaIaO1DLRQLRFh3HXIZakFfMfTWX1T8NVqeMyJF7MzETN4HsokxNuQ==", + "path": "swashbuckle.aspnetcore.swaggergen/7.0.0", + "hashPath": "swashbuckle.aspnetcore.swaggergen.7.0.0.nupkg.sha512" + }, + "Swashbuckle.AspNetCore.SwaggerUI/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-rJJony+jsxvpfJM9ZGVxjp0DVpalZv8cAhiMSLW6L2hgUWb7k5qPVuzQHWXtkT8lrG1hQ8vWeR+HUwgCQm9J3A==", + "path": "swashbuckle.aspnetcore.swaggerui/7.0.0", + "hashPath": "swashbuckle.aspnetcore.swaggerui.7.0.0.nupkg.sha512" + }, + "System.CodeDom/6.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-CPc6tWO1LAer3IzfZufDBRL+UZQcj5uS207NHALQzP84Vp/z6wF0Aa0YZImOQY8iStY0A2zI/e3ihKNPfUm8XA==", + "path": "system.codedom/6.0.0", + "hashPath": "system.codedom.6.0.0.nupkg.sha512" + }, + "System.Collections.Immutable/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dQPcs0U1IKnBdRDBkrCTi1FoajSTBzLcVTpjO4MBCMC7f4pDOIPzgBoX8JjG7X6uZRJ8EBxsi8+DR1JuwjnzOQ==", + "path": "system.collections.immutable/7.0.0", + "hashPath": "system.collections.immutable.7.0.0.nupkg.sha512" + }, + "System.Composition/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-tRwgcAkDd85O8Aq6zHDANzQaq380cek9lbMg5Qma46u5BZXq/G+XvIYmu+UI+BIIZ9zssXLYrkTykEqxxvhcmg==", + "path": "system.composition/7.0.0", + "hashPath": "system.composition.7.0.0.nupkg.sha512" + }, + "System.Composition.AttributedModel/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2QzClqjElKxgI1jK1Jztnq44/8DmSuTSGGahXqQ4TdEV0h9s2KikQZIgcEqVzR7OuWDFPGLHIprBJGQEPr8fAQ==", + "path": "system.composition.attributedmodel/7.0.0", + "hashPath": "system.composition.attributedmodel.7.0.0.nupkg.sha512" + }, + "System.Composition.Convention/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-IMhTlpCs4HmlD8B+J8/kWfwX7vrBBOs6xyjSTzBlYSs7W4OET4tlkR/Sg9NG8jkdJH9Mymq0qGdYS1VPqRTBnQ==", + "path": "system.composition.convention/7.0.0", + "hashPath": "system.composition.convention.7.0.0.nupkg.sha512" + }, + "System.Composition.Hosting/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-eB6gwN9S+54jCTBJ5bpwMOVerKeUfGGTYCzz3QgDr1P55Gg/Wb27ShfPIhLMjmZ3MoAKu8uUSv6fcCdYJTN7Bg==", + "path": "system.composition.hosting/7.0.0", + "hashPath": "system.composition.hosting.7.0.0.nupkg.sha512" + }, + "System.Composition.Runtime/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-aZJ1Zr5Txe925rbo4742XifEyW0MIni1eiUebmcrP3HwLXZ3IbXUj4MFMUH/RmnJOAQiS401leg/2Sz1MkApDw==", + "path": "system.composition.runtime/7.0.0", + "hashPath": "system.composition.runtime.7.0.0.nupkg.sha512" + }, + "System.Composition.TypedParts/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ZK0KNPfbtxVceTwh+oHNGUOYV2WNOHReX2AXipuvkURC7s/jPwoWfsu3SnDBDgofqbiWr96geofdQ2erm/KTHg==", + "path": "system.composition.typedparts/7.0.0", + "hashPath": "system.composition.typedparts.7.0.0.nupkg.sha512" + }, + "System.Diagnostics.DiagnosticSource/8.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "path": "system.diagnostics.diagnosticsource/8.0.0", + "hashPath": "system.diagnostics.diagnosticsource.8.0.0.nupkg.sha512" + }, + "System.IdentityModel.Tokens.Jwt/8.3.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-9GESpDG0Zb17HD5mBW/uEWi2yz/uKPmCthX2UhyLnk42moGH2FpMgXA2Y4l2Qc7P75eXSUTA6wb/c9D9GSVkzw==", + "path": "system.identitymodel.tokens.jwt/8.3.0", + "hashPath": "system.identitymodel.tokens.jwt.8.3.0.nupkg.sha512" + }, + "System.IO.Pipelines/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-jRn6JYnNPW6xgQazROBLSfpdoczRw694vO5kKvMcNnpXuolEixUyw6IBuBs2Y2mlSX/LdLvyyWmfXhaI3ND1Yg==", + "path": "system.io.pipelines/7.0.0", + "hashPath": "system.io.pipelines.7.0.0.nupkg.sha512" + }, + "System.Memory/4.5.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==", + "path": "system.memory/4.5.3", + "hashPath": "system.memory.4.5.3.nupkg.sha512" + }, + "System.Reflection.Metadata/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-MclTG61lsD9sYdpNz9xsKBzjsmsfCtcMZYXz/IUr2zlhaTaABonlr1ESeompTgM+Xk+IwtGYU7/voh3YWB/fWw==", + "path": "system.reflection.metadata/7.0.0", + "hashPath": "system.reflection.metadata.7.0.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/6.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==", + "path": "system.runtime.compilerservices.unsafe/6.0.0", + "hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512" + }, + "System.Text.Json/9.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-js7+qAu/9mQvnhA4EfGMZNEzXtJCDxgkgj8ohuxq/Qxv+R56G+ljefhiJHOxTNiw54q8vmABCWUwkMulNdlZ4A==", + "path": "system.text.json/9.0.0", + "hashPath": "system.text.json.9.0.0.nupkg.sha512" + }, + "System.Threading.Channels/7.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-qmeeYNROMsONF6ndEZcIQ+VxR4Q/TX/7uIVLJqtwIWL7dDWeh0l1UIqgo4wYyjG//5lUNhwkLDSFl+pAWO6oiA==", + "path": "system.threading.channels/7.0.0", + "hashPath": "system.threading.channels.7.0.0.nupkg.sha512" + }, + "WebPush/1.0.12": { + "type": "package", + "serviceable": true, + "sha512": "sha512-vc91Uby6UaQQijOPRY4B1tWFaQJlbfOyfOMIPpdAT6mANcPhHcvDJeLjr6B0Adjij71WIAH718MC7coQdrJZAw==", + "path": "webpush/1.0.12", + "hashPath": "webpush.1.0.12.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/publish/LittleShop.dll b/publish/LittleShop.dll new file mode 100644 index 0000000..d0905f5 Binary files /dev/null and b/publish/LittleShop.dll differ diff --git a/publish/LittleShop.pdb b/publish/LittleShop.pdb new file mode 100644 index 0000000..af3901a Binary files /dev/null and b/publish/LittleShop.pdb differ diff --git a/publish/LittleShop.runtimeconfig.json b/publish/LittleShop.runtimeconfig.json new file mode 100644 index 0000000..b10d651 --- /dev/null +++ b/publish/LittleShop.runtimeconfig.json @@ -0,0 +1,21 @@ +{ + "runtimeOptions": { + "tfm": "net9.0", + "frameworks": [ + { + "name": "Microsoft.NETCore.App", + "version": "9.0.0" + }, + { + "name": "Microsoft.AspNetCore.App", + "version": "9.0.0" + } + ], + "configProperties": { + "System.GC.Server": true, + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false, + "System.Reflection.NullabilityInfoContext.IsSupported": true, + "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false + } + } +} \ No newline at end of file diff --git a/publish/LittleShop.staticwebassets.endpoints.json b/publish/LittleShop.staticwebassets.endpoints.json new file mode 100644 index 0000000..0f6ebbc --- /dev/null +++ b/publish/LittleShop.staticwebassets.endpoints.json @@ -0,0 +1 @@ +{"Version":1,"ManifestType":"Publish","Endpoints":[{"Route":"css/corporate-steel-theme.csnxpa9z00.css","AssetFile":"css/corporate-steel-theme.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000475737393"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2101"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"xP2WMHJdNoU3Mck4PBsWNM0MHy18DBc531ZlTSPyLY4=\""},{"Name":"ETag","Value":"W/\"rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"csnxpa9z00"},{"Name":"integrity","Value":"sha256-rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4="},{"Name":"label","Value":"css/corporate-steel-theme.css"}]},{"Route":"css/corporate-steel-theme.csnxpa9z00.css","AssetFile":"css/corporate-steel-theme.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000567214974"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1762"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"bq3n457OUizynL9wGt7hmZIZ6CbytHkjrWXNnkmAzQQ=\""},{"Name":"ETag","Value":"W/\"rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"csnxpa9z00"},{"Name":"integrity","Value":"sha256-rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4="},{"Name":"label","Value":"css/corporate-steel-theme.css"}]},{"Route":"css/corporate-steel-theme.csnxpa9z00.css","AssetFile":"css/corporate-steel-theme.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"11016"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"csnxpa9z00"},{"Name":"integrity","Value":"sha256-rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4="},{"Name":"label","Value":"css/corporate-steel-theme.css"}]},{"Route":"css/corporate-steel-theme.csnxpa9z00.css.br","AssetFile":"css/corporate-steel-theme.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1762"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"bq3n457OUizynL9wGt7hmZIZ6CbytHkjrWXNnkmAzQQ=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"csnxpa9z00"},{"Name":"integrity","Value":"sha256-bq3n457OUizynL9wGt7hmZIZ6CbytHkjrWXNnkmAzQQ="},{"Name":"label","Value":"css/corporate-steel-theme.css.br"}]},{"Route":"css/corporate-steel-theme.csnxpa9z00.css.gz","AssetFile":"css/corporate-steel-theme.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2101"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"xP2WMHJdNoU3Mck4PBsWNM0MHy18DBc531ZlTSPyLY4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"csnxpa9z00"},{"Name":"integrity","Value":"sha256-xP2WMHJdNoU3Mck4PBsWNM0MHy18DBc531ZlTSPyLY4="},{"Name":"label","Value":"css/corporate-steel-theme.css.gz"}]},{"Route":"css/corporate-steel-theme.css","AssetFile":"css/corporate-steel-theme.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000475737393"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2101"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"xP2WMHJdNoU3Mck4PBsWNM0MHy18DBc531ZlTSPyLY4=\""},{"Name":"ETag","Value":"W/\"rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4="}]},{"Route":"css/corporate-steel-theme.css","AssetFile":"css/corporate-steel-theme.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000567214974"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1762"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"bq3n457OUizynL9wGt7hmZIZ6CbytHkjrWXNnkmAzQQ=\""},{"Name":"ETag","Value":"W/\"rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4="}]},{"Route":"css/corporate-steel-theme.css","AssetFile":"css/corporate-steel-theme.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"11016"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-rGfNPT1uzzgYwJQMA/E9K0Y5Un1FF0y8mrRmWzTPEp4="}]},{"Route":"css/corporate-steel-theme.css.br","AssetFile":"css/corporate-steel-theme.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1762"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"bq3n457OUizynL9wGt7hmZIZ6CbytHkjrWXNnkmAzQQ=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-bq3n457OUizynL9wGt7hmZIZ6CbytHkjrWXNnkmAzQQ="}]},{"Route":"css/corporate-steel-theme.css.gz","AssetFile":"css/corporate-steel-theme.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2101"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"xP2WMHJdNoU3Mck4PBsWNM0MHy18DBc531ZlTSPyLY4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-xP2WMHJdNoU3Mck4PBsWNM0MHy18DBc531ZlTSPyLY4="}]},{"Route":"css/modern-admin.css","AssetFile":"css/modern-admin.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000432525952"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2311"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"L8Y89C8srYVQk/zUNp15qclN5ip9tMHQsNIUK/y2sGM=\""},{"Name":"ETag","Value":"W/\"91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE="}]},{"Route":"css/modern-admin.css","AssetFile":"css/modern-admin.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000513083633"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1948"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"RkbdamGNS1RWvGA2VKkqIamUUazp6ZElZp2LpCVpYHE=\""},{"Name":"ETag","Value":"W/\"91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE="}]},{"Route":"css/modern-admin.css","AssetFile":"css/modern-admin.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"9141"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE="}]},{"Route":"css/modern-admin.css.br","AssetFile":"css/modern-admin.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1948"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"RkbdamGNS1RWvGA2VKkqIamUUazp6ZElZp2LpCVpYHE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-RkbdamGNS1RWvGA2VKkqIamUUazp6ZElZp2LpCVpYHE="}]},{"Route":"css/modern-admin.css.gz","AssetFile":"css/modern-admin.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2311"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"L8Y89C8srYVQk/zUNp15qclN5ip9tMHQsNIUK/y2sGM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-L8Y89C8srYVQk/zUNp15qclN5ip9tMHQsNIUK/y2sGM="}]},{"Route":"css/modern-admin.pot7sfma4v.css","AssetFile":"css/modern-admin.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000432525952"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2311"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"L8Y89C8srYVQk/zUNp15qclN5ip9tMHQsNIUK/y2sGM=\""},{"Name":"ETag","Value":"W/\"91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"pot7sfma4v"},{"Name":"integrity","Value":"sha256-91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE="},{"Name":"label","Value":"css/modern-admin.css"}]},{"Route":"css/modern-admin.pot7sfma4v.css","AssetFile":"css/modern-admin.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000513083633"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1948"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"RkbdamGNS1RWvGA2VKkqIamUUazp6ZElZp2LpCVpYHE=\""},{"Name":"ETag","Value":"W/\"91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"pot7sfma4v"},{"Name":"integrity","Value":"sha256-91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE="},{"Name":"label","Value":"css/modern-admin.css"}]},{"Route":"css/modern-admin.pot7sfma4v.css","AssetFile":"css/modern-admin.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"9141"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"pot7sfma4v"},{"Name":"integrity","Value":"sha256-91UjiRqFDPWOxs9MXU8PLV9SSHt/UiSGNYYl7udkXBE="},{"Name":"label","Value":"css/modern-admin.css"}]},{"Route":"css/modern-admin.pot7sfma4v.css.br","AssetFile":"css/modern-admin.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1948"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"RkbdamGNS1RWvGA2VKkqIamUUazp6ZElZp2LpCVpYHE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"pot7sfma4v"},{"Name":"integrity","Value":"sha256-RkbdamGNS1RWvGA2VKkqIamUUazp6ZElZp2LpCVpYHE="},{"Name":"label","Value":"css/modern-admin.css.br"}]},{"Route":"css/modern-admin.pot7sfma4v.css.gz","AssetFile":"css/modern-admin.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2311"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"L8Y89C8srYVQk/zUNp15qclN5ip9tMHQsNIUK/y2sGM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"pot7sfma4v"},{"Name":"integrity","Value":"sha256-L8Y89C8srYVQk/zUNp15qclN5ip9tMHQsNIUK/y2sGM="},{"Name":"label","Value":"css/modern-admin.css.gz"}]},{"Route":"css/radzen-tech-theme.apk3ca9blf.css","AssetFile":"css/radzen-tech-theme.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000374531835"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"2669"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ds2Q2RA6bO2vt2zlwqpluOAzv8buhhjV9kAqWGsScio=\""},{"Name":"ETag","Value":"W/\"cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"apk3ca9blf"},{"Name":"integrity","Value":"sha256-cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM="},{"Name":"label","Value":"css/radzen-tech-theme.css"}]},{"Route":"css/radzen-tech-theme.apk3ca9blf.css","AssetFile":"css/radzen-tech-theme.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000320512821"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3119"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"IS2xHcdx2VnoC6j0TR9xFEDnpCc2qjhkZp0vdP4kYP0=\""},{"Name":"ETag","Value":"W/\"cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"apk3ca9blf"},{"Name":"integrity","Value":"sha256-cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM="},{"Name":"label","Value":"css/radzen-tech-theme.css"}]},{"Route":"css/radzen-tech-theme.apk3ca9blf.css","AssetFile":"css/radzen-tech-theme.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"15344"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"apk3ca9blf"},{"Name":"integrity","Value":"sha256-cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM="},{"Name":"label","Value":"css/radzen-tech-theme.css"}]},{"Route":"css/radzen-tech-theme.apk3ca9blf.css.br","AssetFile":"css/radzen-tech-theme.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"2669"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ds2Q2RA6bO2vt2zlwqpluOAzv8buhhjV9kAqWGsScio=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"apk3ca9blf"},{"Name":"integrity","Value":"sha256-ds2Q2RA6bO2vt2zlwqpluOAzv8buhhjV9kAqWGsScio="},{"Name":"label","Value":"css/radzen-tech-theme.css.br"}]},{"Route":"css/radzen-tech-theme.apk3ca9blf.css.gz","AssetFile":"css/radzen-tech-theme.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3119"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"IS2xHcdx2VnoC6j0TR9xFEDnpCc2qjhkZp0vdP4kYP0=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"apk3ca9blf"},{"Name":"integrity","Value":"sha256-IS2xHcdx2VnoC6j0TR9xFEDnpCc2qjhkZp0vdP4kYP0="},{"Name":"label","Value":"css/radzen-tech-theme.css.gz"}]},{"Route":"css/radzen-tech-theme.css","AssetFile":"css/radzen-tech-theme.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000374531835"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"2669"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ds2Q2RA6bO2vt2zlwqpluOAzv8buhhjV9kAqWGsScio=\""},{"Name":"ETag","Value":"W/\"cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM="}]},{"Route":"css/radzen-tech-theme.css","AssetFile":"css/radzen-tech-theme.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000320512821"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3119"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"IS2xHcdx2VnoC6j0TR9xFEDnpCc2qjhkZp0vdP4kYP0=\""},{"Name":"ETag","Value":"W/\"cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM="}]},{"Route":"css/radzen-tech-theme.css","AssetFile":"css/radzen-tech-theme.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"15344"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-cjCK2K3O4G//U53PAvdjAQAruHdvew0hARS3xBlhpoM="}]},{"Route":"css/radzen-tech-theme.css.br","AssetFile":"css/radzen-tech-theme.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"2669"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ds2Q2RA6bO2vt2zlwqpluOAzv8buhhjV9kAqWGsScio=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-ds2Q2RA6bO2vt2zlwqpluOAzv8buhhjV9kAqWGsScio="}]},{"Route":"css/radzen-tech-theme.css.gz","AssetFile":"css/radzen-tech-theme.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3119"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"IS2xHcdx2VnoC6j0TR9xFEDnpCc2qjhkZp0vdP4kYP0=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-IS2xHcdx2VnoC6j0TR9xFEDnpCc2qjhkZp0vdP4kYP0="}]},{"Route":"favicon.ico","AssetFile":"favicon.ico.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.027027027027"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"36"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"vCop+Qwjj9SSp50eOIkfqBbbp9nPZkYSOcTtb3Vn7xY=\""},{"Name":"ETag","Value":"W/\"/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk="}]},{"Route":"favicon.ico","AssetFile":"favicon.ico.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.014925373134"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"66"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"g7OXTy4fyV7s3RsZRS7uooFFOtxO2BDcnV74t+M8A8E=\""},{"Name":"ETag","Value":"W/\"/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk="}]},{"Route":"favicon.ico","AssetFile":"favicon.ico","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"343"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk="}]},{"Route":"favicon.ico.br","AssetFile":"favicon.ico.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"36"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"vCop+Qwjj9SSp50eOIkfqBbbp9nPZkYSOcTtb3Vn7xY=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-vCop+Qwjj9SSp50eOIkfqBbbp9nPZkYSOcTtb3Vn7xY="}]},{"Route":"favicon.ico.gz","AssetFile":"favicon.ico.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"66"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"g7OXTy4fyV7s3RsZRS7uooFFOtxO2BDcnV74t+M8A8E=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-g7OXTy4fyV7s3RsZRS7uooFFOtxO2BDcnV74t+M8A8E="}]},{"Route":"favicon.qhgym9xc3m.ico","AssetFile":"favicon.ico.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.027027027027"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"36"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"vCop+Qwjj9SSp50eOIkfqBbbp9nPZkYSOcTtb3Vn7xY=\""},{"Name":"ETag","Value":"W/\"/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"qhgym9xc3m"},{"Name":"integrity","Value":"sha256-/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk="},{"Name":"label","Value":"favicon.ico"}]},{"Route":"favicon.qhgym9xc3m.ico","AssetFile":"favicon.ico.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.014925373134"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"66"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"g7OXTy4fyV7s3RsZRS7uooFFOtxO2BDcnV74t+M8A8E=\""},{"Name":"ETag","Value":"W/\"/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"qhgym9xc3m"},{"Name":"integrity","Value":"sha256-/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk="},{"Name":"label","Value":"favicon.ico"}]},{"Route":"favicon.qhgym9xc3m.ico","AssetFile":"favicon.ico","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"343"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"qhgym9xc3m"},{"Name":"integrity","Value":"sha256-/jGzhUZ8fohWICRDt2xQ1XZ+oml3J0X8Pb7UjmhEzgk="},{"Name":"label","Value":"favicon.ico"}]},{"Route":"favicon.qhgym9xc3m.ico.br","AssetFile":"favicon.ico.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"36"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"vCop+Qwjj9SSp50eOIkfqBbbp9nPZkYSOcTtb3Vn7xY=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"qhgym9xc3m"},{"Name":"integrity","Value":"sha256-vCop+Qwjj9SSp50eOIkfqBbbp9nPZkYSOcTtb3Vn7xY="},{"Name":"label","Value":"favicon.ico.br"}]},{"Route":"favicon.qhgym9xc3m.ico.gz","AssetFile":"favicon.ico.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"66"},{"Name":"Content-Type","Value":"image/x-icon"},{"Name":"ETag","Value":"\"g7OXTy4fyV7s3RsZRS7uooFFOtxO2BDcnV74t+M8A8E=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"qhgym9xc3m"},{"Name":"integrity","Value":"sha256-g7OXTy4fyV7s3RsZRS7uooFFOtxO2BDcnV74t+M8A8E="},{"Name":"label","Value":"favicon.ico.gz"}]},{"Route":"icons/icon-128x128.png","AssetFile":"icons/icon-128x128.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"2574"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"pDaRfU4/neJFFUfdV/xSAOPHmuE4+dlvfW0so2F0t5s=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-pDaRfU4/neJFFUfdV/xSAOPHmuE4+dlvfW0so2F0t5s="}]},{"Route":"icons/icon-128x128.se59jw4sk4.png","AssetFile":"icons/icon-128x128.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"2574"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"pDaRfU4/neJFFUfdV/xSAOPHmuE4+dlvfW0so2F0t5s=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"se59jw4sk4"},{"Name":"integrity","Value":"sha256-pDaRfU4/neJFFUfdV/xSAOPHmuE4+dlvfW0so2F0t5s="},{"Name":"label","Value":"icons/icon-128x128.png"}]},{"Route":"icons/icon-144x144.png","AssetFile":"icons/icon-144x144.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"2827"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"kNEmtElIobYQ7BBMtmJzY2LFLWFIwZrUP7MwimIbGGo=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-kNEmtElIobYQ7BBMtmJzY2LFLWFIwZrUP7MwimIbGGo="}]},{"Route":"icons/icon-144x144.steqgdm9wl.png","AssetFile":"icons/icon-144x144.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"2827"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"kNEmtElIobYQ7BBMtmJzY2LFLWFIwZrUP7MwimIbGGo=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"steqgdm9wl"},{"Name":"integrity","Value":"sha256-kNEmtElIobYQ7BBMtmJzY2LFLWFIwZrUP7MwimIbGGo="},{"Name":"label","Value":"icons/icon-144x144.png"}]},{"Route":"icons/icon-152x152.png","AssetFile":"icons/icon-152x152.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"3025"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"l16C+qfjuDk2VdUSppgwK/kTF9wi2X7KbBFpNFwUmcQ=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-l16C+qfjuDk2VdUSppgwK/kTF9wi2X7KbBFpNFwUmcQ="}]},{"Route":"icons/icon-152x152.rzp4elg3xn.png","AssetFile":"icons/icon-152x152.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"3025"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"l16C+qfjuDk2VdUSppgwK/kTF9wi2X7KbBFpNFwUmcQ=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"rzp4elg3xn"},{"Name":"integrity","Value":"sha256-l16C+qfjuDk2VdUSppgwK/kTF9wi2X7KbBFpNFwUmcQ="},{"Name":"label","Value":"icons/icon-152x152.png"}]},{"Route":"icons/icon-192x192.ezsalfe4ti.png","AssetFile":"icons/icon-192x192.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"4070"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ezsalfe4ti"},{"Name":"integrity","Value":"sha256-xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk="},{"Name":"label","Value":"icons/icon-192x192.png"}]},{"Route":"icons/icon-192x192.png","AssetFile":"icons/icon-192x192.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"4070"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk="}]},{"Route":"icons/icon-384x384.png","AssetFile":"icons/icon-384x384.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"16396"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"jagktBz9awlAADY7bluVqfUNupf6t0aubKwqk1p1Sko=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-jagktBz9awlAADY7bluVqfUNupf6t0aubKwqk1p1Sko="}]},{"Route":"icons/icon-384x384.tk2m638zom.png","AssetFile":"icons/icon-384x384.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"16396"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"jagktBz9awlAADY7bluVqfUNupf6t0aubKwqk1p1Sko=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"tk2m638zom"},{"Name":"integrity","Value":"sha256-jagktBz9awlAADY7bluVqfUNupf6t0aubKwqk1p1Sko="},{"Name":"label","Value":"icons/icon-384x384.png"}]},{"Route":"icons/icon-512x512.45s6w2vf10.png","AssetFile":"icons/icon-512x512.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"20312"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"CBTYNLjlHAuhM6dK0T8HgV5j6oxAhi0mnPaZA+VdYJI=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"45s6w2vf10"},{"Name":"integrity","Value":"sha256-CBTYNLjlHAuhM6dK0T8HgV5j6oxAhi0mnPaZA+VdYJI="},{"Name":"label","Value":"icons/icon-512x512.png"}]},{"Route":"icons/icon-512x512.png","AssetFile":"icons/icon-512x512.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"20312"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"CBTYNLjlHAuhM6dK0T8HgV5j6oxAhi0mnPaZA+VdYJI=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-CBTYNLjlHAuhM6dK0T8HgV5j6oxAhi0mnPaZA+VdYJI="}]},{"Route":"icons/icon-72x72.png","AssetFile":"icons/icon-72x72.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1531"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"hQ8yoRqw75oWnRjH/nvnGuNs8aXxrxlOrD/6FRWITWE=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-hQ8yoRqw75oWnRjH/nvnGuNs8aXxrxlOrD/6FRWITWE="}]},{"Route":"icons/icon-72x72.pzwudszb55.png","AssetFile":"icons/icon-72x72.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"1531"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"hQ8yoRqw75oWnRjH/nvnGuNs8aXxrxlOrD/6FRWITWE=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"pzwudszb55"},{"Name":"integrity","Value":"sha256-hQ8yoRqw75oWnRjH/nvnGuNs8aXxrxlOrD/6FRWITWE="},{"Name":"label","Value":"icons/icon-72x72.png"}]},{"Route":"icons/icon-96x96.png","AssetFile":"icons/icon-96x96.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1956"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"fX8Z86qSOEWgr3pF5YpXTQIXVIPmQlai0txtq6mn3d8=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-fX8Z86qSOEWgr3pF5YpXTQIXVIPmQlai0txtq6mn3d8="}]},{"Route":"icons/icon-96x96.z801t7tlw5.png","AssetFile":"icons/icon-96x96.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"1956"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"fX8Z86qSOEWgr3pF5YpXTQIXVIPmQlai0txtq6mn3d8=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"z801t7tlw5"},{"Name":"integrity","Value":"sha256-fX8Z86qSOEWgr3pF5YpXTQIXVIPmQlai0txtq6mn3d8="},{"Name":"label","Value":"icons/icon-96x96.png"}]},{"Route":"icons/icon-placeholder.jp8a528sgu.svg","AssetFile":"icons/icon-placeholder.svg.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.002493765586"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"400"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"XbffmQSXVjCQv4lS2Lhhj9uTwuepeCwebUDR9a0VCRA=\""},{"Name":"ETag","Value":"W/\"lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"jp8a528sgu"},{"Name":"integrity","Value":"sha256-lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU="},{"Name":"label","Value":"icons/icon-placeholder.svg"}]},{"Route":"icons/icon-placeholder.jp8a528sgu.svg","AssetFile":"icons/icon-placeholder.svg.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.002159827214"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"462"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"w0W67j/UbeZe95Pe1CSquJoIKf7H1cJR3SDgFbEdP70=\""},{"Name":"ETag","Value":"W/\"lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"jp8a528sgu"},{"Name":"integrity","Value":"sha256-lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU="},{"Name":"label","Value":"icons/icon-placeholder.svg"}]},{"Route":"icons/icon-placeholder.jp8a528sgu.svg","AssetFile":"icons/icon-placeholder.svg","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"879"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"jp8a528sgu"},{"Name":"integrity","Value":"sha256-lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU="},{"Name":"label","Value":"icons/icon-placeholder.svg"}]},{"Route":"icons/icon-placeholder.jp8a528sgu.svg.br","AssetFile":"icons/icon-placeholder.svg.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"400"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"XbffmQSXVjCQv4lS2Lhhj9uTwuepeCwebUDR9a0VCRA=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"jp8a528sgu"},{"Name":"integrity","Value":"sha256-XbffmQSXVjCQv4lS2Lhhj9uTwuepeCwebUDR9a0VCRA="},{"Name":"label","Value":"icons/icon-placeholder.svg.br"}]},{"Route":"icons/icon-placeholder.jp8a528sgu.svg.gz","AssetFile":"icons/icon-placeholder.svg.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"462"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"w0W67j/UbeZe95Pe1CSquJoIKf7H1cJR3SDgFbEdP70=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"jp8a528sgu"},{"Name":"integrity","Value":"sha256-w0W67j/UbeZe95Pe1CSquJoIKf7H1cJR3SDgFbEdP70="},{"Name":"label","Value":"icons/icon-placeholder.svg.gz"}]},{"Route":"icons/icon-placeholder.svg","AssetFile":"icons/icon-placeholder.svg.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.002493765586"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"400"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"XbffmQSXVjCQv4lS2Lhhj9uTwuepeCwebUDR9a0VCRA=\""},{"Name":"ETag","Value":"W/\"lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU="}]},{"Route":"icons/icon-placeholder.svg","AssetFile":"icons/icon-placeholder.svg.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.002159827214"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"462"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"w0W67j/UbeZe95Pe1CSquJoIKf7H1cJR3SDgFbEdP70=\""},{"Name":"ETag","Value":"W/\"lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU="}]},{"Route":"icons/icon-placeholder.svg","AssetFile":"icons/icon-placeholder.svg","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"879"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-lzd8vfO/6Hoy91dipAQh6IzcoSBRYTBlqiphlGwaaJU="}]},{"Route":"icons/icon-placeholder.svg.br","AssetFile":"icons/icon-placeholder.svg.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"400"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"XbffmQSXVjCQv4lS2Lhhj9uTwuepeCwebUDR9a0VCRA=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-XbffmQSXVjCQv4lS2Lhhj9uTwuepeCwebUDR9a0VCRA="}]},{"Route":"icons/icon-placeholder.svg.gz","AssetFile":"icons/icon-placeholder.svg.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"462"},{"Name":"Content-Type","Value":"image/svg+xml"},{"Name":"ETag","Value":"\"w0W67j/UbeZe95Pe1CSquJoIKf7H1cJR3SDgFbEdP70=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-w0W67j/UbeZe95Pe1CSquJoIKf7H1cJR3SDgFbEdP70="}]},{"Route":"js/holographic-effects.9wdi1ekpas.js","AssetFile":"js/holographic-effects.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000251762336"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3971"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FP4PgX4jAD3sW4vlzJfSaDcMpKh2ct2i9siS0fEkQvU=\""},{"Name":"ETag","Value":"W/\"J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9wdi1ekpas"},{"Name":"integrity","Value":"sha256-J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA="},{"Name":"label","Value":"js/holographic-effects.js"}]},{"Route":"js/holographic-effects.9wdi1ekpas.js","AssetFile":"js/holographic-effects.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000297000297"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3366"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"tbgz8ChB27W7dfIanURMIdEULJRpboHGqeStTdoO3/0=\""},{"Name":"ETag","Value":"W/\"J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9wdi1ekpas"},{"Name":"integrity","Value":"sha256-J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA="},{"Name":"label","Value":"js/holographic-effects.js"}]},{"Route":"js/holographic-effects.9wdi1ekpas.js","AssetFile":"js/holographic-effects.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"18505"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9wdi1ekpas"},{"Name":"integrity","Value":"sha256-J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA="},{"Name":"label","Value":"js/holographic-effects.js"}]},{"Route":"js/holographic-effects.9wdi1ekpas.js.br","AssetFile":"js/holographic-effects.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3366"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"tbgz8ChB27W7dfIanURMIdEULJRpboHGqeStTdoO3/0=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9wdi1ekpas"},{"Name":"integrity","Value":"sha256-tbgz8ChB27W7dfIanURMIdEULJRpboHGqeStTdoO3/0="},{"Name":"label","Value":"js/holographic-effects.js.br"}]},{"Route":"js/holographic-effects.9wdi1ekpas.js.gz","AssetFile":"js/holographic-effects.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3971"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FP4PgX4jAD3sW4vlzJfSaDcMpKh2ct2i9siS0fEkQvU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9wdi1ekpas"},{"Name":"integrity","Value":"sha256-FP4PgX4jAD3sW4vlzJfSaDcMpKh2ct2i9siS0fEkQvU="},{"Name":"label","Value":"js/holographic-effects.js.gz"}]},{"Route":"js/holographic-effects.js","AssetFile":"js/holographic-effects.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000251762336"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3971"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FP4PgX4jAD3sW4vlzJfSaDcMpKh2ct2i9siS0fEkQvU=\""},{"Name":"ETag","Value":"W/\"J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA="}]},{"Route":"js/holographic-effects.js","AssetFile":"js/holographic-effects.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000297000297"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3366"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"tbgz8ChB27W7dfIanURMIdEULJRpboHGqeStTdoO3/0=\""},{"Name":"ETag","Value":"W/\"J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA="}]},{"Route":"js/holographic-effects.js","AssetFile":"js/holographic-effects.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"18505"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-J9Ao/YkzgX++hFD6wIRjXTNvNFPd12EwmgMb5VpjJAA="}]},{"Route":"js/holographic-effects.js.br","AssetFile":"js/holographic-effects.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3366"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"tbgz8ChB27W7dfIanURMIdEULJRpboHGqeStTdoO3/0=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-tbgz8ChB27W7dfIanURMIdEULJRpboHGqeStTdoO3/0="}]},{"Route":"js/holographic-effects.js.gz","AssetFile":"js/holographic-effects.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"3971"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FP4PgX4jAD3sW4vlzJfSaDcMpKh2ct2i9siS0fEkQvU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-FP4PgX4jAD3sW4vlzJfSaDcMpKh2ct2i9siS0fEkQvU="}]},{"Route":"js/modern-mobile.js","AssetFile":"js/modern-mobile.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000496770989"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2012"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"PT7LV6+sSMVuY9djDEpfkpEgFQ/6nOwMwPD3IqEpPis=\""},{"Name":"ETag","Value":"W/\"rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE="}]},{"Route":"js/modern-mobile.js","AssetFile":"js/modern-mobile.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000618429190"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1616"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"KugA4n/sFvXbrt2KqMoCJrQBy0bj0HolzFZEGHuYFdo=\""},{"Name":"ETag","Value":"W/\"rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE="}]},{"Route":"js/modern-mobile.js","AssetFile":"js/modern-mobile.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"7259"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE="}]},{"Route":"js/modern-mobile.js.br","AssetFile":"js/modern-mobile.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1616"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"KugA4n/sFvXbrt2KqMoCJrQBy0bj0HolzFZEGHuYFdo=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-KugA4n/sFvXbrt2KqMoCJrQBy0bj0HolzFZEGHuYFdo="}]},{"Route":"js/modern-mobile.js.gz","AssetFile":"js/modern-mobile.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2012"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"PT7LV6+sSMVuY9djDEpfkpEgFQ/6nOwMwPD3IqEpPis=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-PT7LV6+sSMVuY9djDEpfkpEgFQ/6nOwMwPD3IqEpPis="}]},{"Route":"js/modern-mobile.oxfcrzikkb.js","AssetFile":"js/modern-mobile.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000496770989"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2012"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"PT7LV6+sSMVuY9djDEpfkpEgFQ/6nOwMwPD3IqEpPis=\""},{"Name":"ETag","Value":"W/\"rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"oxfcrzikkb"},{"Name":"integrity","Value":"sha256-rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE="},{"Name":"label","Value":"js/modern-mobile.js"}]},{"Route":"js/modern-mobile.oxfcrzikkb.js","AssetFile":"js/modern-mobile.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000618429190"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1616"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"KugA4n/sFvXbrt2KqMoCJrQBy0bj0HolzFZEGHuYFdo=\""},{"Name":"ETag","Value":"W/\"rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"oxfcrzikkb"},{"Name":"integrity","Value":"sha256-rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE="},{"Name":"label","Value":"js/modern-mobile.js"}]},{"Route":"js/modern-mobile.oxfcrzikkb.js","AssetFile":"js/modern-mobile.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"7259"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"oxfcrzikkb"},{"Name":"integrity","Value":"sha256-rGJNb8EbnlErToAkwHFP+niy7RECwQtKixc39YF8YjE="},{"Name":"label","Value":"js/modern-mobile.js"}]},{"Route":"js/modern-mobile.oxfcrzikkb.js.br","AssetFile":"js/modern-mobile.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1616"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"KugA4n/sFvXbrt2KqMoCJrQBy0bj0HolzFZEGHuYFdo=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"oxfcrzikkb"},{"Name":"integrity","Value":"sha256-KugA4n/sFvXbrt2KqMoCJrQBy0bj0HolzFZEGHuYFdo="},{"Name":"label","Value":"js/modern-mobile.js.br"}]},{"Route":"js/modern-mobile.oxfcrzikkb.js.gz","AssetFile":"js/modern-mobile.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2012"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"PT7LV6+sSMVuY9djDEpfkpEgFQ/6nOwMwPD3IqEpPis=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"oxfcrzikkb"},{"Name":"integrity","Value":"sha256-PT7LV6+sSMVuY9djDEpfkpEgFQ/6nOwMwPD3IqEpPis="},{"Name":"label","Value":"js/modern-mobile.js.gz"}]},{"Route":"js/pwa.js","AssetFile":"js/pwa.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000211327134"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"4731"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"XMlPb6xOaPPAVzSWaXDJDaTQx96/7lISU2eFsICr7G8=\""},{"Name":"ETag","Value":"W/\"0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568="}]},{"Route":"js/pwa.js","AssetFile":"js/pwa.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000251889169"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3969"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"dIFqmrzl6B5Z5NWPCckCsw8aMzUsER9NWm6jojm7Ce0=\""},{"Name":"ETag","Value":"W/\"0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568="}]},{"Route":"js/pwa.js","AssetFile":"js/pwa.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"20718"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568="}]},{"Route":"js/pwa.js.br","AssetFile":"js/pwa.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3969"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"dIFqmrzl6B5Z5NWPCckCsw8aMzUsER9NWm6jojm7Ce0=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-dIFqmrzl6B5Z5NWPCckCsw8aMzUsER9NWm6jojm7Ce0="}]},{"Route":"js/pwa.js.gz","AssetFile":"js/pwa.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"4731"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"XMlPb6xOaPPAVzSWaXDJDaTQx96/7lISU2eFsICr7G8=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-XMlPb6xOaPPAVzSWaXDJDaTQx96/7lISU2eFsICr7G8="}]},{"Route":"js/pwa.ugxvtbz5la.js","AssetFile":"js/pwa.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000211327134"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"4731"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"XMlPb6xOaPPAVzSWaXDJDaTQx96/7lISU2eFsICr7G8=\""},{"Name":"ETag","Value":"W/\"0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ugxvtbz5la"},{"Name":"integrity","Value":"sha256-0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568="},{"Name":"label","Value":"js/pwa.js"}]},{"Route":"js/pwa.ugxvtbz5la.js","AssetFile":"js/pwa.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000251889169"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3969"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"dIFqmrzl6B5Z5NWPCckCsw8aMzUsER9NWm6jojm7Ce0=\""},{"Name":"ETag","Value":"W/\"0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ugxvtbz5la"},{"Name":"integrity","Value":"sha256-0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568="},{"Name":"label","Value":"js/pwa.js"}]},{"Route":"js/pwa.ugxvtbz5la.js","AssetFile":"js/pwa.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"20718"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ugxvtbz5la"},{"Name":"integrity","Value":"sha256-0osJ1HPo39DkImFAhUPyA0dB6AQm/8/7ujXYQIkt568="},{"Name":"label","Value":"js/pwa.js"}]},{"Route":"js/pwa.ugxvtbz5la.js.br","AssetFile":"js/pwa.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"3969"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"dIFqmrzl6B5Z5NWPCckCsw8aMzUsER9NWm6jojm7Ce0=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ugxvtbz5la"},{"Name":"integrity","Value":"sha256-dIFqmrzl6B5Z5NWPCckCsw8aMzUsER9NWm6jojm7Ce0="},{"Name":"label","Value":"js/pwa.js.br"}]},{"Route":"js/pwa.ugxvtbz5la.js.gz","AssetFile":"js/pwa.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"4731"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"XMlPb6xOaPPAVzSWaXDJDaTQx96/7lISU2eFsICr7G8=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ugxvtbz5la"},{"Name":"integrity","Value":"sha256-XMlPb6xOaPPAVzSWaXDJDaTQx96/7lISU2eFsICr7G8="},{"Name":"label","Value":"js/pwa.js.gz"}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.a35lw2am6e.css","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000073561866"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"13593"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ZZ8Q76qgNK6w7hPTSK8anVtC7Vd5E8rY5ZXnBypfaFM=\""},{"Name":"ETag","Value":"W/\"BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"a35lw2am6e"},{"Name":"integrity","Value":"sha256-BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw="},{"Name":"label","Value":"lib/bootstrap-icons/bootstrap-icons.css"}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.a35lw2am6e.css","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000099690958"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"10030"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"hUAf2pIMNrv5vRLAvvp6DVFb373me1GxzUoAzz8z7gM=\""},{"Name":"ETag","Value":"W/\"BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"a35lw2am6e"},{"Name":"integrity","Value":"sha256-BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw="},{"Name":"label","Value":"lib/bootstrap-icons/bootstrap-icons.css"}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.a35lw2am6e.css","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"95609"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"a35lw2am6e"},{"Name":"integrity","Value":"sha256-BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw="},{"Name":"label","Value":"lib/bootstrap-icons/bootstrap-icons.css"}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.a35lw2am6e.css.br","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"10030"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"hUAf2pIMNrv5vRLAvvp6DVFb373me1GxzUoAzz8z7gM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"a35lw2am6e"},{"Name":"integrity","Value":"sha256-hUAf2pIMNrv5vRLAvvp6DVFb373me1GxzUoAzz8z7gM="},{"Name":"label","Value":"lib/bootstrap-icons/bootstrap-icons.css.br"}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.a35lw2am6e.css.gz","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"13593"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ZZ8Q76qgNK6w7hPTSK8anVtC7Vd5E8rY5ZXnBypfaFM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"a35lw2am6e"},{"Name":"integrity","Value":"sha256-ZZ8Q76qgNK6w7hPTSK8anVtC7Vd5E8rY5ZXnBypfaFM="},{"Name":"label","Value":"lib/bootstrap-icons/bootstrap-icons.css.gz"}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.css","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000073561866"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"13593"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ZZ8Q76qgNK6w7hPTSK8anVtC7Vd5E8rY5ZXnBypfaFM=\""},{"Name":"ETag","Value":"W/\"BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw="}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.css","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000099690958"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"10030"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"hUAf2pIMNrv5vRLAvvp6DVFb373me1GxzUoAzz8z7gM=\""},{"Name":"ETag","Value":"W/\"BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw="}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.css","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"95609"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-BpVWXFHWXgU/9RgZKOYHYE/qxzAEcmxn0n6MymuxIOw="}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.css.br","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"10030"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"hUAf2pIMNrv5vRLAvvp6DVFb373me1GxzUoAzz8z7gM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-hUAf2pIMNrv5vRLAvvp6DVFb373me1GxzUoAzz8z7gM="}]},{"Route":"lib/bootstrap-icons/bootstrap-icons.css.gz","AssetFile":"lib/bootstrap-icons/bootstrap-icons.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"13593"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"ZZ8Q76qgNK6w7hPTSK8anVtC7Vd5E8rY5ZXnBypfaFM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-ZZ8Q76qgNK6w7hPTSK8anVtC7Vd5E8rY5ZXnBypfaFM="}]},{"Route":"lib/bootstrap/css/bootstrap.min.css","AssetFile":"lib/bootstrap/css/bootstrap.min.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000041837503"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23901"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"1LfrnhY4t84rm2t7WMjHTfM+4KSJdI21up7yKJF/m3k=\""},{"Name":"ETag","Value":"W/\"YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs="}]},{"Route":"lib/bootstrap/css/bootstrap.min.css","AssetFile":"lib/bootstrap/css/bootstrap.min.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000057454754"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17404"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"eMyFJJ3sT0rZZcO7Y+mi8gvG/6D2221zR7R9g8C7OTI=\""},{"Name":"ETag","Value":"W/\"YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs="}]},{"Route":"lib/bootstrap/css/bootstrap.min.css","AssetFile":"lib/bootstrap/css/bootstrap.min.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"163873"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs="}]},{"Route":"lib/bootstrap/css/bootstrap.min.css.br","AssetFile":"lib/bootstrap/css/bootstrap.min.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17404"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"eMyFJJ3sT0rZZcO7Y+mi8gvG/6D2221zR7R9g8C7OTI=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-eMyFJJ3sT0rZZcO7Y+mi8gvG/6D2221zR7R9g8C7OTI="}]},{"Route":"lib/bootstrap/css/bootstrap.min.css.gz","AssetFile":"lib/bootstrap/css/bootstrap.min.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23901"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"1LfrnhY4t84rm2t7WMjHTfM+4KSJdI21up7yKJF/m3k=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-1LfrnhY4t84rm2t7WMjHTfM+4KSJdI21up7yKJF/m3k="}]},{"Route":"lib/bootstrap/css/bootstrap.min.ik4heq9zur.css","AssetFile":"lib/bootstrap/css/bootstrap.min.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000041837503"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23901"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"1LfrnhY4t84rm2t7WMjHTfM+4KSJdI21up7yKJF/m3k=\""},{"Name":"ETag","Value":"W/\"YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ik4heq9zur"},{"Name":"integrity","Value":"sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs="},{"Name":"label","Value":"lib/bootstrap/css/bootstrap.min.css"}]},{"Route":"lib/bootstrap/css/bootstrap.min.ik4heq9zur.css","AssetFile":"lib/bootstrap/css/bootstrap.min.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000057454754"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17404"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"eMyFJJ3sT0rZZcO7Y+mi8gvG/6D2221zR7R9g8C7OTI=\""},{"Name":"ETag","Value":"W/\"YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ik4heq9zur"},{"Name":"integrity","Value":"sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs="},{"Name":"label","Value":"lib/bootstrap/css/bootstrap.min.css"}]},{"Route":"lib/bootstrap/css/bootstrap.min.ik4heq9zur.css","AssetFile":"lib/bootstrap/css/bootstrap.min.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"163873"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ik4heq9zur"},{"Name":"integrity","Value":"sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs="},{"Name":"label","Value":"lib/bootstrap/css/bootstrap.min.css"}]},{"Route":"lib/bootstrap/css/bootstrap.min.ik4heq9zur.css.br","AssetFile":"lib/bootstrap/css/bootstrap.min.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17404"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"eMyFJJ3sT0rZZcO7Y+mi8gvG/6D2221zR7R9g8C7OTI=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ik4heq9zur"},{"Name":"integrity","Value":"sha256-eMyFJJ3sT0rZZcO7Y+mi8gvG/6D2221zR7R9g8C7OTI="},{"Name":"label","Value":"lib/bootstrap/css/bootstrap.min.css.br"}]},{"Route":"lib/bootstrap/css/bootstrap.min.ik4heq9zur.css.gz","AssetFile":"lib/bootstrap/css/bootstrap.min.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23901"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"1LfrnhY4t84rm2t7WMjHTfM+4KSJdI21up7yKJF/m3k=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ik4heq9zur"},{"Name":"integrity","Value":"sha256-1LfrnhY4t84rm2t7WMjHTfM+4KSJdI21up7yKJF/m3k="},{"Name":"label","Value":"lib/bootstrap/css/bootstrap.min.css.gz"}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.1hlhnlro98.js","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000043077453"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23213"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FVJNaHsc0uq2Ez5nWN6doWOTWejXcvGU9d17MYNPkeE=\""},{"Name":"ETag","Value":"W/\"9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"1hlhnlro98"},{"Name":"integrity","Value":"sha256-9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M="},{"Name":"label","Value":"lib/bootstrap/js/bootstrap.bundle.min.js"}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.1hlhnlro98.js","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000048728194"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"20521"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"h+VVhnfaJRYXb795VMDYlqMm8Blinwx5eN4MsPUOFBc=\""},{"Name":"ETag","Value":"W/\"9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"1hlhnlro98"},{"Name":"integrity","Value":"sha256-9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M="},{"Name":"label","Value":"lib/bootstrap/js/bootstrap.bundle.min.js"}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.1hlhnlro98.js","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"78129"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"1hlhnlro98"},{"Name":"integrity","Value":"sha256-9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M="},{"Name":"label","Value":"lib/bootstrap/js/bootstrap.bundle.min.js"}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.1hlhnlro98.js.br","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"20521"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"h+VVhnfaJRYXb795VMDYlqMm8Blinwx5eN4MsPUOFBc=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"1hlhnlro98"},{"Name":"integrity","Value":"sha256-h+VVhnfaJRYXb795VMDYlqMm8Blinwx5eN4MsPUOFBc="},{"Name":"label","Value":"lib/bootstrap/js/bootstrap.bundle.min.js.br"}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.1hlhnlro98.js.gz","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23213"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FVJNaHsc0uq2Ez5nWN6doWOTWejXcvGU9d17MYNPkeE=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"1hlhnlro98"},{"Name":"integrity","Value":"sha256-FVJNaHsc0uq2Ez5nWN6doWOTWejXcvGU9d17MYNPkeE="},{"Name":"label","Value":"lib/bootstrap/js/bootstrap.bundle.min.js.gz"}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.js","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000043077453"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23213"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FVJNaHsc0uq2Ez5nWN6doWOTWejXcvGU9d17MYNPkeE=\""},{"Name":"ETag","Value":"W/\"9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M="}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.js","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000048728194"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"20521"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"h+VVhnfaJRYXb795VMDYlqMm8Blinwx5eN4MsPUOFBc=\""},{"Name":"ETag","Value":"W/\"9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M="}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.js","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"78129"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-9SEPo+fwJFpMUet/KACSwO+Z/dKMReF9q4zFhU/fT9M="}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.js.br","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"20521"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"h+VVhnfaJRYXb795VMDYlqMm8Blinwx5eN4MsPUOFBc=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-h+VVhnfaJRYXb795VMDYlqMm8Blinwx5eN4MsPUOFBc="}]},{"Route":"lib/bootstrap/js/bootstrap.bundle.min.js.gz","AssetFile":"lib/bootstrap/js/bootstrap.bundle.min.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"23213"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"FVJNaHsc0uq2Ez5nWN6doWOTWejXcvGU9d17MYNPkeE=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-FVJNaHsc0uq2Ez5nWN6doWOTWejXcvGU9d17MYNPkeE="}]},{"Route":"lib/fontawesome/css/all.min.7fp7thb2jb.css","AssetFile":"lib/fontawesome/css/all.min.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000053410244"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"18722"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"0acwKC+ZX5m33N4Pne7VkoBl3DOeTLk5iB2AbA6Aavs=\""},{"Name":"ETag","Value":"W/\"jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"7fp7thb2jb"},{"Name":"integrity","Value":"sha256-jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4="},{"Name":"label","Value":"lib/fontawesome/css/all.min.css"}]},{"Route":"lib/fontawesome/css/all.min.7fp7thb2jb.css","AssetFile":"lib/fontawesome/css/all.min.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000065578071"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"15248"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"YsbpuSyWp2IYL2FLdn25FAB3vOXC4+J7oMgdY6xizho=\""},{"Name":"ETag","Value":"W/\"jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"7fp7thb2jb"},{"Name":"integrity","Value":"sha256-jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4="},{"Name":"label","Value":"lib/fontawesome/css/all.min.css"}]},{"Route":"lib/fontawesome/css/all.min.7fp7thb2jb.css","AssetFile":"lib/fontawesome/css/all.min.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"89220"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"7fp7thb2jb"},{"Name":"integrity","Value":"sha256-jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4="},{"Name":"label","Value":"lib/fontawesome/css/all.min.css"}]},{"Route":"lib/fontawesome/css/all.min.7fp7thb2jb.css.br","AssetFile":"lib/fontawesome/css/all.min.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"15248"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"YsbpuSyWp2IYL2FLdn25FAB3vOXC4+J7oMgdY6xizho=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"7fp7thb2jb"},{"Name":"integrity","Value":"sha256-YsbpuSyWp2IYL2FLdn25FAB3vOXC4+J7oMgdY6xizho="},{"Name":"label","Value":"lib/fontawesome/css/all.min.css.br"}]},{"Route":"lib/fontawesome/css/all.min.7fp7thb2jb.css.gz","AssetFile":"lib/fontawesome/css/all.min.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"18722"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"0acwKC+ZX5m33N4Pne7VkoBl3DOeTLk5iB2AbA6Aavs=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"7fp7thb2jb"},{"Name":"integrity","Value":"sha256-0acwKC+ZX5m33N4Pne7VkoBl3DOeTLk5iB2AbA6Aavs="},{"Name":"label","Value":"lib/fontawesome/css/all.min.css.gz"}]},{"Route":"lib/fontawesome/css/all.min.css","AssetFile":"lib/fontawesome/css/all.min.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000053410244"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"18722"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"0acwKC+ZX5m33N4Pne7VkoBl3DOeTLk5iB2AbA6Aavs=\""},{"Name":"ETag","Value":"W/\"jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4="}]},{"Route":"lib/fontawesome/css/all.min.css","AssetFile":"lib/fontawesome/css/all.min.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000065578071"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"15248"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"YsbpuSyWp2IYL2FLdn25FAB3vOXC4+J7oMgdY6xizho=\""},{"Name":"ETag","Value":"W/\"jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4="}]},{"Route":"lib/fontawesome/css/all.min.css","AssetFile":"lib/fontawesome/css/all.min.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"89220"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-jTIdiMuX/e3DGJUGwl3pKSxuc6YOuqtJYkM0bGQESA4="}]},{"Route":"lib/fontawesome/css/all.min.css.br","AssetFile":"lib/fontawesome/css/all.min.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"15248"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"YsbpuSyWp2IYL2FLdn25FAB3vOXC4+J7oMgdY6xizho=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-YsbpuSyWp2IYL2FLdn25FAB3vOXC4+J7oMgdY6xizho="}]},{"Route":"lib/fontawesome/css/all.min.css.gz","AssetFile":"lib/fontawesome/css/all.min.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"18722"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"0acwKC+ZX5m33N4Pne7VkoBl3DOeTLk5iB2AbA6Aavs=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-0acwKC+ZX5m33N4Pne7VkoBl3DOeTLk5iB2AbA6Aavs="}]},{"Route":"lib/fontawesome/webfonts/fa-brands-400.r3h5irg3na.woff2","AssetFile":"lib/fontawesome/webfonts/fa-brands-400.woff2","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"104544"},{"Name":"Content-Type","Value":"font/woff2"},{"Name":"ETag","Value":"\"KbxEaUw5SSHR8AJxEoouTNgpNRYhbiTqwHpz+oIfwfU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"r3h5irg3na"},{"Name":"integrity","Value":"sha256-KbxEaUw5SSHR8AJxEoouTNgpNRYhbiTqwHpz+oIfwfU="},{"Name":"label","Value":"lib/fontawesome/webfonts/fa-brands-400.woff2"}]},{"Route":"lib/fontawesome/webfonts/fa-brands-400.woff2","AssetFile":"lib/fontawesome/webfonts/fa-brands-400.woff2","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"104544"},{"Name":"Content-Type","Value":"font/woff2"},{"Name":"ETag","Value":"\"KbxEaUw5SSHR8AJxEoouTNgpNRYhbiTqwHpz+oIfwfU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-KbxEaUw5SSHR8AJxEoouTNgpNRYhbiTqwHpz+oIfwfU="}]},{"Route":"lib/fontawesome/webfonts/fa-solid-900.54pzt4ck8j.woff2","AssetFile":"lib/fontawesome/webfonts/fa-solid-900.woff2","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"126828"},{"Name":"Content-Type","Value":"font/woff2"},{"Name":"ETag","Value":"\"GwmfiMBu0IaYclYcFX8OycvhM6CTnZ7OTuHh9UvUaD0=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"54pzt4ck8j"},{"Name":"integrity","Value":"sha256-GwmfiMBu0IaYclYcFX8OycvhM6CTnZ7OTuHh9UvUaD0="},{"Name":"label","Value":"lib/fontawesome/webfonts/fa-solid-900.woff2"}]},{"Route":"lib/fontawesome/webfonts/fa-solid-900.woff2","AssetFile":"lib/fontawesome/webfonts/fa-solid-900.woff2","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"126828"},{"Name":"Content-Type","Value":"font/woff2"},{"Name":"ETag","Value":"\"GwmfiMBu0IaYclYcFX8OycvhM6CTnZ7OTuHh9UvUaD0=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-GwmfiMBu0IaYclYcFX8OycvhM6CTnZ7OTuHh9UvUaD0="}]},{"Route":"lib/jquery/jquery.min.dd6z7egasc.js","AssetFile":"lib/jquery/jquery.min.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000035755149"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"27967"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"vbSHp79gir+I3EkrXE2CJTU5o+GohQVVQTkcq5c7d0g=\""},{"Name":"ETag","Value":"W/\"/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"dd6z7egasc"},{"Name":"integrity","Value":"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="},{"Name":"label","Value":"lib/jquery/jquery.min.js"}]},{"Route":"lib/jquery/jquery.min.dd6z7egasc.js","AssetFile":"lib/jquery/jquery.min.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000032016392"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"31233"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"IMmj5PToH/EgotPa6pbFvJ59ijKJucGHbt2Or5Jc94Y=\""},{"Name":"ETag","Value":"W/\"/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"dd6z7egasc"},{"Name":"integrity","Value":"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="},{"Name":"label","Value":"lib/jquery/jquery.min.js"}]},{"Route":"lib/jquery/jquery.min.dd6z7egasc.js","AssetFile":"lib/jquery/jquery.min.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"89501"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"dd6z7egasc"},{"Name":"integrity","Value":"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="},{"Name":"label","Value":"lib/jquery/jquery.min.js"}]},{"Route":"lib/jquery/jquery.min.dd6z7egasc.js.br","AssetFile":"lib/jquery/jquery.min.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"27967"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"vbSHp79gir+I3EkrXE2CJTU5o+GohQVVQTkcq5c7d0g=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"dd6z7egasc"},{"Name":"integrity","Value":"sha256-vbSHp79gir+I3EkrXE2CJTU5o+GohQVVQTkcq5c7d0g="},{"Name":"label","Value":"lib/jquery/jquery.min.js.br"}]},{"Route":"lib/jquery/jquery.min.dd6z7egasc.js.gz","AssetFile":"lib/jquery/jquery.min.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"31233"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"IMmj5PToH/EgotPa6pbFvJ59ijKJucGHbt2Or5Jc94Y=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"dd6z7egasc"},{"Name":"integrity","Value":"sha256-IMmj5PToH/EgotPa6pbFvJ59ijKJucGHbt2Or5Jc94Y="},{"Name":"label","Value":"lib/jquery/jquery.min.js.gz"}]},{"Route":"lib/jquery/jquery.min.js","AssetFile":"lib/jquery/jquery.min.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000035755149"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"27967"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"vbSHp79gir+I3EkrXE2CJTU5o+GohQVVQTkcq5c7d0g=\""},{"Name":"ETag","Value":"W/\"/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="}]},{"Route":"lib/jquery/jquery.min.js","AssetFile":"lib/jquery/jquery.min.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000032016392"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"31233"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"IMmj5PToH/EgotPa6pbFvJ59ijKJucGHbt2Or5Jc94Y=\""},{"Name":"ETag","Value":"W/\"/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="}]},{"Route":"lib/jquery/jquery.min.js","AssetFile":"lib/jquery/jquery.min.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"89501"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="}]},{"Route":"lib/jquery/jquery.min.js.br","AssetFile":"lib/jquery/jquery.min.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"27967"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"vbSHp79gir+I3EkrXE2CJTU5o+GohQVVQTkcq5c7d0g=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-vbSHp79gir+I3EkrXE2CJTU5o+GohQVVQTkcq5c7d0g="}]},{"Route":"lib/jquery/jquery.min.js.gz","AssetFile":"lib/jquery/jquery.min.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"31233"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"IMmj5PToH/EgotPa6pbFvJ59ijKJucGHbt2Or5Jc94Y=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-IMmj5PToH/EgotPa6pbFvJ59ijKJucGHbt2Or5Jc94Y="}]},{"Route":"lib/radzen/Radzen.Blazor.9m4ex6rt0m.js","AssetFile":"lib/radzen/Radzen.Blazor.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000056516333"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"17693"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"4gciKMk6eRo5PzTPOkMd1gsPhZH6F1wmeH3ai7YGvys=\""},{"Name":"ETag","Value":"W/\"H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9m4ex6rt0m"},{"Name":"integrity","Value":"sha256-H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o="},{"Name":"label","Value":"lib/radzen/Radzen.Blazor.js"}]},{"Route":"lib/radzen/Radzen.Blazor.9m4ex6rt0m.js","AssetFile":"lib/radzen/Radzen.Blazor.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000066675557"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"14997"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"Djadsy5f4NM2FCUrhsJD/SJzkNv6XH8zeVWUAQ6dYbE=\""},{"Name":"ETag","Value":"W/\"H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9m4ex6rt0m"},{"Name":"integrity","Value":"sha256-H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o="},{"Name":"label","Value":"lib/radzen/Radzen.Blazor.js"}]},{"Route":"lib/radzen/Radzen.Blazor.9m4ex6rt0m.js","AssetFile":"lib/radzen/Radzen.Blazor.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"94021"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9m4ex6rt0m"},{"Name":"integrity","Value":"sha256-H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o="},{"Name":"label","Value":"lib/radzen/Radzen.Blazor.js"}]},{"Route":"lib/radzen/Radzen.Blazor.9m4ex6rt0m.js.br","AssetFile":"lib/radzen/Radzen.Blazor.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"14997"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"Djadsy5f4NM2FCUrhsJD/SJzkNv6XH8zeVWUAQ6dYbE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9m4ex6rt0m"},{"Name":"integrity","Value":"sha256-Djadsy5f4NM2FCUrhsJD/SJzkNv6XH8zeVWUAQ6dYbE="},{"Name":"label","Value":"lib/radzen/Radzen.Blazor.js.br"}]},{"Route":"lib/radzen/Radzen.Blazor.9m4ex6rt0m.js.gz","AssetFile":"lib/radzen/Radzen.Blazor.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"17693"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"4gciKMk6eRo5PzTPOkMd1gsPhZH6F1wmeH3ai7YGvys=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"9m4ex6rt0m"},{"Name":"integrity","Value":"sha256-4gciKMk6eRo5PzTPOkMd1gsPhZH6F1wmeH3ai7YGvys="},{"Name":"label","Value":"lib/radzen/Radzen.Blazor.js.gz"}]},{"Route":"lib/radzen/Radzen.Blazor.js","AssetFile":"lib/radzen/Radzen.Blazor.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000056516333"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"17693"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"4gciKMk6eRo5PzTPOkMd1gsPhZH6F1wmeH3ai7YGvys=\""},{"Name":"ETag","Value":"W/\"H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o="}]},{"Route":"lib/radzen/Radzen.Blazor.js","AssetFile":"lib/radzen/Radzen.Blazor.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000066675557"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"14997"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"Djadsy5f4NM2FCUrhsJD/SJzkNv6XH8zeVWUAQ6dYbE=\""},{"Name":"ETag","Value":"W/\"H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o="}]},{"Route":"lib/radzen/Radzen.Blazor.js","AssetFile":"lib/radzen/Radzen.Blazor.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"94021"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-H2isaZ53T9C9Cjuo3GDKTTVVX2+Jyp49vTQqIizli7o="}]},{"Route":"lib/radzen/Radzen.Blazor.js.br","AssetFile":"lib/radzen/Radzen.Blazor.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"14997"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"Djadsy5f4NM2FCUrhsJD/SJzkNv6XH8zeVWUAQ6dYbE=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-Djadsy5f4NM2FCUrhsJD/SJzkNv6XH8zeVWUAQ6dYbE="}]},{"Route":"lib/radzen/Radzen.Blazor.js.gz","AssetFile":"lib/radzen/Radzen.Blazor.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"17693"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"4gciKMk6eRo5PzTPOkMd1gsPhZH6F1wmeH3ai7YGvys=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-4gciKMk6eRo5PzTPOkMd1gsPhZH6F1wmeH3ai7YGvys="}]},{"Route":"lib/radzen/dark-base.css","AssetFile":"lib/radzen/dark-base.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000014085301"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"70995"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"pWYd3K0199vDOLnr1aIri5u9ULRNfD+rBvC0N9sGFy0=\""},{"Name":"ETag","Value":"W/\"9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I="}]},{"Route":"lib/radzen/dark-base.css","AssetFile":"lib/radzen/dark-base.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000020519976"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48732"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"wXk6s7IV1DMiHTf76ErkEbGw1ZkKBs2U6hvKGeGjFfs=\""},{"Name":"ETag","Value":"W/\"9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I="}]},{"Route":"lib/radzen/dark-base.css","AssetFile":"lib/radzen/dark-base.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"678592"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I="}]},{"Route":"lib/radzen/dark-base.css.br","AssetFile":"lib/radzen/dark-base.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48732"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"wXk6s7IV1DMiHTf76ErkEbGw1ZkKBs2U6hvKGeGjFfs=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-wXk6s7IV1DMiHTf76ErkEbGw1ZkKBs2U6hvKGeGjFfs="}]},{"Route":"lib/radzen/dark-base.css.gz","AssetFile":"lib/radzen/dark-base.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"70995"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"pWYd3K0199vDOLnr1aIri5u9ULRNfD+rBvC0N9sGFy0=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-pWYd3K0199vDOLnr1aIri5u9ULRNfD+rBvC0N9sGFy0="}]},{"Route":"lib/radzen/dark-base.gtdkcacrne.css","AssetFile":"lib/radzen/dark-base.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000014085301"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"70995"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"pWYd3K0199vDOLnr1aIri5u9ULRNfD+rBvC0N9sGFy0=\""},{"Name":"ETag","Value":"W/\"9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"gtdkcacrne"},{"Name":"integrity","Value":"sha256-9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I="},{"Name":"label","Value":"lib/radzen/dark-base.css"}]},{"Route":"lib/radzen/dark-base.gtdkcacrne.css","AssetFile":"lib/radzen/dark-base.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000020519976"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48732"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"wXk6s7IV1DMiHTf76ErkEbGw1ZkKBs2U6hvKGeGjFfs=\""},{"Name":"ETag","Value":"W/\"9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"gtdkcacrne"},{"Name":"integrity","Value":"sha256-9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I="},{"Name":"label","Value":"lib/radzen/dark-base.css"}]},{"Route":"lib/radzen/dark-base.gtdkcacrne.css","AssetFile":"lib/radzen/dark-base.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"678592"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"gtdkcacrne"},{"Name":"integrity","Value":"sha256-9PbgZ56VuowPnf77cvefKuJXy1+STUjw+xoKcB1ZW/I="},{"Name":"label","Value":"lib/radzen/dark-base.css"}]},{"Route":"lib/radzen/dark-base.gtdkcacrne.css.br","AssetFile":"lib/radzen/dark-base.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48732"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"wXk6s7IV1DMiHTf76ErkEbGw1ZkKBs2U6hvKGeGjFfs=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"gtdkcacrne"},{"Name":"integrity","Value":"sha256-wXk6s7IV1DMiHTf76ErkEbGw1ZkKBs2U6hvKGeGjFfs="},{"Name":"label","Value":"lib/radzen/dark-base.css.br"}]},{"Route":"lib/radzen/dark-base.gtdkcacrne.css.gz","AssetFile":"lib/radzen/dark-base.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"70995"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"pWYd3K0199vDOLnr1aIri5u9ULRNfD+rBvC0N9sGFy0=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"gtdkcacrne"},{"Name":"integrity","Value":"sha256-pWYd3K0199vDOLnr1aIri5u9ULRNfD+rBvC0N9sGFy0="},{"Name":"label","Value":"lib/radzen/dark-base.css.gz"}]},{"Route":"lib/radzen/dark.3qojkf4kj4.css","AssetFile":"lib/radzen/dark.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000014044352"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"71202"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"G3Z8/X36NPDMT1KMwP5JHCKUQsBNUuIH/bPtmGRL780=\""},{"Name":"ETag","Value":"W/\"63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"3qojkf4kj4"},{"Name":"integrity","Value":"sha256-63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo="},{"Name":"label","Value":"lib/radzen/dark.css"}]},{"Route":"lib/radzen/dark.3qojkf4kj4.css","AssetFile":"lib/radzen/dark.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000020416080"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48980"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"W16VAmmuZrGqQTA1ZdUaPZhz2ucYBdcfEhX2jr5hpqg=\""},{"Name":"ETag","Value":"W/\"63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"3qojkf4kj4"},{"Name":"integrity","Value":"sha256-63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo="},{"Name":"label","Value":"lib/radzen/dark.css"}]},{"Route":"lib/radzen/dark.3qojkf4kj4.css","AssetFile":"lib/radzen/dark.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"681426"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"3qojkf4kj4"},{"Name":"integrity","Value":"sha256-63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo="},{"Name":"label","Value":"lib/radzen/dark.css"}]},{"Route":"lib/radzen/dark.3qojkf4kj4.css.br","AssetFile":"lib/radzen/dark.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48980"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"W16VAmmuZrGqQTA1ZdUaPZhz2ucYBdcfEhX2jr5hpqg=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"3qojkf4kj4"},{"Name":"integrity","Value":"sha256-W16VAmmuZrGqQTA1ZdUaPZhz2ucYBdcfEhX2jr5hpqg="},{"Name":"label","Value":"lib/radzen/dark.css.br"}]},{"Route":"lib/radzen/dark.3qojkf4kj4.css.gz","AssetFile":"lib/radzen/dark.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"71202"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"G3Z8/X36NPDMT1KMwP5JHCKUQsBNUuIH/bPtmGRL780=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"3qojkf4kj4"},{"Name":"integrity","Value":"sha256-G3Z8/X36NPDMT1KMwP5JHCKUQsBNUuIH/bPtmGRL780="},{"Name":"label","Value":"lib/radzen/dark.css.gz"}]},{"Route":"lib/radzen/dark.css","AssetFile":"lib/radzen/dark.css.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000014044352"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"71202"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"G3Z8/X36NPDMT1KMwP5JHCKUQsBNUuIH/bPtmGRL780=\""},{"Name":"ETag","Value":"W/\"63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo="}]},{"Route":"lib/radzen/dark.css","AssetFile":"lib/radzen/dark.css.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000020416080"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48980"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"W16VAmmuZrGqQTA1ZdUaPZhz2ucYBdcfEhX2jr5hpqg=\""},{"Name":"ETag","Value":"W/\"63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo="}]},{"Route":"lib/radzen/dark.css","AssetFile":"lib/radzen/dark.css","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"681426"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-63PqMAosoklpjnDDl63luluJMqdz4SRgafIjUbYWEAo="}]},{"Route":"lib/radzen/dark.css.br","AssetFile":"lib/radzen/dark.css.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"48980"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"W16VAmmuZrGqQTA1ZdUaPZhz2ucYBdcfEhX2jr5hpqg=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-W16VAmmuZrGqQTA1ZdUaPZhz2ucYBdcfEhX2jr5hpqg="}]},{"Route":"lib/radzen/dark.css.gz","AssetFile":"lib/radzen/dark.css.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"71202"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\"G3Z8/X36NPDMT1KMwP5JHCKUQsBNUuIH/bPtmGRL780=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-G3Z8/X36NPDMT1KMwP5JHCKUQsBNUuIH/bPtmGRL780="}]},{"Route":"manifest.bxzmtfhwvv.json","AssetFile":"manifest.json.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.002487562189"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"401"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"/5fA3VBgpLaLgodz2tT7rTlNSVPigPdixkB3K04JUvs=\""},{"Name":"ETag","Value":"W/\"X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"bxzmtfhwvv"},{"Name":"integrity","Value":"sha256-X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o="},{"Name":"label","Value":"manifest.json"}]},{"Route":"manifest.bxzmtfhwvv.json","AssetFile":"manifest.json.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.001934235977"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"516"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"w61/B7fpi/ojV1+OCBRpmMEkXQNlm5/tRcJtUNCD1TM=\""},{"Name":"ETag","Value":"W/\"X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"bxzmtfhwvv"},{"Name":"integrity","Value":"sha256-X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o="},{"Name":"label","Value":"manifest.json"}]},{"Route":"manifest.bxzmtfhwvv.json","AssetFile":"manifest.json","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"2056"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"bxzmtfhwvv"},{"Name":"integrity","Value":"sha256-X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o="},{"Name":"label","Value":"manifest.json"}]},{"Route":"manifest.bxzmtfhwvv.json.br","AssetFile":"manifest.json.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"401"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"/5fA3VBgpLaLgodz2tT7rTlNSVPigPdixkB3K04JUvs=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"bxzmtfhwvv"},{"Name":"integrity","Value":"sha256-/5fA3VBgpLaLgodz2tT7rTlNSVPigPdixkB3K04JUvs="},{"Name":"label","Value":"manifest.json.br"}]},{"Route":"manifest.bxzmtfhwvv.json.gz","AssetFile":"manifest.json.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"516"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"w61/B7fpi/ojV1+OCBRpmMEkXQNlm5/tRcJtUNCD1TM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"bxzmtfhwvv"},{"Name":"integrity","Value":"sha256-w61/B7fpi/ojV1+OCBRpmMEkXQNlm5/tRcJtUNCD1TM="},{"Name":"label","Value":"manifest.json.gz"}]},{"Route":"manifest.json","AssetFile":"manifest.json.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.002487562189"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"401"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"/5fA3VBgpLaLgodz2tT7rTlNSVPigPdixkB3K04JUvs=\""},{"Name":"ETag","Value":"W/\"X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o="}]},{"Route":"manifest.json","AssetFile":"manifest.json.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.001934235977"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"516"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"w61/B7fpi/ojV1+OCBRpmMEkXQNlm5/tRcJtUNCD1TM=\""},{"Name":"ETag","Value":"W/\"X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o="}]},{"Route":"manifest.json","AssetFile":"manifest.json","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"2056"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-X0j6dxyzpo0slxT0sADBdvrqEK6ukqdeDllCp3Sj+5o="}]},{"Route":"manifest.json.br","AssetFile":"manifest.json.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"401"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"/5fA3VBgpLaLgodz2tT7rTlNSVPigPdixkB3K04JUvs=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-/5fA3VBgpLaLgodz2tT7rTlNSVPigPdixkB3K04JUvs="}]},{"Route":"manifest.json.gz","AssetFile":"manifest.json.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"516"},{"Name":"Content-Type","Value":"application/json"},{"Name":"ETag","Value":"\"w61/B7fpi/ojV1+OCBRpmMEkXQNlm5/tRcJtUNCD1TM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-w61/B7fpi/ojV1+OCBRpmMEkXQNlm5/tRcJtUNCD1TM="}]},{"Route":"sw.iyld461ymi.js","AssetFile":"sw.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000482858522"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2070"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"jA+UYpUab2wu3Xv5mk+IZjjq+HrQI2ld0PCW8OBNuk0=\""},{"Name":"ETag","Value":"W/\"apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"iyld461ymi"},{"Name":"integrity","Value":"sha256-apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU="},{"Name":"label","Value":"sw.js"}]},{"Route":"sw.iyld461ymi.js","AssetFile":"sw.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000597371565"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1673"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"QbTXgH17xljWihUzZDan1RhGe8vaM6ZS+lLOdQ8dvIM=\""},{"Name":"ETag","Value":"W/\"apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"iyld461ymi"},{"Name":"integrity","Value":"sha256-apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU="},{"Name":"label","Value":"sw.js"}]},{"Route":"sw.iyld461ymi.js","AssetFile":"sw.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"6097"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"iyld461ymi"},{"Name":"integrity","Value":"sha256-apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU="},{"Name":"label","Value":"sw.js"}]},{"Route":"sw.iyld461ymi.js.br","AssetFile":"sw.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1673"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"QbTXgH17xljWihUzZDan1RhGe8vaM6ZS+lLOdQ8dvIM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"iyld461ymi"},{"Name":"integrity","Value":"sha256-QbTXgH17xljWihUzZDan1RhGe8vaM6ZS+lLOdQ8dvIM="},{"Name":"label","Value":"sw.js.br"}]},{"Route":"sw.iyld461ymi.js.gz","AssetFile":"sw.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2070"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"jA+UYpUab2wu3Xv5mk+IZjjq+HrQI2ld0PCW8OBNuk0=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"iyld461ymi"},{"Name":"integrity","Value":"sha256-jA+UYpUab2wu3Xv5mk+IZjjq+HrQI2ld0PCW8OBNuk0="},{"Name":"label","Value":"sw.js.gz"}]},{"Route":"sw.js","AssetFile":"sw.js.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.000482858522"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2070"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"jA+UYpUab2wu3Xv5mk+IZjjq+HrQI2ld0PCW8OBNuk0=\""},{"Name":"ETag","Value":"W/\"apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU="}]},{"Route":"sw.js","AssetFile":"sw.js.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.000597371565"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1673"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"QbTXgH17xljWihUzZDan1RhGe8vaM6ZS+lLOdQ8dvIM=\""},{"Name":"ETag","Value":"W/\"apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU="}]},{"Route":"sw.js","AssetFile":"sw.js","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"6097"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-apxRRmiFtOloTK98rgSiXcb3znZzDFNQbZzE+WokoDU="}]},{"Route":"sw.js.br","AssetFile":"sw.js.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"1673"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"QbTXgH17xljWihUzZDan1RhGe8vaM6ZS+lLOdQ8dvIM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-QbTXgH17xljWihUzZDan1RhGe8vaM6ZS+lLOdQ8dvIM="}]},{"Route":"sw.js.gz","AssetFile":"sw.js.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"2070"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\"jA+UYpUab2wu3Xv5mk+IZjjq+HrQI2ld0PCW8OBNuk0=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-jA+UYpUab2wu3Xv5mk+IZjjq+HrQI2ld0PCW8OBNuk0="}]},{"Route":"uploads/products/4b91066c-97d8-4f27-bd0a-f346b9f7edad_Screenshot 2025-05-11 004544.png","AssetFile":"uploads/products/4b91066c-97d8-4f27-bd0a-f346b9f7edad_Screenshot 2025-05-11 004544.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"168870"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"7HQkRMcht6EKcq02sAbbcFUwnuE7YiRfQg+vPtvDtXw=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-7HQkRMcht6EKcq02sAbbcFUwnuE7YiRfQg+vPtvDtXw="}]},{"Route":"uploads/products/4b91066c-97d8-4f27-bd0a-f346b9f7edad_Screenshot 2025-05-11 004544.sk0gqxp4m2.png","AssetFile":"uploads/products/4b91066c-97d8-4f27-bd0a-f346b9f7edad_Screenshot 2025-05-11 004544.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"168870"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"7HQkRMcht6EKcq02sAbbcFUwnuE7YiRfQg+vPtvDtXw=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"sk0gqxp4m2"},{"Name":"integrity","Value":"sha256-7HQkRMcht6EKcq02sAbbcFUwnuE7YiRfQg+vPtvDtXw="},{"Name":"label","Value":"uploads/products/4b91066c-97d8-4f27-bd0a-f346b9f7edad_Screenshot 2025-05-11 004544.png"}]},{"Route":"uploads/products/82f22080-aab5-495c-ba27-b19e0fe88dd2_test-upload.ezsalfe4ti.png","AssetFile":"uploads/products/82f22080-aab5-495c-ba27-b19e0fe88dd2_test-upload.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"4070"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"ezsalfe4ti"},{"Name":"integrity","Value":"sha256-xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk="},{"Name":"label","Value":"uploads/products/82f22080-aab5-495c-ba27-b19e0fe88dd2_test-upload.png"}]},{"Route":"uploads/products/82f22080-aab5-495c-ba27-b19e0fe88dd2_test-upload.png","AssetFile":"uploads/products/82f22080-aab5-495c-ba27-b19e0fe88dd2_test-upload.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"4070"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-xp1dIyg1Q8TqEfxrx9og0lY5+UVOxVNvfuTDkUTXRWk="}]},{"Route":"uploads/products/88d6f3b9-f45f-4833-ad06-58a018a2d042_Screenshot 2025-05-14 112034.m0cfkfet1t.png","AssetFile":"uploads/products/88d6f3b9-f45f-4833-ad06-58a018a2d042_Screenshot 2025-05-14 112034.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"49469"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"asXfggw0dyzCP4MpPW6lMv4kRY3gF4BCtbQYNx6r5G0=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"m0cfkfet1t"},{"Name":"integrity","Value":"sha256-asXfggw0dyzCP4MpPW6lMv4kRY3gF4BCtbQYNx6r5G0="},{"Name":"label","Value":"uploads/products/88d6f3b9-f45f-4833-ad06-58a018a2d042_Screenshot 2025-05-14 112034.png"}]},{"Route":"uploads/products/88d6f3b9-f45f-4833-ad06-58a018a2d042_Screenshot 2025-05-14 112034.png","AssetFile":"uploads/products/88d6f3b9-f45f-4833-ad06-58a018a2d042_Screenshot 2025-05-14 112034.png","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"49469"},{"Name":"Content-Type","Value":"image/png"},{"Name":"ETag","Value":"\"asXfggw0dyzCP4MpPW6lMv4kRY3gF4BCtbQYNx6r5G0=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-asXfggw0dyzCP4MpPW6lMv4kRY3gF4BCtbQYNx6r5G0="}]},{"Route":"uploads/products/a03a3ae5-8954-41cc-9514-7503355222de_test.jpg","AssetFile":"uploads/products/a03a3ae5-8954-41cc-9514-7503355222de_test.jpg","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"19"},{"Name":"Content-Type","Value":"image/jpeg"},{"Name":"ETag","Value":"\"cC+xGu38AWcLoSs2IjttN/9HfNBaW4RuvmgCweNgOeg=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-cC+xGu38AWcLoSs2IjttN/9HfNBaW4RuvmgCweNgOeg="}]},{"Route":"uploads/products/a03a3ae5-8954-41cc-9514-7503355222de_test.o6og57325f.jpg","AssetFile":"uploads/products/a03a3ae5-8954-41cc-9514-7503355222de_test.jpg","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"19"},{"Name":"Content-Type","Value":"image/jpeg"},{"Name":"ETag","Value":"\"cC+xGu38AWcLoSs2IjttN/9HfNBaW4RuvmgCweNgOeg=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"o6og57325f"},{"Name":"integrity","Value":"sha256-cC+xGu38AWcLoSs2IjttN/9HfNBaW4RuvmgCweNgOeg="},{"Name":"label","Value":"uploads/products/a03a3ae5-8954-41cc-9514-7503355222de_test.jpg"}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.j7krww9d4a.txt","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.025641025641"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"38"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"U9J687dqdgkDOGbJwMBN76Qu+r69fKMEWpwJ+uw8YrM=\""},{"Name":"ETag","Value":"W/\"Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"j7krww9d4a"},{"Name":"integrity","Value":"sha256-Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU="},{"Name":"label","Value":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt"}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.j7krww9d4a.txt","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.055555555556"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"bLfVKCSkUCCbMKJo3x+1yZQ1SzFZLH/jlisVfBoH+cM=\""},{"Name":"ETag","Value":"W/\"Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"j7krww9d4a"},{"Name":"integrity","Value":"sha256-Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU="},{"Name":"label","Value":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt"}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.j7krww9d4a.txt","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"18"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"fingerprint","Value":"j7krww9d4a"},{"Name":"integrity","Value":"sha256-Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU="},{"Name":"label","Value":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt"}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.j7krww9d4a.txt.br","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"bLfVKCSkUCCbMKJo3x+1yZQ1SzFZLH/jlisVfBoH+cM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"j7krww9d4a"},{"Name":"integrity","Value":"sha256-bLfVKCSkUCCbMKJo3x+1yZQ1SzFZLH/jlisVfBoH+cM="},{"Name":"label","Value":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.br"}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.j7krww9d4a.txt.gz","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"38"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"U9J687dqdgkDOGbJwMBN76Qu+r69fKMEWpwJ+uw8YrM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"fingerprint","Value":"j7krww9d4a"},{"Name":"integrity","Value":"sha256-U9J687dqdgkDOGbJwMBN76Qu+r69fKMEWpwJ+uw8YrM="},{"Name":"label","Value":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.gz"}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.gz","Selectors":[{"Name":"Content-Encoding","Value":"gzip","Quality":"0.025641025641"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"38"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"U9J687dqdgkDOGbJwMBN76Qu+r69fKMEWpwJ+uw8YrM=\""},{"Name":"ETag","Value":"W/\"Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU="}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.br","Selectors":[{"Name":"Content-Encoding","Value":"br","Quality":"0.055555555556"}],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"bLfVKCSkUCCbMKJo3x+1yZQ1SzFZLH/jlisVfBoH+cM=\""},{"Name":"ETag","Value":"W/\"Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU="}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"18"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU=\""},{"Name":"Last-Modified","Value":"Wed, 17 Sep 2025 20:24:06 GMT"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-Dw/59faU6ZQ3SzfufMkvW8GSkvj05efEnaP2SkEcTSU="}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.br","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.br","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"br"},{"Name":"Content-Length","Value":"17"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"bLfVKCSkUCCbMKJo3x+1yZQ1SzFZLH/jlisVfBoH+cM=\""},{"Name":"Last-Modified","Value":"Fri, 19 Sep 2025 09:36:34 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-bLfVKCSkUCCbMKJo3x+1yZQ1SzFZLH/jlisVfBoH+cM="}]},{"Route":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.gz","AssetFile":"uploads/products/fbb9ff4c-41a7-4649-ab26-5a71aa126ec4_test-image.txt.gz","Selectors":[],"ResponseHeaders":[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Encoding","Value":"gzip"},{"Name":"Content-Length","Value":"38"},{"Name":"Content-Type","Value":"text/plain"},{"Name":"ETag","Value":"\"U9J687dqdgkDOGbJwMBN76Qu+r69fKMEWpwJ+uw8YrM=\""},{"Name":"Last-Modified","Value":"Thu, 18 Sep 2025 18:10:41 GMT"},{"Name":"Vary","Value":"Content-Encoding"}],"EndpointProperties":[{"Name":"integrity","Value":"sha256-U9J687dqdgkDOGbJwMBN76Qu+r69fKMEWpwJ+uw8YrM="}]}]} \ No newline at end of file diff --git a/publish/Microsoft.AspNetCore.Authentication.JwtBearer.dll b/publish/Microsoft.AspNetCore.Authentication.JwtBearer.dll new file mode 100755 index 0000000..ca76774 Binary files /dev/null and b/publish/Microsoft.AspNetCore.Authentication.JwtBearer.dll differ diff --git a/publish/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll b/publish/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll new file mode 100755 index 0000000..a0d03f6 Binary files /dev/null and b/publish/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll differ diff --git a/publish/Microsoft.Data.Sqlite.dll b/publish/Microsoft.Data.Sqlite.dll new file mode 100755 index 0000000..55567a8 Binary files /dev/null and b/publish/Microsoft.Data.Sqlite.dll differ diff --git a/publish/Microsoft.EntityFrameworkCore.Abstractions.dll b/publish/Microsoft.EntityFrameworkCore.Abstractions.dll new file mode 100755 index 0000000..a73a07e Binary files /dev/null and b/publish/Microsoft.EntityFrameworkCore.Abstractions.dll differ diff --git a/publish/Microsoft.EntityFrameworkCore.InMemory.dll b/publish/Microsoft.EntityFrameworkCore.InMemory.dll new file mode 100755 index 0000000..13a1fac Binary files /dev/null and b/publish/Microsoft.EntityFrameworkCore.InMemory.dll differ diff --git a/publish/Microsoft.EntityFrameworkCore.Relational.dll b/publish/Microsoft.EntityFrameworkCore.Relational.dll new file mode 100755 index 0000000..7e313e5 Binary files /dev/null and b/publish/Microsoft.EntityFrameworkCore.Relational.dll differ diff --git a/publish/Microsoft.EntityFrameworkCore.Sqlite.dll b/publish/Microsoft.EntityFrameworkCore.Sqlite.dll new file mode 100755 index 0000000..c395d21 Binary files /dev/null and b/publish/Microsoft.EntityFrameworkCore.Sqlite.dll differ diff --git a/publish/Microsoft.EntityFrameworkCore.dll b/publish/Microsoft.EntityFrameworkCore.dll new file mode 100755 index 0000000..0110c7f Binary files /dev/null and b/publish/Microsoft.EntityFrameworkCore.dll differ diff --git a/publish/Microsoft.Extensions.Caching.Abstractions.dll b/publish/Microsoft.Extensions.Caching.Abstractions.dll new file mode 100755 index 0000000..3817d75 Binary files /dev/null and b/publish/Microsoft.Extensions.Caching.Abstractions.dll differ diff --git a/publish/Microsoft.Extensions.Caching.Memory.dll b/publish/Microsoft.Extensions.Caching.Memory.dll new file mode 100755 index 0000000..99e0248 Binary files /dev/null and b/publish/Microsoft.Extensions.Caching.Memory.dll differ diff --git a/publish/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/publish/Microsoft.Extensions.DependencyInjection.Abstractions.dll new file mode 100755 index 0000000..e7affaf Binary files /dev/null and b/publish/Microsoft.Extensions.DependencyInjection.Abstractions.dll differ diff --git a/publish/Microsoft.Extensions.DependencyInjection.dll b/publish/Microsoft.Extensions.DependencyInjection.dll new file mode 100755 index 0000000..6191756 Binary files /dev/null and b/publish/Microsoft.Extensions.DependencyInjection.dll differ diff --git a/publish/Microsoft.Extensions.DependencyModel.dll b/publish/Microsoft.Extensions.DependencyModel.dll new file mode 100755 index 0000000..e8ee78b Binary files /dev/null and b/publish/Microsoft.Extensions.DependencyModel.dll differ diff --git a/publish/Microsoft.Extensions.Logging.Abstractions.dll b/publish/Microsoft.Extensions.Logging.Abstractions.dll new file mode 100755 index 0000000..cb1d711 Binary files /dev/null and b/publish/Microsoft.Extensions.Logging.Abstractions.dll differ diff --git a/publish/Microsoft.Extensions.Logging.dll b/publish/Microsoft.Extensions.Logging.dll new file mode 100755 index 0000000..61d3a7e Binary files /dev/null and b/publish/Microsoft.Extensions.Logging.dll differ diff --git a/publish/Microsoft.Extensions.Options.dll b/publish/Microsoft.Extensions.Options.dll new file mode 100755 index 0000000..bfb0647 Binary files /dev/null and b/publish/Microsoft.Extensions.Options.dll differ diff --git a/publish/Microsoft.Extensions.Primitives.dll b/publish/Microsoft.Extensions.Primitives.dll new file mode 100755 index 0000000..b7e4481 Binary files /dev/null and b/publish/Microsoft.Extensions.Primitives.dll differ diff --git a/publish/Microsoft.IdentityModel.Abstractions.dll b/publish/Microsoft.IdentityModel.Abstractions.dll new file mode 100755 index 0000000..ab71504 Binary files /dev/null and b/publish/Microsoft.IdentityModel.Abstractions.dll differ diff --git a/publish/Microsoft.IdentityModel.JsonWebTokens.dll b/publish/Microsoft.IdentityModel.JsonWebTokens.dll new file mode 100755 index 0000000..d558709 Binary files /dev/null and b/publish/Microsoft.IdentityModel.JsonWebTokens.dll differ diff --git a/publish/Microsoft.IdentityModel.Logging.dll b/publish/Microsoft.IdentityModel.Logging.dll new file mode 100755 index 0000000..79f1c76 Binary files /dev/null and b/publish/Microsoft.IdentityModel.Logging.dll differ diff --git a/publish/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll b/publish/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll new file mode 100755 index 0000000..6c736d2 Binary files /dev/null and b/publish/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll differ diff --git a/publish/Microsoft.IdentityModel.Protocols.dll b/publish/Microsoft.IdentityModel.Protocols.dll new file mode 100755 index 0000000..9f30508 Binary files /dev/null and b/publish/Microsoft.IdentityModel.Protocols.dll differ diff --git a/publish/Microsoft.IdentityModel.Tokens.dll b/publish/Microsoft.IdentityModel.Tokens.dll new file mode 100755 index 0000000..20ebe63 Binary files /dev/null and b/publish/Microsoft.IdentityModel.Tokens.dll differ diff --git a/publish/Microsoft.OpenApi.dll b/publish/Microsoft.OpenApi.dll new file mode 100755 index 0000000..8ba2ce6 Binary files /dev/null and b/publish/Microsoft.OpenApi.dll differ diff --git a/publish/NBitcoin.dll b/publish/NBitcoin.dll new file mode 100755 index 0000000..10199ad Binary files /dev/null and b/publish/NBitcoin.dll differ diff --git a/publish/Newtonsoft.Json.dll b/publish/Newtonsoft.Json.dll new file mode 100755 index 0000000..d035c38 Binary files /dev/null and b/publish/Newtonsoft.Json.dll differ diff --git a/publish/SQLitePCLRaw.batteries_v2.dll b/publish/SQLitePCLRaw.batteries_v2.dll new file mode 100755 index 0000000..53e53eb Binary files /dev/null and b/publish/SQLitePCLRaw.batteries_v2.dll differ diff --git a/publish/SQLitePCLRaw.core.dll b/publish/SQLitePCLRaw.core.dll new file mode 100755 index 0000000..b563677 Binary files /dev/null and b/publish/SQLitePCLRaw.core.dll differ diff --git a/publish/SQLitePCLRaw.provider.e_sqlite3.dll b/publish/SQLitePCLRaw.provider.e_sqlite3.dll new file mode 100755 index 0000000..a06a782 Binary files /dev/null and b/publish/SQLitePCLRaw.provider.e_sqlite3.dll differ diff --git a/publish/Serilog.AspNetCore.dll b/publish/Serilog.AspNetCore.dll new file mode 100755 index 0000000..6c60013 Binary files /dev/null and b/publish/Serilog.AspNetCore.dll differ diff --git a/publish/Serilog.Extensions.Hosting.dll b/publish/Serilog.Extensions.Hosting.dll new file mode 100755 index 0000000..2204d10 Binary files /dev/null and b/publish/Serilog.Extensions.Hosting.dll differ diff --git a/publish/Serilog.Extensions.Logging.dll b/publish/Serilog.Extensions.Logging.dll new file mode 100755 index 0000000..f2f78c7 Binary files /dev/null and b/publish/Serilog.Extensions.Logging.dll differ diff --git a/publish/Serilog.Formatting.Compact.dll b/publish/Serilog.Formatting.Compact.dll new file mode 100755 index 0000000..7174b83 Binary files /dev/null and b/publish/Serilog.Formatting.Compact.dll differ diff --git a/publish/Serilog.Settings.Configuration.dll b/publish/Serilog.Settings.Configuration.dll new file mode 100755 index 0000000..25692ac Binary files /dev/null and b/publish/Serilog.Settings.Configuration.dll differ diff --git a/publish/Serilog.Sinks.Console.dll b/publish/Serilog.Sinks.Console.dll new file mode 100755 index 0000000..1dcb2d0 Binary files /dev/null and b/publish/Serilog.Sinks.Console.dll differ diff --git a/publish/Serilog.Sinks.Debug.dll b/publish/Serilog.Sinks.Debug.dll new file mode 100755 index 0000000..2bd024b Binary files /dev/null and b/publish/Serilog.Sinks.Debug.dll differ diff --git a/publish/Serilog.Sinks.File.dll b/publish/Serilog.Sinks.File.dll new file mode 100755 index 0000000..17d80f3 Binary files /dev/null and b/publish/Serilog.Sinks.File.dll differ diff --git a/publish/Serilog.dll b/publish/Serilog.dll new file mode 100755 index 0000000..28c98dd Binary files /dev/null and b/publish/Serilog.dll differ diff --git a/publish/Swashbuckle.AspNetCore.Swagger.dll b/publish/Swashbuckle.AspNetCore.Swagger.dll new file mode 100755 index 0000000..4b10c05 Binary files /dev/null and b/publish/Swashbuckle.AspNetCore.Swagger.dll differ diff --git a/publish/Swashbuckle.AspNetCore.SwaggerGen.dll b/publish/Swashbuckle.AspNetCore.SwaggerGen.dll new file mode 100755 index 0000000..f4a050f Binary files /dev/null and b/publish/Swashbuckle.AspNetCore.SwaggerGen.dll differ diff --git a/publish/Swashbuckle.AspNetCore.SwaggerUI.dll b/publish/Swashbuckle.AspNetCore.SwaggerUI.dll new file mode 100755 index 0000000..f535791 Binary files /dev/null and b/publish/Swashbuckle.AspNetCore.SwaggerUI.dll differ diff --git a/publish/System.IdentityModel.Tokens.Jwt.dll b/publish/System.IdentityModel.Tokens.Jwt.dll new file mode 100755 index 0000000..736e782 Binary files /dev/null and b/publish/System.IdentityModel.Tokens.Jwt.dll differ diff --git a/publish/TestAgent_Results/authentication_analysis.json b/publish/TestAgent_Results/authentication_analysis.json new file mode 100644 index 0000000..f89c2d2 --- /dev/null +++ b/publish/TestAgent_Results/authentication_analysis.json @@ -0,0 +1,2447 @@ +{ + "Summary": { + "TotalStates": 3, + "TotalEndpoints": 115, + "ProtectedEndpoints": 10, + "PublicEndpoints": 105, + "IdentifiedGaps": 153, + "AuthenticationTransitions": 7 + }, + "States": [ + { + "Name": "Anonymous", + "IsAuthenticated": false, + "Roles": [], + "Claims": [], + "AccessibleEndpoints": [ + "AuthController/Login", + "BotMessagesController/GetPendingMessages", + "BotMessagesController/MarkMessageAsSent", + "BotMessagesController/MarkMessageAsFailed", + "BotMessagesController/CreateTestMessage", + "BotMessagesController/CreateCustomerMessage", + "BotMessagesController/GetCustomerMessages", + "BotsController/RegisterBot", + "BotsController/AuthenticateBot", + "BotsController/GetBotSettings", + "BotsController/UpdateBotSettings", + "BotsController/RecordHeartbeat", + "BotsController/UpdatePlatformInfo", + "BotsController/RecordMetric", + "BotsController/RecordMetricsBatch", + "BotsController/StartSession", + "BotsController/UpdateSession", + "BotsController/EndSession", + "CatalogController/GetCategories", + "CatalogController/GetCategory", + "CatalogController/GetProducts", + "CatalogController/GetProduct", + "CustomersController/GetCustomers", + "CustomersController/GetCustomer", + "CustomersController/GetCustomerByTelegramId", + "CustomersController/CreateCustomer", + "CustomersController/GetOrCreateCustomer", + "CustomersController/UpdateCustomer", + "CustomersController/BlockCustomer", + "CustomersController/UnblockCustomer", + "CustomersController/DeleteCustomer", + "HomeController/Index", + "MessagesController/SendMessage", + "MessagesController/GetMessage", + "MessagesController/GetCustomerMessages", + "MessagesController/GetOrderMessages", + "MessagesController/GetPendingMessages", + "MessagesController/MarkMessageAsSent", + "MessagesController/MarkMessageAsDelivered", + "MessagesController/MarkMessageAsFailed", + "OrdersController/GetOrdersByIdentity", + "OrdersController/GetOrdersByCustomerId", + "OrdersController/GetOrderByIdentity", + "OrdersController/CreateOrder", + "OrdersController/CreatePayment", + "OrdersController/GetOrderPayments", + "OrdersController/GetPaymentStatus", + "OrdersController/CancelOrder", + "OrdersController/PaymentWebhook", + "TestController/CreateTestProduct", + "TestController/SetupTestData", + "AccountController/Login", + "AccountController/Login", + "AccountController/AccessDenied", + "BotsController/Index", + "BotsController/Details", + "BotsController/Create", + "BotsController/Wizard", + "BotsController/Wizard", + "BotsController/CompleteWizard", + "BotsController/Create", + "BotsController/Edit", + "BotsController/Edit", + "BotsController/Metrics", + "BotsController/Delete", + "BotsController/Suspend", + "BotsController/Activate", + "BotsController/RegenerateKey", + "CategoriesController/Index", + "CategoriesController/Create", + "CategoriesController/Create", + "CategoriesController/Edit", + "CategoriesController/Edit", + "CategoriesController/Delete", + "DashboardController/Index", + "MessagesController/Index", + "MessagesController/Customer", + "MessagesController/Reply", + "OrdersController/Index", + "OrdersController/Details", + "OrdersController/Create", + "OrdersController/Create", + "OrdersController/Edit", + "OrdersController/Edit", + "OrdersController/UpdateStatus", + "ProductsController/Index", + "ProductsController/Create", + "ProductsController/Create", + "ProductsController/Edit", + "ProductsController/Edit", + "ProductsController/UploadPhoto", + "ProductsController/DeletePhoto", + "ProductsController/Delete", + "ShippingRatesController/Index", + "ShippingRatesController/Create", + "ShippingRatesController/Create", + "ShippingRatesController/Edit", + "ShippingRatesController/Edit", + "ShippingRatesController/Delete", + "UsersController/Index", + "UsersController/Create", + "UsersController/Create", + "UsersController/Edit", + "UsersController/Edit", + "UsersController/Delete" + ] + }, + { + "Name": "Authenticated", + "IsAuthenticated": true, + "Roles": [], + "Claims": [], + "AccessibleEndpoints": [ + "AuthController/Login", + "BotMessagesController/GetPendingMessages", + "BotMessagesController/MarkMessageAsSent", + "BotMessagesController/MarkMessageAsFailed", + "BotMessagesController/CreateTestMessage", + "BotMessagesController/CreateCustomerMessage", + "BotMessagesController/GetCustomerMessages", + "BotsController/RegisterBot", + "BotsController/AuthenticateBot", + "BotsController/GetBotSettings", + "BotsController/UpdateBotSettings", + "BotsController/RecordHeartbeat", + "BotsController/UpdatePlatformInfo", + "BotsController/RecordMetric", + "BotsController/RecordMetricsBatch", + "BotsController/StartSession", + "BotsController/UpdateSession", + "BotsController/EndSession", + "CatalogController/GetCategories", + "CatalogController/GetCategory", + "CatalogController/GetProducts", + "CatalogController/GetProduct", + "CustomersController/GetCustomers", + "CustomersController/GetCustomer", + "CustomersController/GetCustomerByTelegramId", + "CustomersController/CreateCustomer", + "CustomersController/GetOrCreateCustomer", + "CustomersController/UpdateCustomer", + "CustomersController/BlockCustomer", + "CustomersController/UnblockCustomer", + "CustomersController/DeleteCustomer", + "HomeController/Index", + "MessagesController/SendMessage", + "MessagesController/GetMessage", + "MessagesController/GetCustomerMessages", + "MessagesController/GetOrderMessages", + "MessagesController/GetPendingMessages", + "MessagesController/MarkMessageAsSent", + "MessagesController/MarkMessageAsDelivered", + "MessagesController/MarkMessageAsFailed", + "OrdersController/GetOrdersByIdentity", + "OrdersController/GetOrdersByCustomerId", + "OrdersController/GetOrderByIdentity", + "OrdersController/CreateOrder", + "OrdersController/CreatePayment", + "OrdersController/GetOrderPayments", + "OrdersController/GetPaymentStatus", + "OrdersController/CancelOrder", + "OrdersController/PaymentWebhook", + "TestController/CreateTestProduct", + "TestController/SetupTestData", + "AccountController/Login", + "AccountController/Login", + "AccountController/Logout", + "AccountController/AccessDenied", + "BotsController/Index", + "BotsController/Details", + "BotsController/Create", + "BotsController/Wizard", + "BotsController/Wizard", + "BotsController/CompleteWizard", + "BotsController/Create", + "BotsController/Edit", + "BotsController/Edit", + "BotsController/Metrics", + "BotsController/Delete", + "BotsController/Suspend", + "BotsController/Activate", + "BotsController/RegenerateKey", + "CategoriesController/Index", + "CategoriesController/Create", + "CategoriesController/Create", + "CategoriesController/Edit", + "CategoriesController/Edit", + "CategoriesController/Delete", + "DashboardController/Index", + "MessagesController/Index", + "MessagesController/Customer", + "MessagesController/Reply", + "OrdersController/Index", + "OrdersController/Details", + "OrdersController/Create", + "OrdersController/Create", + "OrdersController/Edit", + "OrdersController/Edit", + "OrdersController/UpdateStatus", + "ProductsController/Index", + "ProductsController/Create", + "ProductsController/Create", + "ProductsController/Edit", + "ProductsController/Edit", + "ProductsController/UploadPhoto", + "ProductsController/DeletePhoto", + "ProductsController/Delete", + "ShippingRatesController/Index", + "ShippingRatesController/Create", + "ShippingRatesController/Create", + "ShippingRatesController/Edit", + "ShippingRatesController/Edit", + "ShippingRatesController/Delete", + "UsersController/Index", + "UsersController/Create", + "UsersController/Create", + "UsersController/Edit", + "UsersController/Edit", + "UsersController/Delete" + ] + }, + { + "Name": "Authenticated_Admin", + "IsAuthenticated": true, + "Roles": [ + "Admin" + ], + "Claims": [], + "AccessibleEndpoints": [ + "AuthController/Login", + "BotMessagesController/GetPendingMessages", + "BotMessagesController/MarkMessageAsSent", + "BotMessagesController/MarkMessageAsFailed", + "BotMessagesController/CreateTestMessage", + "BotMessagesController/CreateCustomerMessage", + "BotMessagesController/GetCustomerMessages", + "BotsController/RegisterBot", + "BotsController/AuthenticateBot", + "BotsController/GetBotSettings", + "BotsController/UpdateBotSettings", + "BotsController/RecordHeartbeat", + "BotsController/UpdatePlatformInfo", + "BotsController/RecordMetric", + "BotsController/RecordMetricsBatch", + "BotsController/StartSession", + "BotsController/UpdateSession", + "BotsController/EndSession", + "BotsController/GetAllBots", + "BotsController/GetBot", + "BotsController/GetBotMetrics", + "BotsController/GetMetricsSummary", + "BotsController/GetBotSessions", + "BotsController/DeleteBot", + "CatalogController/GetCategories", + "CatalogController/GetCategory", + "CatalogController/GetProducts", + "CatalogController/GetProduct", + "CustomersController/GetCustomers", + "CustomersController/GetCustomer", + "CustomersController/GetCustomerByTelegramId", + "CustomersController/CreateCustomer", + "CustomersController/GetOrCreateCustomer", + "CustomersController/UpdateCustomer", + "CustomersController/BlockCustomer", + "CustomersController/UnblockCustomer", + "CustomersController/DeleteCustomer", + "HomeController/Index", + "MessagesController/SendMessage", + "MessagesController/GetMessage", + "MessagesController/GetCustomerMessages", + "MessagesController/GetOrderMessages", + "MessagesController/GetPendingMessages", + "MessagesController/MarkMessageAsSent", + "MessagesController/MarkMessageAsDelivered", + "MessagesController/MarkMessageAsFailed", + "OrdersController/GetAllOrders", + "OrdersController/GetOrder", + "OrdersController/UpdateOrderStatus", + "OrdersController/GetOrdersByIdentity", + "OrdersController/GetOrdersByCustomerId", + "OrdersController/GetOrderByIdentity", + "OrdersController/CreateOrder", + "OrdersController/CreatePayment", + "OrdersController/GetOrderPayments", + "OrdersController/GetPaymentStatus", + "OrdersController/CancelOrder", + "OrdersController/PaymentWebhook", + "TestController/CreateTestProduct", + "TestController/SetupTestData", + "AccountController/Login", + "AccountController/Login", + "AccountController/Logout", + "AccountController/AccessDenied", + "BotsController/Index", + "BotsController/Details", + "BotsController/Create", + "BotsController/Wizard", + "BotsController/Wizard", + "BotsController/CompleteWizard", + "BotsController/Create", + "BotsController/Edit", + "BotsController/Edit", + "BotsController/Metrics", + "BotsController/Delete", + "BotsController/Suspend", + "BotsController/Activate", + "BotsController/RegenerateKey", + "CategoriesController/Index", + "CategoriesController/Create", + "CategoriesController/Create", + "CategoriesController/Edit", + "CategoriesController/Edit", + "CategoriesController/Delete", + "DashboardController/Index", + "MessagesController/Index", + "MessagesController/Customer", + "MessagesController/Reply", + "OrdersController/Index", + "OrdersController/Details", + "OrdersController/Create", + "OrdersController/Create", + "OrdersController/Edit", + "OrdersController/Edit", + "OrdersController/UpdateStatus", + "ProductsController/Index", + "ProductsController/Create", + "ProductsController/Create", + "ProductsController/Edit", + "ProductsController/Edit", + "ProductsController/UploadPhoto", + "ProductsController/DeletePhoto", + "ProductsController/Delete", + "ShippingRatesController/Index", + "ShippingRatesController/Create", + "ShippingRatesController/Create", + "ShippingRatesController/Edit", + "ShippingRatesController/Edit", + "ShippingRatesController/Delete", + "UsersController/Index", + "UsersController/Create", + "UsersController/Create", + "UsersController/Edit", + "UsersController/Edit", + "UsersController/Delete" + ] + } + ], + "EndpointRequirements": [ + { + "Endpoint": "AuthController/Login", + "Controller": "AuthController", + "Action": "Login", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotMessagesController/GetPendingMessages", + "Controller": "BotMessagesController", + "Action": "GetPendingMessages", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotMessagesController/MarkMessageAsSent", + "Controller": "BotMessagesController", + "Action": "MarkMessageAsSent", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotMessagesController/MarkMessageAsFailed", + "Controller": "BotMessagesController", + "Action": "MarkMessageAsFailed", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotMessagesController/CreateTestMessage", + "Controller": "BotMessagesController", + "Action": "CreateTestMessage", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotMessagesController/CreateCustomerMessage", + "Controller": "BotMessagesController", + "Action": "CreateCustomerMessage", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotMessagesController/GetCustomerMessages", + "Controller": "BotMessagesController", + "Action": "GetCustomerMessages", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/RegisterBot", + "Controller": "BotsController", + "Action": "RegisterBot", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/AuthenticateBot", + "Controller": "BotsController", + "Action": "AuthenticateBot", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/GetBotSettings", + "Controller": "BotsController", + "Action": "GetBotSettings", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/UpdateBotSettings", + "Controller": "BotsController", + "Action": "UpdateBotSettings", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/RecordHeartbeat", + "Controller": "BotsController", + "Action": "RecordHeartbeat", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/UpdatePlatformInfo", + "Controller": "BotsController", + "Action": "UpdatePlatformInfo", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/RecordMetric", + "Controller": "BotsController", + "Action": "RecordMetric", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/RecordMetricsBatch", + "Controller": "BotsController", + "Action": "RecordMetricsBatch", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/StartSession", + "Controller": "BotsController", + "Action": "StartSession", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/UpdateSession", + "Controller": "BotsController", + "Action": "UpdateSession", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/EndSession", + "Controller": "BotsController", + "Action": "EndSession", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/GetAllBots", + "Controller": "BotsController", + "Action": "GetAllBots", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/GetBot", + "Controller": "BotsController", + "Action": "GetBot", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/GetBotMetrics", + "Controller": "BotsController", + "Action": "GetBotMetrics", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/GetMetricsSummary", + "Controller": "BotsController", + "Action": "GetMetricsSummary", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/GetBotSessions", + "Controller": "BotsController", + "Action": "GetBotSessions", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "BotsController/DeleteBot", + "Controller": "BotsController", + "Action": "DeleteBot", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "CatalogController/GetCategories", + "Controller": "CatalogController", + "Action": "GetCategories", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CatalogController/GetCategory", + "Controller": "CatalogController", + "Action": "GetCategory", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CatalogController/GetProducts", + "Controller": "CatalogController", + "Action": "GetProducts", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CatalogController/GetProduct", + "Controller": "CatalogController", + "Action": "GetProduct", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/GetCustomers", + "Controller": "CustomersController", + "Action": "GetCustomers", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/GetCustomer", + "Controller": "CustomersController", + "Action": "GetCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/GetCustomerByTelegramId", + "Controller": "CustomersController", + "Action": "GetCustomerByTelegramId", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/CreateCustomer", + "Controller": "CustomersController", + "Action": "CreateCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/GetOrCreateCustomer", + "Controller": "CustomersController", + "Action": "GetOrCreateCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "CustomersController/UpdateCustomer", + "Controller": "CustomersController", + "Action": "UpdateCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/BlockCustomer", + "Controller": "CustomersController", + "Action": "BlockCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/UnblockCustomer", + "Controller": "CustomersController", + "Action": "UnblockCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CustomersController/DeleteCustomer", + "Controller": "CustomersController", + "Action": "DeleteCustomer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "HomeController/Index", + "Controller": "HomeController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/SendMessage", + "Controller": "MessagesController", + "Action": "SendMessage", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/GetMessage", + "Controller": "MessagesController", + "Action": "GetMessage", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/GetCustomerMessages", + "Controller": "MessagesController", + "Action": "GetCustomerMessages", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/GetOrderMessages", + "Controller": "MessagesController", + "Action": "GetOrderMessages", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/GetPendingMessages", + "Controller": "MessagesController", + "Action": "GetPendingMessages", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "MessagesController/MarkMessageAsSent", + "Controller": "MessagesController", + "Action": "MarkMessageAsSent", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "MessagesController/MarkMessageAsDelivered", + "Controller": "MessagesController", + "Action": "MarkMessageAsDelivered", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/MarkMessageAsFailed", + "Controller": "MessagesController", + "Action": "MarkMessageAsFailed", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/GetAllOrders", + "Controller": "OrdersController", + "Action": "GetAllOrders", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/GetOrder", + "Controller": "OrdersController", + "Action": "GetOrder", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/UpdateOrderStatus", + "Controller": "OrdersController", + "Action": "UpdateOrderStatus", + "RequiresAuth": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/GetOrdersByIdentity", + "Controller": "OrdersController", + "Action": "GetOrdersByIdentity", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/GetOrdersByCustomerId", + "Controller": "OrdersController", + "Action": "GetOrdersByCustomerId", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/GetOrderByIdentity", + "Controller": "OrdersController", + "Action": "GetOrderByIdentity", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/CreateOrder", + "Controller": "OrdersController", + "Action": "CreateOrder", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/CreatePayment", + "Controller": "OrdersController", + "Action": "CreatePayment", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": true, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "Endpoint": "OrdersController/GetOrderPayments", + "Controller": "OrdersController", + "Action": "GetOrderPayments", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/GetPaymentStatus", + "Controller": "OrdersController", + "Action": "GetPaymentStatus", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/CancelOrder", + "Controller": "OrdersController", + "Action": "CancelOrder", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/PaymentWebhook", + "Controller": "OrdersController", + "Action": "PaymentWebhook", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "TestController/CreateTestProduct", + "Controller": "TestController", + "Action": "CreateTestProduct", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "TestController/SetupTestData", + "Controller": "TestController", + "Action": "SetupTestData", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "AccountController/Login", + "Controller": "AccountController", + "Action": "Login", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "AccountController/Login", + "Controller": "AccountController", + "Action": "Login", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "AccountController/Logout", + "Controller": "AccountController", + "Action": "Logout", + "RequiresAuth": true, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "Endpoint": "AccountController/AccessDenied", + "Controller": "AccountController", + "Action": "AccessDenied", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Index", + "Controller": "BotsController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Details", + "Controller": "BotsController", + "Action": "Details", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Create", + "Controller": "BotsController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Wizard", + "Controller": "BotsController", + "Action": "Wizard", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Wizard", + "Controller": "BotsController", + "Action": "Wizard", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/CompleteWizard", + "Controller": "BotsController", + "Action": "CompleteWizard", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Create", + "Controller": "BotsController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Edit", + "Controller": "BotsController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Edit", + "Controller": "BotsController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Metrics", + "Controller": "BotsController", + "Action": "Metrics", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Delete", + "Controller": "BotsController", + "Action": "Delete", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Suspend", + "Controller": "BotsController", + "Action": "Suspend", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/Activate", + "Controller": "BotsController", + "Action": "Activate", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "BotsController/RegenerateKey", + "Controller": "BotsController", + "Action": "RegenerateKey", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CategoriesController/Index", + "Controller": "CategoriesController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CategoriesController/Create", + "Controller": "CategoriesController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CategoriesController/Create", + "Controller": "CategoriesController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CategoriesController/Edit", + "Controller": "CategoriesController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CategoriesController/Edit", + "Controller": "CategoriesController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "CategoriesController/Delete", + "Controller": "CategoriesController", + "Action": "Delete", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "DashboardController/Index", + "Controller": "DashboardController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/Index", + "Controller": "MessagesController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/Customer", + "Controller": "MessagesController", + "Action": "Customer", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "MessagesController/Reply", + "Controller": "MessagesController", + "Action": "Reply", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/Index", + "Controller": "OrdersController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/Details", + "Controller": "OrdersController", + "Action": "Details", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/Create", + "Controller": "OrdersController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/Create", + "Controller": "OrdersController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/Edit", + "Controller": "OrdersController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/Edit", + "Controller": "OrdersController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "OrdersController/UpdateStatus", + "Controller": "OrdersController", + "Action": "UpdateStatus", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/Index", + "Controller": "ProductsController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/Create", + "Controller": "ProductsController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/Create", + "Controller": "ProductsController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/Edit", + "Controller": "ProductsController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/Edit", + "Controller": "ProductsController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/UploadPhoto", + "Controller": "ProductsController", + "Action": "UploadPhoto", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/DeletePhoto", + "Controller": "ProductsController", + "Action": "DeletePhoto", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ProductsController/Delete", + "Controller": "ProductsController", + "Action": "Delete", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ShippingRatesController/Index", + "Controller": "ShippingRatesController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ShippingRatesController/Create", + "Controller": "ShippingRatesController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ShippingRatesController/Create", + "Controller": "ShippingRatesController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ShippingRatesController/Edit", + "Controller": "ShippingRatesController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ShippingRatesController/Edit", + "Controller": "ShippingRatesController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "ShippingRatesController/Delete", + "Controller": "ShippingRatesController", + "Action": "Delete", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "UsersController/Index", + "Controller": "UsersController", + "Action": "Index", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "UsersController/Create", + "Controller": "UsersController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "UsersController/Create", + "Controller": "UsersController", + "Action": "Create", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "UsersController/Edit", + "Controller": "UsersController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "UsersController/Edit", + "Controller": "UsersController", + "Action": "Edit", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + }, + { + "Endpoint": "UsersController/Delete", + "Controller": "UsersController", + "Action": "Delete", + "RequiresAuth": false, + "RequiredRoles": [], + "AllowsAnonymous": false, + "AccessibleByStates": [ + "Anonymous", + "Authenticated", + "Authenticated_Admin" + ], + "TestableStates": [ + "Anonymous" + ] + } + ], + "Transitions": [ + { + "FromState": "Anonymous", + "ToState": "Authenticated", + "Action": "Login", + "Endpoint": "AuthController/Login", + "RequiresValidation": true + }, + { + "FromState": "Anonymous", + "ToState": "Authenticated", + "Action": "Register", + "Endpoint": "BotsController/RegisterBot", + "RequiresValidation": true + }, + { + "FromState": "Anonymous", + "ToState": "Authenticated", + "Action": "Login", + "Endpoint": "BotsController/AuthenticateBot", + "RequiresValidation": true + }, + { + "FromState": "Anonymous", + "ToState": "Authenticated", + "Action": "Login", + "Endpoint": "AccountController/Login", + "RequiresValidation": true + }, + { + "FromState": "Anonymous", + "ToState": "Authenticated", + "Action": "Login", + "Endpoint": "AccountController/Login", + "RequiresValidation": true + }, + { + "FromState": "Authenticated", + "ToState": "Anonymous", + "Action": "Logout", + "Endpoint": "AccountController/Logout", + "RequiresValidation": false + }, + { + "FromState": "Authenticated_Admin", + "ToState": "Anonymous", + "Action": "Logout", + "Endpoint": "AccountController/Logout", + "RequiresValidation": false + } + ], + "TestingGaps": [ + "Untested authentication states for AuthController/Login: Authenticated, Authenticated_Admin", + "Untested authentication states for BotMessagesController/GetPendingMessages: Authenticated, Authenticated_Admin", + "Untested authentication states for BotMessagesController/MarkMessageAsSent: Authenticated, Authenticated_Admin", + "Untested authentication states for BotMessagesController/MarkMessageAsFailed: Authenticated, Authenticated_Admin", + "Untested authentication states for BotMessagesController/CreateTestMessage: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotMessagesController/CreateTestMessage may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotMessagesController/CreateCustomerMessage: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotMessagesController/CreateCustomerMessage may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotMessagesController/GetCustomerMessages: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/GetBotSettings: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/GetBotSettings may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/UpdateBotSettings: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/UpdateBotSettings may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/RecordHeartbeat: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/UpdatePlatformInfo: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/UpdatePlatformInfo may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/RecordMetric: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/RecordMetricsBatch: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/StartSession: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/UpdateSession: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/UpdateSession may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/EndSession: Authenticated, Authenticated_Admin", + "Untested authentication states for CatalogController/GetCategories: Authenticated, Authenticated_Admin", + "Untested authentication states for CatalogController/GetCategory: Authenticated, Authenticated_Admin", + "Untested authentication states for CatalogController/GetProducts: Authenticated, Authenticated_Admin", + "Untested authentication states for CatalogController/GetProduct: Authenticated, Authenticated_Admin", + "Untested authentication states for CustomersController/GetCustomers: Authenticated, Authenticated_Admin", + "Untested authentication states for CustomersController/GetCustomer: Authenticated, Authenticated_Admin", + "Untested authentication states for CustomersController/GetCustomerByTelegramId: Authenticated, Authenticated_Admin", + "Untested authentication states for CustomersController/CreateCustomer: Authenticated, Authenticated_Admin", + "State-dependent endpoint CustomersController/CreateCustomer may show different content for anonymous vs authenticated users - ensure both paths are tested", + "State-dependent endpoint CustomersController/GetOrCreateCustomer may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for CustomersController/UpdateCustomer: Authenticated, Authenticated_Admin", + "State-dependent endpoint CustomersController/UpdateCustomer may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for CustomersController/BlockCustomer: Authenticated, Authenticated_Admin", + "Untested authentication states for CustomersController/UnblockCustomer: Authenticated, Authenticated_Admin", + "Untested authentication states for CustomersController/DeleteCustomer: Authenticated, Authenticated_Admin", + "State-dependent endpoint CustomersController/DeleteCustomer may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for HomeController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for MessagesController/SendMessage: Authenticated, Authenticated_Admin", + "Untested authentication states for MessagesController/GetMessage: Authenticated, Authenticated_Admin", + "Untested authentication states for MessagesController/GetCustomerMessages: Authenticated, Authenticated_Admin", + "Untested authentication states for MessagesController/GetOrderMessages: Authenticated, Authenticated_Admin", + "State-dependent endpoint MessagesController/GetOrderMessages may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for MessagesController/MarkMessageAsDelivered: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/GetOrdersByIdentity may show different content for anonymous vs authenticated users - ensure both paths are tested", + "State-dependent endpoint OrdersController/GetOrdersByCustomerId may show different content for anonymous vs authenticated users - ensure both paths are tested", + "State-dependent endpoint OrdersController/GetOrderByIdentity may show different content for anonymous vs authenticated users - ensure both paths are tested", + "State-dependent endpoint OrdersController/CreateOrder may show different content for anonymous vs authenticated users - ensure both paths are tested", + "State-dependent endpoint OrdersController/CreatePayment may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/GetOrderPayments: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/GetOrderPayments may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/GetPaymentStatus: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/GetPaymentStatus may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/CancelOrder: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/CancelOrder may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/PaymentWebhook: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/PaymentWebhook may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for TestController/CreateTestProduct: Authenticated, Authenticated_Admin", + "State-dependent endpoint TestController/CreateTestProduct may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for TestController/SetupTestData: Authenticated, Authenticated_Admin", + "Untested authentication states for AccountController/Login: Authenticated, Authenticated_Admin", + "State-dependent endpoint AccountController/Login may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for AccountController/Login: Authenticated, Authenticated_Admin", + "State-dependent endpoint AccountController/Login may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for AccountController/Logout: Authenticated_Admin", + "Untested authentication states for AccountController/AccessDenied: Authenticated, Authenticated_Admin", + "State-dependent endpoint AccountController/AccessDenied may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/Details: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/Wizard: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/Wizard: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/CompleteWizard: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/Metrics: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/Delete: Authenticated, Authenticated_Admin", + "State-dependent endpoint BotsController/Delete may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for BotsController/Suspend: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/Activate: Authenticated, Authenticated_Admin", + "Untested authentication states for BotsController/RegenerateKey: Authenticated, Authenticated_Admin", + "Untested authentication states for CategoriesController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for CategoriesController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint CategoriesController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for CategoriesController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint CategoriesController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for CategoriesController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint CategoriesController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for CategoriesController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint CategoriesController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for CategoriesController/Delete: Authenticated, Authenticated_Admin", + "State-dependent endpoint CategoriesController/Delete may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for DashboardController/Index: Authenticated, Authenticated_Admin", + "State-dependent endpoint DashboardController/Index may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for MessagesController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for MessagesController/Customer: Authenticated, Authenticated_Admin", + "Untested authentication states for MessagesController/Reply: Authenticated, Authenticated_Admin", + "Untested authentication states for OrdersController/Index: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/Index may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/Details: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/Details may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for OrdersController/UpdateStatus: Authenticated, Authenticated_Admin", + "State-dependent endpoint OrdersController/UpdateStatus may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ProductsController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for ProductsController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint ProductsController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ProductsController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint ProductsController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ProductsController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint ProductsController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ProductsController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint ProductsController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ProductsController/UploadPhoto: Authenticated, Authenticated_Admin", + "Untested authentication states for ProductsController/DeletePhoto: Authenticated, Authenticated_Admin", + "State-dependent endpoint ProductsController/DeletePhoto may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ProductsController/Delete: Authenticated, Authenticated_Admin", + "State-dependent endpoint ProductsController/Delete may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ShippingRatesController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for ShippingRatesController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint ShippingRatesController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ShippingRatesController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint ShippingRatesController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ShippingRatesController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint ShippingRatesController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ShippingRatesController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint ShippingRatesController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for ShippingRatesController/Delete: Authenticated, Authenticated_Admin", + "State-dependent endpoint ShippingRatesController/Delete may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for UsersController/Index: Authenticated, Authenticated_Admin", + "Untested authentication states for UsersController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint UsersController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for UsersController/Create: Authenticated, Authenticated_Admin", + "State-dependent endpoint UsersController/Create may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for UsersController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint UsersController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for UsersController/Edit: Authenticated, Authenticated_Admin", + "State-dependent endpoint UsersController/Edit may show different content for anonymous vs authenticated users - ensure both paths are tested", + "Untested authentication states for UsersController/Delete: Authenticated, Authenticated_Admin", + "State-dependent endpoint UsersController/Delete may show different content for anonymous vs authenticated users - ensure both paths are tested" + ], + "Recommendations": [ + "High number of testing gaps detected - prioritize implementing missing authentication tests", + "Generate automated integration tests using TestAgent.TestGenerator for comprehensive coverage" + ] +} \ No newline at end of file diff --git a/publish/TestAgent_Results/coverage_analysis.json b/publish/TestAgent_Results/coverage_analysis.json new file mode 100644 index 0000000..1f3998d --- /dev/null +++ b/publish/TestAgent_Results/coverage_analysis.json @@ -0,0 +1,6861 @@ +{ + "EndpointCoverage": [ + { + "Endpoint": "api/Auth/login", + "Controller": "Auth", + "Action": "Login", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/bot/messages/pending", + "Controller": "BotMessages", + "Action": "GetPendingMessages", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/bot/messages/{id}/mark-sent", + "Controller": "BotMessages", + "Action": "MarkMessageAsSent", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/bot/messages/{id}/mark-failed", + "Controller": "BotMessages", + "Action": "MarkMessageAsFailed", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/bot/messages/test-create", + "Controller": "BotMessages", + "Action": "CreateTestMessage", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/bot/messages/customer-create", + "Controller": "BotMessages", + "Action": "CreateCustomerMessage", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/bot/messages/customer/{customerId}", + "Controller": "BotMessages", + "Action": "GetCustomerMessages", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/register", + "Controller": "Bots", + "Action": "RegisterBot", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/authenticate", + "Controller": "Bots", + "Action": "AuthenticateBot", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/settings", + "Controller": "Bots", + "Action": "GetBotSettings", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Bots/settings", + "Controller": "Bots", + "Action": "UpdateBotSettings", + "HttpMethods": [ + "PUT" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/heartbeat", + "Controller": "Bots", + "Action": "RecordHeartbeat", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/platform-info", + "Controller": "Bots", + "Action": "UpdatePlatformInfo", + "HttpMethods": [ + "PUT" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/metrics", + "Controller": "Bots", + "Action": "RecordMetric", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/metrics/batch", + "Controller": "Bots", + "Action": "RecordMetricsBatch", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/sessions/start", + "Controller": "Bots", + "Action": "StartSession", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/sessions/{sessionId}", + "Controller": "Bots", + "Action": "UpdateSession", + "HttpMethods": [ + "PUT" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/sessions/{sessionId}/end", + "Controller": "Bots", + "Action": "EndSession", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/GetAllBots", + "Controller": "Bots", + "Action": "GetAllBots", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Bots/{id}", + "Controller": "Bots", + "Action": "GetBot", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Bots/{id}/metrics", + "Controller": "Bots", + "Action": "GetBotMetrics", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Bots/{id}/metrics/summary", + "Controller": "Bots", + "Action": "GetMetricsSummary", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Bots/{id}/sessions", + "Controller": "Bots", + "Action": "GetBotSessions", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Bots/{id}", + "Controller": "Bots", + "Action": "DeleteBot", + "HttpMethods": [ + "DELETE" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Catalog/categories", + "Controller": "Catalog", + "Action": "GetCategories", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Catalog/categories/{id}", + "Controller": "Catalog", + "Action": "GetCategory", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Catalog/products", + "Controller": "Catalog", + "Action": "GetProducts", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Catalog/products/{id}", + "Controller": "Catalog", + "Action": "GetProduct", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Customers/GetCustomers", + "Controller": "Customers", + "Action": "GetCustomers", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Customers/{id}", + "Controller": "Customers", + "Action": "GetCustomer", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/by-telegram/{telegramUserId}", + "Controller": "Customers", + "Action": "GetCustomerByTelegramId", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/CreateCustomer", + "Controller": "Customers", + "Action": "CreateCustomer", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/get-or-create", + "Controller": "Customers", + "Action": "GetOrCreateCustomer", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test", + "State-Dependent Content Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/{id}", + "Controller": "Customers", + "Action": "UpdateCustomer", + "HttpMethods": [ + "PUT" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/{id}/block", + "Controller": "Customers", + "Action": "BlockCustomer", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/{id}/unblock", + "Controller": "Customers", + "Action": "UnblockCustomer", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Customers/{id}", + "Controller": "Customers", + "Action": "DeleteCustomer", + "HttpMethods": [ + "DELETE" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Home/Index", + "Controller": "Home", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Messages/SendMessage", + "Controller": "Messages", + "Action": "SendMessage", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Messages/{id}", + "Controller": "Messages", + "Action": "GetMessage", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Messages/customer/{customerId}", + "Controller": "Messages", + "Action": "GetCustomerMessages", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Messages/order/{orderId}", + "Controller": "Messages", + "Action": "GetOrderMessages", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Messages/pending", + "Controller": "Messages", + "Action": "GetPendingMessages", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Messages/{id}/mark-sent", + "Controller": "Messages", + "Action": "MarkMessageAsSent", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Messages/{id}/mark-delivered", + "Controller": "Messages", + "Action": "MarkMessageAsDelivered", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Messages/{id}/mark-failed", + "Controller": "Messages", + "Action": "MarkMessageAsFailed", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Orders/GetAllOrders", + "Controller": "Orders", + "Action": "GetAllOrders", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Orders/{id}", + "Controller": "Orders", + "Action": "GetOrder", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Orders/{id}/status", + "Controller": "Orders", + "Action": "UpdateOrderStatus", + "HttpMethods": [ + "PUT" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated", + "Authenticated_Admin" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [ + "Admin" + ], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test", + "Role-Based Authorization Test" + ], + "CoveragePercentage": 0 + }, + { + "Endpoint": "api/Orders/by-identity/{identityReference}", + "Controller": "Orders", + "Action": "GetOrdersByIdentity", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test", + "State-Dependent Content Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/by-customer/{customerId}", + "Controller": "Orders", + "Action": "GetOrdersByCustomerId", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test", + "State-Dependent Content Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "Controller": "Orders", + "Action": "GetOrderByIdentity", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test", + "State-Dependent Content Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/CreateOrder", + "Controller": "Orders", + "Action": "CreateOrder", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test", + "State-Dependent Content Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/{id}/payments", + "Controller": "Orders", + "Action": "CreatePayment", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test", + "State-Dependent Content Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/{id}/payments", + "Controller": "Orders", + "Action": "GetOrderPayments", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/payments/{paymentId}/status", + "Controller": "Orders", + "Action": "GetPaymentStatus", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/{id}/cancel", + "Controller": "Orders", + "Action": "CancelOrder", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/payments/webhook", + "Controller": "Orders", + "Action": "PaymentWebhook", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Test/create-product", + "Controller": "Test", + "Action": "CreateTestProduct", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Test/setup-test-data", + "Controller": "Test", + "Action": "SetupTestData", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Account/Login", + "Controller": "Account", + "Action": "Login", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Account/Login", + "Controller": "Account", + "Action": "Login", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 20 + }, + { + "Endpoint": "api/Account/Logout", + "Controller": "Account", + "Action": "Logout", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Account/AccessDenied", + "Controller": "Account", + "Action": "AccessDenied", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Anonymous" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [], + "CoveragePercentage": 40 + }, + { + "Endpoint": "api/Bots/Index", + "Controller": "Bots", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Bots/Details", + "Controller": "Bots", + "Action": "Details", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Create", + "Controller": "Bots", + "Action": "Create", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Bots/Wizard", + "Controller": "Bots", + "Action": "Wizard", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Bots/Wizard", + "Controller": "Bots", + "Action": "Wizard", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/CompleteWizard", + "Controller": "Bots", + "Action": "CompleteWizard", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Create", + "Controller": "Bots", + "Action": "Create", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Edit", + "Controller": "Bots", + "Action": "Edit", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Edit", + "Controller": "Bots", + "Action": "Edit", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Metrics", + "Controller": "Bots", + "Action": "Metrics", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Delete", + "Controller": "Bots", + "Action": "Delete", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Suspend", + "Controller": "Bots", + "Action": "Suspend", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/Activate", + "Controller": "Bots", + "Action": "Activate", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Bots/RegenerateKey", + "Controller": "Bots", + "Action": "RegenerateKey", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Categories/Index", + "Controller": "Categories", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Categories/Create", + "Controller": "Categories", + "Action": "Create", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Categories/Create", + "Controller": "Categories", + "Action": "Create", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Categories/Edit", + "Controller": "Categories", + "Action": "Edit", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Categories/Edit", + "Controller": "Categories", + "Action": "Edit", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Categories/Delete", + "Controller": "Categories", + "Action": "Delete", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Dashboard/Index", + "Controller": "Dashboard", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Messages/Index", + "Controller": "Messages", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Messages/Customer", + "Controller": "Messages", + "Action": "Customer", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Messages/Reply", + "Controller": "Messages", + "Action": "Reply", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/Index", + "Controller": "Orders", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Orders/Details", + "Controller": "Orders", + "Action": "Details", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/Create", + "Controller": "Orders", + "Action": "Create", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Orders/Create", + "Controller": "Orders", + "Action": "Create", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/Edit", + "Controller": "Orders", + "Action": "Edit", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/Edit", + "Controller": "Orders", + "Action": "Edit", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Orders/UpdateStatus", + "Controller": "Orders", + "Action": "UpdateStatus", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Products/Index", + "Controller": "Products", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Products/Create", + "Controller": "Products", + "Action": "Create", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Products/Create", + "Controller": "Products", + "Action": "Create", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Products/Edit", + "Controller": "Products", + "Action": "Edit", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Products/Edit", + "Controller": "Products", + "Action": "Edit", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Products/UploadPhoto", + "Controller": "Products", + "Action": "UploadPhoto", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Products/DeletePhoto", + "Controller": "Products", + "Action": "DeletePhoto", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Products/Delete", + "Controller": "Products", + "Action": "Delete", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/ShippingRates/Index", + "Controller": "ShippingRates", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/ShippingRates/Create", + "Controller": "ShippingRates", + "Action": "Create", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/ShippingRates/Create", + "Controller": "ShippingRates", + "Action": "Create", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/ShippingRates/Edit", + "Controller": "ShippingRates", + "Action": "Edit", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/ShippingRates/Edit", + "Controller": "ShippingRates", + "Action": "Edit", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/ShippingRates/Delete", + "Controller": "ShippingRates", + "Action": "Delete", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Users/Index", + "Controller": "Users", + "Action": "Index", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Users/Create", + "Controller": "Users", + "Action": "Create", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test" + ], + "CoveragePercentage": 30.000000000000004 + }, + { + "Endpoint": "api/Users/Create", + "Controller": "Users", + "Action": "Create", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Users/Edit", + "Controller": "Users", + "Action": "Edit", + "HttpMethods": [ + "GET" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Users/Edit", + "Controller": "Users", + "Action": "Edit", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + }, + { + "Endpoint": "api/Users/Delete", + "Controller": "Users", + "Action": "Delete", + "HttpMethods": [ + "POST" + ], + "TestedStates": [], + "UntestedStates": [ + "Authenticated" + ], + "HasUnauthorizedTest": false, + "HasValidDataTest": false, + "HasInvalidDataTest": false, + "HasRoleBasedTests": false, + "RequiredRoles": [], + "MissingTestTypes": [ + "Unauthorized Access Test", + "Valid Data Test", + "Invalid Data Test" + ], + "CoveragePercentage": 10 + } + ], + "AuthenticationScenarios": [ + { + "ScenarioName": "Login Flow", + "FromState": "Anonymous", + "ToState": "Authenticated", + "RequiredEndpoints": [ + "AuthController/Login" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Anonymous to Authenticated via login endpoint" + }, + { + "ScenarioName": "Register Flow", + "FromState": "Anonymous", + "ToState": "Authenticated", + "RequiredEndpoints": [ + "BotsController/RegisterBot" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Anonymous to Authenticated via registration endpoint" + }, + { + "ScenarioName": "Login Flow", + "FromState": "Anonymous", + "ToState": "Authenticated", + "RequiredEndpoints": [ + "BotsController/AuthenticateBot" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Anonymous to Authenticated via login endpoint" + }, + { + "ScenarioName": "Login Flow", + "FromState": "Anonymous", + "ToState": "Authenticated", + "RequiredEndpoints": [ + "AccountController/Login" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Anonymous to Authenticated via login endpoint" + }, + { + "ScenarioName": "Login Flow", + "FromState": "Anonymous", + "ToState": "Authenticated", + "RequiredEndpoints": [ + "AccountController/Login" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Anonymous to Authenticated via login endpoint" + }, + { + "ScenarioName": "Logout Flow", + "FromState": "Authenticated", + "ToState": "Anonymous", + "RequiredEndpoints": [ + "AccountController/Logout" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Authenticated to Anonymous via logout endpoint" + }, + { + "ScenarioName": "Logout Flow", + "FromState": "Authenticated_Admin", + "ToState": "Anonymous", + "RequiredEndpoints": [ + "AccountController/Logout" + ], + "IsTested": false, + "TestDescription": "User should be able to transition from Authenticated_Admin to Anonymous via logout endpoint" + }, + { + "ScenarioName": "Session Timeout", + "FromState": "Authenticated", + "ToState": "Anonymous", + "RequiredEndpoints": [], + "IsTested": false, + "TestDescription": "Verify that expired sessions are handled correctly and user is redirected to login" + }, + { + "ScenarioName": "Concurrent Sessions", + "FromState": "Authenticated", + "ToState": "Authenticated", + "RequiredEndpoints": [], + "IsTested": false, + "TestDescription": "Test behavior when same user logs in from multiple locations" + }, + { + "ScenarioName": "Role Switching", + "FromState": "Authenticated_User", + "ToState": "Authenticated_Admin", + "RequiredEndpoints": [], + "IsTested": false, + "TestDescription": "Verify that role changes are reflected in endpoint accessibility" + } + ], + "IdentifiedGaps": [ + { + "GapType": "Low Coverage", + "Endpoint": "api/Auth/login", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/bot/messages/pending", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/bot/messages/{id}/mark-sent", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/bot/messages/{id}/mark-failed", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/bot/messages/test-create", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/bot/messages/customer-create", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/bot/messages/customer/{customerId}", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/register", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/authenticate", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/settings", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/settings", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/heartbeat", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/platform-info", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/metrics", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/metrics/batch", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/sessions/start", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/sessions/{sessionId}", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/sessions/{sessionId}/end", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/GetAllBots", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Bots/GetAllBots", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/{id}", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Bots/{id}", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/{id}/metrics", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Bots/{id}/metrics", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/{id}/metrics/summary", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Bots/{id}/metrics/summary", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/{id}/sessions", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Bots/{id}/sessions", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/{id}", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Bots/{id}", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Catalog/categories", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Catalog/categories/{id}", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Catalog/products", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Catalog/products/{id}", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/GetCustomers", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/{id}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/by-telegram/{telegramUserId}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/CreateCustomer", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/get-or-create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "State-Dependent Logic", + "Endpoint": "api/Customers/get-or-create", + "Description": "Endpoint may show different content based on authentication state", + "Severity": "Warning", + "Recommendation": "Test endpoint with different authentication states to verify content differences", + "AffectedStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/{id}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/{id}/block", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/{id}/unblock", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Customers/{id}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Home/Index", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/SendMessage", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/{id}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/customer/{customerId}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/order/{orderId}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/pending", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/{id}/mark-sent", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/{id}/mark-delivered", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/{id}/mark-failed", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/GetAllOrders", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Orders/GetAllOrders", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/{id}", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Orders/{id}", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/{id}/status", + "Description": "Endpoint has only 0.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated", + "Authenticated_Admin" + ] + }, + { + "GapType": "Missing Authorization Test", + "Endpoint": "api/Orders/{id}/status", + "Description": "Protected endpoint lacks unauthorized access test", + "Severity": "Critical", + "Recommendation": "Add test to verify 401/403 response for unauthorized access", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/by-identity/{identityReference}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "State-Dependent Logic", + "Endpoint": "api/Orders/by-identity/{identityReference}", + "Description": "Endpoint may show different content based on authentication state", + "Severity": "Warning", + "Recommendation": "Test endpoint with different authentication states to verify content differences", + "AffectedStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/by-customer/{customerId}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "State-Dependent Logic", + "Endpoint": "api/Orders/by-customer/{customerId}", + "Description": "Endpoint may show different content based on authentication state", + "Severity": "Warning", + "Recommendation": "Test endpoint with different authentication states to verify content differences", + "AffectedStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "State-Dependent Logic", + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "Description": "Endpoint may show different content based on authentication state", + "Severity": "Warning", + "Recommendation": "Test endpoint with different authentication states to verify content differences", + "AffectedStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/CreateOrder", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "State-Dependent Logic", + "Endpoint": "api/Orders/CreateOrder", + "Description": "Endpoint may show different content based on authentication state", + "Severity": "Warning", + "Recommendation": "Test endpoint with different authentication states to verify content differences", + "AffectedStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/{id}/payments", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "State-Dependent Logic", + "Endpoint": "api/Orders/{id}/payments", + "Description": "Endpoint may show different content based on authentication state", + "Severity": "Warning", + "Recommendation": "Test endpoint with different authentication states to verify content differences", + "AffectedStates": [ + "Anonymous", + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/{id}/payments", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/payments/{paymentId}/status", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/{id}/cancel", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/payments/webhook", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Test/create-product", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Test/setup-test-data", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Account/Login", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Account/Login", + "Description": "Endpoint has only 20.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Account/Logout", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Account/AccessDenied", + "Description": "Endpoint has only 40.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Anonymous" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Details", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Create", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Wizard", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Wizard", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/CompleteWizard", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Metrics", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Delete", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Suspend", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/Activate", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Bots/RegenerateKey", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Categories/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Categories/Create", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Categories/Create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Categories/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Categories/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Categories/Delete", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Dashboard/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/Customer", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Messages/Reply", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/Details", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/Create", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/Create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Orders/UpdateStatus", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/Create", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/Create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/UploadPhoto", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/DeletePhoto", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Products/Delete", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/ShippingRates/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/ShippingRates/Create", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/ShippingRates/Create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/ShippingRates/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/ShippingRates/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/ShippingRates/Delete", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Users/Index", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Users/Create", + "Description": "Endpoint has only 30.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Users/Create", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Users/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Users/Edit", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Low Coverage", + "Endpoint": "api/Users/Delete", + "Description": "Endpoint has only 10.0% test coverage", + "Severity": "Critical", + "Recommendation": "Implement comprehensive test suite covering all authentication states and data scenarios", + "AffectedStates": [ + "Authenticated" + ] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Auth/login", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/bot/messages/{id}/mark-sent", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/bot/messages/{id}/mark-failed", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/bot/messages/test-create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/bot/messages/customer-create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/bot/messages/customer/{customerId}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/register", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/authenticate", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/settings", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/heartbeat", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/platform-info", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/metrics", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/metrics/batch", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/sessions/start", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/sessions/{sessionId}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/sessions/{sessionId}/end", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/{id}/metrics", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/{id}/metrics/summary", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/{id}/sessions", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Catalog/categories/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Catalog/products/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/by-telegram/{telegramUserId}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/CreateCustomer", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/get-or-create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/{id}/block", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/{id}/unblock", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/SendMessage", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/customer/{customerId}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/order/{orderId}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-sent", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-delivered", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-failed", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/{id}/status", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/by-identity/{identityReference}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/by-customer/{customerId}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/CreateOrder", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/{id}/payments", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/{id}/payments", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/payments/{paymentId}/status", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/{id}/cancel", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/payments/webhook", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Account/Login", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Account/Login", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Details", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Wizard", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Wizard", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/CompleteWizard", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Metrics", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Delete", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Suspend", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/Activate", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Bots/RegenerateKey", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Categories/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Categories/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Categories/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Categories/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Categories/Delete", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/Customer", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Messages/Reply", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/Details", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Orders/UpdateStatus", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/UploadPhoto", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/DeletePhoto", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Products/Delete", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/ShippingRates/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/ShippingRates/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/ShippingRates/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/ShippingRates/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/ShippingRates/Delete", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Users/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Users/Create", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Users/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Users/Edit", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + }, + { + "GapType": "Data Validation", + "Endpoint": "api/Users/Delete", + "Description": "Endpoint with complex parameters lacks comprehensive data validation tests", + "Severity": "Warning", + "Recommendation": "Add tests for both valid and invalid data scenarios, including edge cases", + "AffectedStates": [] + } + ], + "SuggestedTests": [ + { + "TestName": "Auth_Login_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Auth/login", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Auth_Login_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Auth/login\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Auth_Login_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Auth/login", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Auth_Login_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Auth/login\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_MarkMessageAsSent_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/{id}/mark-sent", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task BotMessages_MarkMessageAsSent_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/{id}/mark-sent\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_MarkMessageAsSent_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/{id}/mark-sent", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task BotMessages_MarkMessageAsSent_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/{id}/mark-sent\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_MarkMessageAsFailed_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/{id}/mark-failed", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task BotMessages_MarkMessageAsFailed_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/{id}/mark-failed\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_MarkMessageAsFailed_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/{id}/mark-failed", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task BotMessages_MarkMessageAsFailed_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/{id}/mark-failed\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_CreateTestMessage_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/test-create", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task BotMessages_CreateTestMessage_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/test-create\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_CreateTestMessage_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/test-create", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task BotMessages_CreateTestMessage_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/test-create\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_CreateCustomerMessage_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/customer-create", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task BotMessages_CreateCustomerMessage_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/customer-create\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_CreateCustomerMessage_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/customer-create", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task BotMessages_CreateCustomerMessage_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/customer-create\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_GetCustomerMessages_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task BotMessages_GetCustomerMessages_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/customer/{customerId}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "BotMessages_GetCustomerMessages_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/bot/messages/customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task BotMessages_GetCustomerMessages_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/bot/messages/customer/{customerId}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RegisterBot_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/register", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_RegisterBot_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/register\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RegisterBot_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/register", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_RegisterBot_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/register\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_AuthenticateBot_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/authenticate", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_AuthenticateBot_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/authenticate\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_AuthenticateBot_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/authenticate", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_AuthenticateBot_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/authenticate\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_UpdateBotSettings_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/settings", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_UpdateBotSettings_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/settings\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_UpdateBotSettings_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/settings", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_UpdateBotSettings_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/settings\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RecordHeartbeat_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/heartbeat", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_RecordHeartbeat_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/heartbeat\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RecordHeartbeat_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/heartbeat", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_RecordHeartbeat_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/heartbeat\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_UpdatePlatformInfo_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/platform-info", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_UpdatePlatformInfo_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/platform-info\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_UpdatePlatformInfo_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/platform-info", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_UpdatePlatformInfo_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/platform-info\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RecordMetric_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/metrics", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_RecordMetric_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/metrics\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RecordMetric_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/metrics", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_RecordMetric_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/metrics\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RecordMetricsBatch_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/metrics/batch", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_RecordMetricsBatch_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/metrics/batch\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RecordMetricsBatch_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/metrics/batch", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_RecordMetricsBatch_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/metrics/batch\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_StartSession_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/sessions/start", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_StartSession_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/sessions/start\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_StartSession_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/sessions/start", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_StartSession_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/sessions/start\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_UpdateSession_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/sessions/{sessionId}", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_UpdateSession_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/sessions/{sessionId}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_UpdateSession_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/sessions/{sessionId}", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_UpdateSession_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/sessions/{sessionId}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_EndSession_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/sessions/{sessionId}/end", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_EndSession_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/sessions/{sessionId}/end\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_EndSession_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/sessions/{sessionId}/end", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_EndSession_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/sessions/{sessionId}/end\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetAllBots_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Bots/GetAllBots", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Bots_GetAllBots_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/GetAllBots\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetAllBots_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Bots/GetAllBots", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetAllBots_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/GetAllBots\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBot_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Bots_GetBot_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBot_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetBot_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBot_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetBot_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetBot_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_GetBot_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetBotMetrics_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}/metrics", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Bots_GetBotMetrics_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}/metrics\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBotMetrics_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}/metrics", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetBotMetrics_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}/metrics\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBotMetrics_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}/metrics", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetBotMetrics_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}/metrics\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetBotMetrics_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}/metrics", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_GetBotMetrics_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}/metrics\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetMetricsSummary_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}/metrics/summary", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Bots_GetMetricsSummary_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}/metrics/summary\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetMetricsSummary_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}/metrics/summary", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetMetricsSummary_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}/metrics/summary\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetMetricsSummary_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}/metrics/summary", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetMetricsSummary_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}/metrics/summary\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetMetricsSummary_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}/metrics/summary", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_GetMetricsSummary_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}/metrics/summary\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetBotSessions_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}/sessions", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Bots_GetBotSessions_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}/sessions\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBotSessions_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}/sessions", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetBotSessions_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}/sessions\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_GetBotSessions_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}/sessions", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_GetBotSessions_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}/sessions\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_GetBotSessions_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}/sessions", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_GetBotSessions_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}/sessions\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_DeleteBot_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "DELETE", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Bots_DeleteBot_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_DeleteBot_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "DELETE", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_DeleteBot_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Bots/{id}\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Bots_DeleteBot_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "DELETE", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_DeleteBot_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_DeleteBot_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/{id}", + "HttpMethod": "DELETE", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_DeleteBot_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Catalog_GetCategory_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Catalog/categories/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Catalog_GetCategory_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Catalog/categories/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Catalog_GetCategory_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Catalog/categories/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Catalog_GetCategory_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Catalog/categories/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Catalog_GetProduct_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Catalog/products/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Catalog_GetProduct_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Catalog/products/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Catalog_GetProduct_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Catalog/products/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Catalog_GetProduct_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Catalog/products/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_GetCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_GetCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetCustomerByTelegramId_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/by-telegram/{telegramUserId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_GetCustomerByTelegramId_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/by-telegram/{telegramUserId}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetCustomerByTelegramId_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/by-telegram/{telegramUserId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_GetCustomerByTelegramId_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/by-telegram/{telegramUserId}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_CreateCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/CreateCustomer", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_CreateCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/CreateCustomer\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_CreateCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/CreateCustomer", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_CreateCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/CreateCustomer\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetOrCreateCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/get-or-create", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_GetOrCreateCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/get-or-create\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetOrCreateCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/get-or-create", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_GetOrCreateCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/get-or-create\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_GetOrCreateCustomer_StateDependent", + "TestType": "State Dependent", + "Endpoint": "api/Customers/get-or-create", + "HttpMethod": "POST", + "AuthenticationState": "Multiple", + "ExpectedOutcome": "Different Content Based on State", + "TestCode": "[Theory]\n[InlineData(\u0022Anonymous\u0022)]\n[InlineData(\u0022Authenticated\u0022)]\npublic async Task Customers_GetOrCreateCustomer_ShouldShowDifferentContent_BasedOnAuthState(string authState)\n{\n // Arrange\n var client = _factory.CreateClient();\n if (authState == \u0022Authenticated\u0022)\n await AuthenticateAsync(client);\n\n // Act\n var response = await client.GetAsync(\u0022api/Customers/get-or-create\u0022);\n var content = await response.Content.ReadAsStringAsync();\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n // Add specific content assertions based on authentication state\n if (authState == \u0022Authenticated\u0022)\n {\n Assert.Contains(\u0022authenticated-content\u0022, content);\n }\n else\n {\n Assert.Contains(\u0022anonymous-content\u0022, content);\n }\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_UpdateCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_UpdateCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_UpdateCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_UpdateCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_BlockCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}/block", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_BlockCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}/block\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_BlockCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}/block", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_BlockCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}/block\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_UnblockCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}/unblock", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_UnblockCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}/unblock\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_UnblockCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}/unblock", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_UnblockCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}/unblock\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_DeleteCustomer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "HttpMethod": "DELETE", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Customers_DeleteCustomer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Customers_DeleteCustomer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Customers/{id}", + "HttpMethod": "DELETE", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Customers_DeleteCustomer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Customers/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_SendMessage_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/SendMessage", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_SendMessage_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/SendMessage\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_SendMessage_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/SendMessage", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_SendMessage_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/SendMessage\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_GetMessage_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_GetMessage_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_GetMessage_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_GetMessage_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_GetCustomerMessages_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_GetCustomerMessages_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/customer/{customerId}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_GetCustomerMessages_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_GetCustomerMessages_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/customer/{customerId}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_GetOrderMessages_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/order/{orderId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_GetOrderMessages_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/order/{orderId}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_GetOrderMessages_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/order/{orderId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_GetOrderMessages_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/order/{orderId}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_MarkMessageAsSent_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-sent", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_MarkMessageAsSent_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}/mark-sent\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_MarkMessageAsSent_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-sent", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_MarkMessageAsSent_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}/mark-sent\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_MarkMessageAsDelivered_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-delivered", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_MarkMessageAsDelivered_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}/mark-delivered\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_MarkMessageAsDelivered_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-delivered", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_MarkMessageAsDelivered_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}/mark-delivered\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_MarkMessageAsFailed_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-failed", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_MarkMessageAsFailed_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}/mark-failed\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_MarkMessageAsFailed_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/{id}/mark-failed", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_MarkMessageAsFailed_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/{id}/mark-failed\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetAllOrders_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Orders/GetAllOrders", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Orders_GetAllOrders_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/GetAllOrders\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Orders_GetAllOrders_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Orders/GetAllOrders", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetAllOrders_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/GetAllOrders\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Orders_GetOrder_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Orders/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Orders_GetOrder_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/{id}\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Orders_GetOrder_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Orders/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetOrder_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/{id}\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Orders_GetOrder_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetOrder_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrder_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_GetOrder_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_UpdateOrderStatus_UnauthorizedAccess", + "TestType": "Authorization", + "Endpoint": "api/Orders/{id}/status", + "HttpMethod": "PUT", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "401 Unauthorized", + "TestCode": "[Fact]\npublic async Task Orders_UpdateOrderStatus_ShouldReturn401_WhenNotAuthenticated()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/{id}/status\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Orders_UpdateOrderStatus_RequiresRole_Admin", + "TestType": "Authorization", + "Endpoint": "api/Orders/{id}/status", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_UpdateOrderStatus_ShouldReturn200_WhenUserAdmin()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client, \u0022Admin\u0022);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/{id}/status\u0022);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "Orders_UpdateOrderStatus_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/status", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_UpdateOrderStatus_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/status\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_UpdateOrderStatus_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/status", + "HttpMethod": "PUT", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_UpdateOrderStatus_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/status\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrdersByIdentity_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/by-identity/{identityReference}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetOrdersByIdentity_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/by-identity/{identityReference}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrdersByIdentity_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/by-identity/{identityReference}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_GetOrdersByIdentity_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/by-identity/{identityReference}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrdersByIdentity_StateDependent", + "TestType": "State Dependent", + "Endpoint": "api/Orders/by-identity/{identityReference}", + "HttpMethod": "GET", + "AuthenticationState": "Multiple", + "ExpectedOutcome": "Different Content Based on State", + "TestCode": "[Theory]\n[InlineData(\u0022Anonymous\u0022)]\n[InlineData(\u0022Authenticated\u0022)]\npublic async Task Orders_GetOrdersByIdentity_ShouldShowDifferentContent_BasedOnAuthState(string authState)\n{\n // Arrange\n var client = _factory.CreateClient();\n if (authState == \u0022Authenticated\u0022)\n await AuthenticateAsync(client);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/by-identity/{identityReference}\u0022);\n var content = await response.Content.ReadAsStringAsync();\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n // Add specific content assertions based on authentication state\n if (authState == \u0022Authenticated\u0022)\n {\n Assert.Contains(\u0022authenticated-content\u0022, content);\n }\n else\n {\n Assert.Contains(\u0022anonymous-content\u0022, content);\n }\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrdersByCustomerId_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/by-customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetOrdersByCustomerId_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/by-customer/{customerId}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrdersByCustomerId_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/by-customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_GetOrdersByCustomerId_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/by-customer/{customerId}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrdersByCustomerId_StateDependent", + "TestType": "State Dependent", + "Endpoint": "api/Orders/by-customer/{customerId}", + "HttpMethod": "GET", + "AuthenticationState": "Multiple", + "ExpectedOutcome": "Different Content Based on State", + "TestCode": "[Theory]\n[InlineData(\u0022Anonymous\u0022)]\n[InlineData(\u0022Authenticated\u0022)]\npublic async Task Orders_GetOrdersByCustomerId_ShouldShowDifferentContent_BasedOnAuthState(string authState)\n{\n // Arrange\n var client = _factory.CreateClient();\n if (authState == \u0022Authenticated\u0022)\n await AuthenticateAsync(client);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/by-customer/{customerId}\u0022);\n var content = await response.Content.ReadAsStringAsync();\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n // Add specific content assertions based on authentication state\n if (authState == \u0022Authenticated\u0022)\n {\n Assert.Contains(\u0022authenticated-content\u0022, content);\n }\n else\n {\n Assert.Contains(\u0022anonymous-content\u0022, content);\n }\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrderByIdentity_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetOrderByIdentity_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/by-identity/{identityReference}/{id}\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrderByIdentity_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_GetOrderByIdentity_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/by-identity/{identityReference}/{id}\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrderByIdentity_StateDependent", + "TestType": "State Dependent", + "Endpoint": "api/Orders/by-identity/{identityReference}/{id}", + "HttpMethod": "GET", + "AuthenticationState": "Multiple", + "ExpectedOutcome": "Different Content Based on State", + "TestCode": "[Theory]\n[InlineData(\u0022Anonymous\u0022)]\n[InlineData(\u0022Authenticated\u0022)]\npublic async Task Orders_GetOrderByIdentity_ShouldShowDifferentContent_BasedOnAuthState(string authState)\n{\n // Arrange\n var client = _factory.CreateClient();\n if (authState == \u0022Authenticated\u0022)\n await AuthenticateAsync(client);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/by-identity/{identityReference}/{id}\u0022);\n var content = await response.Content.ReadAsStringAsync();\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n // Add specific content assertions based on authentication state\n if (authState == \u0022Authenticated\u0022)\n {\n Assert.Contains(\u0022authenticated-content\u0022, content);\n }\n else\n {\n Assert.Contains(\u0022anonymous-content\u0022, content);\n }\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CreateOrder_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/CreateOrder", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_CreateOrder_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/CreateOrder\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CreateOrder_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/CreateOrder", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_CreateOrder_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/CreateOrder\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CreateOrder_StateDependent", + "TestType": "State Dependent", + "Endpoint": "api/Orders/CreateOrder", + "HttpMethod": "POST", + "AuthenticationState": "Multiple", + "ExpectedOutcome": "Different Content Based on State", + "TestCode": "[Theory]\n[InlineData(\u0022Anonymous\u0022)]\n[InlineData(\u0022Authenticated\u0022)]\npublic async Task Orders_CreateOrder_ShouldShowDifferentContent_BasedOnAuthState(string authState)\n{\n // Arrange\n var client = _factory.CreateClient();\n if (authState == \u0022Authenticated\u0022)\n await AuthenticateAsync(client);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/CreateOrder\u0022);\n var content = await response.Content.ReadAsStringAsync();\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n // Add specific content assertions based on authentication state\n if (authState == \u0022Authenticated\u0022)\n {\n Assert.Contains(\u0022authenticated-content\u0022, content);\n }\n else\n {\n Assert.Contains(\u0022anonymous-content\u0022, content);\n }\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CreatePayment_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/payments", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_CreatePayment_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/payments\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CreatePayment_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/payments", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_CreatePayment_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/payments\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CreatePayment_StateDependent", + "TestType": "State Dependent", + "Endpoint": "api/Orders/{id}/payments", + "HttpMethod": "POST", + "AuthenticationState": "Multiple", + "ExpectedOutcome": "Different Content Based on State", + "TestCode": "[Theory]\n[InlineData(\u0022Anonymous\u0022)]\n[InlineData(\u0022Authenticated\u0022)]\npublic async Task Orders_CreatePayment_ShouldShowDifferentContent_BasedOnAuthState(string authState)\n{\n // Arrange\n var client = _factory.CreateClient();\n if (authState == \u0022Authenticated\u0022)\n await AuthenticateAsync(client);\n\n // Act\n var response = await client.GetAsync(\u0022api/Orders/{id}/payments\u0022);\n var content = await response.Content.ReadAsStringAsync();\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n // Add specific content assertions based on authentication state\n if (authState == \u0022Authenticated\u0022)\n {\n Assert.Contains(\u0022authenticated-content\u0022, content);\n }\n else\n {\n Assert.Contains(\u0022anonymous-content\u0022, content);\n }\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrderPayments_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/payments", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetOrderPayments_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/payments\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetOrderPayments_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/payments", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_GetOrderPayments_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/payments\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetPaymentStatus_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/payments/{paymentId}/status", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_GetPaymentStatus_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/payments/{paymentId}/status\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_GetPaymentStatus_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/payments/{paymentId}/status", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_GetPaymentStatus_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/payments/{paymentId}/status\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CancelOrder_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/cancel", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_CancelOrder_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/cancel\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_CancelOrder_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/{id}/cancel", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_CancelOrder_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/{id}/cancel\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_PaymentWebhook_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/payments/webhook", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_PaymentWebhook_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/payments/webhook\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_PaymentWebhook_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/payments/webhook", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_PaymentWebhook_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/payments/webhook\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Details_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Details", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Details_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Details\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Details_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Details", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Details_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Details\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_CompleteWizard_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/CompleteWizard", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_CompleteWizard_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/CompleteWizard\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_CompleteWizard_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/CompleteWizard", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_CompleteWizard_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/CompleteWizard\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Metrics_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Metrics", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Metrics_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Metrics\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Metrics_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Metrics", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Metrics_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Metrics\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Delete_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Delete_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Delete\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Delete_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Delete_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Delete\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Suspend_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Suspend", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Suspend_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Suspend\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Suspend_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Suspend", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Suspend_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Suspend\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Activate_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Activate", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_Activate_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Activate\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_Activate_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/Activate", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_Activate_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/Activate\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RegenerateKey_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/RegenerateKey", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Bots_RegenerateKey_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/RegenerateKey\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Bots_RegenerateKey_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Bots/RegenerateKey", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Bots_RegenerateKey_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Bots/RegenerateKey\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Categories_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Categories/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Categories_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Categories/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Categories_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Categories/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Categories_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Categories/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Categories_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Categories/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Categories_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Categories/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Categories_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Categories/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Categories_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Categories/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Categories_Delete_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Categories/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Categories_Delete_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Categories/Delete\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Categories_Delete_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Categories/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Categories_Delete_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Categories/Delete\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_Customer_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/Customer", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_Customer_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/Customer\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_Customer_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/Customer", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_Customer_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/Customer\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_Reply_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/Reply", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Messages_Reply_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/Reply\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Messages_Reply_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Messages/Reply", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Messages_Reply_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Messages/Reply\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_Details_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/Details", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_Details_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/Details\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_Details_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/Details", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_Details_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/Details\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_UpdateStatus_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/UpdateStatus", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Orders_UpdateStatus_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/UpdateStatus\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Orders_UpdateStatus_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Orders/UpdateStatus", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Orders_UpdateStatus_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Orders/UpdateStatus\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Products_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Products_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Products_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Products_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_UploadPhoto_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/UploadPhoto", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Products_UploadPhoto_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/UploadPhoto\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_UploadPhoto_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/UploadPhoto", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Products_UploadPhoto_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/UploadPhoto\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_DeletePhoto_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/DeletePhoto", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Products_DeletePhoto_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/DeletePhoto\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_DeletePhoto_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/DeletePhoto", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Products_DeletePhoto_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/DeletePhoto\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_Delete_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Products_Delete_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/Delete\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Products_Delete_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Products/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Products_Delete_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Products/Delete\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "ShippingRates_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/ShippingRates/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task ShippingRates_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/ShippingRates/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "ShippingRates_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/ShippingRates/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task ShippingRates_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/ShippingRates/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "ShippingRates_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/ShippingRates/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task ShippingRates_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/ShippingRates/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "ShippingRates_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/ShippingRates/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task ShippingRates_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/ShippingRates/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "ShippingRates_Delete_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/ShippingRates/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task ShippingRates_Delete_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/ShippingRates/Delete\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "ShippingRates_Delete_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/ShippingRates/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task ShippingRates_Delete_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/ShippingRates/Delete\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Users_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Users/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Users_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Users/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Users_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Users/Edit", + "HttpMethod": "GET", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Users_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Users/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Users_Edit_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Users/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Users_Edit_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Users/Edit\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Users_Edit_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Users/Edit", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Users_Edit_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Users/Edit\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Users_Delete_ValidData", + "TestType": "Data Validation", + "Endpoint": "api/Users/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "200 OK", + "TestCode": "[Fact]\npublic async Task Users_Delete_ShouldReturn200_WithValidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var validData = CreateValidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Users/Delete\u0022, validData);\n\n // Assert\n Assert.Equal(HttpStatusCode.OK, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "Users_Delete_InvalidData", + "TestType": "Data Validation", + "Endpoint": "api/Users/Delete", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "400 Bad Request", + "TestCode": "[Fact]\npublic async Task Users_Delete_ShouldReturn400_WithInvalidData()\n{\n // Arrange\n var client = _factory.CreateClient();\n await AuthenticateAsync(client);\n var invalidData = CreateInvalidTestData();\n\n // Act\n var response = await client.PostAsJsonAsync(\u0022api/Users/Delete\u0022, invalidData);\n\n // Assert\n Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);\n}", + "TestData": [], + "Priority": "Medium" + }, + { + "TestName": "AuthFlow_Login_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "Transition to Authenticated", + "TestCode": "[Fact]\npublic async Task Login_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Anonymous to Authenticated via login endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Register_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "Transition to Authenticated", + "TestCode": "[Fact]\npublic async Task Register_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Anonymous to Authenticated via registration endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Login_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "Transition to Authenticated", + "TestCode": "[Fact]\npublic async Task Login_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Anonymous to Authenticated via login endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Login_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "Transition to Authenticated", + "TestCode": "[Fact]\npublic async Task Login_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Anonymous to Authenticated via login endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Login_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Anonymous", + "ExpectedOutcome": "Transition to Authenticated", + "TestCode": "[Fact]\npublic async Task Login_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Anonymous to Authenticated via login endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Logout_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "Transition to Anonymous", + "TestCode": "[Fact]\npublic async Task Logout_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Authenticated to Anonymous via logout endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Logout_Flow", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated_Admin", + "ExpectedOutcome": "Transition to Anonymous", + "TestCode": "[Fact]\npublic async Task Logout_Flow_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // User should be able to transition from Authenticated_Admin to Anonymous via logout endpoint\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Session_Timeout", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "Transition to Anonymous", + "TestCode": "[Fact]\npublic async Task Session_Timeout_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // Verify that expired sessions are handled correctly and user is redirected to login\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Concurrent_Sessions", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated", + "ExpectedOutcome": "Transition to Authenticated", + "TestCode": "[Fact]\npublic async Task Concurrent_Sessions_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // Test behavior when same user logs in from multiple locations\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + }, + { + "TestName": "AuthFlow_Role_Switching", + "TestType": "Authentication Flow", + "Endpoint": "Multiple", + "HttpMethod": "POST", + "AuthenticationState": "Authenticated_User", + "ExpectedOutcome": "Transition to Authenticated_Admin", + "TestCode": "[Fact]\npublic async Task Role_Switching_ShouldWork()\n{\n // Arrange\n var client = _factory.CreateClient();\n\n // Act \u0026 Assert\n // Verify that role changes are reflected in endpoint accessibility\n // TODO: Implement specific flow testing based on scenario\n}", + "TestData": [], + "Priority": "High" + } + ], + "Summary": { + "TotalEndpoints": 115, + "FullyCoveredEndpoints": 0, + "PartiallyCoveredEndpoints": 27, + "UncoveredEndpoints": 88, + "OverallCoveragePercentage": 16.956521739130434, + "CriticalGaps": 124, + "WarningGaps": 100, + "InfoGaps": 0, + "SuggestedTests": 190, + "TopPriorities": [ + "Bots_GetAllBots_UnauthorizedAccess", + "Bots_GetAllBots_RequiresRole_Admin", + "Bots_GetBot_UnauthorizedAccess", + "Bots_GetBot_RequiresRole_Admin", + "Bots_GetBotMetrics_UnauthorizedAccess" + ] + } +} \ No newline at end of file diff --git a/publish/TestAgent_Results/endpoint_discovery.json b/publish/TestAgent_Results/endpoint_discovery.json new file mode 100644 index 0000000..3835a79 --- /dev/null +++ b/publish/TestAgent_Results/endpoint_discovery.json @@ -0,0 +1,2940 @@ +{ + "Summary": { + "TotalEndpoints": 115, + "TotalControllers": 18, + "AuthenticatedEndpoints": 78, + "AnonymousEndpoints": 37, + "DetectedRoutes": 96 + }, + "Controllers": [ + "Auth", + "BotMessages", + "Bots", + "Catalog", + "Customers", + "Home", + "Messages", + "Orders", + "Test", + "Account", + "Bots", + "Categories", + "Dashboard", + "Messages", + "Orders", + "Products", + "ShippingRates", + "Users" + ], + "Endpoints": [ + { + "Controller": "Auth", + "Action": "Login", + "Template": "api/Auth/login", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "loginDto", + "Type": "LoginDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "BotMessages", + "Action": "GetPendingMessages", + "Template": "api/bot/messages/pending", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "platform", + "Type": "String", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "BotMessages", + "Action": "MarkMessageAsSent", + "Template": "api/bot/messages/{id}/mark-sent", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "platformMessageId", + "Type": "String", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "BotMessages", + "Action": "MarkMessageAsFailed", + "Template": "api/bot/messages/{id}/mark-failed", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "reason", + "Type": "String", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "BotMessages", + "Action": "CreateTestMessage", + "Template": "api/bot/messages/test-create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "CreateTestMessageDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "BotMessages", + "Action": "CreateCustomerMessage", + "Template": "api/bot/messages/customer-create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "CreateCustomerMessageFromTelegramDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "BotMessages", + "Action": "GetCustomerMessages", + "Template": "api/bot/messages/customer/{customerId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "customerId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "RegisterBot", + "Template": "api/Bots/register", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotRegistrationDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "AuthenticateBot", + "Template": "api/Bots/authenticate", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotAuthenticateDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "GetBotSettings", + "Template": "api/Bots/settings", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "UpdateBotSettings", + "Template": "api/Bots/settings", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "UpdateBotSettingsDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "RecordHeartbeat", + "Template": "api/Bots/heartbeat", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotHeartbeatDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "UpdatePlatformInfo", + "Template": "api/Bots/platform-info", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "UpdatePlatformInfoDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "RecordMetric", + "Template": "api/Bots/metrics", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "CreateBotMetricDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "RecordMetricsBatch", + "Template": "api/Bots/metrics/batch", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotMetricsBatchDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "StartSession", + "Template": "api/Bots/sessions/start", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "CreateBotSessionDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "UpdateSession", + "Template": "api/Bots/sessions/{sessionId}", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + { + "Name": "sessionId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "dto", + "Type": "UpdateBotSessionDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "EndSession", + "Template": "api/Bots/sessions/{sessionId}/end", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "sessionId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "GetAllBots", + "Template": "api/Bots/GetAllBots", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "GetBot", + "Template": "api/Bots/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "GetBotMetrics", + "Template": "api/Bots/{id}/metrics", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "startDate", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Query" + }, + { + "Name": "endDate", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "GetMetricsSummary", + "Template": "api/Bots/{id}/metrics/summary", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "startDate", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Query" + }, + { + "Name": "endDate", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "GetBotSessions", + "Template": "api/Bots/{id}/sessions", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "activeOnly", + "Type": "Boolean", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Bots", + "Action": "DeleteBot", + "Template": "api/Bots/{id}", + "HttpMethods": [ + "DELETE" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Catalog", + "Action": "GetCategories", + "Template": "api/Catalog/categories", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Catalog", + "Action": "GetCategory", + "Template": "api/Catalog/categories/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Catalog", + "Action": "GetProducts", + "Template": "api/Catalog/products", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "pageNumber", + "Type": "Int32", + "IsRequired": false, + "Binding": "Query" + }, + { + "Name": "pageSize", + "Type": "Int32", + "IsRequired": false, + "Binding": "Query" + }, + { + "Name": "categoryId", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Catalog", + "Action": "GetProduct", + "Template": "api/Catalog/products/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "GetCustomers", + "Template": "api/Customers/GetCustomers", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "search", + "Type": "String", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "GetCustomer", + "Template": "api/Customers/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "GetCustomerByTelegramId", + "Template": "api/Customers/by-telegram/{telegramUserId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "telegramUserId", + "Type": "Int64", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "CreateCustomer", + "Template": "api/Customers/CreateCustomer", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "createCustomerDto", + "Type": "CreateCustomerDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "GetOrCreateCustomer", + "Template": "api/Customers/get-or-create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "createCustomerDto", + "Type": "CreateCustomerDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "UpdateCustomer", + "Template": "api/Customers/{id}", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "updateCustomerDto", + "Type": "UpdateCustomerDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "BlockCustomer", + "Template": "api/Customers/{id}/block", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "reason", + "Type": "String", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "UnblockCustomer", + "Template": "api/Customers/{id}/unblock", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Customers", + "Action": "DeleteCustomer", + "Template": "api/Customers/{id}", + "HttpMethods": [ + "DELETE" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Home", + "Action": "Index", + "Template": "api/Home/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "SendMessage", + "Template": "api/Messages/SendMessage", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "createMessageDto", + "Type": "CreateCustomerMessageDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "GetMessage", + "Template": "api/Messages/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "GetCustomerMessages", + "Template": "api/Messages/customer/{customerId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "customerId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "GetOrderMessages", + "Template": "api/Messages/order/{orderId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "orderId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "GetPendingMessages", + "Template": "api/Messages/pending", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "platform", + "Type": "String", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "MarkMessageAsSent", + "Template": "api/Messages/{id}/mark-sent", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "platformMessageId", + "Type": "String", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "MarkMessageAsDelivered", + "Template": "api/Messages/{id}/mark-delivered", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Messages", + "Action": "MarkMessageAsFailed", + "Template": "api/Messages/{id}/mark-failed", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "reason", + "Type": "String", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetAllOrders", + "Template": "api/Orders/GetAllOrders", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetOrder", + "Template": "api/Orders/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "UpdateOrderStatus", + "Template": "api/Orders/{id}/status", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "updateOrderStatusDto", + "Type": "UpdateOrderStatusDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [ + "Admin" + ] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetOrdersByIdentity", + "Template": "api/Orders/by-identity/{identityReference}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "identityReference", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetOrdersByCustomerId", + "Template": "api/Orders/by-customer/{customerId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "customerId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetOrderByIdentity", + "Template": "api/Orders/by-identity/{identityReference}/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "identityReference", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "CreateOrder", + "Template": "api/Orders/CreateOrder", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "createOrderDto", + "Type": "CreateOrderDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "CreatePayment", + "Template": "api/Orders/{id}/payments", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "createPaymentDto", + "Type": "CreatePaymentDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": true, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetOrderPayments", + "Template": "api/Orders/{id}/payments", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "GetPaymentStatus", + "Template": "api/Orders/payments/{paymentId}/status", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "paymentId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "CancelOrder", + "Template": "api/Orders/{id}/cancel", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "cancelOrderDto", + "Type": "CancelOrderDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Orders", + "Action": "PaymentWebhook", + "Template": "api/Orders/payments/webhook", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "webhookDto", + "Type": "PaymentWebhookDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Test", + "Action": "CreateTestProduct", + "Template": "api/Test/create-product", + "HttpMethods": [ + "POST" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Test", + "Action": "SetupTestData", + "Template": "api/Test/setup-test-data", + "HttpMethods": [ + "POST" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": true, + "Area": "" + }, + { + "Controller": "Account", + "Action": "Login", + "Template": "api/Account/Login", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Account", + "Action": "Login", + "Template": "api/Account/Login", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "username", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "password", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Account", + "Action": "Logout", + "Template": "api/Account/Logout", + "HttpMethods": [ + "POST" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Account", + "Action": "AccessDenied", + "Template": "api/Account/AccessDenied", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": false, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Index", + "Template": "api/Bots/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Details", + "Template": "api/Bots/Details", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Create", + "Template": "api/Bots/Create", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Wizard", + "Template": "api/Bots/Wizard", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Wizard", + "Template": "api/Bots/Wizard", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotWizardDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "CompleteWizard", + "Template": "api/Bots/CompleteWizard", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotWizardDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Create", + "Template": "api/Bots/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "dto", + "Type": "BotRegistrationDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Edit", + "Template": "api/Bots/Edit", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Edit", + "Template": "api/Bots/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "settingsJson", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "status", + "Type": "BotStatus", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Metrics", + "Template": "api/Bots/Metrics", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "startDate", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Body" + }, + { + "Name": "endDate", + "Type": "Nullable\u00601", + "IsRequired": false, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Delete", + "Template": "api/Bots/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Suspend", + "Template": "api/Bots/Suspend", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "Activate", + "Template": "api/Bots/Activate", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Bots", + "Action": "RegenerateKey", + "Template": "api/Bots/RegenerateKey", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Categories", + "Action": "Index", + "Template": "api/Categories/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Categories", + "Action": "Create", + "Template": "api/Categories/Create", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Categories", + "Action": "Create", + "Template": "api/Categories/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "model", + "Type": "CreateCategoryDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Categories", + "Action": "Edit", + "Template": "api/Categories/Edit", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Categories", + "Action": "Edit", + "Template": "api/Categories/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "model", + "Type": "UpdateCategoryDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Categories", + "Action": "Delete", + "Template": "api/Categories/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Dashboard", + "Action": "Index", + "Template": "api/Dashboard/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Messages", + "Action": "Index", + "Template": "api/Messages/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Messages", + "Action": "Customer", + "Template": "api/Messages/Customer", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Messages", + "Action": "Reply", + "Template": "api/Messages/Reply", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "customerId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "content", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "isUrgent", + "Type": "Boolean", + "IsRequired": false, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "Index", + "Template": "api/Orders/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "Details", + "Template": "api/Orders/Details", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "Create", + "Template": "api/Orders/Create", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "Create", + "Template": "api/Orders/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "model", + "Type": "CreateOrderDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "Edit", + "Template": "api/Orders/Edit", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "Edit", + "Template": "api/Orders/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "model", + "Type": "OrderDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Orders", + "Action": "UpdateStatus", + "Template": "api/Orders/UpdateStatus", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "model", + "Type": "UpdateOrderStatusDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "Index", + "Template": "api/Products/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "Create", + "Template": "api/Products/Create", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "Create", + "Template": "api/Products/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "model", + "Type": "CreateProductDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "Edit", + "Template": "api/Products/Edit", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "Edit", + "Template": "api/Products/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "model", + "Type": "UpdateProductDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "UploadPhoto", + "Template": "api/Products/UploadPhoto", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "file", + "Type": "IFormFile", + "IsRequired": true, + "Binding": "Body" + }, + { + "Name": "altText", + "Type": "String", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "DeletePhoto", + "Template": "api/Products/DeletePhoto", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "photoId", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Products", + "Action": "Delete", + "Template": "api/Products/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "ShippingRates", + "Action": "Index", + "Template": "api/ShippingRates/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "ShippingRates", + "Action": "Create", + "Template": "api/ShippingRates/Create", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "ShippingRates", + "Action": "Create", + "Template": "api/ShippingRates/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "model", + "Type": "CreateShippingRateDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "ShippingRates", + "Action": "Edit", + "Template": "api/ShippingRates/Edit", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "ShippingRates", + "Action": "Edit", + "Template": "api/ShippingRates/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "model", + "Type": "UpdateShippingRateDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "ShippingRates", + "Action": "Delete", + "Template": "api/ShippingRates/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Users", + "Action": "Index", + "Template": "api/Users/Index", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Users", + "Action": "Create", + "Template": "api/Users/Create", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "IActionResult", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Users", + "Action": "Create", + "Template": "api/Users/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "model", + "Type": "CreateUserDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Users", + "Action": "Edit", + "Template": "api/Users/Edit", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Users", + "Action": "Edit", + "Template": "api/Users/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + }, + { + "Name": "model", + "Type": "UpdateUserDto", + "IsRequired": true, + "Binding": "Body" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + }, + { + "Controller": "Users", + "Action": "Delete", + "Template": "api/Users/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + { + "Name": "id", + "Type": "Guid", + "IsRequired": true, + "Binding": "Query" + } + ], + "Authentication": { + "RequiresAuthentication": true, + "AllowsAnonymous": false, + "RequiredRoles": [] + }, + "ReturnType": "Task\u00601", + "IsApiController": false, + "Area": "Admin" + } + ], + "Routes": [ + "api/Auth/login", + "api/bot/messages/pending", + "api/bot/messages/{id}/mark-sent", + "api/bot/messages/{id}/mark-failed", + "api/bot/messages/test-create", + "api/bot/messages/customer-create", + "api/bot/messages/customer/{customerId}", + "api/Bots/register", + "api/Bots/authenticate", + "api/Bots/settings", + "api/Bots/heartbeat", + "api/Bots/platform-info", + "api/Bots/metrics", + "api/Bots/metrics/batch", + "api/Bots/sessions/start", + "api/Bots/sessions/{sessionId}", + "api/Bots/sessions/{sessionId}/end", + "api/Bots/GetAllBots", + "api/Bots/{id}", + "api/Bots/{id}/metrics", + "api/Bots/{id}/metrics/summary", + "api/Bots/{id}/sessions", + "api/Catalog/categories", + "api/Catalog/categories/{id}", + "api/Catalog/products", + "api/Catalog/products/{id}", + "api/Customers/GetCustomers", + "api/Customers/{id}", + "api/Customers/by-telegram/{telegramUserId}", + "api/Customers/CreateCustomer", + "api/Customers/get-or-create", + "api/Customers/{id}/block", + "api/Customers/{id}/unblock", + "api/Home/Index", + "api/Messages/SendMessage", + "api/Messages/{id}", + "api/Messages/customer/{customerId}", + "api/Messages/order/{orderId}", + "api/Messages/pending", + "api/Messages/{id}/mark-sent", + "api/Messages/{id}/mark-delivered", + "api/Messages/{id}/mark-failed", + "api/Orders/GetAllOrders", + "api/Orders/{id}", + "api/Orders/{id}/status", + "api/Orders/by-identity/{identityReference}", + "api/Orders/by-customer/{customerId}", + "api/Orders/by-identity/{identityReference}/{id}", + "api/Orders/CreateOrder", + "api/Orders/{id}/payments", + "api/Orders/payments/{paymentId}/status", + "api/Orders/{id}/cancel", + "api/Orders/payments/webhook", + "api/Test/create-product", + "api/Test/setup-test-data", + "api/Account/Login", + "api/Account/Logout", + "api/Account/AccessDenied", + "api/Bots/Index", + "api/Bots/Details", + "api/Bots/Create", + "api/Bots/Wizard", + "api/Bots/CompleteWizard", + "api/Bots/Edit", + "api/Bots/Metrics", + "api/Bots/Delete", + "api/Bots/Suspend", + "api/Bots/Activate", + "api/Bots/RegenerateKey", + "api/Categories/Index", + "api/Categories/Create", + "api/Categories/Edit", + "api/Categories/Delete", + "api/Dashboard/Index", + "api/Messages/Index", + "api/Messages/Customer", + "api/Messages/Reply", + "api/Orders/Index", + "api/Orders/Details", + "api/Orders/Create", + "api/Orders/Edit", + "api/Orders/UpdateStatus", + "api/Products/Index", + "api/Products/Create", + "api/Products/Edit", + "api/Products/UploadPhoto", + "api/Products/DeletePhoto", + "api/Products/Delete", + "api/ShippingRates/Index", + "api/ShippingRates/Create", + "api/ShippingRates/Edit", + "api/ShippingRates/Delete", + "api/Users/Index", + "api/Users/Create", + "api/Users/Edit", + "api/Users/Delete" + ], + "Recommendations": [ + "Generate comprehensive integration tests for all discovered endpoints", + "Implement automated testing for each authentication state combination" + ] +} \ No newline at end of file diff --git a/publish/TestAgent_Results/error_detection.json b/publish/TestAgent_Results/error_detection.json new file mode 100644 index 0000000..e91946f --- /dev/null +++ b/publish/TestAgent_Results/error_detection.json @@ -0,0 +1,1386 @@ +{ + "DeadLinks": [], + "HttpErrors": [ + { + "Url": "https://localhost:5001", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:28.4136605Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Auth/login", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:32.5436482Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/bot/messages/pending", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:36.6469969Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/bot/messages/{id}/mark-sent", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:40.7476995Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/bot/messages/{id}/mark-failed", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:44.8542098Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/bot/messages/test-create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:48.9511168Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/bot/messages/customer-create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:53.0454505Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/bot/messages/customer/{customerId}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:01:57.1338792Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/register", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:01.232331Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/authenticate", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:05.3330182Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/settings", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:09.4484546Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/heartbeat", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:13.5371766Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/platform-info", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:17.62977Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/metrics", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:21.7406881Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/metrics/batch", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:25.8460004Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/sessions/start", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:29.9369627Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/sessions/{sessionId}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:34.0160421Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/sessions/{sessionId}/end", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:38.1270391Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/GetAllBots", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:42.2021072Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:46.2746696Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/{id}/metrics", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:50.371648Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/{id}/metrics/summary", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:54.4743135Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/{id}/sessions", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:02:58.5796266Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Catalog/categories", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:02.6935242Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Catalog/categories/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:06.7861415Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Catalog/products", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:10.8647424Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Catalog/products/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:14.9635341Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/GetCustomers", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:19.0531897Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:23.1449361Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/by-telegram/{telegramUserId}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:27.2051658Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/CreateCustomer", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:31.2992272Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/get-or-create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:35.4127184Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/{id}/block", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:39.5164822Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Customers/{id}/unblock", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:43.6094425Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Home/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:47.7123897Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/SendMessage", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:51.8111238Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:03:55.9120061Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/customer/{customerId}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:00.0263436Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/order/{orderId}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:04.0957564Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/pending", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:08.1837105Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/{id}/mark-sent", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:12.2933729Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/{id}/mark-delivered", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:16.3972755Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/{id}/mark-failed", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:20.5078118Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/GetAllOrders", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:24.6140465Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:28.7189056Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/{id}/status", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:32.8146936Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/by-identity/{identityReference}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:36.9277025Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/by-customer/{customerId}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:41.0367094Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/by-identity/{identityReference}/{id}", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:45.1452805Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/CreateOrder", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:49.2507478Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/{id}/payments", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:53.3592069Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/payments/{paymentId}/status", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:04:57.4483854Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/{id}/cancel", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:01.5250997Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/payments/webhook", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:05.6162125Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Test/create-product", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:09.7291304Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Test/setup-test-data", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:13.8328986Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Account/Login", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:17.9426604Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Account/Logout", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:22.0380505Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Account/AccessDenied", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:26.132658Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:30.2398169Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Details", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:34.3611802Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:38.4911537Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Wizard", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:42.5907293Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/CompleteWizard", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:46.6953453Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Edit", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:50.7952952Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Metrics", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:54.9143643Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Delete", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:05:59.0163648Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Suspend", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:03.1186323Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/Activate", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:07.2022025Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Bots/RegenerateKey", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:11.3097333Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Categories/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:15.4086275Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Categories/Create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:19.5136129Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Categories/Edit", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:23.6274057Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Categories/Delete", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:27.7263273Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Dashboard/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:31.8379425Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:35.9331167Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/Customer", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:40.0351949Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Messages/Reply", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:44.1463343Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:48.238581Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/Details", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:52.3489959Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/Create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:06:56.428006Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/Edit", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:00.5241235Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Orders/UpdateStatus", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:04.6177956Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Products/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:08.6951581Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Products/Create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:12.7712549Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Products/Edit", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:16.8580047Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Products/UploadPhoto", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:20.952471Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Products/DeletePhoto", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:25.0647841Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Products/Delete", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:29.1780938Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/ShippingRates/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:33.2450233Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/ShippingRates/Create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:37.3162413Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/ShippingRates/Edit", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:41.410048Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/ShippingRates/Delete", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:45.5106106Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Users/Index", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:49.6152188Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Users/Create", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:53.7222161Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Users/Edit", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:07:57.8234889Z", + "IsFormSubmission": false, + "FormData": null + }, + { + "Url": "https://localhost:5001/api/Users/Delete", + "StatusCode": 503, + "Method": "GET", + "ErrorMessage": "No connection could be made because the target machine actively refused it. (localhost:5001)", + "ResponseContent": "", + "RequestHeaders": {}, + "ResponseHeaders": {}, + "AuthenticationState": "Anonymous", + "DetectedAt": "2025-08-27T21:08:01.8909603Z", + "IsFormSubmission": false, + "FormData": null + } + ], + "JavaScriptErrors": [], + "FormErrors": [], + "ResourceErrors": [], + "Summary": { + "TotalUrls": 97, + "TestedUrls": 97, + "DeadLinks": 0, + "HttpErrors": 97, + "JavaScriptErrors": 0, + "FormErrors": 0, + "ResourceErrors": 0, + "SuccessRate": 0, + "MostCommonErrors": [ + "ServiceUnavailable (97 occurrences)" + ], + "Recommendations": [ + "Overall success rate is below 95% - prioritize fixing critical errors", + "Implement automated monitoring for dead links and errors in CI/CD pipeline" + ] + }, + "TestedUrls": [ + "https://localhost:5001", + "https://localhost:5001/api/Auth/login", + "https://localhost:5001/api/bot/messages/pending", + "https://localhost:5001/api/bot/messages/{id}/mark-sent", + "https://localhost:5001/api/bot/messages/{id}/mark-failed", + "https://localhost:5001/api/bot/messages/test-create", + "https://localhost:5001/api/bot/messages/customer-create", + "https://localhost:5001/api/bot/messages/customer/{customerId}", + "https://localhost:5001/api/Bots/register", + "https://localhost:5001/api/Bots/authenticate", + "https://localhost:5001/api/Bots/settings", + "https://localhost:5001/api/Bots/heartbeat", + "https://localhost:5001/api/Bots/platform-info", + "https://localhost:5001/api/Bots/metrics", + "https://localhost:5001/api/Bots/metrics/batch", + "https://localhost:5001/api/Bots/sessions/start", + "https://localhost:5001/api/Bots/sessions/{sessionId}", + "https://localhost:5001/api/Bots/sessions/{sessionId}/end", + "https://localhost:5001/api/Bots/GetAllBots", + "https://localhost:5001/api/Bots/{id}", + "https://localhost:5001/api/Bots/{id}/metrics", + "https://localhost:5001/api/Bots/{id}/metrics/summary", + "https://localhost:5001/api/Bots/{id}/sessions", + "https://localhost:5001/api/Catalog/categories", + "https://localhost:5001/api/Catalog/categories/{id}", + "https://localhost:5001/api/Catalog/products", + "https://localhost:5001/api/Catalog/products/{id}", + "https://localhost:5001/api/Customers/GetCustomers", + "https://localhost:5001/api/Customers/{id}", + "https://localhost:5001/api/Customers/by-telegram/{telegramUserId}", + "https://localhost:5001/api/Customers/CreateCustomer", + "https://localhost:5001/api/Customers/get-or-create", + "https://localhost:5001/api/Customers/{id}/block", + "https://localhost:5001/api/Customers/{id}/unblock", + "https://localhost:5001/api/Home/Index", + "https://localhost:5001/api/Messages/SendMessage", + "https://localhost:5001/api/Messages/{id}", + "https://localhost:5001/api/Messages/customer/{customerId}", + "https://localhost:5001/api/Messages/order/{orderId}", + "https://localhost:5001/api/Messages/pending", + "https://localhost:5001/api/Messages/{id}/mark-sent", + "https://localhost:5001/api/Messages/{id}/mark-delivered", + "https://localhost:5001/api/Messages/{id}/mark-failed", + "https://localhost:5001/api/Orders/GetAllOrders", + "https://localhost:5001/api/Orders/{id}", + "https://localhost:5001/api/Orders/{id}/status", + "https://localhost:5001/api/Orders/by-identity/{identityReference}", + "https://localhost:5001/api/Orders/by-customer/{customerId}", + "https://localhost:5001/api/Orders/by-identity/{identityReference}/{id}", + "https://localhost:5001/api/Orders/CreateOrder", + "https://localhost:5001/api/Orders/{id}/payments", + "https://localhost:5001/api/Orders/payments/{paymentId}/status", + "https://localhost:5001/api/Orders/{id}/cancel", + "https://localhost:5001/api/Orders/payments/webhook", + "https://localhost:5001/api/Test/create-product", + "https://localhost:5001/api/Test/setup-test-data", + "https://localhost:5001/api/Account/Login", + "https://localhost:5001/api/Account/Logout", + "https://localhost:5001/api/Account/AccessDenied", + "https://localhost:5001/api/Bots/Index", + "https://localhost:5001/api/Bots/Details", + "https://localhost:5001/api/Bots/Create", + "https://localhost:5001/api/Bots/Wizard", + "https://localhost:5001/api/Bots/CompleteWizard", + "https://localhost:5001/api/Bots/Edit", + "https://localhost:5001/api/Bots/Metrics", + "https://localhost:5001/api/Bots/Delete", + "https://localhost:5001/api/Bots/Suspend", + "https://localhost:5001/api/Bots/Activate", + "https://localhost:5001/api/Bots/RegenerateKey", + "https://localhost:5001/api/Categories/Index", + "https://localhost:5001/api/Categories/Create", + "https://localhost:5001/api/Categories/Edit", + "https://localhost:5001/api/Categories/Delete", + "https://localhost:5001/api/Dashboard/Index", + "https://localhost:5001/api/Messages/Index", + "https://localhost:5001/api/Messages/Customer", + "https://localhost:5001/api/Messages/Reply", + "https://localhost:5001/api/Orders/Index", + "https://localhost:5001/api/Orders/Details", + "https://localhost:5001/api/Orders/Create", + "https://localhost:5001/api/Orders/Edit", + "https://localhost:5001/api/Orders/UpdateStatus", + "https://localhost:5001/api/Products/Index", + "https://localhost:5001/api/Products/Create", + "https://localhost:5001/api/Products/Edit", + "https://localhost:5001/api/Products/UploadPhoto", + "https://localhost:5001/api/Products/DeletePhoto", + "https://localhost:5001/api/Products/Delete", + "https://localhost:5001/api/ShippingRates/Index", + "https://localhost:5001/api/ShippingRates/Create", + "https://localhost:5001/api/ShippingRates/Edit", + "https://localhost:5001/api/ShippingRates/Delete", + "https://localhost:5001/api/Users/Index", + "https://localhost:5001/api/Users/Create", + "https://localhost:5001/api/Users/Edit", + "https://localhost:5001/api/Users/Delete" + ], + "SkippedUrls": [] +} \ No newline at end of file diff --git a/publish/TestAgent_Results/executive_summary.json b/publish/TestAgent_Results/executive_summary.json new file mode 100644 index 0000000..56da6a8 --- /dev/null +++ b/publish/TestAgent_Results/executive_summary.json @@ -0,0 +1,31 @@ +{ + "ProjectPath": "C:\\Production\\Source\\LittleShop\\LittleShop", + "ProjectType": "Project (ASP.NET Core)", + "TotalEndpoints": 115, + "AuthenticatedEndpoints": 78, + "TestableStates": 3, + "IdentifiedGaps": 224, + "SuggestedTests": 190, + "DeadLinks": 0, + "HttpErrors": 97, + "VisualIssues": 0, + "SecurityInsights": 1, + "PerformanceInsights": 1, + "OverallTestCoverage": 16.956521739130434, + "VisualConsistencyScore": 0, + "CriticalRecommendations": [ + "CRITICAL: Test coverage is only 17.0% - implement comprehensive test suite", + "HIGH: Address 97 HTTP errors in the application", + "MEDIUM: Improve visual consistency - current score 0.0%", + "HIGH: Address 224 testing gaps for comprehensive coverage" + ], + "GeneratedFiles": [ + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\project_structure.json", + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\authentication_analysis.json", + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\endpoint_discovery.json", + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\coverage_analysis.json", + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\error_detection.json", + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\visual_testing.json", + "C:\\Production\\Source\\LittleShop\\LittleShop\\TestAgent_Results\\intelligent_analysis.json" + ] +} \ No newline at end of file diff --git a/publish/TestAgent_Results/intelligent_analysis.json b/publish/TestAgent_Results/intelligent_analysis.json new file mode 100644 index 0000000..bc052bc --- /dev/null +++ b/publish/TestAgent_Results/intelligent_analysis.json @@ -0,0 +1,79 @@ +{ + "BusinessLogicInsights": [ + { + "Component": "Claude CLI Integration", + "Insight": "Error analyzing business logic: Failed to execute Claude CLI: An error occurred trying to start process \u0027claude\u0027 with working directory \u0027C:\\Production\\Source\\TestAgent\u0027. The system cannot find the file specified.", + "Complexity": "Unknown", + "PotentialIssues": [], + "TestingRecommendations": [], + "Priority": "Medium" + } + ], + "TestScenarioSuggestions": [ + { + "ScenarioName": "Claude CLI Integration Error", + "Description": "Error generating test scenarios: Failed to execute Claude CLI: An error occurred trying to start process \u0027claude\u0027 with working directory \u0027C:\\Production\\Source\\TestAgent\u0027. The system cannot find the file specified.", + "TestType": "", + "Steps": [], + "ExpectedOutcomes": [], + "Priority": "Medium", + "RequiredData": [], + "Dependencies": [] + } + ], + "SecurityInsights": [ + { + "VulnerabilityType": "Analysis Error", + "Location": "", + "Description": "Error analyzing security: Failed to execute Claude CLI: An error occurred trying to start process \u0027claude\u0027 with working directory \u0027C:\\Production\\Source\\TestAgent\u0027. The system cannot find the file specified.", + "Severity": "Medium", + "Recommendations": [], + "TestingApproaches": [] + } + ], + "PerformanceInsights": [ + { + "Component": "Analysis Error", + "PotentialBottleneck": "Error analyzing performance: Failed to execute Claude CLI: An error occurred trying to start process \u0027claude\u0027 with working directory \u0027C:\\Production\\Source\\TestAgent\u0027. The system cannot find the file specified.", + "Impact": "Unknown", + "OptimizationSuggestions": [], + "TestingStrategies": [] + } + ], + "ArchitecturalRecommendations": [ + { + "Category": "Analysis Error", + "Recommendation": "Error generating architectural recommendations: Failed to execute Claude CLI: An error occurred trying to start process \u0027claude\u0027 with working directory \u0027C:\\Production\\Source\\TestAgent\u0027. The system cannot find the file specified.", + "Rationale": "", + "Impact": "Unknown", + "ImplementationSteps": [] + } + ], + "GeneratedTestCases": [ + { + "TestName": "Claude CLI Integration Error", + "TestCategory": "Error", + "Description": "Error generating test cases: Failed to execute Claude CLI: An error occurred trying to start process \u0027claude\u0027 with working directory \u0027C:\\Production\\Source\\TestAgent\u0027. The system cannot find the file specified.", + "TestCode": "", + "TestData": [], + "ExpectedOutcome": "", + "Reasoning": "" + } + ], + "Summary": { + "TotalInsights": 4, + "HighPriorityItems": 0, + "GeneratedTestCases": 1, + "SecurityIssuesFound": 1, + "PerformanceOptimizations": 1, + "KeyFindings": [ + "Performance optimization opportunities identified" + ], + "NextSteps": [ + "Review and prioritize security recommendations", + "Implement generated test cases", + "Address high-priority business logic testing gaps", + "Consider architectural improvements for better testability" + ] + } +} \ No newline at end of file diff --git a/publish/TestAgent_Results/project_structure.json b/publish/TestAgent_Results/project_structure.json new file mode 100644 index 0000000..3f2eee1 --- /dev/null +++ b/publish/TestAgent_Results/project_structure.json @@ -0,0 +1,1669 @@ +{ + "ProjectPath": "C:\\Production\\Source\\LittleShop\\LittleShop", + "ProjectType": "Project (ASP.NET Core)", + "Controllers": [ + "AuthController", + "BotMessagesController", + "BotsController", + "CatalogController", + "CustomersController", + "HomeController", + "MessagesController", + "OrdersController", + "TestController", + "AccountController", + "BotsController", + "CategoriesController", + "DashboardController", + "MessagesController", + "OrdersController", + "ProductsController", + "ShippingRatesController", + "UsersController" + ], + "Endpoints": [ + { + "Controller": "AuthController", + "Action": "Login", + "Route": "login", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "LoginDto loginDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotMessagesController", + "Action": "GetPendingMessages", + "Route": "pending", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "string platform" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotMessagesController", + "Action": "MarkMessageAsSent", + "Route": "{id}/mark-sent", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "string? platformMessageId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotMessagesController", + "Action": "MarkMessageAsFailed", + "Route": "{id}/mark-failed", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "string reason" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotMessagesController", + "Action": "CreateTestMessage", + "Route": "test-create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateTestMessageDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotMessagesController", + "Action": "CreateCustomerMessage", + "Route": "customer-create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateCustomerMessageFromTelegramDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotMessagesController", + "Action": "GetCustomerMessages", + "Route": "customer/{customerId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid customerId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "RegisterBot", + "Route": "register", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotRegistrationDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "BotsController", + "Action": "AuthenticateBot", + "Route": "authenticate", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotAuthenticateDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "BotsController", + "Action": "GetBotSettings", + "Route": "settings", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "UpdateBotSettings", + "Route": "settings", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + "UpdateBotSettingsDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "RecordHeartbeat", + "Route": "heartbeat", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotHeartbeatDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "UpdatePlatformInfo", + "Route": "platform-info", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + "UpdatePlatformInfoDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "RecordMetric", + "Route": "metrics", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateBotMetricDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "RecordMetricsBatch", + "Route": "metrics/batch", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotMetricsBatchDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "StartSession", + "Route": "sessions/start", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateBotSessionDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "UpdateSession", + "Route": "sessions/{sessionId}", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + "Guid sessionId", + "UpdateBotSessionDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "EndSession", + "Route": "sessions/{sessionId}/end", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid sessionId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "GetAllBots", + "Route": "Bots/GetAllBots", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "GetBot", + "Route": "{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "GetBotMetrics", + "Route": "{id}/metrics", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id", + "DateTime? startDate", + "DateTime? endDate" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "GetMetricsSummary", + "Route": "{id}/metrics/summary", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id", + "DateTime? startDate", + "DateTime? endDate" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "GetBotSessions", + "Route": "{id}/sessions", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id", + "bool activeOnly" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "DeleteBot", + "Route": "{id}", + "HttpMethods": [ + "DELETE" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "CatalogController", + "Action": "GetCategories", + "Route": "categories", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CatalogController", + "Action": "GetCategory", + "Route": "categories/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CatalogController", + "Action": "GetProducts", + "Route": "products", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "int pageNumber", + "int pageSize", + "Guid? categoryId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CatalogController", + "Action": "GetProduct", + "Route": "products/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "GetCustomers", + "Route": "Customers/GetCustomers", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "string? search" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "GetCustomer", + "Route": "{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "GetCustomerByTelegramId", + "Route": "by-telegram/{telegramUserId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "long telegramUserId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "CreateCustomer", + "Route": "Customers/CreateCustomer", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateCustomerDto createCustomerDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "GetOrCreateCustomer", + "Route": "get-or-create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateCustomerDto createCustomerDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "CustomersController", + "Action": "UpdateCustomer", + "Route": "{id}", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + "Guid id", + "UpdateCustomerDto updateCustomerDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "BlockCustomer", + "Route": "{id}/block", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "string reason" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "UnblockCustomer", + "Route": "{id}/unblock", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CustomersController", + "Action": "DeleteCustomer", + "Route": "{id}", + "HttpMethods": [ + "DELETE" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "HomeController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "SendMessage", + "Route": "Messages/SendMessage", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateCustomerMessageDto createMessageDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "GetMessage", + "Route": "{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "GetCustomerMessages", + "Route": "customer/{customerId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid customerId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "GetOrderMessages", + "Route": "order/{orderId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid orderId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "GetPendingMessages", + "Route": "pending", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "string platform" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "MessagesController", + "Action": "MarkMessageAsSent", + "Route": "{id}/mark-sent", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "string? platformMessageId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "MessagesController", + "Action": "MarkMessageAsDelivered", + "Route": "{id}/mark-delivered", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "MarkMessageAsFailed", + "Route": "{id}/mark-failed", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "string reason" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "OrdersController", + "Action": "GetAllOrders", + "Route": "Orders/GetAllOrders", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "GetOrder", + "Route": "{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "UpdateOrderStatus", + "Route": "{id}/status", + "HttpMethods": [ + "PUT" + ], + "Parameters": [ + "Guid id", + "UpdateOrderStatusDto updateOrderStatusDto" + ], + "RequiresAuthentication": true, + "RequiredRoles": [ + "Admin" + ], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "GetOrdersByIdentity", + "Route": "by-identity/{identityReference}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "string identityReference" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "OrdersController", + "Action": "GetOrdersByCustomerId", + "Route": "by-customer/{customerId}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid customerId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "OrdersController", + "Action": "GetOrderByIdentity", + "Route": "by-identity/{identityReference}/{id}", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "string identityReference", + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "OrdersController", + "Action": "CreateOrder", + "Route": "Orders/CreateOrder", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateOrderDto createOrderDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "OrdersController", + "Action": "CreatePayment", + "Route": "{id}/payments", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "CreatePaymentDto createPaymentDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": true + }, + { + "Controller": "OrdersController", + "Action": "GetOrderPayments", + "Route": "{id}/payments", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "GetPaymentStatus", + "Route": "payments/{paymentId}/status", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid paymentId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "CancelOrder", + "Route": "{id}/cancel", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "CancelOrderDto cancelOrderDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "PaymentWebhook", + "Route": "payments/webhook", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "PaymentWebhookDto webhookDto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "TestController", + "Action": "CreateTestProduct", + "Route": "create-product", + "HttpMethods": [ + "POST" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "TestController", + "Action": "SetupTestData", + "Route": "setup-test-data", + "HttpMethods": [ + "POST" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "AccountController", + "Action": "Login", + "Route": "Account/Login", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "AccountController", + "Action": "Login", + "Route": "Account/Login", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "string username", + "string password" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "AccountController", + "Action": "Logout", + "Route": "Account/Logout", + "HttpMethods": [ + "POST" + ], + "Parameters": [], + "RequiresAuthentication": true, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "AccountController", + "Action": "AccessDenied", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Details", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Create", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Wizard", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Wizard", + "Route": "Bots/Wizard", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotWizardDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "CompleteWizard", + "Route": "Bots/CompleteWizard", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotWizardDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Create", + "Route": "Bots/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "BotRegistrationDto dto" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Edit", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Edit", + "Route": "Bots/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "string settingsJson", + "BotStatus status" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Metrics", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id", + "DateTime? startDate", + "DateTime? endDate" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Delete", + "Route": "Bots/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Suspend", + "Route": "Bots/Suspend", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "Activate", + "Route": "Bots/Activate", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "BotsController", + "Action": "RegenerateKey", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CategoriesController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CategoriesController", + "Action": "Create", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CategoriesController", + "Action": "Create", + "Route": "Categories/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateCategoryDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CategoriesController", + "Action": "Edit", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CategoriesController", + "Action": "Edit", + "Route": "Categories/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "UpdateCategoryDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "CategoriesController", + "Action": "Delete", + "Route": "Categories/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "DashboardController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "Customer", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "MessagesController", + "Action": "Reply", + "Route": "Messages/Reply", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid customerId", + "string content", + "bool isUrgent" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "Details", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "Create", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "Create", + "Route": "Orders/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateOrderDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "Edit", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "Edit", + "Route": "Orders/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "OrderDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "OrdersController", + "Action": "UpdateStatus", + "Route": "Orders/UpdateStatus", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "UpdateOrderStatusDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "Create", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "Create", + "Route": "Products/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateProductDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "Edit", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "Edit", + "Route": "Products/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "UpdateProductDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "UploadPhoto", + "Route": "Products/UploadPhoto", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "IFormFile file", + "string? altText" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "DeletePhoto", + "Route": "Products/DeletePhoto", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "Guid photoId" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ProductsController", + "Action": "Delete", + "Route": "Products/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ShippingRatesController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ShippingRatesController", + "Action": "Create", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ShippingRatesController", + "Action": "Create", + "Route": "ShippingRates/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateShippingRateDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ShippingRatesController", + "Action": "Edit", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ShippingRatesController", + "Action": "Edit", + "Route": "ShippingRates/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "UpdateShippingRateDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "ShippingRatesController", + "Action": "Delete", + "Route": "ShippingRates/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "UsersController", + "Action": "Index", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "UsersController", + "Action": "Create", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "UsersController", + "Action": "Create", + "Route": "Users/Create", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "CreateUserDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "UsersController", + "Action": "Edit", + "Route": "", + "HttpMethods": [ + "GET" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "UsersController", + "Action": "Edit", + "Route": "Users/Edit", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id", + "UpdateUserDto model" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + }, + { + "Controller": "UsersController", + "Action": "Delete", + "Route": "Users/Delete", + "HttpMethods": [ + "POST" + ], + "Parameters": [ + "Guid id" + ], + "RequiresAuthentication": false, + "RequiredRoles": [], + "AllowsAnonymous": false + } + ], + "Authentication": { + "HasAuthentication": true, + "AuthenticationSchemes": [ + "Identity", + "JWT", + "Cookies" + ], + "HasAuthorizeAttributes": true, + "HasIdentity": true, + "HasJWT": true, + "HasCookieAuth": true + }, + "Dependencies": [ + "Microsoft.AspNetCore.Authentication.JwtBearer", + "Microsoft.EntityFrameworkCore.Design", + "Microsoft.EntityFrameworkCore.Sqlite", + "AutoMapper", + "FluentValidation", + "FluentValidation.AspNetCore", + "Serilog.AspNetCore", + "Serilog.Sinks.File", + "Swashbuckle.AspNetCore", + "Microsoft.AspNetCore.Identity.EntityFrameworkCore", + "System.IdentityModel.Tokens.Jwt", + "BTCPayServer.Client", + "NBitcoin", + "Newtonsoft.Json" + ], + "HasIdentity": true, + "HasSwagger": true, + "StartupClass": "Program" +} \ No newline at end of file diff --git a/publish/TestAgent_Results/visual_testing.json b/publish/TestAgent_Results/visual_testing.json new file mode 100644 index 0000000..1a2dc0b --- /dev/null +++ b/publish/TestAgent_Results/visual_testing.json @@ -0,0 +1,17 @@ +{ + "ConsistencyTests": [], + "AuthStateComparisons": [], + "ResponsiveTests": [], + "ComponentTests": [], + "Regressions": [], + "Summary": { + "TotalTests": 0, + "PassedTests": 0, + "FailedTests": 0, + "ConsistencyViolations": 0, + "ResponsiveIssues": 0, + "VisualRegressions": 0, + "OverallScore": 0, + "Recommendations": [] + } +} \ No newline at end of file diff --git a/publish/WebPush.dll b/publish/WebPush.dll new file mode 100755 index 0000000..cb48d17 Binary files /dev/null and b/publish/WebPush.dll differ diff --git a/publish/appsettings.Hostinger.json b/publish/appsettings.Hostinger.json new file mode 100644 index 0000000..b2cd502 --- /dev/null +++ b/publish/appsettings.Hostinger.json @@ -0,0 +1,46 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=/app/data/littleshop.db" + }, + "Jwt": { + "Key": "YourSuperSecretKeyThatIsAtLeast32CharactersLong!", + "Issuer": "LittleShop", + "Audience": "LittleShop", + "ExpiryInHours": 24 + }, + "BTCPayServer": { + "BaseUrl": "https://thebankofdebbie.giize.com", + "ApiKey": "994589c8b514531f867dd24c83a02b6381a5f4a2", + "StoreId": "AoxXjM9NJT6P9C1MErkaawXaSchz8sFPYdQ9FyhmQz33", + "WebhookSecret": "your-webhook-secret-here" + }, + "RoyalMail": { + "ClientId": "", + "ClientSecret": "", + "BaseUrl": "https://api.royalmail.net/", + "SenderAddress1": "SilverLabs Ltd, 123 Business Street", + "SenderCity": "London", + "SenderPostCode": "SW1A 1AA", + "SenderCountry": "United Kingdom" + }, + "WebPush": { + "VapidPublicKey": "BMc6fFJZ8oIQKQzcl3kMnP9tTsjrm3oI_VxLt3lAGYUMWGInzDKn7jqclEoZzjvXy1QXGFb3dIun8mVBwh-QuS4", + "VapidPrivateKey": "dYuuagbz2CzCnPDFUpO_qkGLBgnN3MEFZQnjXNkc1MY", + "Subject": "mailto:admin@littleshop.local" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "BTCPayServer": "Debug" + } + }, + "AllowedHosts": "*", + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://0.0.0.0:8080" + } + } + } +} \ No newline at end of file diff --git a/publish/appsettings.Production.json b/publish/appsettings.Production.json new file mode 100644 index 0000000..cc43d42 --- /dev/null +++ b/publish/appsettings.Production.json @@ -0,0 +1,52 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Warning" + } + }, + "ConnectionStrings": { + "DefaultConnection": "Data Source=littleshop.db" + }, + "Jwt": { + "Key": "${JWT_SECRET_KEY}", + "Issuer": "LittleShop", + "Audience": "LittleShop-API", + "ExpiryMinutes": 60 + }, + "BTCPayServer": { + "ServerUrl": "${BTCPAY_SERVER_URL}", + "StoreId": "${BTCPAY_STORE_ID}", + "ApiKey": "${BTCPAY_API_KEY}", + "WebhookSecret": "${BTCPAY_WEBHOOK_SECRET}" + }, + "AllowedHosts": "*", + "Urls": "http://+:8080", + "ForwardedHeaders": { + "ForwardedProtoHeaderName": "X-Forwarded-Proto", + "ForwardedForHeaderName": "X-Forwarded-For", + "ForwardedHostHeaderName": "X-Forwarded-Host" + }, + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": "Information", + "WriteTo": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "/app/logs/littleshop-.log", + "rollingInterval": "Day", + "retainedFileCountLimit": 7, + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}" + } + } + ] + } +} \ No newline at end of file diff --git a/publish/appsettings.json b/publish/appsettings.json new file mode 100644 index 0000000..e129dcb --- /dev/null +++ b/publish/appsettings.json @@ -0,0 +1,38 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Data Source=littleshop.db" + }, + "Jwt": { + "Key": "YourSuperSecretKeyThatIsAtLeast32CharactersLong!", + "Issuer": "LittleShop", + "Audience": "LittleShop", + "ExpiryInHours": 24 + }, + "BTCPayServer": { + "BaseUrl": "https://pay.silverlabs.uk", + "ApiKey": "994589c8b514531f867dd24c83a02b6381a5f4a2", + "StoreId": "AoxXjM9NJT6P9C1MErkaawXaSchz8sFPYdQ9FyhmQz33", + "WebhookSecret": "" + }, + "RoyalMail": { + "ClientId": "", + "ClientSecret": "", + "BaseUrl": "https://api.royalmail.net/", + "SenderAddress1": "SilverLabs Ltd, 123 Business Street", + "SenderCity": "London", + "SenderPostCode": "SW1A 1AA", + "SenderCountry": "United Kingdom" + }, + "WebPush": { + "VapidPublicKey": "BMc6fFJZ8oIQKQzcl3kMnP9tTsjrm3oI_VxLt3lAGYUMWGInzDKn7jqclEoZzjvXy1QXGFb3dIun8mVBwh-QuS4", + "VapidPrivateKey": "dYuuagbz2CzCnPDFUpO_qkGLBgnN3MEFZQnjXNkc1MY", + "Subject": "mailto:admin@littleshop.local" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/publish/runtimes/browser-wasm/nativeassets/net9.0/e_sqlite3.a b/publish/runtimes/browser-wasm/nativeassets/net9.0/e_sqlite3.a new file mode 100755 index 0000000..5a5a2a3 Binary files /dev/null and b/publish/runtimes/browser-wasm/nativeassets/net9.0/e_sqlite3.a differ diff --git a/publish/runtimes/linux-arm/native/libe_sqlite3.so b/publish/runtimes/linux-arm/native/libe_sqlite3.so new file mode 100755 index 0000000..a6a80a4 Binary files /dev/null and b/publish/runtimes/linux-arm/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-arm64/native/libe_sqlite3.so b/publish/runtimes/linux-arm64/native/libe_sqlite3.so new file mode 100755 index 0000000..a1030eb Binary files /dev/null and b/publish/runtimes/linux-arm64/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-armel/native/libe_sqlite3.so b/publish/runtimes/linux-armel/native/libe_sqlite3.so new file mode 100755 index 0000000..56fc44d Binary files /dev/null and b/publish/runtimes/linux-armel/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-mips64/native/libe_sqlite3.so b/publish/runtimes/linux-mips64/native/libe_sqlite3.so new file mode 100755 index 0000000..15883be Binary files /dev/null and b/publish/runtimes/linux-mips64/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-musl-arm/native/libe_sqlite3.so b/publish/runtimes/linux-musl-arm/native/libe_sqlite3.so new file mode 100755 index 0000000..28eaa8b Binary files /dev/null and b/publish/runtimes/linux-musl-arm/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-musl-arm64/native/libe_sqlite3.so b/publish/runtimes/linux-musl-arm64/native/libe_sqlite3.so new file mode 100755 index 0000000..5a6a8f7 Binary files /dev/null and b/publish/runtimes/linux-musl-arm64/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-musl-s390x/native/libe_sqlite3.so b/publish/runtimes/linux-musl-s390x/native/libe_sqlite3.so new file mode 100755 index 0000000..c576551 Binary files /dev/null and b/publish/runtimes/linux-musl-s390x/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-musl-x64/native/libe_sqlite3.so b/publish/runtimes/linux-musl-x64/native/libe_sqlite3.so new file mode 100755 index 0000000..980a4a6 Binary files /dev/null and b/publish/runtimes/linux-musl-x64/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-ppc64le/native/libe_sqlite3.so b/publish/runtimes/linux-ppc64le/native/libe_sqlite3.so new file mode 100755 index 0000000..3f7dca6 Binary files /dev/null and b/publish/runtimes/linux-ppc64le/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-s390x/native/libe_sqlite3.so b/publish/runtimes/linux-s390x/native/libe_sqlite3.so new file mode 100755 index 0000000..a4bb64d Binary files /dev/null and b/publish/runtimes/linux-s390x/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-x64/native/libe_sqlite3.so b/publish/runtimes/linux-x64/native/libe_sqlite3.so new file mode 100755 index 0000000..705798a Binary files /dev/null and b/publish/runtimes/linux-x64/native/libe_sqlite3.so differ diff --git a/publish/runtimes/linux-x86/native/libe_sqlite3.so b/publish/runtimes/linux-x86/native/libe_sqlite3.so new file mode 100755 index 0000000..c32107b Binary files /dev/null and b/publish/runtimes/linux-x86/native/libe_sqlite3.so differ diff --git a/publish/runtimes/maccatalyst-arm64/native/libe_sqlite3.dylib b/publish/runtimes/maccatalyst-arm64/native/libe_sqlite3.dylib new file mode 100755 index 0000000..f32c878 Binary files /dev/null and b/publish/runtimes/maccatalyst-arm64/native/libe_sqlite3.dylib differ diff --git a/publish/runtimes/maccatalyst-x64/native/libe_sqlite3.dylib b/publish/runtimes/maccatalyst-x64/native/libe_sqlite3.dylib new file mode 100755 index 0000000..33a1c68 Binary files /dev/null and b/publish/runtimes/maccatalyst-x64/native/libe_sqlite3.dylib differ diff --git a/publish/runtimes/osx-arm64/native/libe_sqlite3.dylib b/publish/runtimes/osx-arm64/native/libe_sqlite3.dylib new file mode 100755 index 0000000..05932eb Binary files /dev/null and b/publish/runtimes/osx-arm64/native/libe_sqlite3.dylib differ diff --git a/publish/runtimes/osx-x64/native/libe_sqlite3.dylib b/publish/runtimes/osx-x64/native/libe_sqlite3.dylib new file mode 100755 index 0000000..0cd9a57 Binary files /dev/null and b/publish/runtimes/osx-x64/native/libe_sqlite3.dylib differ diff --git a/publish/runtimes/win-arm/native/e_sqlite3.dll b/publish/runtimes/win-arm/native/e_sqlite3.dll new file mode 100755 index 0000000..8294262 Binary files /dev/null and b/publish/runtimes/win-arm/native/e_sqlite3.dll differ diff --git a/publish/runtimes/win-arm64/native/e_sqlite3.dll b/publish/runtimes/win-arm64/native/e_sqlite3.dll new file mode 100755 index 0000000..4ac1f79 Binary files /dev/null and b/publish/runtimes/win-arm64/native/e_sqlite3.dll differ diff --git a/publish/runtimes/win-x64/native/e_sqlite3.dll b/publish/runtimes/win-x64/native/e_sqlite3.dll new file mode 100755 index 0000000..8c1c1d9 Binary files /dev/null and b/publish/runtimes/win-x64/native/e_sqlite3.dll differ diff --git a/publish/runtimes/win-x86/native/e_sqlite3.dll b/publish/runtimes/win-x86/native/e_sqlite3.dll new file mode 100755 index 0000000..0e05ac0 Binary files /dev/null and b/publish/runtimes/win-x86/native/e_sqlite3.dll differ diff --git a/publish/web.config b/publish/web.config new file mode 100644 index 0000000..21b87dc --- /dev/null +++ b/publish/web.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/publish/wwwroot/css/corporate-steel-theme.css b/publish/wwwroot/css/corporate-steel-theme.css new file mode 100644 index 0000000..55059a3 --- /dev/null +++ b/publish/wwwroot/css/corporate-steel-theme.css @@ -0,0 +1,415 @@ +/* + * 🏢 CORPORATE STEEL THEME 🏢 + * Professional dark theme with subtle metallic accents + * Clean, corporate aesthetic with steel/metal textures + */ + +:root { + /* Corporate Color Palette */ + --corp-primary: #6A4C93; /* Muted Purple */ + --corp-secondary: #8B5A8C; /* Soft Purple */ + --corp-accent: #9B69B0; /* Light Purple */ + + /* Steel/Metal Colors */ + --steel-dark: #1C1C1E; /* Dark Steel */ + --steel-medium: #2C2C2E; /* Medium Steel */ + --steel-light: #3A3A3C; /* Light Steel */ + --steel-accent: #48484A; /* Steel Accent */ + + /* Text Colors */ + --text-primary: #FFFFFF; /* White */ + --text-secondary: #E5E5E7; /* Light Grey */ + --text-muted: #AEAEB2; /* Muted Grey */ + + /* Subtle Gradients */ + --steel-gradient: linear-gradient(135deg, + var(--steel-dark) 0%, + var(--steel-medium) 50%, + var(--steel-light) 100%); + + --purple-gradient: linear-gradient(135deg, + var(--corp-primary) 0%, + var(--corp-secondary) 100%); + + /* Shadows */ + --shadow-subtle: 0 2px 8px rgba(0, 0, 0, 0.3); + --shadow-medium: 0 4px 16px rgba(0, 0, 0, 0.4); + --shadow-strong: 0 8px 32px rgba(0, 0, 0, 0.5); + + /* Transitions */ + --transition-smooth: 0.2s ease; +} + +/* Global Corporate Base */ +body { + background: var(--steel-dark) !important; + background-image: + linear-gradient(45deg, transparent 49%, rgba(106, 76, 147, 0.03) 50%, transparent 51%), + linear-gradient(-45deg, transparent 49%, rgba(139, 90, 140, 0.02) 50%, transparent 51%); + background-size: 20px 20px, 24px 24px; + color: var(--text-primary) !important; + font-family: 'Segoe UI', 'Roboto', 'Arial', sans-serif !important; + font-weight: 400; + line-height: 1.6; +} + +/* Card Styling */ +.card, +.rz-card { + background: var(--steel-gradient) !important; + border: 1px solid var(--steel-accent) !important; + border-radius: 8px !important; + box-shadow: var(--shadow-medium) !important; + color: var(--text-primary) !important; + transition: all var(--transition-smooth) !important; +} + +.card:hover, +.rz-card:hover { + transform: translateY(-2px) !important; + box-shadow: var(--shadow-strong) !important; + border-color: var(--corp-accent) !important; +} + +.card-header, +.rz-card-header { + background: linear-gradient(90deg, + var(--steel-medium) 0%, + var(--steel-light) 100%) !important; + border-bottom: 1px solid var(--steel-accent) !important; + color: var(--text-primary) !important; + font-weight: 600 !important; +} + +.card-body, +.rz-card-body { + background: var(--steel-medium) !important; + color: var(--text-primary) !important; +} + +/* Button Styling */ +.btn, +.rz-button { + background: var(--purple-gradient) !important; + border: 1px solid var(--corp-accent) !important; + border-radius: 6px !important; + color: var(--text-primary) !important; + font-weight: 500 !important; + transition: all var(--transition-smooth) !important; + position: relative !important; +} + +.btn:hover, +.rz-button:hover { + background: linear-gradient(135deg, + var(--corp-secondary) 0%, + var(--corp-accent) 100%) !important; + border-color: var(--corp-accent) !important; + transform: translateY(-1px) !important; + color: var(--text-primary) !important; +} + +.btn:active, +.rz-button:active { + transform: scale(0.98) !important; +} + +/* Navigation */ +.navbar-dark { + background: var(--steel-gradient) !important; + border-bottom: 1px solid var(--steel-accent) !important; +} + +.navbar-brand { + color: var(--text-primary) !important; + font-weight: 600 !important; +} + +.nav-link { + color: var(--text-secondary) !important; + transition: all var(--transition-smooth) !important; +} + +.nav-link:hover { + color: var(--corp-accent) !important; +} + +/* Form Controls */ +.form-control, +.form-select, +.rz-textbox, +.rz-dropdown { + background: var(--steel-medium) !important; + border: 2px solid var(--steel-accent) !important; + border-radius: 6px !important; + color: var(--text-primary) !important; + transition: all var(--transition-smooth) !important; +} + +.form-control:focus, +.form-select:focus, +.rz-textbox:focus, +.rz-dropdown:focus { + background: var(--steel-light) !important; + border-color: var(--corp-primary) !important; + box-shadow: 0 0 0 0.25rem rgba(106, 76, 147, 0.25) !important; + outline: none !important; +} + +.form-label { + color: var(--text-secondary) !important; + font-weight: 500 !important; +} + +/* Tables */ +.table { + background: var(--steel-medium) !important; + color: var(--text-primary) !important; + border-radius: 8px !important; + overflow: hidden !important; +} + +.table th { + background: var(--steel-light) !important; + color: var(--text-primary) !important; + border-bottom: 2px solid var(--steel-accent) !important; + font-weight: 600 !important; +} + +.table td { + border-bottom: 1px solid var(--steel-accent) !important; + color: var(--text-primary) !important; +} + +.table tbody tr:hover { + background: rgba(106, 76, 147, 0.1) !important; +} + +/* Mobile Navigation */ +.mobile-header { + background: var(--steel-gradient) !important; + border-bottom: 1px solid var(--steel-accent) !important; +} + +.mobile-bottom-nav { + background: var(--steel-medium) !important; + border-top: 1px solid var(--steel-accent) !important; +} + +.mobile-nav-item { + color: var(--text-secondary) !important; + transition: all var(--transition-smooth) !important; +} + +.mobile-nav-item:hover { + color: var(--corp-accent) !important; + background: rgba(106, 76, 147, 0.1) !important; +} + +.mobile-nav-item.active { + color: var(--text-primary) !important; + background: var(--purple-gradient) !important; +} + +.mobile-sidebar { + background: var(--steel-gradient) !important; + border-right: 1px solid var(--steel-accent) !important; +} + +.mobile-sidebar-header { + background: var(--purple-gradient) !important; +} + +.mobile-sidebar-link { + color: var(--text-secondary) !important; + transition: all var(--transition-smooth) !important; +} + +.mobile-sidebar-link:hover { + background: rgba(106, 76, 147, 0.1) !important; + color: var(--corp-accent) !important; +} + +.mobile-sidebar-link.active { + background: var(--purple-gradient) !important; + color: var(--text-primary) !important; +} + +/* Alerts and Notifications */ +.alert { + background: var(--steel-medium) !important; + border: 1px solid var(--steel-accent) !important; + color: var(--text-primary) !important; +} + +.alert-success { + border-color: #28a745 !important; + background: linear-gradient(135deg, var(--steel-medium), rgba(40, 167, 69, 0.1)) !important; +} + +.alert-danger { + border-color: #dc3545 !important; + background: linear-gradient(135deg, var(--steel-medium), rgba(220, 53, 69, 0.1)) !important; +} + +.alert-warning { + border-color: #ffc107 !important; + background: linear-gradient(135deg, var(--steel-medium), rgba(255, 193, 7, 0.1)) !important; +} + +/* Mobile Cards */ +.mobile-card, +.order-card { + background: var(--steel-gradient) !important; + border: 1px solid var(--steel-accent) !important; + color: var(--text-primary) !important; +} + +.mobile-card-header, +.order-header { + background: var(--steel-light) !important; + color: var(--text-primary) !important; + border-bottom: 1px solid var(--steel-accent) !important; +} + +.mobile-card-body, +.order-body { + background: var(--steel-medium) !important; + color: var(--text-primary) !important; +} + +.mobile-card-footer { + background: var(--steel-light) !important; + color: var(--text-primary) !important; + border-top: 1px solid var(--steel-accent) !important; +} + +/* Status Badges */ +.status-badge { + background: var(--steel-light) !important; + color: var(--text-primary) !important; + border: 1px solid var(--steel-accent) !important; +} + +.status-badge.pending { + background: linear-gradient(135deg, var(--steel-light), rgba(255, 193, 7, 0.2)) !important; + color: #ffc107 !important; +} + +.status-badge.processing { + background: linear-gradient(135deg, var(--steel-light), rgba(23, 162, 184, 0.2)) !important; + color: #17a2b8 !important; +} + +.status-badge.shipped { + background: linear-gradient(135deg, var(--steel-light), rgba(40, 167, 69, 0.2)) !important; + color: #28a745 !important; +} + +/* Breadcrumbs and Links */ +a { + color: var(--corp-accent) !important; + transition: color var(--transition-smooth) !important; +} + +a:hover { + color: var(--text-primary) !important; +} + +/* Dropdowns */ +.dropdown-menu { + background: var(--steel-medium) !important; + border: 1px solid var(--steel-accent) !important; + box-shadow: var(--shadow-medium) !important; +} + +.dropdown-item { + color: var(--text-secondary) !important; + transition: all var(--transition-smooth) !important; +} + +.dropdown-item:hover { + background: rgba(106, 76, 147, 0.2) !important; + color: var(--text-primary) !important; +} + +/* List Groups */ +.list-group-item { + background: var(--steel-medium) !important; + border: 1px solid var(--steel-accent) !important; + color: var(--text-primary) !important; +} + +.list-group-item:hover { + background: var(--steel-light) !important; +} + +/* Override any remaining Bootstrap defaults */ +.container, +.container-fluid { + color: var(--text-primary) !important; +} + +h1, h2, h3, h4, h5, h6 { + color: var(--text-primary) !important; + font-weight: 600 !important; +} + +p { + color: var(--text-secondary) !important; +} + +/* Subtle Steel Texture */ +.steel-texture { + background-image: + linear-gradient(45deg, rgba(255,255,255,0.02) 25%, transparent 25%), + linear-gradient(-45deg, rgba(255,255,255,0.02) 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.02) 75%), + linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.02) 75%); + background-size: 4px 4px; + background-position: 0 0, 0 2px, 2px -2px, -2px 0px; +} + +/* Corporate Professional Styling */ +.corporate-card { + background: var(--steel-gradient) !important; + border: 1px solid var(--steel-accent) !important; + border-radius: 8px !important; + box-shadow: var(--shadow-subtle) !important; +} + +.corporate-card:hover { + box-shadow: var(--shadow-medium) !important; + transform: translateY(-1px) !important; +} + +/* Remove any epileptic-inducing effects */ +* { + animation: none !important; +} + +/* Clean scrollbars */ +::-webkit-scrollbar { + width: 8px; + background: var(--steel-dark); +} + +::-webkit-scrollbar-track { + background: var(--steel-medium); +} + +::-webkit-scrollbar-thumb { + background: var(--steel-light); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--corp-primary); +} + +/* Professional Focus States */ +.form-control:focus, +.form-select:focus { + border-color: var(--corp-primary) !important; + box-shadow: 0 0 0 0.2rem rgba(106, 76, 147, 0.25) !important; +} \ No newline at end of file diff --git a/publish/wwwroot/css/corporate-steel-theme.css.br b/publish/wwwroot/css/corporate-steel-theme.css.br new file mode 100644 index 0000000..abda6b4 Binary files /dev/null and b/publish/wwwroot/css/corporate-steel-theme.css.br differ diff --git a/publish/wwwroot/css/corporate-steel-theme.css.gz b/publish/wwwroot/css/corporate-steel-theme.css.gz new file mode 100644 index 0000000..0a15c8b Binary files /dev/null and b/publish/wwwroot/css/corporate-steel-theme.css.gz differ diff --git a/publish/wwwroot/css/modern-admin.css b/publish/wwwroot/css/modern-admin.css new file mode 100644 index 0000000..b1f32cd --- /dev/null +++ b/publish/wwwroot/css/modern-admin.css @@ -0,0 +1,444 @@ +/* + * Modern Clean Admin Theme + * Mobile-first, professional, and user-friendly + */ + +:root { + /* Modern Color Palette */ + --primary-blue: #2563eb; + --primary-purple: #7c3aed; + --success-green: #059669; + --warning-orange: #d97706; + --danger-red: #dc2626; + + /* Neutral Greys */ + --grey-50: #f9fafb; + --grey-100: #f3f4f6; + --grey-200: #e5e7eb; + --grey-300: #d1d5db; + --grey-400: #9ca3af; + --grey-500: #6b7280; + --grey-600: #4b5563; + --grey-700: #374151; + --grey-800: #1f2937; + --grey-900: #111827; + + /* Spacing */ + --spacing-xs: 0.25rem; + --spacing-sm: 0.5rem; + --spacing-md: 1rem; + --spacing-lg: 1.5rem; + --spacing-xl: 2rem; + + /* Border Radius */ + --radius-sm: 0.375rem; + --radius-md: 0.5rem; + --radius-lg: 0.75rem; + --radius-xl: 1rem; + + /* Shadows */ + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + + /* Typography */ + --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace; +} + +/* Global Styles */ +body { + font-family: var(--font-sans); + background-color: var(--grey-50); + color: var(--grey-900); + line-height: 1.6; +} + +/* Modern Card Styling */ +.card { + border: 1px solid var(--grey-200); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-sm); + background: white; + transition: all 0.2s ease; +} + +.card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-1px); +} + +.card-header { + background: var(--grey-50); + border-bottom: 1px solid var(--grey-200); + padding: var(--spacing-lg); + font-weight: 600; + color: var(--grey-700); +} + +.card-body { + padding: var(--spacing-lg); +} + +/* Modern Button Styling */ +.btn { + border-radius: var(--radius-md); + font-weight: 500; + padding: 0.625rem 1.25rem; + transition: all 0.2s ease; + border: none; +} + +.btn-primary { + background: linear-gradient(135deg, var(--primary-blue) 0%, var(--primary-purple) 100%); + color: white; +} + +.btn-primary:hover { + background: linear-gradient(135deg, #1d4ed8 0%, #6d28d9 100%); + transform: translateY(-1px); + box-shadow: var(--shadow-md); +} + +.btn-success { + background: var(--success-green); + color: white; +} + +.btn-success:hover { + background: #047857; + transform: translateY(-1px); +} + +.btn-outline-primary { + border: 2px solid var(--primary-blue); + color: var(--primary-blue); + background: white; +} + +.btn-outline-primary:hover { + background: var(--primary-blue); + color: white; + transform: translateY(-1px); +} + +.btn-sm { + padding: 0.5rem 1rem; + font-size: 0.875rem; +} + +/* Modern Navigation */ +.navbar { + background: white !important; + border-bottom: 1px solid var(--grey-200); + box-shadow: var(--shadow-sm); + padding: var(--spacing-md) 0; +} + +.navbar-brand { + color: var(--grey-900) !important; + font-weight: 700; + font-size: 1.25rem; +} + +.navbar-nav .nav-link { + color: var(--grey-600) !important; + font-weight: 500; + padding: 0.75rem 1rem; + border-radius: var(--radius-md); + margin: 0 0.25rem; + transition: all 0.2s ease; +} + +.navbar-nav .nav-link:hover { + color: var(--primary-blue) !important; + background: var(--grey-50); +} + +/* Form Controls */ +.form-control, +.form-select { + border: 2px solid var(--grey-200); + border-radius: var(--radius-md); + padding: 0.75rem 1rem; + transition: all 0.2s ease; + background: white; +} + +.form-control:focus, +.form-select:focus { + border-color: var(--primary-blue); + box-shadow: 0 0 0 0.25rem rgba(37, 99, 235, 0.1); + outline: none; +} + +.form-label { + font-weight: 600; + color: var(--grey-700); + margin-bottom: var(--spacing-sm); +} + +/* Table Styling */ +.table { + background: white; + border-radius: var(--radius-lg); + overflow: hidden; + box-shadow: var(--shadow-sm); +} + +.table thead th { + background: var(--grey-50); + border-bottom: 2px solid var(--grey-200); + font-weight: 600; + color: var(--grey-700); + padding: 1rem; +} + +.table tbody td { + padding: 1rem; + border-bottom: 1px solid var(--grey-100); + vertical-align: middle; +} + +.table tbody tr:hover { + background: var(--grey-50); +} + +/* Status Badges */ +.badge { + font-weight: 500; + padding: 0.5rem 0.75rem; + border-radius: var(--radius-sm); +} + +.bg-success { + background-color: var(--success-green) !important; +} + +.bg-warning { + background-color: var(--warning-orange) !important; +} + +.bg-danger { + background-color: var(--danger-red) !important; +} + +.bg-info { + background-color: var(--primary-blue) !important; +} + +/* Page Headers */ +h1, h2, h3, h4, h5, h6 { + color: var(--grey-900); + font-weight: 700; + line-height: 1.25; +} + +h1 { + font-size: 2rem; + margin-bottom: var(--spacing-lg); +} + +/* Mobile Responsive Design */ +@media (max-width: 768px) { + .container-fluid { + padding: var(--spacing-md); + } + + .card { + margin-bottom: var(--spacing-lg); + border-radius: var(--radius-md); + } + + .card-header { + padding: var(--spacing-md); + } + + .card-body { + padding: var(--spacing-md); + } + + .btn { + width: 100%; + margin-bottom: var(--spacing-sm); + } + + .btn:last-child { + margin-bottom: 0; + } + + /* Mobile Table - Stack on Small Screens */ + @media (max-width: 768px) { + .table-responsive { + border: none; + } + + .table { + font-size: 0.875rem; + } + + .table thead { + display: none; + } + + .table tbody, + .table tbody tr, + .table tbody td { + display: block; + width: 100%; + } + + .table tbody tr { + background: white; + border: 1px solid var(--grey-200); + border-radius: var(--radius-md); + margin-bottom: var(--spacing-md); + padding: var(--spacing-md); + box-shadow: var(--shadow-sm); + } + + .table tbody td { + border: none; + padding: var(--spacing-sm) 0; + position: relative; + padding-left: 40%; + } + + .table tbody td:before { + content: attr(data-label) ": "; + position: absolute; + left: 0; + width: 35%; + font-weight: 600; + color: var(--grey-600); + } + } + + /* Mobile Navigation */ + .navbar-toggler { + border: none; + padding: 0.25rem 0.5rem; + } + + .navbar-collapse { + margin-top: var(--spacing-md); + } + + .navbar-nav .nav-link { + padding: var(--spacing-md); + margin: var(--spacing-xs) 0; + background: var(--grey-50); + border-radius: var(--radius-md); + } +} + +/* Modern Form Layout */ +.row .col-md-6 .form-group, +.row .col-md-6 .mb-3 { + margin-bottom: var(--spacing-lg); +} + +/* Action Buttons */ +.d-flex.justify-content-between .btn { + min-width: 120px; +} + +/* Loading States */ +.btn:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +/* Focus States for Accessibility */ +.btn:focus, +.form-control:focus, +.form-select:focus { + outline: 2px solid var(--primary-blue); + outline-offset: 2px; +} + +/* Toast/Alert Improvements */ +.alert { + border: none; + border-radius: var(--radius-md); + border-left: 4px solid; +} + +.alert-success { + background: #ecfdf5; + color: #065f46; + border-left-color: var(--success-green); +} + +.alert-danger { + background: #fef2f2; + color: #991b1b; + border-left-color: var(--danger-red); +} + +.alert-warning { + background: #fffbeb; + color: #92400e; + border-left-color: var(--warning-orange); +} + +/* Clean List Styling */ +.list-group-item { + border: 1px solid var(--grey-200); + background: white; + transition: all 0.2s ease; +} + +.list-group-item:hover { + background: var(--grey-50); + transform: translateX(4px); +} + +.list-group-item-action { + color: var(--grey-700); +} + +.list-group-item-action:hover { + color: var(--primary-blue); +} + +/* Typography Improvements */ +.text-muted { + color: var(--grey-500) !important; +} + +code { + background: var(--grey-100); + color: var(--grey-800); + padding: 0.125rem 0.375rem; + border-radius: var(--radius-sm); + font-family: var(--font-mono); + font-size: 0.875em; +} + +/* Utility Classes */ +.rounded-modern { + border-radius: var(--radius-lg) !important; +} + +.shadow-modern { + box-shadow: var(--shadow-md) !important; +} + +.bg-gradient-primary { + background: linear-gradient(135deg, var(--primary-blue) 0%, var(--primary-purple) 100%) !important; +} + +/* Print Styles */ +@media print { + .navbar, + .btn, + .card-header { + display: none !important; + } + + .card { + border: 1px solid #ccc !important; + box-shadow: none !important; + } +} \ No newline at end of file diff --git a/publish/wwwroot/css/modern-admin.css.br b/publish/wwwroot/css/modern-admin.css.br new file mode 100644 index 0000000..b4bf425 Binary files /dev/null and b/publish/wwwroot/css/modern-admin.css.br differ diff --git a/publish/wwwroot/css/modern-admin.css.gz b/publish/wwwroot/css/modern-admin.css.gz new file mode 100644 index 0000000..1a4b4a6 Binary files /dev/null and b/publish/wwwroot/css/modern-admin.css.gz differ diff --git a/publish/wwwroot/css/radzen-tech-theme.css b/publish/wwwroot/css/radzen-tech-theme.css new file mode 100644 index 0000000..0b063dc --- /dev/null +++ b/publish/wwwroot/css/radzen-tech-theme.css @@ -0,0 +1,534 @@ +/* + * 🤖 RADZEN TECH HOLOGRAPHIC THEME 🤖 + * Dark Purple Metallic with Holographic Effects + * Pixel Perfect Robot/Tech Aesthetic + */ + +:root { + /* Core Theme Colors */ + --tech-primary: #8A2BE2; /* Blue Violet */ + --tech-secondary: #9932CC; /* Dark Orchid */ + --tech-accent: #DA70D6; /* Orchid */ + --tech-highlight: #FF00FF; /* Magenta */ + --tech-neon: #00FFFF; /* Cyan */ + + /* Dark Base Colors */ + --tech-dark-base: #0D0014; /* Ultra Dark Purple */ + --tech-dark-surface: #1A0A2E; /* Dark Purple */ + --tech-dark-card: #16213E; /* Dark Blue Purple */ + --tech-dark-accent: #0F3460; /* Deep Blue */ + + /* Metallic Colors */ + --tech-metallic-silver: #C0C0C0; + --tech-metallic-gold: #FFD700; + --tech-metallic-copper: #B87333; + --tech-metallic-chrome: #E5E5E5; + + /* Holographic Gradient */ + --holographic-gradient: linear-gradient(45deg, + #FF0080 0%, + #7928CA 25%, + #0070F3 50%, + #00DFD8 75%, + #FF0080 100%); + + /* Glow Effects */ + --tech-glow-primary: 0 0 20px rgba(138, 43, 226, 0.8); + --tech-glow-secondary: 0 0 30px rgba(153, 50, 204, 0.6); + --tech-glow-accent: 0 0 15px rgba(218, 112, 214, 0.9); + --tech-glow-neon: 0 0 25px rgba(0, 255, 255, 0.7); + + /* Animation Timings */ + --tech-transition-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1); + --tech-transition-smooth: 0.3s cubic-bezier(0.4, 0, 0.2, 1); + --tech-transition-glow: 0.5s cubic-bezier(0.4, 0, 0.2, 1); +} + +/* Holographic Animation Keyframes */ +@keyframes holographic-shift { + 0% { background-position: 0% 50%; } + 25% { background-position: 100% 50%; } + 50% { background-position: 100% 0%; } + 75% { background-position: 0% 0%; } + 100% { background-position: 0% 50%; } +} + +@keyframes tech-pulse { + 0%, 100% { + transform: scale(1); + box-shadow: var(--tech-glow-primary); + } + 50% { + transform: scale(1.05); + box-shadow: var(--tech-glow-secondary); + } +} + +@keyframes neon-flicker { + 0%, 100% { opacity: 1; } + 2% { opacity: 0.8; } + 4% { opacity: 1; } + 8% { opacity: 0.9; } + 10% { opacity: 1; } +} + +@keyframes data-stream { + 0% { transform: translateY(-100%); opacity: 0; } + 10% { opacity: 1; } + 90% { opacity: 1; } + 100% { transform: translateY(100vh); opacity: 0; } +} + +/* Global Dark Theme Base */ +body { + background: var(--tech-dark-base) !important; + background-image: + radial-gradient(circle at 25% 25%, rgba(138, 43, 226, 0.1) 0%, transparent 50%), + radial-gradient(circle at 75% 75%, rgba(153, 50, 204, 0.1) 0%, transparent 50%), + linear-gradient(45deg, transparent 45%, rgba(0, 255, 255, 0.03) 50%, transparent 55%); + color: var(--tech-metallic-chrome) !important; + font-family: 'Segoe UI', 'Roboto Mono', 'Courier New', monospace !important; + font-weight: 400; + line-height: 1.5; + min-height: 100vh; +} + +/* Radzen Component Overrides */ +.rz-card { + background: linear-gradient(135deg, + var(--tech-dark-surface) 0%, + var(--tech-dark-card) 100%) !important; + border: 1px solid rgba(138, 43, 226, 0.3) !important; + border-radius: 12px !important; + box-shadow: + 0 8px 32px rgba(13, 0, 20, 0.8), + inset 0 1px 0 rgba(218, 112, 214, 0.2), + 0 0 0 1px rgba(138, 43, 226, 0.1) !important; + color: var(--tech-metallic-chrome) !important; + transition: all var(--tech-transition-smooth) !important; + backdrop-filter: blur(20px) !important; +} + +.rz-card:hover { + transform: translateY(-2px) !important; + box-shadow: + 0 16px 64px rgba(13, 0, 20, 0.9), + inset 0 1px 0 rgba(218, 112, 214, 0.4), + var(--tech-glow-primary) !important; + border-color: var(--tech-primary) !important; +} + +.rz-card-header { + background: linear-gradient(90deg, + rgba(138, 43, 226, 0.2) 0%, + rgba(153, 50, 204, 0.1) 100%) !important; + border-bottom: 1px solid rgba(218, 112, 214, 0.3) !important; + color: var(--tech-metallic-chrome) !important; + font-weight: 600 !important; + padding: 1rem 1.5rem !important; + position: relative !important; +} + +.rz-card-header::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: var(--holographic-gradient); + background-size: 200% 100%; + animation: holographic-shift 3s ease-in-out infinite; +} + +.rz-card-body { + padding: 1.5rem !important; + background: rgba(22, 33, 62, 0.3) !important; +} + +/* Radzen Buttons */ +.rz-button { + background: linear-gradient(135deg, + var(--tech-primary) 0%, + var(--tech-secondary) 100%) !important; + border: 1px solid var(--tech-accent) !important; + border-radius: 8px !important; + color: white !important; + font-weight: 600 !important; + text-transform: uppercase !important; + letter-spacing: 0.5px !important; + transition: all var(--tech-transition-smooth) !important; + position: relative !important; + overflow: hidden !important; +} + +.rz-button::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: var(--holographic-gradient); + background-size: 200% 200%; + border-radius: inherit; + z-index: -1; + opacity: 0; + transition: opacity var(--tech-transition-smooth); + animation: holographic-shift 2s ease-in-out infinite; +} + +.rz-button:hover::before { + opacity: 1; +} + +.rz-button:hover { + transform: translateY(-1px) !important; + /* box-shadow: var(--tech-glow-primary) !important; */ + /* text-shadow: 0 0 10px rgba(255, 255, 255, 0.8) !important; */ +} + +.rz-button:active { + transform: scale(0.98) !important; +} + +.rz-button-primary { + background: linear-gradient(135deg, + var(--tech-primary) 0%, + var(--tech-highlight) 100%) !important; +} + +.rz-button-secondary { + background: linear-gradient(135deg, + var(--tech-dark-accent) 0%, + var(--tech-secondary) 100%) !important; +} + +/* Radzen Data Grid */ +.rz-datatable, +.rz-grid { + background: var(--tech-dark-surface) !important; + border: 1px solid rgba(138, 43, 226, 0.3) !important; + border-radius: 12px !important; + overflow: hidden !important; +} + +.rz-datatable-header, +.rz-grid-header { + background: linear-gradient(90deg, + var(--tech-dark-card) 0%, + var(--tech-dark-accent) 100%) !important; + color: var(--tech-metallic-chrome) !important; + font-weight: 600 !important; + border-bottom: 2px solid var(--tech-primary) !important; +} + +.rz-datatable-header th, +.rz-grid-header th { + border-right: 1px solid rgba(138, 43, 226, 0.2) !important; + padding: 1rem !important; + text-transform: uppercase !important; + letter-spacing: 0.5px !important; + font-size: 0.85rem !important; +} + +.rz-datatable-data tr, +.rz-grid-table tr { + background: rgba(26, 10, 46, 0.5) !important; + border-bottom: 1px solid rgba(218, 112, 214, 0.1) !important; + transition: all var(--tech-transition-fast) !important; +} + +.rz-datatable-data tr:hover, +.rz-grid-table tr:hover { + background: rgba(138, 43, 226, 0.1) !important; + box-shadow: inset 0 0 20px rgba(218, 112, 214, 0.1) !important; +} + +.rz-datatable-data td, +.rz-grid-table td { + border-right: 1px solid rgba(138, 43, 226, 0.1) !important; + padding: 1rem !important; + color: var(--tech-metallic-chrome) !important; +} + +/* Radzen Form Controls */ +.rz-textbox, +.rz-dropdown, +.rz-multiselect, +.rz-textarea { + background: rgba(22, 33, 62, 0.8) !important; + border: 2px solid rgba(138, 43, 226, 0.3) !important; + border-radius: 8px !important; + color: var(--tech-metallic-chrome) !important; + padding: 0.75rem 1rem !important; + transition: all var(--tech-transition-smooth) !important; + backdrop-filter: blur(10px) !important; +} + +.rz-textbox:focus, +.rz-dropdown:focus, +.rz-multiselect:focus, +.rz-textarea:focus { + border-color: var(--tech-primary) !important; + box-shadow: + var(--tech-glow-primary), + inset 0 0 20px rgba(138, 43, 226, 0.1) !important; + outline: none !important; + background: rgba(22, 33, 62, 1) !important; +} + +.rz-textbox::placeholder, +.rz-dropdown::placeholder, +.rz-textarea::placeholder { + color: rgba(192, 192, 192, 0.6) !important; + font-style: italic !important; +} + +/* Radzen Navigation */ +.rz-navigation { + background: linear-gradient(180deg, + var(--tech-dark-surface) 0%, + var(--tech-dark-base) 100%) !important; + border-right: 1px solid rgba(138, 43, 226, 0.3) !important; + backdrop-filter: blur(20px) !important; +} + +.rz-navigation-item { + color: var(--tech-metallic-chrome) !important; + padding: 0.75rem 1.5rem !important; + transition: all var(--tech-transition-fast) !important; + border-radius: 0 25px 25px 0 !important; + margin: 0.25rem 0 !important; + position: relative !important; +} + +.rz-navigation-item:hover { + background: linear-gradient(90deg, + rgba(138, 43, 226, 0.2) 0%, + rgba(153, 50, 204, 0.1) 100%) !important; + color: var(--tech-accent) !important; + transform: translateX(5px) !important; +} + +.rz-navigation-item.rz-state-active { + background: linear-gradient(90deg, + var(--tech-primary) 0%, + var(--tech-secondary) 100%) !important; + color: white !important; + box-shadow: var(--tech-glow-primary) !important; +} + +.rz-navigation-item.rz-state-active::after { + content: ''; + position: absolute; + right: -1px; + top: 0; + bottom: 0; + width: 3px; + background: var(--tech-neon); + box-shadow: var(--tech-glow-neon); + animation: neon-flicker 2s infinite; +} + +/* Radzen Panels */ +.rz-panel { + background: var(--tech-dark-surface) !important; + border: 1px solid rgba(138, 43, 226, 0.3) !important; + border-radius: 12px !important; + box-shadow: 0 8px 32px rgba(13, 0, 20, 0.6) !important; + backdrop-filter: blur(20px) !important; +} + +.rz-panel-header { + background: linear-gradient(90deg, + var(--tech-dark-card) 0%, + var(--tech-dark-accent) 100%) !important; + border-bottom: 1px solid rgba(218, 112, 214, 0.3) !important; + color: var(--tech-metallic-chrome) !important; + font-weight: 600 !important; + padding: 1rem 1.5rem !important; + position: relative !important; +} + +/* Radzen Dialogs */ +.rz-dialog { + background: linear-gradient(135deg, + var(--tech-dark-surface) 0%, + var(--tech-dark-card) 100%) !important; + border: 2px solid var(--tech-primary) !important; + border-radius: 16px !important; + box-shadow: + 0 20px 60px rgba(13, 0, 20, 0.9), + var(--tech-glow-primary) !important; + backdrop-filter: blur(30px) !important; +} + +.rz-dialog-header { + background: linear-gradient(90deg, + rgba(138, 43, 226, 0.3) 0%, + rgba(153, 50, 204, 0.2) 100%) !important; + border-bottom: 1px solid rgba(218, 112, 214, 0.4) !important; + color: var(--tech-metallic-chrome) !important; + font-weight: 700 !important; + text-transform: uppercase !important; + letter-spacing: 1px !important; +} + +/* Radzen Notifications */ +.rz-notification { + background: linear-gradient(135deg, + var(--tech-dark-surface) 0%, + var(--tech-dark-card) 100%) !important; + border: 1px solid var(--tech-primary) !important; + border-radius: 12px !important; + color: var(--tech-metallic-chrome) !important; + box-shadow: + 0 8px 32px rgba(13, 0, 20, 0.8), + var(--tech-glow-primary) !important; + backdrop-filter: blur(20px) !important; +} + +.rz-notification-success { + border-color: var(--tech-neon) !important; + box-shadow: var(--tech-glow-neon) !important; +} + +.rz-notification-error { + border-color: var(--tech-highlight) !important; + box-shadow: 0 0 25px rgba(255, 0, 255, 0.7) !important; +} + +/* Holographic Border Effect */ +.tech-holographic-border { + position: relative; + border: 2px solid transparent !important; + background: linear-gradient(var(--tech-dark-surface), var(--tech-dark-surface)) padding-box, + var(--holographic-gradient) border-box !important; + background-size: 200% 200%; + animation: holographic-shift 3s ease-in-out infinite; +} + +/* Tech Grid Pattern Overlay */ +.tech-grid-overlay { + background-image: + linear-gradient(rgba(138, 43, 226, 0.1) 1px, transparent 1px), + linear-gradient(90deg, rgba(138, 43, 226, 0.1) 1px, transparent 1px); + background-size: 20px 20px; +} + +/* Scrollbar Styling */ +::-webkit-scrollbar { + width: 12px; + background: var(--tech-dark-base); +} + +::-webkit-scrollbar-track { + background: rgba(26, 10, 46, 0.5); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb { + background: linear-gradient(180deg, + var(--tech-primary) 0%, + var(--tech-secondary) 100%); + border-radius: 6px; + border: 1px solid rgba(218, 112, 214, 0.3); +} + +::-webkit-scrollbar-thumb:hover { + background: linear-gradient(180deg, + var(--tech-accent) 0%, + var(--tech-highlight) 100%); + box-shadow: var(--tech-glow-accent); +} + +/* Loading Spinner Override */ +.rz-spinner { + border: 3px solid rgba(138, 43, 226, 0.3); + border-top: 3px solid var(--tech-primary); + box-shadow: var(--tech-glow-primary); +} + +/* Mobile Responsive Adjustments */ +@media (max-width: 768px) { + .rz-card { + margin: 0.5rem !important; + border-radius: 8px !important; + } + + .rz-button { + padding: 0.75rem 1.5rem !important; + font-size: 0.9rem !important; + } + + .rz-navigation-item { + padding: 1rem !important; + border-radius: 0 20px 20px 0 !important; + } +} + +/* Print Styles */ +@media print { + body { + background: white !important; + color: black !important; + } + + .rz-card { + background: white !important; + border: 1px solid #ccc !important; + box-shadow: none !important; + } +} + +/* High Contrast Mode */ +@media (prefers-contrast: high) { + :root { + --tech-primary: #FF00FF; + --tech-secondary: #00FFFF; + --tech-accent: #FFFF00; + } +} + +/* Reduced Motion */ +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} + +/* Dark Theme Class for Radzen */ +.dark-theme { + --rz-primary: var(--tech-primary); + --rz-secondary: var(--tech-secondary); + --rz-success: var(--tech-neon); + --rz-info: var(--tech-accent); + --rz-warning: var(--tech-metallic-gold); + --rz-danger: var(--tech-highlight); + --rz-dark: var(--tech-dark-base); + --rz-light: var(--tech-metallic-chrome); +} + +/* Tech Enhancement Classes */ +.tech-glow { + box-shadow: var(--tech-glow-primary) !important; + animation: tech-pulse 2s infinite !important; +} + +.tech-holographic { + background: var(--holographic-gradient) !important; + background-size: 200% 200% !important; + animation: holographic-shift 3s ease-in-out infinite !important; + -webkit-background-clip: text !important; + background-clip: text !important; + color: transparent !important; +} + +.tech-neon { + color: var(--tech-neon) !important; + text-shadow: var(--tech-glow-neon) !important; + animation: neon-flicker 2s infinite !important; +} \ No newline at end of file diff --git a/publish/wwwroot/css/radzen-tech-theme.css.br b/publish/wwwroot/css/radzen-tech-theme.css.br new file mode 100644 index 0000000..9ac8f08 Binary files /dev/null and b/publish/wwwroot/css/radzen-tech-theme.css.br differ diff --git a/publish/wwwroot/css/radzen-tech-theme.css.gz b/publish/wwwroot/css/radzen-tech-theme.css.gz new file mode 100644 index 0000000..5b79d2d Binary files /dev/null and b/publish/wwwroot/css/radzen-tech-theme.css.gz differ diff --git a/publish/wwwroot/favicon.ico b/publish/wwwroot/favicon.ico new file mode 100644 index 0000000..f2979e8 --- /dev/null +++ b/publish/wwwroot/favicon.ico @@ -0,0 +1 @@ +AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA \ No newline at end of file diff --git a/publish/wwwroot/favicon.ico.br b/publish/wwwroot/favicon.ico.br new file mode 100644 index 0000000..8249480 Binary files /dev/null and b/publish/wwwroot/favicon.ico.br differ diff --git a/publish/wwwroot/favicon.ico.gz b/publish/wwwroot/favicon.ico.gz new file mode 100644 index 0000000..6d36821 Binary files /dev/null and b/publish/wwwroot/favicon.ico.gz differ diff --git a/publish/wwwroot/icons/icon-128x128.png b/publish/wwwroot/icons/icon-128x128.png new file mode 100644 index 0000000..849c587 Binary files /dev/null and b/publish/wwwroot/icons/icon-128x128.png differ diff --git a/publish/wwwroot/icons/icon-144x144.png b/publish/wwwroot/icons/icon-144x144.png new file mode 100644 index 0000000..b106006 Binary files /dev/null and b/publish/wwwroot/icons/icon-144x144.png differ diff --git a/publish/wwwroot/icons/icon-152x152.png b/publish/wwwroot/icons/icon-152x152.png new file mode 100644 index 0000000..5ce3dee Binary files /dev/null and b/publish/wwwroot/icons/icon-152x152.png differ diff --git a/publish/wwwroot/icons/icon-192x192.png b/publish/wwwroot/icons/icon-192x192.png new file mode 100644 index 0000000..f3e33ab Binary files /dev/null and b/publish/wwwroot/icons/icon-192x192.png differ diff --git a/publish/wwwroot/icons/icon-384x384.png b/publish/wwwroot/icons/icon-384x384.png new file mode 100644 index 0000000..b96e415 Binary files /dev/null and b/publish/wwwroot/icons/icon-384x384.png differ diff --git a/publish/wwwroot/icons/icon-512x512.png b/publish/wwwroot/icons/icon-512x512.png new file mode 100644 index 0000000..cf3bba8 Binary files /dev/null and b/publish/wwwroot/icons/icon-512x512.png differ diff --git a/publish/wwwroot/icons/icon-72x72.png b/publish/wwwroot/icons/icon-72x72.png new file mode 100644 index 0000000..36576e9 Binary files /dev/null and b/publish/wwwroot/icons/icon-72x72.png differ diff --git a/publish/wwwroot/icons/icon-96x96.png b/publish/wwwroot/icons/icon-96x96.png new file mode 100644 index 0000000..e853433 Binary files /dev/null and b/publish/wwwroot/icons/icon-96x96.png differ diff --git a/publish/wwwroot/icons/icon-placeholder.svg b/publish/wwwroot/icons/icon-placeholder.svg new file mode 100644 index 0000000..7f51ea7 --- /dev/null +++ b/publish/wwwroot/icons/icon-placeholder.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + LS + \ No newline at end of file diff --git a/publish/wwwroot/icons/icon-placeholder.svg.br b/publish/wwwroot/icons/icon-placeholder.svg.br new file mode 100644 index 0000000..c2af8d4 --- /dev/null +++ b/publish/wwwroot/icons/icon-placeholder.svg.br @@ -0,0 +1,2 @@ +n 3!qSlrZuz*ds=S0E қcbub`@0pͼӸɢA>/ !ϔ_HqT[l+ٟxe0d\$qBw:@%vkT +!?p기JPߛTwo_so&[4Ig7J(Y)q .k-2Q0vG+*bp;H~3g1:"mɈ2`#S$m`O>Ϝ$$%RlBoX˔,Cڑ`6BOV?%͝Z('uV5f,^ 84i6:T&t?l$Ε>0csWh \ No newline at end of file diff --git a/publish/wwwroot/icons/icon-placeholder.svg.gz b/publish/wwwroot/icons/icon-placeholder.svg.gz new file mode 100644 index 0000000..42b0d35 Binary files /dev/null and b/publish/wwwroot/icons/icon-placeholder.svg.gz differ diff --git a/publish/wwwroot/js/holographic-effects.js b/publish/wwwroot/js/holographic-effects.js new file mode 100644 index 0000000..9e1d3c0 --- /dev/null +++ b/publish/wwwroot/js/holographic-effects.js @@ -0,0 +1,537 @@ +// 🤖 Holographic Tech Robot Effects System 🤖 +// Advanced pixel-perfect holographic animations and tech aesthetics + +class HolographicEffectsSystem { + constructor() { + this.isInitialized = false; + this.effectsActive = true; + this.dataStreams = []; + this.glitchElements = []; + this.init(); + } + + init() { + if (this.isInitialized) return; + + console.log('🤖 Initializing Holographic Effects System...'); + + // Initialize effects when DOM is ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => this.setupEffects()); + } else { + this.setupEffects(); + } + + this.isInitialized = true; + } + + setupEffects() { + // this.createDataStreamBackground(); // Removed + // this.setupHolographicBorders(); // Removed + this.initializeGlitchEffects(); + this.createParticleSystem(); + this.setupTechScanlines(); + this.initializeRobotAnimations(); + // this.setupInteractiveHovers(); // Removed + } + + // Create animated data streams in background + createDataStreamBackground() { + const dataStreamContainer = document.createElement('div'); + dataStreamContainer.className = 'data-stream-container'; + dataStreamContainer.style.cssText = ` + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + pointer-events: none; + z-index: -1; + overflow: hidden; + `; + + // Create multiple data streams + for (let i = 0; i < 8; i++) { + setTimeout(() => { + this.createDataStream(dataStreamContainer, i); + }, i * 500); + } + + document.body.appendChild(dataStreamContainer); + } + + createDataStream(container, index) { + const stream = document.createElement('div'); + stream.className = 'data-stream'; + + const left = Math.random() * 100; + const animationDuration = 3 + Math.random() * 4; + const delay = Math.random() * 2; + + stream.style.cssText = ` + position: absolute; + left: ${left}%; + width: 2px; + height: 100px; + background: linear-gradient(to bottom, + transparent 0%, + rgba(0, 255, 255, 0.8) 20%, + rgba(138, 43, 226, 0.6) 80%, + transparent 100%); + animation: dataStreamFlow ${animationDuration}s linear infinite; + animation-delay: ${delay}s; + box-shadow: 0 0 10px rgba(0, 255, 255, 0.5); + `; + + // Add random tech symbols + const symbols = ['01', '10', '11', '00', 'Ω', '∆', '∇', '◊', '◈']; + const symbol = document.createElement('span'); + symbol.textContent = symbols[Math.floor(Math.random() * symbols.length)]; + symbol.style.cssText = ` + position: absolute; + top: 10px; + left: -5px; + color: rgba(0, 255, 255, 0.8); + font-size: 8px; + font-family: 'Courier New', monospace; + text-shadow: 0 0 5px rgba(0, 255, 255, 0.8); + `; + + stream.appendChild(symbol); + container.appendChild(stream); + + // Remove and recreate after animation + setTimeout(() => { + if (stream.parentNode) { + stream.parentNode.removeChild(stream); + } + if (this.effectsActive) { + this.createDataStream(container, index); + } + }, (animationDuration + delay) * 1000); + } + + // Setup holographic borders for cards + setupHolographicBorders() { + const style = document.createElement('style'); + style.textContent = ` + @keyframes dataStreamFlow { + 0% { + transform: translateY(-100px); + opacity: 0; + } + 10% { opacity: 1; } + 90% { opacity: 1; } + 100% { + transform: translateY(calc(100vh + 100px)); + opacity: 0; + } + } + + @keyframes holographicBorderShift { + 0% { border-image-source: linear-gradient(45deg, #8A2BE2, #9932CC, #DA70D6, #FF00FF); } + 25% { border-image-source: linear-gradient(90deg, #00FFFF, #8A2BE2, #9932CC, #DA70D6); } + 50% { border-image-source: linear-gradient(135deg, #FF00FF, #00FFFF, #8A2BE2, #9932CC); } + 75% { border-image-source: linear-gradient(180deg, #DA70D6, #FF00FF, #00FFFF, #8A2BE2); } + 100% { border-image-source: linear-gradient(45deg, #8A2BE2, #9932CC, #DA70D6, #FF00FF); } + } + `; + document.head.appendChild(style); + + // Apply to cards + setTimeout(() => { + const cards = document.querySelectorAll('.rz-card, .card, .mobile-card'); + cards.forEach(card => { + card.style.borderImage = 'linear-gradient(45deg, #8A2BE2, #9932CC, #DA70D6, #FF00FF) 1'; + card.style.animation = 'holographicBorderShift 4s ease-in-out infinite'; + }); + }, 100); + } + + // Initialize glitch effects on hover + initializeGlitchEffects() { + const glitchStyle = document.createElement('style'); + glitchStyle.textContent = ` + .tech-glitch { + position: relative; + } + + .tech-glitch::before, + .tech-glitch::after { + content: attr(data-text); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + transition: opacity 0.3s; + } + + .tech-glitch::before { + color: #FF00FF; + animation: glitch1 0.5s infinite; + clip: rect(0, 900px, 0, 0); + } + + .tech-glitch::after { + color: #00FFFF; + animation: glitch2 0.5s infinite; + clip: rect(0, 900px, 0, 0); + } + + .tech-glitch:hover::before, + .tech-glitch:hover::after { + opacity: 0.8; + } + + @keyframes glitch1 { + 0% { clip: rect(42px, 9999px, 44px, 0); } + 20% { clip: rect(12px, 9999px, 59px, 0); } + 40% { clip: rect(63px, 9999px, 34px, 0); } + 60% { clip: rect(18px, 9999px, 76px, 0); } + 80% { clip: rect(54px, 9999px, 91px, 0); } + 100% { clip: rect(25px, 9999px, 38px, 0); } + } + + @keyframes glitch2 { + 0% { clip: rect(65px, 9999px, 23px, 0); } + 20% { clip: rect(87px, 9999px, 45px, 0); } + 40% { clip: rect(29px, 9999px, 78px, 0); } + 60% { clip: rect(52px, 9999px, 31px, 0); } + 80% { clip: rect(15px, 9999px, 89px, 0); } + 100% { clip: rect(73px, 9999px, 16px, 0); } + } + `; + document.head.appendChild(glitchStyle); + + // Apply to headings + setTimeout(() => { + const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); + headings.forEach(heading => { + heading.classList.add('tech-glitch'); + heading.setAttribute('data-text', heading.textContent); + }); + }, 200); + } + + // Create particle system + createParticleSystem() { + const particleContainer = document.createElement('div'); + particleContainer.className = 'particle-system'; + particleContainer.style.cssText = ` + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + pointer-events: none; + z-index: -2; + overflow: hidden; + `; + + // Create floating particles + for (let i = 0; i < 20; i++) { + setTimeout(() => { + this.createParticle(particleContainer); + }, i * 100); + } + + document.body.appendChild(particleContainer); + } + + createParticle(container) { + const particle = document.createElement('div'); + const size = Math.random() * 3 + 1; + const x = Math.random() * window.innerWidth; + const y = Math.random() * window.innerHeight; + const duration = Math.random() * 20 + 10; + + particle.style.cssText = ` + position: absolute; + width: ${size}px; + height: ${size}px; + background: radial-gradient(circle, rgba(138, 43, 226, 0.8) 0%, transparent 70%); + left: ${x}px; + top: ${y}px; + border-radius: 50%; + animation: particleFloat ${duration}s linear infinite; + box-shadow: 0 0 ${size * 3}px rgba(138, 43, 226, 0.6); + `; + + const floatDistance = Math.random() * 100 + 50; + const angle = Math.random() * 360; + + particle.style.setProperty('--float-x', `${Math.cos(angle * Math.PI / 180) * floatDistance}px`); + particle.style.setProperty('--float-y', `${Math.sin(angle * Math.PI / 180) * floatDistance}px`); + + container.appendChild(particle); + + // Remove after animation + setTimeout(() => { + if (particle.parentNode) { + particle.parentNode.removeChild(particle); + } + if (this.effectsActive) { + this.createParticle(container); + } + }, duration * 1000); + } + + // Setup tech scanlines + setupTechScanlines() { + const scanlineStyle = document.createElement('style'); + scanlineStyle.textContent = ` + @keyframes particleFloat { + 0%, 100% { + transform: translate(0, 0) scale(1); + opacity: 0.3; + } + 50% { + transform: translate(var(--float-x), var(--float-y)) scale(1.5); + opacity: 0.8; + } + } + + .tech-scanlines::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient( + 0deg, + transparent, + transparent 2px, + rgba(0, 255, 255, 0.03) 2px, + rgba(0, 255, 255, 0.03) 4px + ); + pointer-events: none; + animation: scanlineMove 2s linear infinite; + } + + @keyframes scanlineMove { + 0% { transform: translateY(0); } + 100% { transform: translateY(4px); } + } + `; + document.head.appendChild(scanlineStyle); + + // Apply to main containers + setTimeout(() => { + const containers = document.querySelectorAll('.container, .container-fluid, .main-content'); + containers.forEach(container => { + container.classList.add('tech-scanlines'); + container.style.position = 'relative'; + }); + }, 300); + } + + // Initialize robot-style animations + initializeRobotAnimations() { + const robotStyle = document.createElement('style'); + robotStyle.textContent = ` + .robot-pulse { + animation: robotPulse 3s ease-in-out infinite; + } + + .robot-scan { + position: relative; + overflow: hidden; + } + + .robot-scan::after { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, + transparent 40%, + rgba(0, 255, 255, 0.1) 50%, + transparent 60%); + animation: robotScan 4s ease-in-out infinite; + } + + @keyframes robotPulse { + 0%, 100% { + transform: scale(1); + box-shadow: 0 0 20px rgba(138, 43, 226, 0.3); + } + 50% { + transform: scale(1.02); + box-shadow: 0 0 40px rgba(138, 43, 226, 0.8); + } + } + + @keyframes robotScan { + 0% { transform: translate(-100%, -100%) rotate(0deg); } + 100% { transform: translate(100%, 100%) rotate(360deg); } + } + + .tech-loading { + position: relative; + } + + .tech-loading::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(45deg, #8A2BE2, #00FFFF, #8A2BE2); + background-size: 200% 200%; + border-radius: inherit; + z-index: -1; + animation: techLoadingPulse 2s ease-in-out infinite; + } + + @keyframes techLoadingPulse { + 0%, 100% { + opacity: 0.3; + background-position: 0% 50%; + } + 50% { + opacity: 0.8; + background-position: 100% 50%; + } + } + `; + document.head.appendChild(robotStyle); + + // Apply to cards only (removed button glow effects) + setTimeout(() => { + // const buttons = document.querySelectorAll('.rz-button, .btn'); + // buttons.forEach(button => { + // button.classList.add('robot-pulse'); + // }); + + const cards = document.querySelectorAll('.rz-card, .card'); + cards.forEach(card => { + card.classList.add('robot-scan'); + }); + }, 400); + } + + // Setup interactive hover effects + setupInteractiveHovers() { + setTimeout(() => { + // Add hover effects to interactive elements + const interactiveElements = document.querySelectorAll('button, .rz-button, .btn, a, .card'); + + interactiveElements.forEach(element => { + element.addEventListener('mouseenter', (e) => { + this.createHoverEffect(e.target); + }); + + element.addEventListener('mouseleave', (e) => { + this.removeHoverEffect(e.target); + }); + }); + }, 500); + } + + createHoverEffect(element) { + // Create ripple effect + const ripple = document.createElement('div'); + ripple.style.cssText = ` + position: absolute; + border-radius: 50%; + background: radial-gradient(circle, rgba(0, 255, 255, 0.6) 0%, transparent 70%); + transform: scale(0); + animation: rippleEffect 0.6s linear; + pointer-events: none; + z-index: 1000; + `; + + const rect = element.getBoundingClientRect(); + const size = Math.max(rect.width, rect.height); + ripple.style.width = ripple.style.height = size + 'px'; + ripple.style.left = (rect.left + rect.width / 2 - size / 2) + 'px'; + ripple.style.top = (rect.top + rect.height / 2 - size / 2) + 'px'; + + document.body.appendChild(ripple); + + // Remove after animation + setTimeout(() => { + if (ripple.parentNode) { + ripple.parentNode.removeChild(ripple); + } + }, 600); + + // Add tech glow to element + element.style.transition = 'all 0.3s ease'; + element.style.boxShadow = '0 0 30px rgba(0, 255, 255, 0.8), inset 0 0 20px rgba(138, 43, 226, 0.4)'; + element.style.transform = 'scale(1.05)'; + + if (!document.getElementById('ripple-style')) { + const rippleStyle = document.createElement('style'); + rippleStyle.id = 'ripple-style'; + rippleStyle.textContent = ` + @keyframes rippleEffect { + to { + transform: scale(4); + opacity: 0; + } + } + `; + document.head.appendChild(rippleStyle); + } + } + + removeHoverEffect(element) { + element.style.boxShadow = ''; + element.style.transform = ''; + } + + // Toggle effects on/off + toggleEffects() { + this.effectsActive = !this.effectsActive; + + if (!this.effectsActive) { + // Remove all effect containers + const effectContainers = document.querySelectorAll('.data-stream-container, .particle-system'); + effectContainers.forEach(container => { + if (container.parentNode) { + container.parentNode.removeChild(container); + } + }); + } else { + // Restart effects + this.setupEffects(); + } + + console.log(`🤖 Holographic effects ${this.effectsActive ? 'enabled' : 'disabled'}`); + } + + // Performance monitoring + checkPerformance() { + const start = performance.now(); + setTimeout(() => { + const delta = performance.now() - start; + if (delta > 50) { // If frame time is too long + console.warn('🤖 Performance warning: Consider reducing effects'); + } + }, 0); + } +} + +// Initialize the system +const holographicSystem = new HolographicEffectsSystem(); + +// Expose control functions globally +window.toggleHolographicEffects = () => holographicSystem.toggleEffects(); +window.holographicSystem = holographicSystem; + +// Add keyboard shortcut (Ctrl+H) to toggle effects +document.addEventListener('keydown', (e) => { + if (e.ctrlKey && e.key === 'h') { + e.preventDefault(); + holographicSystem.toggleEffects(); + } +}); + +console.log('🤖 Holographic Tech System loaded! Press Ctrl+H to toggle effects.'); \ No newline at end of file diff --git a/publish/wwwroot/js/holographic-effects.js.br b/publish/wwwroot/js/holographic-effects.js.br new file mode 100644 index 0000000..479f37f Binary files /dev/null and b/publish/wwwroot/js/holographic-effects.js.br differ diff --git a/publish/wwwroot/js/holographic-effects.js.gz b/publish/wwwroot/js/holographic-effects.js.gz new file mode 100644 index 0000000..d900881 Binary files /dev/null and b/publish/wwwroot/js/holographic-effects.js.gz differ diff --git a/publish/wwwroot/js/modern-mobile.js b/publish/wwwroot/js/modern-mobile.js new file mode 100644 index 0000000..ead206a --- /dev/null +++ b/publish/wwwroot/js/modern-mobile.js @@ -0,0 +1,221 @@ +// Modern Mobile Enhancements +// Clean, simple mobile-friendly functionality + +class ModernMobile { + constructor() { + this.init(); + } + + init() { + this.setupMobileTableLabels(); + this.setupResponsiveNavigation(); + this.setupFormEnhancements(); + this.setupSmoothInteractions(); + } + + // Add data labels for mobile table stacking + setupMobileTableLabels() { + const tables = document.querySelectorAll('.table'); + + tables.forEach(table => { + const headers = Array.from(table.querySelectorAll('thead th')).map(th => th.textContent.trim()); + const rows = table.querySelectorAll('tbody tr'); + + rows.forEach(row => { + const cells = row.querySelectorAll('td'); + cells.forEach((cell, index) => { + if (headers[index]) { + cell.setAttribute('data-label', headers[index]); + } + }); + }); + }); + } + + // Enhanced mobile navigation + setupResponsiveNavigation() { + const navbar = document.querySelector('.navbar'); + const toggler = document.querySelector('.navbar-toggler'); + const collapse = document.querySelector('.navbar-collapse'); + + if (toggler && collapse) { + // Smooth collapse animation + toggler.addEventListener('click', () => { + collapse.classList.toggle('show'); + }); + + // Close menu when clicking outside + document.addEventListener('click', (e) => { + if (!navbar.contains(e.target) && collapse.classList.contains('show')) { + collapse.classList.remove('show'); + } + }); + } + } + + // Form enhancements for better mobile UX + setupFormEnhancements() { + // Auto-focus first input on desktop + if (window.innerWidth > 768) { + const firstInput = document.querySelector('.form-control:not([readonly]):not([disabled])'); + if (firstInput) { + firstInput.focus(); + } + } + + // Enhanced form validation feedback + const forms = document.querySelectorAll('form'); + forms.forEach(form => { + form.addEventListener('submit', (e) => { + // Skip validation for file upload forms + if (form.enctype === 'multipart/form-data') { + console.log('Mobile: Skipping validation for file upload form'); + return; + } + + const invalidInputs = form.querySelectorAll(':invalid'); + if (invalidInputs.length > 0) { + e.preventDefault(); + console.log('Mobile: Form validation failed, focusing on first invalid input'); + invalidInputs[0].focus(); + invalidInputs[0].scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + }); + }); + + // Floating labels effect + const inputs = document.querySelectorAll('.form-control, .form-select'); + inputs.forEach(input => { + if (input.value) { + input.parentElement.classList.add('has-value'); + } + + input.addEventListener('blur', () => { + if (input.value) { + input.parentElement.classList.add('has-value'); + } else { + input.parentElement.classList.remove('has-value'); + } + }); + }); + } + + // Smooth interactions and feedback + setupSmoothInteractions() { + // Button click feedback + const buttons = document.querySelectorAll('.btn'); + buttons.forEach(button => { + button.addEventListener('click', (e) => { + if (!button.disabled) { + button.style.transform = 'scale(0.95)'; + setTimeout(() => { + button.style.transform = ''; + }, 100); + } + }); + }); + + // Card hover enhancement + const cards = document.querySelectorAll('.card'); + cards.forEach(card => { + card.addEventListener('mouseenter', () => { + card.style.transform = 'translateY(-2px)'; + }); + + card.addEventListener('mouseleave', () => { + card.style.transform = ''; + }); + }); + + // Smooth scroll for anchor links + const anchorLinks = document.querySelectorAll('a[href^="#"]'); + anchorLinks.forEach(link => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const target = document.querySelector(link.getAttribute('href')); + if (target) { + target.scrollIntoView({ behavior: 'smooth' }); + } + }); + }); + } + + // Show toast notification + showToast(message, type = 'info') { + const toastContainer = document.getElementById('toast-container') || this.createToastContainer(); + + const toast = document.createElement('div'); + toast.className = `alert alert-${type} alert-dismissible fade show`; + toast.style.cssText = ` + margin-bottom: 0.5rem; + animation: slideInRight 0.3s ease; + `; + + toast.innerHTML = ` + ${message} + + `; + + toastContainer.appendChild(toast); + + // Auto-remove after 4 seconds + setTimeout(() => { + toast.classList.add('fade'); + setTimeout(() => { + if (toast.parentNode) { + toast.parentNode.removeChild(toast); + } + }, 150); + }, 4000); + + // Manual close + const closeBtn = toast.querySelector('.btn-close'); + closeBtn.addEventListener('click', () => { + toast.classList.add('fade'); + setTimeout(() => { + if (toast.parentNode) { + toast.parentNode.removeChild(toast); + } + }, 150); + }); + } + + createToastContainer() { + const container = document.createElement('div'); + container.id = 'toast-container'; + container.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + z-index: 1050; + max-width: 300px; + `; + document.body.appendChild(container); + return container; + } +} + +// CSS for toast animations +const style = document.createElement('style'); +style.textContent = ` + @keyframes slideInRight { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } + } + + .fade { + opacity: 0 !important; + transition: opacity 0.15s linear !important; + } +`; +document.head.appendChild(style); + +// Initialize +const modernMobile = new ModernMobile(); +window.modernMobile = modernMobile; \ No newline at end of file diff --git a/publish/wwwroot/js/modern-mobile.js.br b/publish/wwwroot/js/modern-mobile.js.br new file mode 100644 index 0000000..2b1adcf Binary files /dev/null and b/publish/wwwroot/js/modern-mobile.js.br differ diff --git a/publish/wwwroot/js/modern-mobile.js.gz b/publish/wwwroot/js/modern-mobile.js.gz new file mode 100644 index 0000000..4357db2 Binary files /dev/null and b/publish/wwwroot/js/modern-mobile.js.gz differ diff --git a/publish/wwwroot/js/pwa.js b/publish/wwwroot/js/pwa.js new file mode 100644 index 0000000..dcb5606 --- /dev/null +++ b/publish/wwwroot/js/pwa.js @@ -0,0 +1,537 @@ +// Progressive Web App functionality +// Handles service worker registration and PWA features + +class PWAManager { + constructor() { + this.swRegistration = null; + this.vapidPublicKey = null; + this.pushSubscription = null; + this.init(); + } + + async init() { + console.log('PWA: Initializing PWA Manager...'); + + if ('serviceWorker' in navigator) { + try { + this.swRegistration = await navigator.serviceWorker.register('/sw.js'); + console.log('SW: Service Worker registered successfully'); + + // Listen for updates + this.swRegistration.addEventListener('updatefound', () => { + console.log('SW: New version available'); + this.showUpdateNotification(); + }); + + } catch (error) { + console.log('SW: Service Worker registration failed:', error); + } + } + + // Setup PWA install prompt + this.setupInstallPrompt(); + + // Setup notifications (if enabled) + this.setupNotifications(); + + // Setup push notifications + this.setupPushNotifications(); + + // Show manual install option after 5 seconds if no prompt appeared and app not installed + setTimeout(() => { + if (!document.getElementById('pwa-install-btn') && !this.isInstalled()) { + console.log('PWA: No install prompt appeared, showing manual install guide'); + this.showManualInstallButton(); + } + }, 5000); + } + + setupInstallPrompt() { + let deferredPrompt; + + window.addEventListener('beforeinstallprompt', (e) => { + console.log('PWA: beforeinstallprompt event fired'); + // Prevent Chrome 67 and earlier from automatically showing the prompt + e.preventDefault(); + deferredPrompt = e; + + // Show custom install button + this.showInstallButton(deferredPrompt); + }); + + window.addEventListener('appinstalled', () => { + console.log('PWA: App was installed'); + this.hideInstallButton(); + }); + + // Debug: Check if app is already installed + if (this.isInstalled()) { + console.log('PWA: App is already installed (standalone mode)'); + // Hide any existing install buttons + this.hideInstallButton(); + } else { + console.log('PWA: App is not installed, waiting for install prompt...'); + console.log('PWA: Current URL:', window.location.href); + console.log('PWA: Display mode:', window.matchMedia('(display-mode: standalone)').matches ? 'standalone' : 'browser'); + console.log('PWA: User agent:', navigator.userAgent); + } + + // Periodically check if app becomes installed (for cases where user installs via browser menu) + setInterval(() => { + if (this.isInstalled()) { + this.hideInstallButton(); + } + }, 2000); + } + + showInstallButton(deferredPrompt) { + // Don't show install button if app is already installed + if (this.isInstalled()) { + console.log('PWA: App already installed, skipping install button'); + return; + } + + // Create install button + const installBtn = document.createElement('button'); + installBtn.id = 'pwa-install-btn'; + installBtn.className = 'btn btn-primary btn-sm'; + installBtn.innerHTML = ' Install App'; + installBtn.style.cssText = ` + position: fixed; + bottom: 20px; + right: 20px; + z-index: 1000; + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); + `; + + installBtn.addEventListener('click', async () => { + if (deferredPrompt) { + deferredPrompt.prompt(); + const { outcome } = await deferredPrompt.userChoice; + console.log('PWA: User response to install prompt:', outcome); + deferredPrompt = null; + this.hideInstallButton(); + } + }); + + document.body.appendChild(installBtn); + } + + hideInstallButton() { + const installBtn = document.getElementById('pwa-install-btn'); + if (installBtn) { + installBtn.remove(); + } + } + + showUpdateNotification() { + // Show update available notification + const notification = document.createElement('div'); + notification.className = 'alert alert-info alert-dismissible'; + notification.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + z-index: 1050; + max-width: 300px; + `; + + notification.innerHTML = ` + Update Available!
+ A new version of the app is ready. + + + `; + + document.body.appendChild(notification); + + // Handle update + document.getElementById('update-btn').addEventListener('click', () => { + if (this.swRegistration && this.swRegistration.waiting) { + this.swRegistration.waiting.postMessage({ type: 'SKIP_WAITING' }); + window.location.reload(); + } + }); + } + + async setupNotifications() { + // Check if notifications are supported and get permission + if ('Notification' in window) { + const permission = await this.requestNotificationPermission(); + console.log('Notifications permission:', permission); + } + } + + async requestNotificationPermission() { + if (Notification.permission === 'default') { + // Only request permission when user interacts with a relevant feature + // For now, just return the current status + return Notification.permission; + } + return Notification.permission; + } + + // Show notification (if permission granted) + showNotification(title, options = {}) { + if (Notification.permission === 'granted') { + const notification = new Notification(title, { + icon: '/icons/icon-192x192.png', + badge: '/icons/icon-72x72.png', + tag: 'littleshop-admin', + ...options + }); + + // Auto-close after 5 seconds + setTimeout(() => { + notification.close(); + }, 5000); + + return notification; + } + } + + // Show manual install button for browsers that don't auto-prompt + showManualInstallButton() { + // Don't show install button if app is already installed + if (this.isInstalled()) { + console.log('PWA: App already installed, skipping manual install button'); + return; + } + + console.log('PWA: Showing manual install button'); + const installBtn = document.createElement('button'); + installBtn.id = 'pwa-install-btn'; + installBtn.className = 'btn btn-primary btn-sm'; + installBtn.innerHTML = ' Install as App'; + installBtn.style.cssText = ` + position: fixed; + bottom: 20px; + right: 20px; + z-index: 1000; + box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); + `; + + installBtn.addEventListener('click', () => { + const isChrome = navigator.userAgent.includes('Chrome'); + const isEdge = navigator.userAgent.includes('Edge'); + const isFirefox = navigator.userAgent.includes('Firefox'); + + let instructions = 'To install this app:\\n\\n'; + + if (isChrome || isEdge) { + instructions += '1. Look for the install icon (⬇️) in the address bar\\n'; + instructions += '2. Or click the browser menu (⋮) → "Install LittleShop Admin"\\n'; + instructions += '3. Or check if there\'s an "Install app" option in the browser menu'; + } else if (isFirefox) { + instructions += '1. Firefox doesn\'t support PWA installation yet\\n'; + instructions += '2. You can bookmark this page for easy access\\n'; + instructions += '3. Or use Chrome/Edge for the full PWA experience'; + } else { + instructions += '1. Look for an install or "Add to Home Screen" option\\n'; + instructions += '2. Check your browser menu for app installation\\n'; + instructions += '3. Or bookmark this page for quick access'; + } + + alert(instructions); + }); + + document.body.appendChild(installBtn); + } + + // Check if app is installed + isInstalled() { + return window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone === true; + } + + // Setup push notifications + async setupPushNotifications() { + if (!('serviceWorker' in navigator) || !('PushManager' in window)) { + console.log('PWA: Push notifications not supported'); + return; + } + + try { + // Get VAPID public key from server + await this.getVapidPublicKey(); + + // Check if user is already subscribed + await this.checkPushSubscription(); + + // Simple logic: only show prompt if user is not subscribed + if (!this.pushSubscription) { + // Check if we've already asked this session + if (!sessionStorage.getItem('pushNotificationPromptShown')) { + this.showPushNotificationSetup(); + sessionStorage.setItem('pushNotificationPromptShown', 'true'); + } + } else { + console.log('PWA: User already subscribed to push notifications'); + } + + } catch (error) { + console.error('PWA: Failed to setup push notifications:', error); + } + } + + async getVapidPublicKey() { + try { + const response = await fetch('/api/push/vapid-key'); + if (response.ok) { + const data = await response.json(); + this.vapidPublicKey = data.publicKey; + console.log('PWA: VAPID public key retrieved'); + } else { + throw new Error('Failed to get VAPID public key'); + } + } catch (error) { + console.error('PWA: Error getting VAPID public key:', error); + throw error; + } + } + + async checkPushSubscription() { + if (!this.swRegistration) { + return; + } + + try { + this.pushSubscription = await this.swRegistration.pushManager.getSubscription(); + if (this.pushSubscription) { + console.log('PWA: User has active push subscription'); + } else { + console.log('PWA: User is not subscribed to push notifications'); + } + } catch (error) { + console.error('PWA: Error checking push subscription:', error); + } + } + + async subscribeToPushNotifications() { + if (!this.swRegistration || !this.vapidPublicKey) { + throw new Error('Service worker or VAPID key not available'); + } + + try { + // Check current permission status + if (Notification.permission === 'denied') { + throw new Error('Notification permission was denied. Please enable notifications in your browser settings.'); + } + + // Request notification permission if not already granted + let permission = Notification.permission; + if (permission === 'default') { + permission = await Notification.requestPermission(); + } + + if (permission !== 'granted') { + throw new Error('Notification permission is required for push notifications. Please allow notifications and try again.'); + } + + // Subscribe to push notifications + const subscription = await this.swRegistration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: this.urlBase64ToUint8Array(this.vapidPublicKey) + }); + + // Send subscription to server with timeout + console.log('PWA: Sending subscription to server...'); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout + + const response = await fetch('/api/push/subscribe', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + endpoint: subscription.endpoint, + p256dh: btoa(String.fromCharCode(...new Uint8Array(subscription.getKey('p256dh')))), + auth: btoa(String.fromCharCode(...new Uint8Array(subscription.getKey('auth')))) + }), + credentials: 'same-origin', + signal: controller.signal + }); + + clearTimeout(timeoutId); + console.log('PWA: Server response received:', response.status, response.statusText); + + if (response.ok) { + this.pushSubscription = subscription; + console.log('PWA: Successfully subscribed to push notifications'); + this.hidePushNotificationSetup(); + return true; + } else { + throw new Error('Failed to save push subscription to server'); + } + } catch (error) { + console.error('PWA: Failed to subscribe to push notifications:', error); + throw error; + } + } + + async unsubscribeFromPushNotifications() { + if (!this.pushSubscription) { + return true; + } + + try { + // Unsubscribe from push manager + await this.pushSubscription.unsubscribe(); + + // Notify server + await fetch('/api/push/unsubscribe', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + endpoint: this.pushSubscription.endpoint + }), + credentials: 'same-origin' + }); + + this.pushSubscription = null; + console.log('PWA: Successfully unsubscribed from push notifications'); + return true; + } catch (error) { + console.error('PWA: Failed to unsubscribe from push notifications:', error); + throw error; + } + } + + showPushNotificationSetup() { + // Check if setup UI already exists + if (document.getElementById('push-notification-setup')) { + return; + } + + const setupDiv = document.createElement('div'); + setupDiv.id = 'push-notification-setup'; + setupDiv.className = 'alert alert-info alert-dismissible'; + setupDiv.style.cssText = ` + position: fixed; + top: 80px; + right: 20px; + z-index: 1050; + max-width: 350px; + `; + + setupDiv.innerHTML = ` +
+ +
+ Push Notifications
+ Get notified of new orders and updates +
+
+ +
+
+ + `; + + document.body.appendChild(setupDiv); + + // Add event listener for subscribe button + const subscribeBtn = document.getElementById('subscribe-push-btn'); + + if (subscribeBtn) { + subscribeBtn.addEventListener('click', async () => { + subscribeBtn.disabled = true; + subscribeBtn.innerHTML = 'Subscribing...'; + + try { + // Add timeout to prevent infinite hanging + const subscriptionPromise = this.subscribeToPushNotifications(); + const timeoutPromise = new Promise((_, reject) => + setTimeout(() => reject(new Error('Push subscription timed out after 15 seconds. This may be due to network connectivity or browser push service issues.')), 15000) + ); + + await Promise.race([subscriptionPromise, timeoutPromise]); + + this.showNotification('Push notifications enabled!', { + body: 'You will now receive notifications for new orders and updates.' + }); + } catch (error) { + console.error('PWA: Push subscription failed:', error); + + // Provide user-friendly error messages + let userMessage = error.message; + if (error.message.includes('permission')) { + userMessage = 'Please allow notifications when your browser asks, then try again.'; + } else if (error.message.includes('timeout')) { + userMessage = 'Push notification setup timed out. This may be due to network or browser issues. Please try again or check your internet connection.'; + } + + alert('Failed to enable push notifications: ' + userMessage); + subscribeBtn.disabled = false; + subscribeBtn.innerHTML = 'Enable'; + } + }); + } + } + + hidePushNotificationSetup() { + const setupDiv = document.getElementById('push-notification-setup'); + if (setupDiv) { + setupDiv.remove(); + console.log('PWA: Push notification setup hidden'); + } + } + + async sendTestNotification() { + try { + const response = await fetch('/api/push/test', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + title: 'Test Notification', + body: 'This is a test push notification from LittleShop Admin!' + }), + credentials: 'same-origin' + }); + + const result = await response.json(); + if (response.ok) { + console.log('PWA: Test notification sent successfully'); + return true; + } else { + throw new Error(result.error || 'Failed to send test notification'); + } + } catch (error) { + console.error('PWA: Failed to send test notification:', error); + throw error; + } + } + + // Helper function to convert VAPID key + urlBase64ToUint8Array(base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + .replace(/\-/g, '+') + .replace(/_/g, '/'); + + const rawData = window.atob(base64); + const outputArray = new Uint8Array(rawData.length); + + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; + } +} + +// Initialize PWA Manager +const pwaManager = new PWAManager(); +window.pwaManager = pwaManager; + +// Expose notification functions globally +window.showNotification = (title, options) => pwaManager.showNotification(title, options); +window.sendTestPushNotification = () => pwaManager.sendTestNotification(); +window.subscribeToPushNotifications = () => pwaManager.subscribeToPushNotifications(); +window.unsubscribeFromPushNotifications = () => pwaManager.unsubscribeFromPushNotifications(); \ No newline at end of file diff --git a/publish/wwwroot/js/pwa.js.br b/publish/wwwroot/js/pwa.js.br new file mode 100644 index 0000000..eb64f82 Binary files /dev/null and b/publish/wwwroot/js/pwa.js.br differ diff --git a/publish/wwwroot/js/pwa.js.gz b/publish/wwwroot/js/pwa.js.gz new file mode 100644 index 0000000..b00d4c6 Binary files /dev/null and b/publish/wwwroot/js/pwa.js.gz differ diff --git a/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css b/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css new file mode 100644 index 0000000..7d93a97 --- /dev/null +++ b/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css @@ -0,0 +1,2018 @@ +@font-face { + font-display: block; + font-family: "bootstrap-icons"; + src: url("./fonts/bootstrap-icons.woff2?2ab2cbbe07fcebb53bdaa7313bb290f2") format("woff2"), +url("./fonts/bootstrap-icons.woff?2ab2cbbe07fcebb53bdaa7313bb290f2") format("woff"); +} + +.bi::before, +[class^="bi-"]::before, +[class*=" bi-"]::before { + display: inline-block; + font-family: bootstrap-icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: -.125em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bi-123::before { content: "\f67f"; } +.bi-alarm-fill::before { content: "\f101"; } +.bi-alarm::before { content: "\f102"; } +.bi-align-bottom::before { content: "\f103"; } +.bi-align-center::before { content: "\f104"; } +.bi-align-end::before { content: "\f105"; } +.bi-align-middle::before { content: "\f106"; } +.bi-align-start::before { content: "\f107"; } +.bi-align-top::before { content: "\f108"; } +.bi-alt::before { content: "\f109"; } +.bi-app-indicator::before { content: "\f10a"; } +.bi-app::before { content: "\f10b"; } +.bi-archive-fill::before { content: "\f10c"; } +.bi-archive::before { content: "\f10d"; } +.bi-arrow-90deg-down::before { content: "\f10e"; } +.bi-arrow-90deg-left::before { content: "\f10f"; } +.bi-arrow-90deg-right::before { content: "\f110"; } +.bi-arrow-90deg-up::before { content: "\f111"; } +.bi-arrow-bar-down::before { content: "\f112"; } +.bi-arrow-bar-left::before { content: "\f113"; } +.bi-arrow-bar-right::before { content: "\f114"; } +.bi-arrow-bar-up::before { content: "\f115"; } +.bi-arrow-clockwise::before { content: "\f116"; } +.bi-arrow-counterclockwise::before { content: "\f117"; } +.bi-arrow-down-circle-fill::before { content: "\f118"; } +.bi-arrow-down-circle::before { content: "\f119"; } +.bi-arrow-down-left-circle-fill::before { content: "\f11a"; } +.bi-arrow-down-left-circle::before { content: "\f11b"; } +.bi-arrow-down-left-square-fill::before { content: "\f11c"; } +.bi-arrow-down-left-square::before { content: "\f11d"; } +.bi-arrow-down-left::before { content: "\f11e"; } +.bi-arrow-down-right-circle-fill::before { content: "\f11f"; } +.bi-arrow-down-right-circle::before { content: "\f120"; } +.bi-arrow-down-right-square-fill::before { content: "\f121"; } +.bi-arrow-down-right-square::before { content: "\f122"; } +.bi-arrow-down-right::before { content: "\f123"; } +.bi-arrow-down-short::before { content: "\f124"; } +.bi-arrow-down-square-fill::before { content: "\f125"; } +.bi-arrow-down-square::before { content: "\f126"; } +.bi-arrow-down-up::before { content: "\f127"; } +.bi-arrow-down::before { content: "\f128"; } +.bi-arrow-left-circle-fill::before { content: "\f129"; } +.bi-arrow-left-circle::before { content: "\f12a"; } +.bi-arrow-left-right::before { content: "\f12b"; } +.bi-arrow-left-short::before { content: "\f12c"; } +.bi-arrow-left-square-fill::before { content: "\f12d"; } +.bi-arrow-left-square::before { content: "\f12e"; } +.bi-arrow-left::before { content: "\f12f"; } +.bi-arrow-repeat::before { content: "\f130"; } +.bi-arrow-return-left::before { content: "\f131"; } +.bi-arrow-return-right::before { content: "\f132"; } +.bi-arrow-right-circle-fill::before { content: "\f133"; } +.bi-arrow-right-circle::before { content: "\f134"; } +.bi-arrow-right-short::before { content: "\f135"; } +.bi-arrow-right-square-fill::before { content: "\f136"; } +.bi-arrow-right-square::before { content: "\f137"; } +.bi-arrow-right::before { content: "\f138"; } +.bi-arrow-up-circle-fill::before { content: "\f139"; } +.bi-arrow-up-circle::before { content: "\f13a"; } +.bi-arrow-up-left-circle-fill::before { content: "\f13b"; } +.bi-arrow-up-left-circle::before { content: "\f13c"; } +.bi-arrow-up-left-square-fill::before { content: "\f13d"; } +.bi-arrow-up-left-square::before { content: "\f13e"; } +.bi-arrow-up-left::before { content: "\f13f"; } +.bi-arrow-up-right-circle-fill::before { content: "\f140"; } +.bi-arrow-up-right-circle::before { content: "\f141"; } +.bi-arrow-up-right-square-fill::before { content: "\f142"; } +.bi-arrow-up-right-square::before { content: "\f143"; } +.bi-arrow-up-right::before { content: "\f144"; } +.bi-arrow-up-short::before { content: "\f145"; } +.bi-arrow-up-square-fill::before { content: "\f146"; } +.bi-arrow-up-square::before { content: "\f147"; } +.bi-arrow-up::before { content: "\f148"; } +.bi-arrows-angle-contract::before { content: "\f149"; } +.bi-arrows-angle-expand::before { content: "\f14a"; } +.bi-arrows-collapse::before { content: "\f14b"; } +.bi-arrows-expand::before { content: "\f14c"; } +.bi-arrows-fullscreen::before { content: "\f14d"; } +.bi-arrows-move::before { content: "\f14e"; } +.bi-aspect-ratio-fill::before { content: "\f14f"; } +.bi-aspect-ratio::before { content: "\f150"; } +.bi-asterisk::before { content: "\f151"; } +.bi-at::before { content: "\f152"; } +.bi-award-fill::before { content: "\f153"; } +.bi-award::before { content: "\f154"; } +.bi-back::before { content: "\f155"; } +.bi-backspace-fill::before { content: "\f156"; } +.bi-backspace-reverse-fill::before { content: "\f157"; } +.bi-backspace-reverse::before { content: "\f158"; } +.bi-backspace::before { content: "\f159"; } +.bi-badge-3d-fill::before { content: "\f15a"; } +.bi-badge-3d::before { content: "\f15b"; } +.bi-badge-4k-fill::before { content: "\f15c"; } +.bi-badge-4k::before { content: "\f15d"; } +.bi-badge-8k-fill::before { content: "\f15e"; } +.bi-badge-8k::before { content: "\f15f"; } +.bi-badge-ad-fill::before { content: "\f160"; } +.bi-badge-ad::before { content: "\f161"; } +.bi-badge-ar-fill::before { content: "\f162"; } +.bi-badge-ar::before { content: "\f163"; } +.bi-badge-cc-fill::before { content: "\f164"; } +.bi-badge-cc::before { content: "\f165"; } +.bi-badge-hd-fill::before { content: "\f166"; } +.bi-badge-hd::before { content: "\f167"; } +.bi-badge-tm-fill::before { content: "\f168"; } +.bi-badge-tm::before { content: "\f169"; } +.bi-badge-vo-fill::before { content: "\f16a"; } +.bi-badge-vo::before { content: "\f16b"; } +.bi-badge-vr-fill::before { content: "\f16c"; } +.bi-badge-vr::before { content: "\f16d"; } +.bi-badge-wc-fill::before { content: "\f16e"; } +.bi-badge-wc::before { content: "\f16f"; } +.bi-bag-check-fill::before { content: "\f170"; } +.bi-bag-check::before { content: "\f171"; } +.bi-bag-dash-fill::before { content: "\f172"; } +.bi-bag-dash::before { content: "\f173"; } +.bi-bag-fill::before { content: "\f174"; } +.bi-bag-plus-fill::before { content: "\f175"; } +.bi-bag-plus::before { content: "\f176"; } +.bi-bag-x-fill::before { content: "\f177"; } +.bi-bag-x::before { content: "\f178"; } +.bi-bag::before { content: "\f179"; } +.bi-bar-chart-fill::before { content: "\f17a"; } +.bi-bar-chart-line-fill::before { content: "\f17b"; } +.bi-bar-chart-line::before { content: "\f17c"; } +.bi-bar-chart-steps::before { content: "\f17d"; } +.bi-bar-chart::before { content: "\f17e"; } +.bi-basket-fill::before { content: "\f17f"; } +.bi-basket::before { content: "\f180"; } +.bi-basket2-fill::before { content: "\f181"; } +.bi-basket2::before { content: "\f182"; } +.bi-basket3-fill::before { content: "\f183"; } +.bi-basket3::before { content: "\f184"; } +.bi-battery-charging::before { content: "\f185"; } +.bi-battery-full::before { content: "\f186"; } +.bi-battery-half::before { content: "\f187"; } +.bi-battery::before { content: "\f188"; } +.bi-bell-fill::before { content: "\f189"; } +.bi-bell::before { content: "\f18a"; } +.bi-bezier::before { content: "\f18b"; } +.bi-bezier2::before { content: "\f18c"; } +.bi-bicycle::before { content: "\f18d"; } +.bi-binoculars-fill::before { content: "\f18e"; } +.bi-binoculars::before { content: "\f18f"; } +.bi-blockquote-left::before { content: "\f190"; } +.bi-blockquote-right::before { content: "\f191"; } +.bi-book-fill::before { content: "\f192"; } +.bi-book-half::before { content: "\f193"; } +.bi-book::before { content: "\f194"; } +.bi-bookmark-check-fill::before { content: "\f195"; } +.bi-bookmark-check::before { content: "\f196"; } +.bi-bookmark-dash-fill::before { content: "\f197"; } +.bi-bookmark-dash::before { content: "\f198"; } +.bi-bookmark-fill::before { content: "\f199"; } +.bi-bookmark-heart-fill::before { content: "\f19a"; } +.bi-bookmark-heart::before { content: "\f19b"; } +.bi-bookmark-plus-fill::before { content: "\f19c"; } +.bi-bookmark-plus::before { content: "\f19d"; } +.bi-bookmark-star-fill::before { content: "\f19e"; } +.bi-bookmark-star::before { content: "\f19f"; } +.bi-bookmark-x-fill::before { content: "\f1a0"; } +.bi-bookmark-x::before { content: "\f1a1"; } +.bi-bookmark::before { content: "\f1a2"; } +.bi-bookmarks-fill::before { content: "\f1a3"; } +.bi-bookmarks::before { content: "\f1a4"; } +.bi-bookshelf::before { content: "\f1a5"; } +.bi-bootstrap-fill::before { content: "\f1a6"; } +.bi-bootstrap-reboot::before { content: "\f1a7"; } +.bi-bootstrap::before { content: "\f1a8"; } +.bi-border-all::before { content: "\f1a9"; } +.bi-border-bottom::before { content: "\f1aa"; } +.bi-border-center::before { content: "\f1ab"; } +.bi-border-inner::before { content: "\f1ac"; } +.bi-border-left::before { content: "\f1ad"; } +.bi-border-middle::before { content: "\f1ae"; } +.bi-border-outer::before { content: "\f1af"; } +.bi-border-right::before { content: "\f1b0"; } +.bi-border-style::before { content: "\f1b1"; } +.bi-border-top::before { content: "\f1b2"; } +.bi-border-width::before { content: "\f1b3"; } +.bi-border::before { content: "\f1b4"; } +.bi-bounding-box-circles::before { content: "\f1b5"; } +.bi-bounding-box::before { content: "\f1b6"; } +.bi-box-arrow-down-left::before { content: "\f1b7"; } +.bi-box-arrow-down-right::before { content: "\f1b8"; } +.bi-box-arrow-down::before { content: "\f1b9"; } +.bi-box-arrow-in-down-left::before { content: "\f1ba"; } +.bi-box-arrow-in-down-right::before { content: "\f1bb"; } +.bi-box-arrow-in-down::before { content: "\f1bc"; } +.bi-box-arrow-in-left::before { content: "\f1bd"; } +.bi-box-arrow-in-right::before { content: "\f1be"; } +.bi-box-arrow-in-up-left::before { content: "\f1bf"; } +.bi-box-arrow-in-up-right::before { content: "\f1c0"; } +.bi-box-arrow-in-up::before { content: "\f1c1"; } +.bi-box-arrow-left::before { content: "\f1c2"; } +.bi-box-arrow-right::before { content: "\f1c3"; } +.bi-box-arrow-up-left::before { content: "\f1c4"; } +.bi-box-arrow-up-right::before { content: "\f1c5"; } +.bi-box-arrow-up::before { content: "\f1c6"; } +.bi-box-seam::before { content: "\f1c7"; } +.bi-box::before { content: "\f1c8"; } +.bi-braces::before { content: "\f1c9"; } +.bi-bricks::before { content: "\f1ca"; } +.bi-briefcase-fill::before { content: "\f1cb"; } +.bi-briefcase::before { content: "\f1cc"; } +.bi-brightness-alt-high-fill::before { content: "\f1cd"; } +.bi-brightness-alt-high::before { content: "\f1ce"; } +.bi-brightness-alt-low-fill::before { content: "\f1cf"; } +.bi-brightness-alt-low::before { content: "\f1d0"; } +.bi-brightness-high-fill::before { content: "\f1d1"; } +.bi-brightness-high::before { content: "\f1d2"; } +.bi-brightness-low-fill::before { content: "\f1d3"; } +.bi-brightness-low::before { content: "\f1d4"; } +.bi-broadcast-pin::before { content: "\f1d5"; } +.bi-broadcast::before { content: "\f1d6"; } +.bi-brush-fill::before { content: "\f1d7"; } +.bi-brush::before { content: "\f1d8"; } +.bi-bucket-fill::before { content: "\f1d9"; } +.bi-bucket::before { content: "\f1da"; } +.bi-bug-fill::before { content: "\f1db"; } +.bi-bug::before { content: "\f1dc"; } +.bi-building::before { content: "\f1dd"; } +.bi-bullseye::before { content: "\f1de"; } +.bi-calculator-fill::before { content: "\f1df"; } +.bi-calculator::before { content: "\f1e0"; } +.bi-calendar-check-fill::before { content: "\f1e1"; } +.bi-calendar-check::before { content: "\f1e2"; } +.bi-calendar-date-fill::before { content: "\f1e3"; } +.bi-calendar-date::before { content: "\f1e4"; } +.bi-calendar-day-fill::before { content: "\f1e5"; } +.bi-calendar-day::before { content: "\f1e6"; } +.bi-calendar-event-fill::before { content: "\f1e7"; } +.bi-calendar-event::before { content: "\f1e8"; } +.bi-calendar-fill::before { content: "\f1e9"; } +.bi-calendar-minus-fill::before { content: "\f1ea"; } +.bi-calendar-minus::before { content: "\f1eb"; } +.bi-calendar-month-fill::before { content: "\f1ec"; } +.bi-calendar-month::before { content: "\f1ed"; } +.bi-calendar-plus-fill::before { content: "\f1ee"; } +.bi-calendar-plus::before { content: "\f1ef"; } +.bi-calendar-range-fill::before { content: "\f1f0"; } +.bi-calendar-range::before { content: "\f1f1"; } +.bi-calendar-week-fill::before { content: "\f1f2"; } +.bi-calendar-week::before { content: "\f1f3"; } +.bi-calendar-x-fill::before { content: "\f1f4"; } +.bi-calendar-x::before { content: "\f1f5"; } +.bi-calendar::before { content: "\f1f6"; } +.bi-calendar2-check-fill::before { content: "\f1f7"; } +.bi-calendar2-check::before { content: "\f1f8"; } +.bi-calendar2-date-fill::before { content: "\f1f9"; } +.bi-calendar2-date::before { content: "\f1fa"; } +.bi-calendar2-day-fill::before { content: "\f1fb"; } +.bi-calendar2-day::before { content: "\f1fc"; } +.bi-calendar2-event-fill::before { content: "\f1fd"; } +.bi-calendar2-event::before { content: "\f1fe"; } +.bi-calendar2-fill::before { content: "\f1ff"; } +.bi-calendar2-minus-fill::before { content: "\f200"; } +.bi-calendar2-minus::before { content: "\f201"; } +.bi-calendar2-month-fill::before { content: "\f202"; } +.bi-calendar2-month::before { content: "\f203"; } +.bi-calendar2-plus-fill::before { content: "\f204"; } +.bi-calendar2-plus::before { content: "\f205"; } +.bi-calendar2-range-fill::before { content: "\f206"; } +.bi-calendar2-range::before { content: "\f207"; } +.bi-calendar2-week-fill::before { content: "\f208"; } +.bi-calendar2-week::before { content: "\f209"; } +.bi-calendar2-x-fill::before { content: "\f20a"; } +.bi-calendar2-x::before { content: "\f20b"; } +.bi-calendar2::before { content: "\f20c"; } +.bi-calendar3-event-fill::before { content: "\f20d"; } +.bi-calendar3-event::before { content: "\f20e"; } +.bi-calendar3-fill::before { content: "\f20f"; } +.bi-calendar3-range-fill::before { content: "\f210"; } +.bi-calendar3-range::before { content: "\f211"; } +.bi-calendar3-week-fill::before { content: "\f212"; } +.bi-calendar3-week::before { content: "\f213"; } +.bi-calendar3::before { content: "\f214"; } +.bi-calendar4-event::before { content: "\f215"; } +.bi-calendar4-range::before { content: "\f216"; } +.bi-calendar4-week::before { content: "\f217"; } +.bi-calendar4::before { content: "\f218"; } +.bi-camera-fill::before { content: "\f219"; } +.bi-camera-reels-fill::before { content: "\f21a"; } +.bi-camera-reels::before { content: "\f21b"; } +.bi-camera-video-fill::before { content: "\f21c"; } +.bi-camera-video-off-fill::before { content: "\f21d"; } +.bi-camera-video-off::before { content: "\f21e"; } +.bi-camera-video::before { content: "\f21f"; } +.bi-camera::before { content: "\f220"; } +.bi-camera2::before { content: "\f221"; } +.bi-capslock-fill::before { content: "\f222"; } +.bi-capslock::before { content: "\f223"; } +.bi-card-checklist::before { content: "\f224"; } +.bi-card-heading::before { content: "\f225"; } +.bi-card-image::before { content: "\f226"; } +.bi-card-list::before { content: "\f227"; } +.bi-card-text::before { content: "\f228"; } +.bi-caret-down-fill::before { content: "\f229"; } +.bi-caret-down-square-fill::before { content: "\f22a"; } +.bi-caret-down-square::before { content: "\f22b"; } +.bi-caret-down::before { content: "\f22c"; } +.bi-caret-left-fill::before { content: "\f22d"; } +.bi-caret-left-square-fill::before { content: "\f22e"; } +.bi-caret-left-square::before { content: "\f22f"; } +.bi-caret-left::before { content: "\f230"; } +.bi-caret-right-fill::before { content: "\f231"; } +.bi-caret-right-square-fill::before { content: "\f232"; } +.bi-caret-right-square::before { content: "\f233"; } +.bi-caret-right::before { content: "\f234"; } +.bi-caret-up-fill::before { content: "\f235"; } +.bi-caret-up-square-fill::before { content: "\f236"; } +.bi-caret-up-square::before { content: "\f237"; } +.bi-caret-up::before { content: "\f238"; } +.bi-cart-check-fill::before { content: "\f239"; } +.bi-cart-check::before { content: "\f23a"; } +.bi-cart-dash-fill::before { content: "\f23b"; } +.bi-cart-dash::before { content: "\f23c"; } +.bi-cart-fill::before { content: "\f23d"; } +.bi-cart-plus-fill::before { content: "\f23e"; } +.bi-cart-plus::before { content: "\f23f"; } +.bi-cart-x-fill::before { content: "\f240"; } +.bi-cart-x::before { content: "\f241"; } +.bi-cart::before { content: "\f242"; } +.bi-cart2::before { content: "\f243"; } +.bi-cart3::before { content: "\f244"; } +.bi-cart4::before { content: "\f245"; } +.bi-cash-stack::before { content: "\f246"; } +.bi-cash::before { content: "\f247"; } +.bi-cast::before { content: "\f248"; } +.bi-chat-dots-fill::before { content: "\f249"; } +.bi-chat-dots::before { content: "\f24a"; } +.bi-chat-fill::before { content: "\f24b"; } +.bi-chat-left-dots-fill::before { content: "\f24c"; } +.bi-chat-left-dots::before { content: "\f24d"; } +.bi-chat-left-fill::before { content: "\f24e"; } +.bi-chat-left-quote-fill::before { content: "\f24f"; } +.bi-chat-left-quote::before { content: "\f250"; } +.bi-chat-left-text-fill::before { content: "\f251"; } +.bi-chat-left-text::before { content: "\f252"; } +.bi-chat-left::before { content: "\f253"; } +.bi-chat-quote-fill::before { content: "\f254"; } +.bi-chat-quote::before { content: "\f255"; } +.bi-chat-right-dots-fill::before { content: "\f256"; } +.bi-chat-right-dots::before { content: "\f257"; } +.bi-chat-right-fill::before { content: "\f258"; } +.bi-chat-right-quote-fill::before { content: "\f259"; } +.bi-chat-right-quote::before { content: "\f25a"; } +.bi-chat-right-text-fill::before { content: "\f25b"; } +.bi-chat-right-text::before { content: "\f25c"; } +.bi-chat-right::before { content: "\f25d"; } +.bi-chat-square-dots-fill::before { content: "\f25e"; } +.bi-chat-square-dots::before { content: "\f25f"; } +.bi-chat-square-fill::before { content: "\f260"; } +.bi-chat-square-quote-fill::before { content: "\f261"; } +.bi-chat-square-quote::before { content: "\f262"; } +.bi-chat-square-text-fill::before { content: "\f263"; } +.bi-chat-square-text::before { content: "\f264"; } +.bi-chat-square::before { content: "\f265"; } +.bi-chat-text-fill::before { content: "\f266"; } +.bi-chat-text::before { content: "\f267"; } +.bi-chat::before { content: "\f268"; } +.bi-check-all::before { content: "\f269"; } +.bi-check-circle-fill::before { content: "\f26a"; } +.bi-check-circle::before { content: "\f26b"; } +.bi-check-square-fill::before { content: "\f26c"; } +.bi-check-square::before { content: "\f26d"; } +.bi-check::before { content: "\f26e"; } +.bi-check2-all::before { content: "\f26f"; } +.bi-check2-circle::before { content: "\f270"; } +.bi-check2-square::before { content: "\f271"; } +.bi-check2::before { content: "\f272"; } +.bi-chevron-bar-contract::before { content: "\f273"; } +.bi-chevron-bar-down::before { content: "\f274"; } +.bi-chevron-bar-expand::before { content: "\f275"; } +.bi-chevron-bar-left::before { content: "\f276"; } +.bi-chevron-bar-right::before { content: "\f277"; } +.bi-chevron-bar-up::before { content: "\f278"; } +.bi-chevron-compact-down::before { content: "\f279"; } +.bi-chevron-compact-left::before { content: "\f27a"; } +.bi-chevron-compact-right::before { content: "\f27b"; } +.bi-chevron-compact-up::before { content: "\f27c"; } +.bi-chevron-contract::before { content: "\f27d"; } +.bi-chevron-double-down::before { content: "\f27e"; } +.bi-chevron-double-left::before { content: "\f27f"; } +.bi-chevron-double-right::before { content: "\f280"; } +.bi-chevron-double-up::before { content: "\f281"; } +.bi-chevron-down::before { content: "\f282"; } +.bi-chevron-expand::before { content: "\f283"; } +.bi-chevron-left::before { content: "\f284"; } +.bi-chevron-right::before { content: "\f285"; } +.bi-chevron-up::before { content: "\f286"; } +.bi-circle-fill::before { content: "\f287"; } +.bi-circle-half::before { content: "\f288"; } +.bi-circle-square::before { content: "\f289"; } +.bi-circle::before { content: "\f28a"; } +.bi-clipboard-check::before { content: "\f28b"; } +.bi-clipboard-data::before { content: "\f28c"; } +.bi-clipboard-minus::before { content: "\f28d"; } +.bi-clipboard-plus::before { content: "\f28e"; } +.bi-clipboard-x::before { content: "\f28f"; } +.bi-clipboard::before { content: "\f290"; } +.bi-clock-fill::before { content: "\f291"; } +.bi-clock-history::before { content: "\f292"; } +.bi-clock::before { content: "\f293"; } +.bi-cloud-arrow-down-fill::before { content: "\f294"; } +.bi-cloud-arrow-down::before { content: "\f295"; } +.bi-cloud-arrow-up-fill::before { content: "\f296"; } +.bi-cloud-arrow-up::before { content: "\f297"; } +.bi-cloud-check-fill::before { content: "\f298"; } +.bi-cloud-check::before { content: "\f299"; } +.bi-cloud-download-fill::before { content: "\f29a"; } +.bi-cloud-download::before { content: "\f29b"; } +.bi-cloud-drizzle-fill::before { content: "\f29c"; } +.bi-cloud-drizzle::before { content: "\f29d"; } +.bi-cloud-fill::before { content: "\f29e"; } +.bi-cloud-fog-fill::before { content: "\f29f"; } +.bi-cloud-fog::before { content: "\f2a0"; } +.bi-cloud-fog2-fill::before { content: "\f2a1"; } +.bi-cloud-fog2::before { content: "\f2a2"; } +.bi-cloud-hail-fill::before { content: "\f2a3"; } +.bi-cloud-hail::before { content: "\f2a4"; } +.bi-cloud-haze-1::before { content: "\f2a5"; } +.bi-cloud-haze-fill::before { content: "\f2a6"; } +.bi-cloud-haze::before { content: "\f2a7"; } +.bi-cloud-haze2-fill::before { content: "\f2a8"; } +.bi-cloud-lightning-fill::before { content: "\f2a9"; } +.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; } +.bi-cloud-lightning-rain::before { content: "\f2ab"; } +.bi-cloud-lightning::before { content: "\f2ac"; } +.bi-cloud-minus-fill::before { content: "\f2ad"; } +.bi-cloud-minus::before { content: "\f2ae"; } +.bi-cloud-moon-fill::before { content: "\f2af"; } +.bi-cloud-moon::before { content: "\f2b0"; } +.bi-cloud-plus-fill::before { content: "\f2b1"; } +.bi-cloud-plus::before { content: "\f2b2"; } +.bi-cloud-rain-fill::before { content: "\f2b3"; } +.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; } +.bi-cloud-rain-heavy::before { content: "\f2b5"; } +.bi-cloud-rain::before { content: "\f2b6"; } +.bi-cloud-slash-fill::before { content: "\f2b7"; } +.bi-cloud-slash::before { content: "\f2b8"; } +.bi-cloud-sleet-fill::before { content: "\f2b9"; } +.bi-cloud-sleet::before { content: "\f2ba"; } +.bi-cloud-snow-fill::before { content: "\f2bb"; } +.bi-cloud-snow::before { content: "\f2bc"; } +.bi-cloud-sun-fill::before { content: "\f2bd"; } +.bi-cloud-sun::before { content: "\f2be"; } +.bi-cloud-upload-fill::before { content: "\f2bf"; } +.bi-cloud-upload::before { content: "\f2c0"; } +.bi-cloud::before { content: "\f2c1"; } +.bi-clouds-fill::before { content: "\f2c2"; } +.bi-clouds::before { content: "\f2c3"; } +.bi-cloudy-fill::before { content: "\f2c4"; } +.bi-cloudy::before { content: "\f2c5"; } +.bi-code-slash::before { content: "\f2c6"; } +.bi-code-square::before { content: "\f2c7"; } +.bi-code::before { content: "\f2c8"; } +.bi-collection-fill::before { content: "\f2c9"; } +.bi-collection-play-fill::before { content: "\f2ca"; } +.bi-collection-play::before { content: "\f2cb"; } +.bi-collection::before { content: "\f2cc"; } +.bi-columns-gap::before { content: "\f2cd"; } +.bi-columns::before { content: "\f2ce"; } +.bi-command::before { content: "\f2cf"; } +.bi-compass-fill::before { content: "\f2d0"; } +.bi-compass::before { content: "\f2d1"; } +.bi-cone-striped::before { content: "\f2d2"; } +.bi-cone::before { content: "\f2d3"; } +.bi-controller::before { content: "\f2d4"; } +.bi-cpu-fill::before { content: "\f2d5"; } +.bi-cpu::before { content: "\f2d6"; } +.bi-credit-card-2-back-fill::before { content: "\f2d7"; } +.bi-credit-card-2-back::before { content: "\f2d8"; } +.bi-credit-card-2-front-fill::before { content: "\f2d9"; } +.bi-credit-card-2-front::before { content: "\f2da"; } +.bi-credit-card-fill::before { content: "\f2db"; } +.bi-credit-card::before { content: "\f2dc"; } +.bi-crop::before { content: "\f2dd"; } +.bi-cup-fill::before { content: "\f2de"; } +.bi-cup-straw::before { content: "\f2df"; } +.bi-cup::before { content: "\f2e0"; } +.bi-cursor-fill::before { content: "\f2e1"; } +.bi-cursor-text::before { content: "\f2e2"; } +.bi-cursor::before { content: "\f2e3"; } +.bi-dash-circle-dotted::before { content: "\f2e4"; } +.bi-dash-circle-fill::before { content: "\f2e5"; } +.bi-dash-circle::before { content: "\f2e6"; } +.bi-dash-square-dotted::before { content: "\f2e7"; } +.bi-dash-square-fill::before { content: "\f2e8"; } +.bi-dash-square::before { content: "\f2e9"; } +.bi-dash::before { content: "\f2ea"; } +.bi-diagram-2-fill::before { content: "\f2eb"; } +.bi-diagram-2::before { content: "\f2ec"; } +.bi-diagram-3-fill::before { content: "\f2ed"; } +.bi-diagram-3::before { content: "\f2ee"; } +.bi-diamond-fill::before { content: "\f2ef"; } +.bi-diamond-half::before { content: "\f2f0"; } +.bi-diamond::before { content: "\f2f1"; } +.bi-dice-1-fill::before { content: "\f2f2"; } +.bi-dice-1::before { content: "\f2f3"; } +.bi-dice-2-fill::before { content: "\f2f4"; } +.bi-dice-2::before { content: "\f2f5"; } +.bi-dice-3-fill::before { content: "\f2f6"; } +.bi-dice-3::before { content: "\f2f7"; } +.bi-dice-4-fill::before { content: "\f2f8"; } +.bi-dice-4::before { content: "\f2f9"; } +.bi-dice-5-fill::before { content: "\f2fa"; } +.bi-dice-5::before { content: "\f2fb"; } +.bi-dice-6-fill::before { content: "\f2fc"; } +.bi-dice-6::before { content: "\f2fd"; } +.bi-disc-fill::before { content: "\f2fe"; } +.bi-disc::before { content: "\f2ff"; } +.bi-discord::before { content: "\f300"; } +.bi-display-fill::before { content: "\f301"; } +.bi-display::before { content: "\f302"; } +.bi-distribute-horizontal::before { content: "\f303"; } +.bi-distribute-vertical::before { content: "\f304"; } +.bi-door-closed-fill::before { content: "\f305"; } +.bi-door-closed::before { content: "\f306"; } +.bi-door-open-fill::before { content: "\f307"; } +.bi-door-open::before { content: "\f308"; } +.bi-dot::before { content: "\f309"; } +.bi-download::before { content: "\f30a"; } +.bi-droplet-fill::before { content: "\f30b"; } +.bi-droplet-half::before { content: "\f30c"; } +.bi-droplet::before { content: "\f30d"; } +.bi-earbuds::before { content: "\f30e"; } +.bi-easel-fill::before { content: "\f30f"; } +.bi-easel::before { content: "\f310"; } +.bi-egg-fill::before { content: "\f311"; } +.bi-egg-fried::before { content: "\f312"; } +.bi-egg::before { content: "\f313"; } +.bi-eject-fill::before { content: "\f314"; } +.bi-eject::before { content: "\f315"; } +.bi-emoji-angry-fill::before { content: "\f316"; } +.bi-emoji-angry::before { content: "\f317"; } +.bi-emoji-dizzy-fill::before { content: "\f318"; } +.bi-emoji-dizzy::before { content: "\f319"; } +.bi-emoji-expressionless-fill::before { content: "\f31a"; } +.bi-emoji-expressionless::before { content: "\f31b"; } +.bi-emoji-frown-fill::before { content: "\f31c"; } +.bi-emoji-frown::before { content: "\f31d"; } +.bi-emoji-heart-eyes-fill::before { content: "\f31e"; } +.bi-emoji-heart-eyes::before { content: "\f31f"; } +.bi-emoji-laughing-fill::before { content: "\f320"; } +.bi-emoji-laughing::before { content: "\f321"; } +.bi-emoji-neutral-fill::before { content: "\f322"; } +.bi-emoji-neutral::before { content: "\f323"; } +.bi-emoji-smile-fill::before { content: "\f324"; } +.bi-emoji-smile-upside-down-fill::before { content: "\f325"; } +.bi-emoji-smile-upside-down::before { content: "\f326"; } +.bi-emoji-smile::before { content: "\f327"; } +.bi-emoji-sunglasses-fill::before { content: "\f328"; } +.bi-emoji-sunglasses::before { content: "\f329"; } +.bi-emoji-wink-fill::before { content: "\f32a"; } +.bi-emoji-wink::before { content: "\f32b"; } +.bi-envelope-fill::before { content: "\f32c"; } +.bi-envelope-open-fill::before { content: "\f32d"; } +.bi-envelope-open::before { content: "\f32e"; } +.bi-envelope::before { content: "\f32f"; } +.bi-eraser-fill::before { content: "\f330"; } +.bi-eraser::before { content: "\f331"; } +.bi-exclamation-circle-fill::before { content: "\f332"; } +.bi-exclamation-circle::before { content: "\f333"; } +.bi-exclamation-diamond-fill::before { content: "\f334"; } +.bi-exclamation-diamond::before { content: "\f335"; } +.bi-exclamation-octagon-fill::before { content: "\f336"; } +.bi-exclamation-octagon::before { content: "\f337"; } +.bi-exclamation-square-fill::before { content: "\f338"; } +.bi-exclamation-square::before { content: "\f339"; } +.bi-exclamation-triangle-fill::before { content: "\f33a"; } +.bi-exclamation-triangle::before { content: "\f33b"; } +.bi-exclamation::before { content: "\f33c"; } +.bi-exclude::before { content: "\f33d"; } +.bi-eye-fill::before { content: "\f33e"; } +.bi-eye-slash-fill::before { content: "\f33f"; } +.bi-eye-slash::before { content: "\f340"; } +.bi-eye::before { content: "\f341"; } +.bi-eyedropper::before { content: "\f342"; } +.bi-eyeglasses::before { content: "\f343"; } +.bi-facebook::before { content: "\f344"; } +.bi-file-arrow-down-fill::before { content: "\f345"; } +.bi-file-arrow-down::before { content: "\f346"; } +.bi-file-arrow-up-fill::before { content: "\f347"; } +.bi-file-arrow-up::before { content: "\f348"; } +.bi-file-bar-graph-fill::before { content: "\f349"; } +.bi-file-bar-graph::before { content: "\f34a"; } +.bi-file-binary-fill::before { content: "\f34b"; } +.bi-file-binary::before { content: "\f34c"; } +.bi-file-break-fill::before { content: "\f34d"; } +.bi-file-break::before { content: "\f34e"; } +.bi-file-check-fill::before { content: "\f34f"; } +.bi-file-check::before { content: "\f350"; } +.bi-file-code-fill::before { content: "\f351"; } +.bi-file-code::before { content: "\f352"; } +.bi-file-diff-fill::before { content: "\f353"; } +.bi-file-diff::before { content: "\f354"; } +.bi-file-earmark-arrow-down-fill::before { content: "\f355"; } +.bi-file-earmark-arrow-down::before { content: "\f356"; } +.bi-file-earmark-arrow-up-fill::before { content: "\f357"; } +.bi-file-earmark-arrow-up::before { content: "\f358"; } +.bi-file-earmark-bar-graph-fill::before { content: "\f359"; } +.bi-file-earmark-bar-graph::before { content: "\f35a"; } +.bi-file-earmark-binary-fill::before { content: "\f35b"; } +.bi-file-earmark-binary::before { content: "\f35c"; } +.bi-file-earmark-break-fill::before { content: "\f35d"; } +.bi-file-earmark-break::before { content: "\f35e"; } +.bi-file-earmark-check-fill::before { content: "\f35f"; } +.bi-file-earmark-check::before { content: "\f360"; } +.bi-file-earmark-code-fill::before { content: "\f361"; } +.bi-file-earmark-code::before { content: "\f362"; } +.bi-file-earmark-diff-fill::before { content: "\f363"; } +.bi-file-earmark-diff::before { content: "\f364"; } +.bi-file-earmark-easel-fill::before { content: "\f365"; } +.bi-file-earmark-easel::before { content: "\f366"; } +.bi-file-earmark-excel-fill::before { content: "\f367"; } +.bi-file-earmark-excel::before { content: "\f368"; } +.bi-file-earmark-fill::before { content: "\f369"; } +.bi-file-earmark-font-fill::before { content: "\f36a"; } +.bi-file-earmark-font::before { content: "\f36b"; } +.bi-file-earmark-image-fill::before { content: "\f36c"; } +.bi-file-earmark-image::before { content: "\f36d"; } +.bi-file-earmark-lock-fill::before { content: "\f36e"; } +.bi-file-earmark-lock::before { content: "\f36f"; } +.bi-file-earmark-lock2-fill::before { content: "\f370"; } +.bi-file-earmark-lock2::before { content: "\f371"; } +.bi-file-earmark-medical-fill::before { content: "\f372"; } +.bi-file-earmark-medical::before { content: "\f373"; } +.bi-file-earmark-minus-fill::before { content: "\f374"; } +.bi-file-earmark-minus::before { content: "\f375"; } +.bi-file-earmark-music-fill::before { content: "\f376"; } +.bi-file-earmark-music::before { content: "\f377"; } +.bi-file-earmark-person-fill::before { content: "\f378"; } +.bi-file-earmark-person::before { content: "\f379"; } +.bi-file-earmark-play-fill::before { content: "\f37a"; } +.bi-file-earmark-play::before { content: "\f37b"; } +.bi-file-earmark-plus-fill::before { content: "\f37c"; } +.bi-file-earmark-plus::before { content: "\f37d"; } +.bi-file-earmark-post-fill::before { content: "\f37e"; } +.bi-file-earmark-post::before { content: "\f37f"; } +.bi-file-earmark-ppt-fill::before { content: "\f380"; } +.bi-file-earmark-ppt::before { content: "\f381"; } +.bi-file-earmark-richtext-fill::before { content: "\f382"; } +.bi-file-earmark-richtext::before { content: "\f383"; } +.bi-file-earmark-ruled-fill::before { content: "\f384"; } +.bi-file-earmark-ruled::before { content: "\f385"; } +.bi-file-earmark-slides-fill::before { content: "\f386"; } +.bi-file-earmark-slides::before { content: "\f387"; } +.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; } +.bi-file-earmark-spreadsheet::before { content: "\f389"; } +.bi-file-earmark-text-fill::before { content: "\f38a"; } +.bi-file-earmark-text::before { content: "\f38b"; } +.bi-file-earmark-word-fill::before { content: "\f38c"; } +.bi-file-earmark-word::before { content: "\f38d"; } +.bi-file-earmark-x-fill::before { content: "\f38e"; } +.bi-file-earmark-x::before { content: "\f38f"; } +.bi-file-earmark-zip-fill::before { content: "\f390"; } +.bi-file-earmark-zip::before { content: "\f391"; } +.bi-file-earmark::before { content: "\f392"; } +.bi-file-easel-fill::before { content: "\f393"; } +.bi-file-easel::before { content: "\f394"; } +.bi-file-excel-fill::before { content: "\f395"; } +.bi-file-excel::before { content: "\f396"; } +.bi-file-fill::before { content: "\f397"; } +.bi-file-font-fill::before { content: "\f398"; } +.bi-file-font::before { content: "\f399"; } +.bi-file-image-fill::before { content: "\f39a"; } +.bi-file-image::before { content: "\f39b"; } +.bi-file-lock-fill::before { content: "\f39c"; } +.bi-file-lock::before { content: "\f39d"; } +.bi-file-lock2-fill::before { content: "\f39e"; } +.bi-file-lock2::before { content: "\f39f"; } +.bi-file-medical-fill::before { content: "\f3a0"; } +.bi-file-medical::before { content: "\f3a1"; } +.bi-file-minus-fill::before { content: "\f3a2"; } +.bi-file-minus::before { content: "\f3a3"; } +.bi-file-music-fill::before { content: "\f3a4"; } +.bi-file-music::before { content: "\f3a5"; } +.bi-file-person-fill::before { content: "\f3a6"; } +.bi-file-person::before { content: "\f3a7"; } +.bi-file-play-fill::before { content: "\f3a8"; } +.bi-file-play::before { content: "\f3a9"; } +.bi-file-plus-fill::before { content: "\f3aa"; } +.bi-file-plus::before { content: "\f3ab"; } +.bi-file-post-fill::before { content: "\f3ac"; } +.bi-file-post::before { content: "\f3ad"; } +.bi-file-ppt-fill::before { content: "\f3ae"; } +.bi-file-ppt::before { content: "\f3af"; } +.bi-file-richtext-fill::before { content: "\f3b0"; } +.bi-file-richtext::before { content: "\f3b1"; } +.bi-file-ruled-fill::before { content: "\f3b2"; } +.bi-file-ruled::before { content: "\f3b3"; } +.bi-file-slides-fill::before { content: "\f3b4"; } +.bi-file-slides::before { content: "\f3b5"; } +.bi-file-spreadsheet-fill::before { content: "\f3b6"; } +.bi-file-spreadsheet::before { content: "\f3b7"; } +.bi-file-text-fill::before { content: "\f3b8"; } +.bi-file-text::before { content: "\f3b9"; } +.bi-file-word-fill::before { content: "\f3ba"; } +.bi-file-word::before { content: "\f3bb"; } +.bi-file-x-fill::before { content: "\f3bc"; } +.bi-file-x::before { content: "\f3bd"; } +.bi-file-zip-fill::before { content: "\f3be"; } +.bi-file-zip::before { content: "\f3bf"; } +.bi-file::before { content: "\f3c0"; } +.bi-files-alt::before { content: "\f3c1"; } +.bi-files::before { content: "\f3c2"; } +.bi-film::before { content: "\f3c3"; } +.bi-filter-circle-fill::before { content: "\f3c4"; } +.bi-filter-circle::before { content: "\f3c5"; } +.bi-filter-left::before { content: "\f3c6"; } +.bi-filter-right::before { content: "\f3c7"; } +.bi-filter-square-fill::before { content: "\f3c8"; } +.bi-filter-square::before { content: "\f3c9"; } +.bi-filter::before { content: "\f3ca"; } +.bi-flag-fill::before { content: "\f3cb"; } +.bi-flag::before { content: "\f3cc"; } +.bi-flower1::before { content: "\f3cd"; } +.bi-flower2::before { content: "\f3ce"; } +.bi-flower3::before { content: "\f3cf"; } +.bi-folder-check::before { content: "\f3d0"; } +.bi-folder-fill::before { content: "\f3d1"; } +.bi-folder-minus::before { content: "\f3d2"; } +.bi-folder-plus::before { content: "\f3d3"; } +.bi-folder-symlink-fill::before { content: "\f3d4"; } +.bi-folder-symlink::before { content: "\f3d5"; } +.bi-folder-x::before { content: "\f3d6"; } +.bi-folder::before { content: "\f3d7"; } +.bi-folder2-open::before { content: "\f3d8"; } +.bi-folder2::before { content: "\f3d9"; } +.bi-fonts::before { content: "\f3da"; } +.bi-forward-fill::before { content: "\f3db"; } +.bi-forward::before { content: "\f3dc"; } +.bi-front::before { content: "\f3dd"; } +.bi-fullscreen-exit::before { content: "\f3de"; } +.bi-fullscreen::before { content: "\f3df"; } +.bi-funnel-fill::before { content: "\f3e0"; } +.bi-funnel::before { content: "\f3e1"; } +.bi-gear-fill::before { content: "\f3e2"; } +.bi-gear-wide-connected::before { content: "\f3e3"; } +.bi-gear-wide::before { content: "\f3e4"; } +.bi-gear::before { content: "\f3e5"; } +.bi-gem::before { content: "\f3e6"; } +.bi-geo-alt-fill::before { content: "\f3e7"; } +.bi-geo-alt::before { content: "\f3e8"; } +.bi-geo-fill::before { content: "\f3e9"; } +.bi-geo::before { content: "\f3ea"; } +.bi-gift-fill::before { content: "\f3eb"; } +.bi-gift::before { content: "\f3ec"; } +.bi-github::before { content: "\f3ed"; } +.bi-globe::before { content: "\f3ee"; } +.bi-globe2::before { content: "\f3ef"; } +.bi-google::before { content: "\f3f0"; } +.bi-graph-down::before { content: "\f3f1"; } +.bi-graph-up::before { content: "\f3f2"; } +.bi-grid-1x2-fill::before { content: "\f3f3"; } +.bi-grid-1x2::before { content: "\f3f4"; } +.bi-grid-3x2-gap-fill::before { content: "\f3f5"; } +.bi-grid-3x2-gap::before { content: "\f3f6"; } +.bi-grid-3x2::before { content: "\f3f7"; } +.bi-grid-3x3-gap-fill::before { content: "\f3f8"; } +.bi-grid-3x3-gap::before { content: "\f3f9"; } +.bi-grid-3x3::before { content: "\f3fa"; } +.bi-grid-fill::before { content: "\f3fb"; } +.bi-grid::before { content: "\f3fc"; } +.bi-grip-horizontal::before { content: "\f3fd"; } +.bi-grip-vertical::before { content: "\f3fe"; } +.bi-hammer::before { content: "\f3ff"; } +.bi-hand-index-fill::before { content: "\f400"; } +.bi-hand-index-thumb-fill::before { content: "\f401"; } +.bi-hand-index-thumb::before { content: "\f402"; } +.bi-hand-index::before { content: "\f403"; } +.bi-hand-thumbs-down-fill::before { content: "\f404"; } +.bi-hand-thumbs-down::before { content: "\f405"; } +.bi-hand-thumbs-up-fill::before { content: "\f406"; } +.bi-hand-thumbs-up::before { content: "\f407"; } +.bi-handbag-fill::before { content: "\f408"; } +.bi-handbag::before { content: "\f409"; } +.bi-hash::before { content: "\f40a"; } +.bi-hdd-fill::before { content: "\f40b"; } +.bi-hdd-network-fill::before { content: "\f40c"; } +.bi-hdd-network::before { content: "\f40d"; } +.bi-hdd-rack-fill::before { content: "\f40e"; } +.bi-hdd-rack::before { content: "\f40f"; } +.bi-hdd-stack-fill::before { content: "\f410"; } +.bi-hdd-stack::before { content: "\f411"; } +.bi-hdd::before { content: "\f412"; } +.bi-headphones::before { content: "\f413"; } +.bi-headset::before { content: "\f414"; } +.bi-heart-fill::before { content: "\f415"; } +.bi-heart-half::before { content: "\f416"; } +.bi-heart::before { content: "\f417"; } +.bi-heptagon-fill::before { content: "\f418"; } +.bi-heptagon-half::before { content: "\f419"; } +.bi-heptagon::before { content: "\f41a"; } +.bi-hexagon-fill::before { content: "\f41b"; } +.bi-hexagon-half::before { content: "\f41c"; } +.bi-hexagon::before { content: "\f41d"; } +.bi-hourglass-bottom::before { content: "\f41e"; } +.bi-hourglass-split::before { content: "\f41f"; } +.bi-hourglass-top::before { content: "\f420"; } +.bi-hourglass::before { content: "\f421"; } +.bi-house-door-fill::before { content: "\f422"; } +.bi-house-door::before { content: "\f423"; } +.bi-house-fill::before { content: "\f424"; } +.bi-house::before { content: "\f425"; } +.bi-hr::before { content: "\f426"; } +.bi-hurricane::before { content: "\f427"; } +.bi-image-alt::before { content: "\f428"; } +.bi-image-fill::before { content: "\f429"; } +.bi-image::before { content: "\f42a"; } +.bi-images::before { content: "\f42b"; } +.bi-inbox-fill::before { content: "\f42c"; } +.bi-inbox::before { content: "\f42d"; } +.bi-inboxes-fill::before { content: "\f42e"; } +.bi-inboxes::before { content: "\f42f"; } +.bi-info-circle-fill::before { content: "\f430"; } +.bi-info-circle::before { content: "\f431"; } +.bi-info-square-fill::before { content: "\f432"; } +.bi-info-square::before { content: "\f433"; } +.bi-info::before { content: "\f434"; } +.bi-input-cursor-text::before { content: "\f435"; } +.bi-input-cursor::before { content: "\f436"; } +.bi-instagram::before { content: "\f437"; } +.bi-intersect::before { content: "\f438"; } +.bi-journal-album::before { content: "\f439"; } +.bi-journal-arrow-down::before { content: "\f43a"; } +.bi-journal-arrow-up::before { content: "\f43b"; } +.bi-journal-bookmark-fill::before { content: "\f43c"; } +.bi-journal-bookmark::before { content: "\f43d"; } +.bi-journal-check::before { content: "\f43e"; } +.bi-journal-code::before { content: "\f43f"; } +.bi-journal-medical::before { content: "\f440"; } +.bi-journal-minus::before { content: "\f441"; } +.bi-journal-plus::before { content: "\f442"; } +.bi-journal-richtext::before { content: "\f443"; } +.bi-journal-text::before { content: "\f444"; } +.bi-journal-x::before { content: "\f445"; } +.bi-journal::before { content: "\f446"; } +.bi-journals::before { content: "\f447"; } +.bi-joystick::before { content: "\f448"; } +.bi-justify-left::before { content: "\f449"; } +.bi-justify-right::before { content: "\f44a"; } +.bi-justify::before { content: "\f44b"; } +.bi-kanban-fill::before { content: "\f44c"; } +.bi-kanban::before { content: "\f44d"; } +.bi-key-fill::before { content: "\f44e"; } +.bi-key::before { content: "\f44f"; } +.bi-keyboard-fill::before { content: "\f450"; } +.bi-keyboard::before { content: "\f451"; } +.bi-ladder::before { content: "\f452"; } +.bi-lamp-fill::before { content: "\f453"; } +.bi-lamp::before { content: "\f454"; } +.bi-laptop-fill::before { content: "\f455"; } +.bi-laptop::before { content: "\f456"; } +.bi-layer-backward::before { content: "\f457"; } +.bi-layer-forward::before { content: "\f458"; } +.bi-layers-fill::before { content: "\f459"; } +.bi-layers-half::before { content: "\f45a"; } +.bi-layers::before { content: "\f45b"; } +.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; } +.bi-layout-sidebar-inset::before { content: "\f45d"; } +.bi-layout-sidebar-reverse::before { content: "\f45e"; } +.bi-layout-sidebar::before { content: "\f45f"; } +.bi-layout-split::before { content: "\f460"; } +.bi-layout-text-sidebar-reverse::before { content: "\f461"; } +.bi-layout-text-sidebar::before { content: "\f462"; } +.bi-layout-text-window-reverse::before { content: "\f463"; } +.bi-layout-text-window::before { content: "\f464"; } +.bi-layout-three-columns::before { content: "\f465"; } +.bi-layout-wtf::before { content: "\f466"; } +.bi-life-preserver::before { content: "\f467"; } +.bi-lightbulb-fill::before { content: "\f468"; } +.bi-lightbulb-off-fill::before { content: "\f469"; } +.bi-lightbulb-off::before { content: "\f46a"; } +.bi-lightbulb::before { content: "\f46b"; } +.bi-lightning-charge-fill::before { content: "\f46c"; } +.bi-lightning-charge::before { content: "\f46d"; } +.bi-lightning-fill::before { content: "\f46e"; } +.bi-lightning::before { content: "\f46f"; } +.bi-link-45deg::before { content: "\f470"; } +.bi-link::before { content: "\f471"; } +.bi-linkedin::before { content: "\f472"; } +.bi-list-check::before { content: "\f473"; } +.bi-list-nested::before { content: "\f474"; } +.bi-list-ol::before { content: "\f475"; } +.bi-list-stars::before { content: "\f476"; } +.bi-list-task::before { content: "\f477"; } +.bi-list-ul::before { content: "\f478"; } +.bi-list::before { content: "\f479"; } +.bi-lock-fill::before { content: "\f47a"; } +.bi-lock::before { content: "\f47b"; } +.bi-mailbox::before { content: "\f47c"; } +.bi-mailbox2::before { content: "\f47d"; } +.bi-map-fill::before { content: "\f47e"; } +.bi-map::before { content: "\f47f"; } +.bi-markdown-fill::before { content: "\f480"; } +.bi-markdown::before { content: "\f481"; } +.bi-mask::before { content: "\f482"; } +.bi-megaphone-fill::before { content: "\f483"; } +.bi-megaphone::before { content: "\f484"; } +.bi-menu-app-fill::before { content: "\f485"; } +.bi-menu-app::before { content: "\f486"; } +.bi-menu-button-fill::before { content: "\f487"; } +.bi-menu-button-wide-fill::before { content: "\f488"; } +.bi-menu-button-wide::before { content: "\f489"; } +.bi-menu-button::before { content: "\f48a"; } +.bi-menu-down::before { content: "\f48b"; } +.bi-menu-up::before { content: "\f48c"; } +.bi-mic-fill::before { content: "\f48d"; } +.bi-mic-mute-fill::before { content: "\f48e"; } +.bi-mic-mute::before { content: "\f48f"; } +.bi-mic::before { content: "\f490"; } +.bi-minecart-loaded::before { content: "\f491"; } +.bi-minecart::before { content: "\f492"; } +.bi-moisture::before { content: "\f493"; } +.bi-moon-fill::before { content: "\f494"; } +.bi-moon-stars-fill::before { content: "\f495"; } +.bi-moon-stars::before { content: "\f496"; } +.bi-moon::before { content: "\f497"; } +.bi-mouse-fill::before { content: "\f498"; } +.bi-mouse::before { content: "\f499"; } +.bi-mouse2-fill::before { content: "\f49a"; } +.bi-mouse2::before { content: "\f49b"; } +.bi-mouse3-fill::before { content: "\f49c"; } +.bi-mouse3::before { content: "\f49d"; } +.bi-music-note-beamed::before { content: "\f49e"; } +.bi-music-note-list::before { content: "\f49f"; } +.bi-music-note::before { content: "\f4a0"; } +.bi-music-player-fill::before { content: "\f4a1"; } +.bi-music-player::before { content: "\f4a2"; } +.bi-newspaper::before { content: "\f4a3"; } +.bi-node-minus-fill::before { content: "\f4a4"; } +.bi-node-minus::before { content: "\f4a5"; } +.bi-node-plus-fill::before { content: "\f4a6"; } +.bi-node-plus::before { content: "\f4a7"; } +.bi-nut-fill::before { content: "\f4a8"; } +.bi-nut::before { content: "\f4a9"; } +.bi-octagon-fill::before { content: "\f4aa"; } +.bi-octagon-half::before { content: "\f4ab"; } +.bi-octagon::before { content: "\f4ac"; } +.bi-option::before { content: "\f4ad"; } +.bi-outlet::before { content: "\f4ae"; } +.bi-paint-bucket::before { content: "\f4af"; } +.bi-palette-fill::before { content: "\f4b0"; } +.bi-palette::before { content: "\f4b1"; } +.bi-palette2::before { content: "\f4b2"; } +.bi-paperclip::before { content: "\f4b3"; } +.bi-paragraph::before { content: "\f4b4"; } +.bi-patch-check-fill::before { content: "\f4b5"; } +.bi-patch-check::before { content: "\f4b6"; } +.bi-patch-exclamation-fill::before { content: "\f4b7"; } +.bi-patch-exclamation::before { content: "\f4b8"; } +.bi-patch-minus-fill::before { content: "\f4b9"; } +.bi-patch-minus::before { content: "\f4ba"; } +.bi-patch-plus-fill::before { content: "\f4bb"; } +.bi-patch-plus::before { content: "\f4bc"; } +.bi-patch-question-fill::before { content: "\f4bd"; } +.bi-patch-question::before { content: "\f4be"; } +.bi-pause-btn-fill::before { content: "\f4bf"; } +.bi-pause-btn::before { content: "\f4c0"; } +.bi-pause-circle-fill::before { content: "\f4c1"; } +.bi-pause-circle::before { content: "\f4c2"; } +.bi-pause-fill::before { content: "\f4c3"; } +.bi-pause::before { content: "\f4c4"; } +.bi-peace-fill::before { content: "\f4c5"; } +.bi-peace::before { content: "\f4c6"; } +.bi-pen-fill::before { content: "\f4c7"; } +.bi-pen::before { content: "\f4c8"; } +.bi-pencil-fill::before { content: "\f4c9"; } +.bi-pencil-square::before { content: "\f4ca"; } +.bi-pencil::before { content: "\f4cb"; } +.bi-pentagon-fill::before { content: "\f4cc"; } +.bi-pentagon-half::before { content: "\f4cd"; } +.bi-pentagon::before { content: "\f4ce"; } +.bi-people-fill::before { content: "\f4cf"; } +.bi-people::before { content: "\f4d0"; } +.bi-percent::before { content: "\f4d1"; } +.bi-person-badge-fill::before { content: "\f4d2"; } +.bi-person-badge::before { content: "\f4d3"; } +.bi-person-bounding-box::before { content: "\f4d4"; } +.bi-person-check-fill::before { content: "\f4d5"; } +.bi-person-check::before { content: "\f4d6"; } +.bi-person-circle::before { content: "\f4d7"; } +.bi-person-dash-fill::before { content: "\f4d8"; } +.bi-person-dash::before { content: "\f4d9"; } +.bi-person-fill::before { content: "\f4da"; } +.bi-person-lines-fill::before { content: "\f4db"; } +.bi-person-plus-fill::before { content: "\f4dc"; } +.bi-person-plus::before { content: "\f4dd"; } +.bi-person-square::before { content: "\f4de"; } +.bi-person-x-fill::before { content: "\f4df"; } +.bi-person-x::before { content: "\f4e0"; } +.bi-person::before { content: "\f4e1"; } +.bi-phone-fill::before { content: "\f4e2"; } +.bi-phone-landscape-fill::before { content: "\f4e3"; } +.bi-phone-landscape::before { content: "\f4e4"; } +.bi-phone-vibrate-fill::before { content: "\f4e5"; } +.bi-phone-vibrate::before { content: "\f4e6"; } +.bi-phone::before { content: "\f4e7"; } +.bi-pie-chart-fill::before { content: "\f4e8"; } +.bi-pie-chart::before { content: "\f4e9"; } +.bi-pin-angle-fill::before { content: "\f4ea"; } +.bi-pin-angle::before { content: "\f4eb"; } +.bi-pin-fill::before { content: "\f4ec"; } +.bi-pin::before { content: "\f4ed"; } +.bi-pip-fill::before { content: "\f4ee"; } +.bi-pip::before { content: "\f4ef"; } +.bi-play-btn-fill::before { content: "\f4f0"; } +.bi-play-btn::before { content: "\f4f1"; } +.bi-play-circle-fill::before { content: "\f4f2"; } +.bi-play-circle::before { content: "\f4f3"; } +.bi-play-fill::before { content: "\f4f4"; } +.bi-play::before { content: "\f4f5"; } +.bi-plug-fill::before { content: "\f4f6"; } +.bi-plug::before { content: "\f4f7"; } +.bi-plus-circle-dotted::before { content: "\f4f8"; } +.bi-plus-circle-fill::before { content: "\f4f9"; } +.bi-plus-circle::before { content: "\f4fa"; } +.bi-plus-square-dotted::before { content: "\f4fb"; } +.bi-plus-square-fill::before { content: "\f4fc"; } +.bi-plus-square::before { content: "\f4fd"; } +.bi-plus::before { content: "\f4fe"; } +.bi-power::before { content: "\f4ff"; } +.bi-printer-fill::before { content: "\f500"; } +.bi-printer::before { content: "\f501"; } +.bi-puzzle-fill::before { content: "\f502"; } +.bi-puzzle::before { content: "\f503"; } +.bi-question-circle-fill::before { content: "\f504"; } +.bi-question-circle::before { content: "\f505"; } +.bi-question-diamond-fill::before { content: "\f506"; } +.bi-question-diamond::before { content: "\f507"; } +.bi-question-octagon-fill::before { content: "\f508"; } +.bi-question-octagon::before { content: "\f509"; } +.bi-question-square-fill::before { content: "\f50a"; } +.bi-question-square::before { content: "\f50b"; } +.bi-question::before { content: "\f50c"; } +.bi-rainbow::before { content: "\f50d"; } +.bi-receipt-cutoff::before { content: "\f50e"; } +.bi-receipt::before { content: "\f50f"; } +.bi-reception-0::before { content: "\f510"; } +.bi-reception-1::before { content: "\f511"; } +.bi-reception-2::before { content: "\f512"; } +.bi-reception-3::before { content: "\f513"; } +.bi-reception-4::before { content: "\f514"; } +.bi-record-btn-fill::before { content: "\f515"; } +.bi-record-btn::before { content: "\f516"; } +.bi-record-circle-fill::before { content: "\f517"; } +.bi-record-circle::before { content: "\f518"; } +.bi-record-fill::before { content: "\f519"; } +.bi-record::before { content: "\f51a"; } +.bi-record2-fill::before { content: "\f51b"; } +.bi-record2::before { content: "\f51c"; } +.bi-reply-all-fill::before { content: "\f51d"; } +.bi-reply-all::before { content: "\f51e"; } +.bi-reply-fill::before { content: "\f51f"; } +.bi-reply::before { content: "\f520"; } +.bi-rss-fill::before { content: "\f521"; } +.bi-rss::before { content: "\f522"; } +.bi-rulers::before { content: "\f523"; } +.bi-save-fill::before { content: "\f524"; } +.bi-save::before { content: "\f525"; } +.bi-save2-fill::before { content: "\f526"; } +.bi-save2::before { content: "\f527"; } +.bi-scissors::before { content: "\f528"; } +.bi-screwdriver::before { content: "\f529"; } +.bi-search::before { content: "\f52a"; } +.bi-segmented-nav::before { content: "\f52b"; } +.bi-server::before { content: "\f52c"; } +.bi-share-fill::before { content: "\f52d"; } +.bi-share::before { content: "\f52e"; } +.bi-shield-check::before { content: "\f52f"; } +.bi-shield-exclamation::before { content: "\f530"; } +.bi-shield-fill-check::before { content: "\f531"; } +.bi-shield-fill-exclamation::before { content: "\f532"; } +.bi-shield-fill-minus::before { content: "\f533"; } +.bi-shield-fill-plus::before { content: "\f534"; } +.bi-shield-fill-x::before { content: "\f535"; } +.bi-shield-fill::before { content: "\f536"; } +.bi-shield-lock-fill::before { content: "\f537"; } +.bi-shield-lock::before { content: "\f538"; } +.bi-shield-minus::before { content: "\f539"; } +.bi-shield-plus::before { content: "\f53a"; } +.bi-shield-shaded::before { content: "\f53b"; } +.bi-shield-slash-fill::before { content: "\f53c"; } +.bi-shield-slash::before { content: "\f53d"; } +.bi-shield-x::before { content: "\f53e"; } +.bi-shield::before { content: "\f53f"; } +.bi-shift-fill::before { content: "\f540"; } +.bi-shift::before { content: "\f541"; } +.bi-shop-window::before { content: "\f542"; } +.bi-shop::before { content: "\f543"; } +.bi-shuffle::before { content: "\f544"; } +.bi-signpost-2-fill::before { content: "\f545"; } +.bi-signpost-2::before { content: "\f546"; } +.bi-signpost-fill::before { content: "\f547"; } +.bi-signpost-split-fill::before { content: "\f548"; } +.bi-signpost-split::before { content: "\f549"; } +.bi-signpost::before { content: "\f54a"; } +.bi-sim-fill::before { content: "\f54b"; } +.bi-sim::before { content: "\f54c"; } +.bi-skip-backward-btn-fill::before { content: "\f54d"; } +.bi-skip-backward-btn::before { content: "\f54e"; } +.bi-skip-backward-circle-fill::before { content: "\f54f"; } +.bi-skip-backward-circle::before { content: "\f550"; } +.bi-skip-backward-fill::before { content: "\f551"; } +.bi-skip-backward::before { content: "\f552"; } +.bi-skip-end-btn-fill::before { content: "\f553"; } +.bi-skip-end-btn::before { content: "\f554"; } +.bi-skip-end-circle-fill::before { content: "\f555"; } +.bi-skip-end-circle::before { content: "\f556"; } +.bi-skip-end-fill::before { content: "\f557"; } +.bi-skip-end::before { content: "\f558"; } +.bi-skip-forward-btn-fill::before { content: "\f559"; } +.bi-skip-forward-btn::before { content: "\f55a"; } +.bi-skip-forward-circle-fill::before { content: "\f55b"; } +.bi-skip-forward-circle::before { content: "\f55c"; } +.bi-skip-forward-fill::before { content: "\f55d"; } +.bi-skip-forward::before { content: "\f55e"; } +.bi-skip-start-btn-fill::before { content: "\f55f"; } +.bi-skip-start-btn::before { content: "\f560"; } +.bi-skip-start-circle-fill::before { content: "\f561"; } +.bi-skip-start-circle::before { content: "\f562"; } +.bi-skip-start-fill::before { content: "\f563"; } +.bi-skip-start::before { content: "\f564"; } +.bi-slack::before { content: "\f565"; } +.bi-slash-circle-fill::before { content: "\f566"; } +.bi-slash-circle::before { content: "\f567"; } +.bi-slash-square-fill::before { content: "\f568"; } +.bi-slash-square::before { content: "\f569"; } +.bi-slash::before { content: "\f56a"; } +.bi-sliders::before { content: "\f56b"; } +.bi-smartwatch::before { content: "\f56c"; } +.bi-snow::before { content: "\f56d"; } +.bi-snow2::before { content: "\f56e"; } +.bi-snow3::before { content: "\f56f"; } +.bi-sort-alpha-down-alt::before { content: "\f570"; } +.bi-sort-alpha-down::before { content: "\f571"; } +.bi-sort-alpha-up-alt::before { content: "\f572"; } +.bi-sort-alpha-up::before { content: "\f573"; } +.bi-sort-down-alt::before { content: "\f574"; } +.bi-sort-down::before { content: "\f575"; } +.bi-sort-numeric-down-alt::before { content: "\f576"; } +.bi-sort-numeric-down::before { content: "\f577"; } +.bi-sort-numeric-up-alt::before { content: "\f578"; } +.bi-sort-numeric-up::before { content: "\f579"; } +.bi-sort-up-alt::before { content: "\f57a"; } +.bi-sort-up::before { content: "\f57b"; } +.bi-soundwave::before { content: "\f57c"; } +.bi-speaker-fill::before { content: "\f57d"; } +.bi-speaker::before { content: "\f57e"; } +.bi-speedometer::before { content: "\f57f"; } +.bi-speedometer2::before { content: "\f580"; } +.bi-spellcheck::before { content: "\f581"; } +.bi-square-fill::before { content: "\f582"; } +.bi-square-half::before { content: "\f583"; } +.bi-square::before { content: "\f584"; } +.bi-stack::before { content: "\f585"; } +.bi-star-fill::before { content: "\f586"; } +.bi-star-half::before { content: "\f587"; } +.bi-star::before { content: "\f588"; } +.bi-stars::before { content: "\f589"; } +.bi-stickies-fill::before { content: "\f58a"; } +.bi-stickies::before { content: "\f58b"; } +.bi-sticky-fill::before { content: "\f58c"; } +.bi-sticky::before { content: "\f58d"; } +.bi-stop-btn-fill::before { content: "\f58e"; } +.bi-stop-btn::before { content: "\f58f"; } +.bi-stop-circle-fill::before { content: "\f590"; } +.bi-stop-circle::before { content: "\f591"; } +.bi-stop-fill::before { content: "\f592"; } +.bi-stop::before { content: "\f593"; } +.bi-stoplights-fill::before { content: "\f594"; } +.bi-stoplights::before { content: "\f595"; } +.bi-stopwatch-fill::before { content: "\f596"; } +.bi-stopwatch::before { content: "\f597"; } +.bi-subtract::before { content: "\f598"; } +.bi-suit-club-fill::before { content: "\f599"; } +.bi-suit-club::before { content: "\f59a"; } +.bi-suit-diamond-fill::before { content: "\f59b"; } +.bi-suit-diamond::before { content: "\f59c"; } +.bi-suit-heart-fill::before { content: "\f59d"; } +.bi-suit-heart::before { content: "\f59e"; } +.bi-suit-spade-fill::before { content: "\f59f"; } +.bi-suit-spade::before { content: "\f5a0"; } +.bi-sun-fill::before { content: "\f5a1"; } +.bi-sun::before { content: "\f5a2"; } +.bi-sunglasses::before { content: "\f5a3"; } +.bi-sunrise-fill::before { content: "\f5a4"; } +.bi-sunrise::before { content: "\f5a5"; } +.bi-sunset-fill::before { content: "\f5a6"; } +.bi-sunset::before { content: "\f5a7"; } +.bi-symmetry-horizontal::before { content: "\f5a8"; } +.bi-symmetry-vertical::before { content: "\f5a9"; } +.bi-table::before { content: "\f5aa"; } +.bi-tablet-fill::before { content: "\f5ab"; } +.bi-tablet-landscape-fill::before { content: "\f5ac"; } +.bi-tablet-landscape::before { content: "\f5ad"; } +.bi-tablet::before { content: "\f5ae"; } +.bi-tag-fill::before { content: "\f5af"; } +.bi-tag::before { content: "\f5b0"; } +.bi-tags-fill::before { content: "\f5b1"; } +.bi-tags::before { content: "\f5b2"; } +.bi-telegram::before { content: "\f5b3"; } +.bi-telephone-fill::before { content: "\f5b4"; } +.bi-telephone-forward-fill::before { content: "\f5b5"; } +.bi-telephone-forward::before { content: "\f5b6"; } +.bi-telephone-inbound-fill::before { content: "\f5b7"; } +.bi-telephone-inbound::before { content: "\f5b8"; } +.bi-telephone-minus-fill::before { content: "\f5b9"; } +.bi-telephone-minus::before { content: "\f5ba"; } +.bi-telephone-outbound-fill::before { content: "\f5bb"; } +.bi-telephone-outbound::before { content: "\f5bc"; } +.bi-telephone-plus-fill::before { content: "\f5bd"; } +.bi-telephone-plus::before { content: "\f5be"; } +.bi-telephone-x-fill::before { content: "\f5bf"; } +.bi-telephone-x::before { content: "\f5c0"; } +.bi-telephone::before { content: "\f5c1"; } +.bi-terminal-fill::before { content: "\f5c2"; } +.bi-terminal::before { content: "\f5c3"; } +.bi-text-center::before { content: "\f5c4"; } +.bi-text-indent-left::before { content: "\f5c5"; } +.bi-text-indent-right::before { content: "\f5c6"; } +.bi-text-left::before { content: "\f5c7"; } +.bi-text-paragraph::before { content: "\f5c8"; } +.bi-text-right::before { content: "\f5c9"; } +.bi-textarea-resize::before { content: "\f5ca"; } +.bi-textarea-t::before { content: "\f5cb"; } +.bi-textarea::before { content: "\f5cc"; } +.bi-thermometer-half::before { content: "\f5cd"; } +.bi-thermometer-high::before { content: "\f5ce"; } +.bi-thermometer-low::before { content: "\f5cf"; } +.bi-thermometer-snow::before { content: "\f5d0"; } +.bi-thermometer-sun::before { content: "\f5d1"; } +.bi-thermometer::before { content: "\f5d2"; } +.bi-three-dots-vertical::before { content: "\f5d3"; } +.bi-three-dots::before { content: "\f5d4"; } +.bi-toggle-off::before { content: "\f5d5"; } +.bi-toggle-on::before { content: "\f5d6"; } +.bi-toggle2-off::before { content: "\f5d7"; } +.bi-toggle2-on::before { content: "\f5d8"; } +.bi-toggles::before { content: "\f5d9"; } +.bi-toggles2::before { content: "\f5da"; } +.bi-tools::before { content: "\f5db"; } +.bi-tornado::before { content: "\f5dc"; } +.bi-trash-fill::before { content: "\f5dd"; } +.bi-trash::before { content: "\f5de"; } +.bi-trash2-fill::before { content: "\f5df"; } +.bi-trash2::before { content: "\f5e0"; } +.bi-tree-fill::before { content: "\f5e1"; } +.bi-tree::before { content: "\f5e2"; } +.bi-triangle-fill::before { content: "\f5e3"; } +.bi-triangle-half::before { content: "\f5e4"; } +.bi-triangle::before { content: "\f5e5"; } +.bi-trophy-fill::before { content: "\f5e6"; } +.bi-trophy::before { content: "\f5e7"; } +.bi-tropical-storm::before { content: "\f5e8"; } +.bi-truck-flatbed::before { content: "\f5e9"; } +.bi-truck::before { content: "\f5ea"; } +.bi-tsunami::before { content: "\f5eb"; } +.bi-tv-fill::before { content: "\f5ec"; } +.bi-tv::before { content: "\f5ed"; } +.bi-twitch::before { content: "\f5ee"; } +.bi-twitter::before { content: "\f5ef"; } +.bi-type-bold::before { content: "\f5f0"; } +.bi-type-h1::before { content: "\f5f1"; } +.bi-type-h2::before { content: "\f5f2"; } +.bi-type-h3::before { content: "\f5f3"; } +.bi-type-italic::before { content: "\f5f4"; } +.bi-type-strikethrough::before { content: "\f5f5"; } +.bi-type-underline::before { content: "\f5f6"; } +.bi-type::before { content: "\f5f7"; } +.bi-ui-checks-grid::before { content: "\f5f8"; } +.bi-ui-checks::before { content: "\f5f9"; } +.bi-ui-radios-grid::before { content: "\f5fa"; } +.bi-ui-radios::before { content: "\f5fb"; } +.bi-umbrella-fill::before { content: "\f5fc"; } +.bi-umbrella::before { content: "\f5fd"; } +.bi-union::before { content: "\f5fe"; } +.bi-unlock-fill::before { content: "\f5ff"; } +.bi-unlock::before { content: "\f600"; } +.bi-upc-scan::before { content: "\f601"; } +.bi-upc::before { content: "\f602"; } +.bi-upload::before { content: "\f603"; } +.bi-vector-pen::before { content: "\f604"; } +.bi-view-list::before { content: "\f605"; } +.bi-view-stacked::before { content: "\f606"; } +.bi-vinyl-fill::before { content: "\f607"; } +.bi-vinyl::before { content: "\f608"; } +.bi-voicemail::before { content: "\f609"; } +.bi-volume-down-fill::before { content: "\f60a"; } +.bi-volume-down::before { content: "\f60b"; } +.bi-volume-mute-fill::before { content: "\f60c"; } +.bi-volume-mute::before { content: "\f60d"; } +.bi-volume-off-fill::before { content: "\f60e"; } +.bi-volume-off::before { content: "\f60f"; } +.bi-volume-up-fill::before { content: "\f610"; } +.bi-volume-up::before { content: "\f611"; } +.bi-vr::before { content: "\f612"; } +.bi-wallet-fill::before { content: "\f613"; } +.bi-wallet::before { content: "\f614"; } +.bi-wallet2::before { content: "\f615"; } +.bi-watch::before { content: "\f616"; } +.bi-water::before { content: "\f617"; } +.bi-whatsapp::before { content: "\f618"; } +.bi-wifi-1::before { content: "\f619"; } +.bi-wifi-2::before { content: "\f61a"; } +.bi-wifi-off::before { content: "\f61b"; } +.bi-wifi::before { content: "\f61c"; } +.bi-wind::before { content: "\f61d"; } +.bi-window-dock::before { content: "\f61e"; } +.bi-window-sidebar::before { content: "\f61f"; } +.bi-window::before { content: "\f620"; } +.bi-wrench::before { content: "\f621"; } +.bi-x-circle-fill::before { content: "\f622"; } +.bi-x-circle::before { content: "\f623"; } +.bi-x-diamond-fill::before { content: "\f624"; } +.bi-x-diamond::before { content: "\f625"; } +.bi-x-octagon-fill::before { content: "\f626"; } +.bi-x-octagon::before { content: "\f627"; } +.bi-x-square-fill::before { content: "\f628"; } +.bi-x-square::before { content: "\f629"; } +.bi-x::before { content: "\f62a"; } +.bi-youtube::before { content: "\f62b"; } +.bi-zoom-in::before { content: "\f62c"; } +.bi-zoom-out::before { content: "\f62d"; } +.bi-bank::before { content: "\f62e"; } +.bi-bank2::before { content: "\f62f"; } +.bi-bell-slash-fill::before { content: "\f630"; } +.bi-bell-slash::before { content: "\f631"; } +.bi-cash-coin::before { content: "\f632"; } +.bi-check-lg::before { content: "\f633"; } +.bi-coin::before { content: "\f634"; } +.bi-currency-bitcoin::before { content: "\f635"; } +.bi-currency-dollar::before { content: "\f636"; } +.bi-currency-euro::before { content: "\f637"; } +.bi-currency-exchange::before { content: "\f638"; } +.bi-currency-pound::before { content: "\f639"; } +.bi-currency-yen::before { content: "\f63a"; } +.bi-dash-lg::before { content: "\f63b"; } +.bi-exclamation-lg::before { content: "\f63c"; } +.bi-file-earmark-pdf-fill::before { content: "\f63d"; } +.bi-file-earmark-pdf::before { content: "\f63e"; } +.bi-file-pdf-fill::before { content: "\f63f"; } +.bi-file-pdf::before { content: "\f640"; } +.bi-gender-ambiguous::before { content: "\f641"; } +.bi-gender-female::before { content: "\f642"; } +.bi-gender-male::before { content: "\f643"; } +.bi-gender-trans::before { content: "\f644"; } +.bi-headset-vr::before { content: "\f645"; } +.bi-info-lg::before { content: "\f646"; } +.bi-mastodon::before { content: "\f647"; } +.bi-messenger::before { content: "\f648"; } +.bi-piggy-bank-fill::before { content: "\f649"; } +.bi-piggy-bank::before { content: "\f64a"; } +.bi-pin-map-fill::before { content: "\f64b"; } +.bi-pin-map::before { content: "\f64c"; } +.bi-plus-lg::before { content: "\f64d"; } +.bi-question-lg::before { content: "\f64e"; } +.bi-recycle::before { content: "\f64f"; } +.bi-reddit::before { content: "\f650"; } +.bi-safe-fill::before { content: "\f651"; } +.bi-safe2-fill::before { content: "\f652"; } +.bi-safe2::before { content: "\f653"; } +.bi-sd-card-fill::before { content: "\f654"; } +.bi-sd-card::before { content: "\f655"; } +.bi-skype::before { content: "\f656"; } +.bi-slash-lg::before { content: "\f657"; } +.bi-translate::before { content: "\f658"; } +.bi-x-lg::before { content: "\f659"; } +.bi-safe::before { content: "\f65a"; } +.bi-apple::before { content: "\f65b"; } +.bi-microsoft::before { content: "\f65d"; } +.bi-windows::before { content: "\f65e"; } +.bi-behance::before { content: "\f65c"; } +.bi-dribbble::before { content: "\f65f"; } +.bi-line::before { content: "\f660"; } +.bi-medium::before { content: "\f661"; } +.bi-paypal::before { content: "\f662"; } +.bi-pinterest::before { content: "\f663"; } +.bi-signal::before { content: "\f664"; } +.bi-snapchat::before { content: "\f665"; } +.bi-spotify::before { content: "\f666"; } +.bi-stack-overflow::before { content: "\f667"; } +.bi-strava::before { content: "\f668"; } +.bi-wordpress::before { content: "\f669"; } +.bi-vimeo::before { content: "\f66a"; } +.bi-activity::before { content: "\f66b"; } +.bi-easel2-fill::before { content: "\f66c"; } +.bi-easel2::before { content: "\f66d"; } +.bi-easel3-fill::before { content: "\f66e"; } +.bi-easel3::before { content: "\f66f"; } +.bi-fan::before { content: "\f670"; } +.bi-fingerprint::before { content: "\f671"; } +.bi-graph-down-arrow::before { content: "\f672"; } +.bi-graph-up-arrow::before { content: "\f673"; } +.bi-hypnotize::before { content: "\f674"; } +.bi-magic::before { content: "\f675"; } +.bi-person-rolodex::before { content: "\f676"; } +.bi-person-video::before { content: "\f677"; } +.bi-person-video2::before { content: "\f678"; } +.bi-person-video3::before { content: "\f679"; } +.bi-person-workspace::before { content: "\f67a"; } +.bi-radioactive::before { content: "\f67b"; } +.bi-webcam-fill::before { content: "\f67c"; } +.bi-webcam::before { content: "\f67d"; } +.bi-yin-yang::before { content: "\f67e"; } +.bi-bandaid-fill::before { content: "\f680"; } +.bi-bandaid::before { content: "\f681"; } +.bi-bluetooth::before { content: "\f682"; } +.bi-body-text::before { content: "\f683"; } +.bi-boombox::before { content: "\f684"; } +.bi-boxes::before { content: "\f685"; } +.bi-dpad-fill::before { content: "\f686"; } +.bi-dpad::before { content: "\f687"; } +.bi-ear-fill::before { content: "\f688"; } +.bi-ear::before { content: "\f689"; } +.bi-envelope-check-1::before { content: "\f68a"; } +.bi-envelope-check-fill::before { content: "\f68b"; } +.bi-envelope-check::before { content: "\f68c"; } +.bi-envelope-dash-1::before { content: "\f68d"; } +.bi-envelope-dash-fill::before { content: "\f68e"; } +.bi-envelope-dash::before { content: "\f68f"; } +.bi-envelope-exclamation-1::before { content: "\f690"; } +.bi-envelope-exclamation-fill::before { content: "\f691"; } +.bi-envelope-exclamation::before { content: "\f692"; } +.bi-envelope-plus-fill::before { content: "\f693"; } +.bi-envelope-plus::before { content: "\f694"; } +.bi-envelope-slash-1::before { content: "\f695"; } +.bi-envelope-slash-fill::before { content: "\f696"; } +.bi-envelope-slash::before { content: "\f697"; } +.bi-envelope-x-1::before { content: "\f698"; } +.bi-envelope-x-fill::before { content: "\f699"; } +.bi-envelope-x::before { content: "\f69a"; } +.bi-explicit-fill::before { content: "\f69b"; } +.bi-explicit::before { content: "\f69c"; } +.bi-git::before { content: "\f69d"; } +.bi-infinity::before { content: "\f69e"; } +.bi-list-columns-reverse::before { content: "\f69f"; } +.bi-list-columns::before { content: "\f6a0"; } +.bi-meta::before { content: "\f6a1"; } +.bi-mortorboard-fill::before { content: "\f6a2"; } +.bi-mortorboard::before { content: "\f6a3"; } +.bi-nintendo-switch::before { content: "\f6a4"; } +.bi-pc-display-horizontal::before { content: "\f6a5"; } +.bi-pc-display::before { content: "\f6a6"; } +.bi-pc-horizontal::before { content: "\f6a7"; } +.bi-pc::before { content: "\f6a8"; } +.bi-playstation::before { content: "\f6a9"; } +.bi-plus-slash-minus::before { content: "\f6aa"; } +.bi-projector-fill::before { content: "\f6ab"; } +.bi-projector::before { content: "\f6ac"; } +.bi-qr-code-scan::before { content: "\f6ad"; } +.bi-qr-code::before { content: "\f6ae"; } +.bi-quora::before { content: "\f6af"; } +.bi-quote::before { content: "\f6b0"; } +.bi-robot::before { content: "\f6b1"; } +.bi-send-check-fill::before { content: "\f6b2"; } +.bi-send-check::before { content: "\f6b3"; } +.bi-send-dash-fill::before { content: "\f6b4"; } +.bi-send-dash::before { content: "\f6b5"; } +.bi-send-exclamation-1::before { content: "\f6b6"; } +.bi-send-exclamation-fill::before { content: "\f6b7"; } +.bi-send-exclamation::before { content: "\f6b8"; } +.bi-send-fill::before { content: "\f6b9"; } +.bi-send-plus-fill::before { content: "\f6ba"; } +.bi-send-plus::before { content: "\f6bb"; } +.bi-send-slash-fill::before { content: "\f6bc"; } +.bi-send-slash::before { content: "\f6bd"; } +.bi-send-x-fill::before { content: "\f6be"; } +.bi-send-x::before { content: "\f6bf"; } +.bi-send::before { content: "\f6c0"; } +.bi-steam::before { content: "\f6c1"; } +.bi-terminal-dash-1::before { content: "\f6c2"; } +.bi-terminal-dash::before { content: "\f6c3"; } +.bi-terminal-plus::before { content: "\f6c4"; } +.bi-terminal-split::before { content: "\f6c5"; } +.bi-ticket-detailed-fill::before { content: "\f6c6"; } +.bi-ticket-detailed::before { content: "\f6c7"; } +.bi-ticket-fill::before { content: "\f6c8"; } +.bi-ticket-perforated-fill::before { content: "\f6c9"; } +.bi-ticket-perforated::before { content: "\f6ca"; } +.bi-ticket::before { content: "\f6cb"; } +.bi-tiktok::before { content: "\f6cc"; } +.bi-window-dash::before { content: "\f6cd"; } +.bi-window-desktop::before { content: "\f6ce"; } +.bi-window-fullscreen::before { content: "\f6cf"; } +.bi-window-plus::before { content: "\f6d0"; } +.bi-window-split::before { content: "\f6d1"; } +.bi-window-stack::before { content: "\f6d2"; } +.bi-window-x::before { content: "\f6d3"; } +.bi-xbox::before { content: "\f6d4"; } +.bi-ethernet::before { content: "\f6d5"; } +.bi-hdmi-fill::before { content: "\f6d6"; } +.bi-hdmi::before { content: "\f6d7"; } +.bi-usb-c-fill::before { content: "\f6d8"; } +.bi-usb-c::before { content: "\f6d9"; } +.bi-usb-fill::before { content: "\f6da"; } +.bi-usb-plug-fill::before { content: "\f6db"; } +.bi-usb-plug::before { content: "\f6dc"; } +.bi-usb-symbol::before { content: "\f6dd"; } +.bi-usb::before { content: "\f6de"; } +.bi-boombox-fill::before { content: "\f6df"; } +.bi-displayport-1::before { content: "\f6e0"; } +.bi-displayport::before { content: "\f6e1"; } +.bi-gpu-card::before { content: "\f6e2"; } +.bi-memory::before { content: "\f6e3"; } +.bi-modem-fill::before { content: "\f6e4"; } +.bi-modem::before { content: "\f6e5"; } +.bi-motherboard-fill::before { content: "\f6e6"; } +.bi-motherboard::before { content: "\f6e7"; } +.bi-optical-audio-fill::before { content: "\f6e8"; } +.bi-optical-audio::before { content: "\f6e9"; } +.bi-pci-card::before { content: "\f6ea"; } +.bi-router-fill::before { content: "\f6eb"; } +.bi-router::before { content: "\f6ec"; } +.bi-ssd-fill::before { content: "\f6ed"; } +.bi-ssd::before { content: "\f6ee"; } +.bi-thunderbolt-fill::before { content: "\f6ef"; } +.bi-thunderbolt::before { content: "\f6f0"; } +.bi-usb-drive-fill::before { content: "\f6f1"; } +.bi-usb-drive::before { content: "\f6f2"; } +.bi-usb-micro-fill::before { content: "\f6f3"; } +.bi-usb-micro::before { content: "\f6f4"; } +.bi-usb-mini-fill::before { content: "\f6f5"; } +.bi-usb-mini::before { content: "\f6f6"; } +.bi-cloud-haze2::before { content: "\f6f7"; } +.bi-device-hdd-fill::before { content: "\f6f8"; } +.bi-device-hdd::before { content: "\f6f9"; } +.bi-device-ssd-fill::before { content: "\f6fa"; } +.bi-device-ssd::before { content: "\f6fb"; } +.bi-displayport-fill::before { content: "\f6fc"; } +.bi-mortarboard-fill::before { content: "\f6fd"; } +.bi-mortarboard::before { content: "\f6fe"; } +.bi-terminal-x::before { content: "\f6ff"; } +.bi-arrow-through-heart-fill::before { content: "\f700"; } +.bi-arrow-through-heart::before { content: "\f701"; } +.bi-badge-sd-fill::before { content: "\f702"; } +.bi-badge-sd::before { content: "\f703"; } +.bi-bag-heart-fill::before { content: "\f704"; } +.bi-bag-heart::before { content: "\f705"; } +.bi-balloon-fill::before { content: "\f706"; } +.bi-balloon-heart-fill::before { content: "\f707"; } +.bi-balloon-heart::before { content: "\f708"; } +.bi-balloon::before { content: "\f709"; } +.bi-box2-fill::before { content: "\f70a"; } +.bi-box2-heart-fill::before { content: "\f70b"; } +.bi-box2-heart::before { content: "\f70c"; } +.bi-box2::before { content: "\f70d"; } +.bi-braces-asterisk::before { content: "\f70e"; } +.bi-calendar-heart-fill::before { content: "\f70f"; } +.bi-calendar-heart::before { content: "\f710"; } +.bi-calendar2-heart-fill::before { content: "\f711"; } +.bi-calendar2-heart::before { content: "\f712"; } +.bi-chat-heart-fill::before { content: "\f713"; } +.bi-chat-heart::before { content: "\f714"; } +.bi-chat-left-heart-fill::before { content: "\f715"; } +.bi-chat-left-heart::before { content: "\f716"; } +.bi-chat-right-heart-fill::before { content: "\f717"; } +.bi-chat-right-heart::before { content: "\f718"; } +.bi-chat-square-heart-fill::before { content: "\f719"; } +.bi-chat-square-heart::before { content: "\f71a"; } +.bi-clipboard-check-fill::before { content: "\f71b"; } +.bi-clipboard-data-fill::before { content: "\f71c"; } +.bi-clipboard-fill::before { content: "\f71d"; } +.bi-clipboard-heart-fill::before { content: "\f71e"; } +.bi-clipboard-heart::before { content: "\f71f"; } +.bi-clipboard-minus-fill::before { content: "\f720"; } +.bi-clipboard-plus-fill::before { content: "\f721"; } +.bi-clipboard-pulse::before { content: "\f722"; } +.bi-clipboard-x-fill::before { content: "\f723"; } +.bi-clipboard2-check-fill::before { content: "\f724"; } +.bi-clipboard2-check::before { content: "\f725"; } +.bi-clipboard2-data-fill::before { content: "\f726"; } +.bi-clipboard2-data::before { content: "\f727"; } +.bi-clipboard2-fill::before { content: "\f728"; } +.bi-clipboard2-heart-fill::before { content: "\f729"; } +.bi-clipboard2-heart::before { content: "\f72a"; } +.bi-clipboard2-minus-fill::before { content: "\f72b"; } +.bi-clipboard2-minus::before { content: "\f72c"; } +.bi-clipboard2-plus-fill::before { content: "\f72d"; } +.bi-clipboard2-plus::before { content: "\f72e"; } +.bi-clipboard2-pulse-fill::before { content: "\f72f"; } +.bi-clipboard2-pulse::before { content: "\f730"; } +.bi-clipboard2-x-fill::before { content: "\f731"; } +.bi-clipboard2-x::before { content: "\f732"; } +.bi-clipboard2::before { content: "\f733"; } +.bi-emoji-kiss-fill::before { content: "\f734"; } +.bi-emoji-kiss::before { content: "\f735"; } +.bi-envelope-heart-fill::before { content: "\f736"; } +.bi-envelope-heart::before { content: "\f737"; } +.bi-envelope-open-heart-fill::before { content: "\f738"; } +.bi-envelope-open-heart::before { content: "\f739"; } +.bi-envelope-paper-fill::before { content: "\f73a"; } +.bi-envelope-paper-heart-fill::before { content: "\f73b"; } +.bi-envelope-paper-heart::before { content: "\f73c"; } +.bi-envelope-paper::before { content: "\f73d"; } +.bi-filetype-aac::before { content: "\f73e"; } +.bi-filetype-ai::before { content: "\f73f"; } +.bi-filetype-bmp::before { content: "\f740"; } +.bi-filetype-cs::before { content: "\f741"; } +.bi-filetype-css::before { content: "\f742"; } +.bi-filetype-csv::before { content: "\f743"; } +.bi-filetype-doc::before { content: "\f744"; } +.bi-filetype-docx::before { content: "\f745"; } +.bi-filetype-exe::before { content: "\f746"; } +.bi-filetype-gif::before { content: "\f747"; } +.bi-filetype-heic::before { content: "\f748"; } +.bi-filetype-html::before { content: "\f749"; } +.bi-filetype-java::before { content: "\f74a"; } +.bi-filetype-jpg::before { content: "\f74b"; } +.bi-filetype-js::before { content: "\f74c"; } +.bi-filetype-jsx::before { content: "\f74d"; } +.bi-filetype-key::before { content: "\f74e"; } +.bi-filetype-m4p::before { content: "\f74f"; } +.bi-filetype-md::before { content: "\f750"; } +.bi-filetype-mdx::before { content: "\f751"; } +.bi-filetype-mov::before { content: "\f752"; } +.bi-filetype-mp3::before { content: "\f753"; } +.bi-filetype-mp4::before { content: "\f754"; } +.bi-filetype-otf::before { content: "\f755"; } +.bi-filetype-pdf::before { content: "\f756"; } +.bi-filetype-php::before { content: "\f757"; } +.bi-filetype-png::before { content: "\f758"; } +.bi-filetype-ppt-1::before { content: "\f759"; } +.bi-filetype-ppt::before { content: "\f75a"; } +.bi-filetype-psd::before { content: "\f75b"; } +.bi-filetype-py::before { content: "\f75c"; } +.bi-filetype-raw::before { content: "\f75d"; } +.bi-filetype-rb::before { content: "\f75e"; } +.bi-filetype-sass::before { content: "\f75f"; } +.bi-filetype-scss::before { content: "\f760"; } +.bi-filetype-sh::before { content: "\f761"; } +.bi-filetype-svg::before { content: "\f762"; } +.bi-filetype-tiff::before { content: "\f763"; } +.bi-filetype-tsx::before { content: "\f764"; } +.bi-filetype-ttf::before { content: "\f765"; } +.bi-filetype-txt::before { content: "\f766"; } +.bi-filetype-wav::before { content: "\f767"; } +.bi-filetype-woff::before { content: "\f768"; } +.bi-filetype-xls-1::before { content: "\f769"; } +.bi-filetype-xls::before { content: "\f76a"; } +.bi-filetype-xml::before { content: "\f76b"; } +.bi-filetype-yml::before { content: "\f76c"; } +.bi-heart-arrow::before { content: "\f76d"; } +.bi-heart-pulse-fill::before { content: "\f76e"; } +.bi-heart-pulse::before { content: "\f76f"; } +.bi-heartbreak-fill::before { content: "\f770"; } +.bi-heartbreak::before { content: "\f771"; } +.bi-hearts::before { content: "\f772"; } +.bi-hospital-fill::before { content: "\f773"; } +.bi-hospital::before { content: "\f774"; } +.bi-house-heart-fill::before { content: "\f775"; } +.bi-house-heart::before { content: "\f776"; } +.bi-incognito::before { content: "\f777"; } +.bi-magnet-fill::before { content: "\f778"; } +.bi-magnet::before { content: "\f779"; } +.bi-person-heart::before { content: "\f77a"; } +.bi-person-hearts::before { content: "\f77b"; } +.bi-phone-flip::before { content: "\f77c"; } +.bi-plugin::before { content: "\f77d"; } +.bi-postage-fill::before { content: "\f77e"; } +.bi-postage-heart-fill::before { content: "\f77f"; } +.bi-postage-heart::before { content: "\f780"; } +.bi-postage::before { content: "\f781"; } +.bi-postcard-fill::before { content: "\f782"; } +.bi-postcard-heart-fill::before { content: "\f783"; } +.bi-postcard-heart::before { content: "\f784"; } +.bi-postcard::before { content: "\f785"; } +.bi-search-heart-fill::before { content: "\f786"; } +.bi-search-heart::before { content: "\f787"; } +.bi-sliders2-vertical::before { content: "\f788"; } +.bi-sliders2::before { content: "\f789"; } +.bi-trash3-fill::before { content: "\f78a"; } +.bi-trash3::before { content: "\f78b"; } +.bi-valentine::before { content: "\f78c"; } +.bi-valentine2::before { content: "\f78d"; } +.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; } +.bi-wrench-adjustable-circle::before { content: "\f78f"; } +.bi-wrench-adjustable::before { content: "\f790"; } +.bi-filetype-json::before { content: "\f791"; } +.bi-filetype-pptx::before { content: "\f792"; } +.bi-filetype-xlsx::before { content: "\f793"; } +.bi-1-circle-1::before { content: "\f794"; } +.bi-1-circle-fill-1::before { content: "\f795"; } +.bi-1-circle-fill::before { content: "\f796"; } +.bi-1-circle::before { content: "\f797"; } +.bi-1-square-fill::before { content: "\f798"; } +.bi-1-square::before { content: "\f799"; } +.bi-2-circle-1::before { content: "\f79a"; } +.bi-2-circle-fill-1::before { content: "\f79b"; } +.bi-2-circle-fill::before { content: "\f79c"; } +.bi-2-circle::before { content: "\f79d"; } +.bi-2-square-fill::before { content: "\f79e"; } +.bi-2-square::before { content: "\f79f"; } +.bi-3-circle-1::before { content: "\f7a0"; } +.bi-3-circle-fill-1::before { content: "\f7a1"; } +.bi-3-circle-fill::before { content: "\f7a2"; } +.bi-3-circle::before { content: "\f7a3"; } +.bi-3-square-fill::before { content: "\f7a4"; } +.bi-3-square::before { content: "\f7a5"; } +.bi-4-circle-1::before { content: "\f7a6"; } +.bi-4-circle-fill-1::before { content: "\f7a7"; } +.bi-4-circle-fill::before { content: "\f7a8"; } +.bi-4-circle::before { content: "\f7a9"; } +.bi-4-square-fill::before { content: "\f7aa"; } +.bi-4-square::before { content: "\f7ab"; } +.bi-5-circle-1::before { content: "\f7ac"; } +.bi-5-circle-fill-1::before { content: "\f7ad"; } +.bi-5-circle-fill::before { content: "\f7ae"; } +.bi-5-circle::before { content: "\f7af"; } +.bi-5-square-fill::before { content: "\f7b0"; } +.bi-5-square::before { content: "\f7b1"; } +.bi-6-circle-1::before { content: "\f7b2"; } +.bi-6-circle-fill-1::before { content: "\f7b3"; } +.bi-6-circle-fill::before { content: "\f7b4"; } +.bi-6-circle::before { content: "\f7b5"; } +.bi-6-square-fill::before { content: "\f7b6"; } +.bi-6-square::before { content: "\f7b7"; } +.bi-7-circle-1::before { content: "\f7b8"; } +.bi-7-circle-fill-1::before { content: "\f7b9"; } +.bi-7-circle-fill::before { content: "\f7ba"; } +.bi-7-circle::before { content: "\f7bb"; } +.bi-7-square-fill::before { content: "\f7bc"; } +.bi-7-square::before { content: "\f7bd"; } +.bi-8-circle-1::before { content: "\f7be"; } +.bi-8-circle-fill-1::before { content: "\f7bf"; } +.bi-8-circle-fill::before { content: "\f7c0"; } +.bi-8-circle::before { content: "\f7c1"; } +.bi-8-square-fill::before { content: "\f7c2"; } +.bi-8-square::before { content: "\f7c3"; } +.bi-9-circle-1::before { content: "\f7c4"; } +.bi-9-circle-fill-1::before { content: "\f7c5"; } +.bi-9-circle-fill::before { content: "\f7c6"; } +.bi-9-circle::before { content: "\f7c7"; } +.bi-9-square-fill::before { content: "\f7c8"; } +.bi-9-square::before { content: "\f7c9"; } +.bi-airplane-engines-fill::before { content: "\f7ca"; } +.bi-airplane-engines::before { content: "\f7cb"; } +.bi-airplane-fill::before { content: "\f7cc"; } +.bi-airplane::before { content: "\f7cd"; } +.bi-alexa::before { content: "\f7ce"; } +.bi-alipay::before { content: "\f7cf"; } +.bi-android::before { content: "\f7d0"; } +.bi-android2::before { content: "\f7d1"; } +.bi-box-fill::before { content: "\f7d2"; } +.bi-box-seam-fill::before { content: "\f7d3"; } +.bi-browser-chrome::before { content: "\f7d4"; } +.bi-browser-edge::before { content: "\f7d5"; } +.bi-browser-firefox::before { content: "\f7d6"; } +.bi-browser-safari::before { content: "\f7d7"; } +.bi-c-circle-1::before { content: "\f7d8"; } +.bi-c-circle-fill-1::before { content: "\f7d9"; } +.bi-c-circle-fill::before { content: "\f7da"; } +.bi-c-circle::before { content: "\f7db"; } +.bi-c-square-fill::before { content: "\f7dc"; } +.bi-c-square::before { content: "\f7dd"; } +.bi-capsule-pill::before { content: "\f7de"; } +.bi-capsule::before { content: "\f7df"; } +.bi-car-front-fill::before { content: "\f7e0"; } +.bi-car-front::before { content: "\f7e1"; } +.bi-cassette-fill::before { content: "\f7e2"; } +.bi-cassette::before { content: "\f7e3"; } +.bi-cc-circle-1::before { content: "\f7e4"; } +.bi-cc-circle-fill-1::before { content: "\f7e5"; } +.bi-cc-circle-fill::before { content: "\f7e6"; } +.bi-cc-circle::before { content: "\f7e7"; } +.bi-cc-square-fill::before { content: "\f7e8"; } +.bi-cc-square::before { content: "\f7e9"; } +.bi-cup-hot-fill::before { content: "\f7ea"; } +.bi-cup-hot::before { content: "\f7eb"; } +.bi-currency-rupee::before { content: "\f7ec"; } +.bi-dropbox::before { content: "\f7ed"; } +.bi-escape::before { content: "\f7ee"; } +.bi-fast-forward-btn-fill::before { content: "\f7ef"; } +.bi-fast-forward-btn::before { content: "\f7f0"; } +.bi-fast-forward-circle-fill::before { content: "\f7f1"; } +.bi-fast-forward-circle::before { content: "\f7f2"; } +.bi-fast-forward-fill::before { content: "\f7f3"; } +.bi-fast-forward::before { content: "\f7f4"; } +.bi-filetype-sql::before { content: "\f7f5"; } +.bi-fire::before { content: "\f7f6"; } +.bi-google-play::before { content: "\f7f7"; } +.bi-h-circle-1::before { content: "\f7f8"; } +.bi-h-circle-fill-1::before { content: "\f7f9"; } +.bi-h-circle-fill::before { content: "\f7fa"; } +.bi-h-circle::before { content: "\f7fb"; } +.bi-h-square-fill::before { content: "\f7fc"; } +.bi-h-square::before { content: "\f7fd"; } +.bi-indent::before { content: "\f7fe"; } +.bi-lungs-fill::before { content: "\f7ff"; } +.bi-lungs::before { content: "\f800"; } +.bi-microsoft-teams::before { content: "\f801"; } +.bi-p-circle-1::before { content: "\f802"; } +.bi-p-circle-fill-1::before { content: "\f803"; } +.bi-p-circle-fill::before { content: "\f804"; } +.bi-p-circle::before { content: "\f805"; } +.bi-p-square-fill::before { content: "\f806"; } +.bi-p-square::before { content: "\f807"; } +.bi-pass-fill::before { content: "\f808"; } +.bi-pass::before { content: "\f809"; } +.bi-prescription::before { content: "\f80a"; } +.bi-prescription2::before { content: "\f80b"; } +.bi-r-circle-1::before { content: "\f80c"; } +.bi-r-circle-fill-1::before { content: "\f80d"; } +.bi-r-circle-fill::before { content: "\f80e"; } +.bi-r-circle::before { content: "\f80f"; } +.bi-r-square-fill::before { content: "\f810"; } +.bi-r-square::before { content: "\f811"; } +.bi-repeat-1::before { content: "\f812"; } +.bi-repeat::before { content: "\f813"; } +.bi-rewind-btn-fill::before { content: "\f814"; } +.bi-rewind-btn::before { content: "\f815"; } +.bi-rewind-circle-fill::before { content: "\f816"; } +.bi-rewind-circle::before { content: "\f817"; } +.bi-rewind-fill::before { content: "\f818"; } +.bi-rewind::before { content: "\f819"; } +.bi-train-freight-front-fill::before { content: "\f81a"; } +.bi-train-freight-front::before { content: "\f81b"; } +.bi-train-front-fill::before { content: "\f81c"; } +.bi-train-front::before { content: "\f81d"; } +.bi-train-lightrail-front-fill::before { content: "\f81e"; } +.bi-train-lightrail-front::before { content: "\f81f"; } +.bi-truck-front-fill::before { content: "\f820"; } +.bi-truck-front::before { content: "\f821"; } +.bi-ubuntu::before { content: "\f822"; } +.bi-unindent::before { content: "\f823"; } +.bi-unity::before { content: "\f824"; } +.bi-universal-access-circle::before { content: "\f825"; } +.bi-universal-access::before { content: "\f826"; } +.bi-virus::before { content: "\f827"; } +.bi-virus2::before { content: "\f828"; } +.bi-wechat::before { content: "\f829"; } +.bi-yelp::before { content: "\f82a"; } +.bi-sign-stop-fill::before { content: "\f82b"; } +.bi-sign-stop-lights-fill::before { content: "\f82c"; } +.bi-sign-stop-lights::before { content: "\f82d"; } +.bi-sign-stop::before { content: "\f82e"; } +.bi-sign-turn-left-fill::before { content: "\f82f"; } +.bi-sign-turn-left::before { content: "\f830"; } +.bi-sign-turn-right-fill::before { content: "\f831"; } +.bi-sign-turn-right::before { content: "\f832"; } +.bi-sign-turn-slight-left-fill::before { content: "\f833"; } +.bi-sign-turn-slight-left::before { content: "\f834"; } +.bi-sign-turn-slight-right-fill::before { content: "\f835"; } +.bi-sign-turn-slight-right::before { content: "\f836"; } +.bi-sign-yield-fill::before { content: "\f837"; } +.bi-sign-yield::before { content: "\f838"; } +.bi-ev-station-fill::before { content: "\f839"; } +.bi-ev-station::before { content: "\f83a"; } +.bi-fuel-pump-diesel-fill::before { content: "\f83b"; } +.bi-fuel-pump-diesel::before { content: "\f83c"; } +.bi-fuel-pump-fill::before { content: "\f83d"; } +.bi-fuel-pump::before { content: "\f83e"; } +.bi-0-circle-fill::before { content: "\f83f"; } +.bi-0-circle::before { content: "\f840"; } +.bi-0-square-fill::before { content: "\f841"; } +.bi-0-square::before { content: "\f842"; } +.bi-rocket-fill::before { content: "\f843"; } +.bi-rocket-takeoff-fill::before { content: "\f844"; } +.bi-rocket-takeoff::before { content: "\f845"; } +.bi-rocket::before { content: "\f846"; } +.bi-stripe::before { content: "\f847"; } +.bi-subscript::before { content: "\f848"; } +.bi-superscript::before { content: "\f849"; } +.bi-trello::before { content: "\f84a"; } +.bi-envelope-at-fill::before { content: "\f84b"; } +.bi-envelope-at::before { content: "\f84c"; } +.bi-regex::before { content: "\f84d"; } +.bi-text-wrap::before { content: "\f84e"; } +.bi-sign-dead-end-fill::before { content: "\f84f"; } +.bi-sign-dead-end::before { content: "\f850"; } +.bi-sign-do-not-enter-fill::before { content: "\f851"; } +.bi-sign-do-not-enter::before { content: "\f852"; } +.bi-sign-intersection-fill::before { content: "\f853"; } +.bi-sign-intersection-side-fill::before { content: "\f854"; } +.bi-sign-intersection-side::before { content: "\f855"; } +.bi-sign-intersection-t-fill::before { content: "\f856"; } +.bi-sign-intersection-t::before { content: "\f857"; } +.bi-sign-intersection-y-fill::before { content: "\f858"; } +.bi-sign-intersection-y::before { content: "\f859"; } +.bi-sign-intersection::before { content: "\f85a"; } +.bi-sign-merge-left-fill::before { content: "\f85b"; } +.bi-sign-merge-left::before { content: "\f85c"; } +.bi-sign-merge-right-fill::before { content: "\f85d"; } +.bi-sign-merge-right::before { content: "\f85e"; } +.bi-sign-no-left-turn-fill::before { content: "\f85f"; } +.bi-sign-no-left-turn::before { content: "\f860"; } +.bi-sign-no-parking-fill::before { content: "\f861"; } +.bi-sign-no-parking::before { content: "\f862"; } +.bi-sign-no-right-turn-fill::before { content: "\f863"; } +.bi-sign-no-right-turn::before { content: "\f864"; } +.bi-sign-railroad-fill::before { content: "\f865"; } +.bi-sign-railroad::before { content: "\f866"; } +.bi-building-add::before { content: "\f867"; } +.bi-building-check::before { content: "\f868"; } +.bi-building-dash::before { content: "\f869"; } +.bi-building-down::before { content: "\f86a"; } +.bi-building-exclamation::before { content: "\f86b"; } +.bi-building-fill-add::before { content: "\f86c"; } +.bi-building-fill-check::before { content: "\f86d"; } +.bi-building-fill-dash::before { content: "\f86e"; } +.bi-building-fill-down::before { content: "\f86f"; } +.bi-building-fill-exclamation::before { content: "\f870"; } +.bi-building-fill-gear::before { content: "\f871"; } +.bi-building-fill-lock::before { content: "\f872"; } +.bi-building-fill-slash::before { content: "\f873"; } +.bi-building-fill-up::before { content: "\f874"; } +.bi-building-fill-x::before { content: "\f875"; } +.bi-building-fill::before { content: "\f876"; } +.bi-building-gear::before { content: "\f877"; } +.bi-building-lock::before { content: "\f878"; } +.bi-building-slash::before { content: "\f879"; } +.bi-building-up::before { content: "\f87a"; } +.bi-building-x::before { content: "\f87b"; } +.bi-buildings-fill::before { content: "\f87c"; } +.bi-buildings::before { content: "\f87d"; } +.bi-bus-front-fill::before { content: "\f87e"; } +.bi-bus-front::before { content: "\f87f"; } +.bi-ev-front-fill::before { content: "\f880"; } +.bi-ev-front::before { content: "\f881"; } +.bi-globe-americas::before { content: "\f882"; } +.bi-globe-asia-australia::before { content: "\f883"; } +.bi-globe-central-south-asia::before { content: "\f884"; } +.bi-globe-europe-africa::before { content: "\f885"; } +.bi-house-add-fill::before { content: "\f886"; } +.bi-house-add::before { content: "\f887"; } +.bi-house-check-fill::before { content: "\f888"; } +.bi-house-check::before { content: "\f889"; } +.bi-house-dash-fill::before { content: "\f88a"; } +.bi-house-dash::before { content: "\f88b"; } +.bi-house-down-fill::before { content: "\f88c"; } +.bi-house-down::before { content: "\f88d"; } +.bi-house-exclamation-fill::before { content: "\f88e"; } +.bi-house-exclamation::before { content: "\f88f"; } +.bi-house-gear-fill::before { content: "\f890"; } +.bi-house-gear::before { content: "\f891"; } +.bi-house-lock-fill::before { content: "\f892"; } +.bi-house-lock::before { content: "\f893"; } +.bi-house-slash-fill::before { content: "\f894"; } +.bi-house-slash::before { content: "\f895"; } +.bi-house-up-fill::before { content: "\f896"; } +.bi-house-up::before { content: "\f897"; } +.bi-house-x-fill::before { content: "\f898"; } +.bi-house-x::before { content: "\f899"; } +.bi-person-add::before { content: "\f89a"; } +.bi-person-down::before { content: "\f89b"; } +.bi-person-exclamation::before { content: "\f89c"; } +.bi-person-fill-add::before { content: "\f89d"; } +.bi-person-fill-check::before { content: "\f89e"; } +.bi-person-fill-dash::before { content: "\f89f"; } +.bi-person-fill-down::before { content: "\f8a0"; } +.bi-person-fill-exclamation::before { content: "\f8a1"; } +.bi-person-fill-gear::before { content: "\f8a2"; } +.bi-person-fill-lock::before { content: "\f8a3"; } +.bi-person-fill-slash::before { content: "\f8a4"; } +.bi-person-fill-up::before { content: "\f8a5"; } +.bi-person-fill-x::before { content: "\f8a6"; } +.bi-person-gear::before { content: "\f8a7"; } +.bi-person-lock::before { content: "\f8a8"; } +.bi-person-slash::before { content: "\f8a9"; } +.bi-person-up::before { content: "\f8aa"; } +.bi-scooter::before { content: "\f8ab"; } +.bi-taxi-front-fill::before { content: "\f8ac"; } +.bi-taxi-front::before { content: "\f8ad"; } +.bi-amd::before { content: "\f8ae"; } +.bi-database-add::before { content: "\f8af"; } +.bi-database-check::before { content: "\f8b0"; } +.bi-database-dash::before { content: "\f8b1"; } +.bi-database-down::before { content: "\f8b2"; } +.bi-database-exclamation::before { content: "\f8b3"; } +.bi-database-fill-add::before { content: "\f8b4"; } +.bi-database-fill-check::before { content: "\f8b5"; } +.bi-database-fill-dash::before { content: "\f8b6"; } +.bi-database-fill-down::before { content: "\f8b7"; } +.bi-database-fill-exclamation::before { content: "\f8b8"; } +.bi-database-fill-gear::before { content: "\f8b9"; } +.bi-database-fill-lock::before { content: "\f8ba"; } +.bi-database-fill-slash::before { content: "\f8bb"; } +.bi-database-fill-up::before { content: "\f8bc"; } +.bi-database-fill-x::before { content: "\f8bd"; } +.bi-database-fill::before { content: "\f8be"; } +.bi-database-gear::before { content: "\f8bf"; } +.bi-database-lock::before { content: "\f8c0"; } +.bi-database-slash::before { content: "\f8c1"; } +.bi-database-up::before { content: "\f8c2"; } +.bi-database-x::before { content: "\f8c3"; } +.bi-database::before { content: "\f8c4"; } +.bi-houses-fill::before { content: "\f8c5"; } +.bi-houses::before { content: "\f8c6"; } +.bi-nvidia::before { content: "\f8c7"; } +.bi-person-vcard-fill::before { content: "\f8c8"; } +.bi-person-vcard::before { content: "\f8c9"; } +.bi-sina-weibo::before { content: "\f8ca"; } +.bi-tencent-qq::before { content: "\f8cb"; } +.bi-wikipedia::before { content: "\f8cc"; } diff --git a/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css.br b/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css.br new file mode 100644 index 0000000..6efed5a Binary files /dev/null and b/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css.br differ diff --git a/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css.gz b/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css.gz new file mode 100644 index 0000000..71ae2a0 Binary files /dev/null and b/publish/wwwroot/lib/bootstrap-icons/bootstrap-icons.css.gz differ diff --git a/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css b/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css new file mode 100644 index 0000000..1472dec --- /dev/null +++ b/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css @@ -0,0 +1,7 @@ +@charset "UTF-8";/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-accent-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#cfe2ff;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:#000;border-color:#bacbe6}.table-secondary{--bs-table-bg:#e2e3e5;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:#000;border-color:#cbccce}.table-success{--bs-table-bg:#d1e7dd;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:#000;border-color:#bcd0c7}.table-info{--bs-table-bg:#cff4fc;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:#000;border-color:#badce3}.table-warning{--bs-table-bg:#fff3cd;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:#000;border-color:#e6dbb9}.table-danger{--bs-table-bg:#f8d7da;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:#000;border-color:#dfc2c4}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg:#212529;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:#fff;border-color:#373b3e}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.2rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.3rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(25,135,84,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#198754;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:1}.input-group .form-control.is-valid:focus,.input-group .form-select.is-valid:focus,.was-validated .input-group .form-control:valid:focus,.was-validated .input-group .form-select:valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:2}.input-group .form-control.is-invalid:focus,.input-group .form-select.is-invalid:focus,.was-validated .input-group .form-control:invalid:focus,.was-validated .input-group .form-select:invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#0b5ed7;border-color:#0a58ca}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#0b5ed7;border-color:#0a58ca;box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-check:active+.btn-primary,.btn-check:checked+.btn-primary,.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0a58ca;border-color:#0a53be}.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary:focus,.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:active+.btn-secondary,.btn-check:checked+.btn-secondary,.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#198754;border-color:#198754}.btn-success:hover{color:#fff;background-color:#157347;border-color:#146c43}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#157347;border-color:#146c43;box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-check:active+.btn-success,.btn-check:checked+.btn-success,.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#146c43;border-color:#13653f}.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success:focus,.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#198754;border-color:#198754}.btn-info{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-info:hover{color:#000;background-color:#31d2f2;border-color:#25cff2}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#31d2f2;border-color:#25cff2;box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-check:active+.btn-info,.btn-check:checked+.btn-info,.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#3dd5f3;border-color:#25cff2}.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info:focus,.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-info.disabled,.btn-info:disabled{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#000;background-color:#ffca2c;border-color:#ffc720}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#ffca2c;border-color:#ffc720;box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-check:active+.btn-warning,.btn-check:checked+.btn-warning,.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#ffcd39;border-color:#ffc720}.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning:focus,.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#bb2d3b;border-color:#b02a37}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#bb2d3b;border-color:#b02a37;box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-check:active+.btn-danger,.btn-check:checked+.btn-danger,.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b02a37;border-color:#a52834}.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger:focus,.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:active+.btn-light,.btn-check:checked+.btn-light,.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light:focus,.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light.disabled,.btn-light:disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#212529;border-color:#212529}.btn-dark:hover{color:#fff;background-color:#1c1f23;border-color:#1a1e21}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#1c1f23;border-color:#1a1e21;box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-check:active+.btn-dark,.btn-check:checked+.btn-dark,.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1a1e21;border-color:#191c1f}.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark:focus,.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#198754;border-color:#198754}.btn-outline-success:hover{color:#fff;background-color:#198754;border-color:#198754}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#198754;border-color:#198754}.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#198754;background-color:transparent}.btn-outline-info{color:#0dcaf0;border-color:#0dcaf0}.btn-outline-info:hover{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#0dcaf0;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-dark{color:#212529;border-color:#212529}.btn-outline-dark:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#212529;border-color:#212529}.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#212529;background-color:transparent}.btn-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#0a58ca}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropend,.dropstart,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:focus,.dropdown-menu-dark .dropdown-item:hover{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#0d6efd}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:#0a58ca}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:0 0;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#0d6efd}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-bottom,.navbar-expand-sm .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-bottom,.navbar-expand-md .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-bottom,.navbar-expand-lg .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-bottom,.navbar-expand-xl .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-bottom,.navbar-expand-xxl .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-bottom,.navbar-expand .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:#fff;border:0;border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#0c63e4;background-color:#e7f1ff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#0a58ca;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#0a58ca;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{color:#084298;background-color:#cfe2ff;border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0f5132;background-color:#d1e7dd;border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{color:#055160;background-color:#cff4fc;border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{color:#664d03;background-color:#fff3cd;border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{color:#842029;background-color:#f8d7da;border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{color:#636464;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{color:#141619;background-color:#d3d3d4;border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#0d6efd;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#084298;background-color:#cfe2ff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#084298;background-color:#bacbe6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#084298;border-color:#084298}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0f5132;background-color:#d1e7dd}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#0f5132;background-color:#bcd0c7}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0f5132;border-color:#0f5132}.list-group-item-info{color:#055160;background-color:#cff4fc}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#055160;background-color:#badce3}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#055160;border-color:#055160}.list-group-item-warning{color:#664d03;background-color:#fff3cd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#664d03;background-color:#e6dbb9}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#664d03;border-color:#664d03}.list-group-item-danger{color:#842029;background-color:#f8d7da}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#842029;background-color:#dfc2c4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#842029;border-color:#842029}.list-group-item-light{color:#636464;background-color:#fefefe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#636464;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#636464;border-color:#636464}.list-group-item-dark{color:#141619;background-color:#d3d3d4}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#141619;background-color:#bebebf}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#141619;border-color:#141619}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-header .btn-close{margin-right:-.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[data-popper-placement^=right],.bs-tooltip-end{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[data-popper-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[data-popper-placement^=left],.bs-tooltip-start{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2);border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-.5rem;margin-right:-.5rem;margin-bottom:-.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentColor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#0a58ca}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#565e64}.link-success{color:#198754}.link-success:focus,.link-success:hover{color:#146c43}.link-info{color:#0dcaf0}.link-info:focus,.link-info:hover{color:#3dd5f3}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ffcd39}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#b02a37}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#f9fafb}.link-dark{color:#212529}.link-dark:focus,.link-dark:hover{color:#1a1e21}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-end{border-right:1px solid #dee2e6!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:1px solid #dee2e6!important}.border-start-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#198754!important}.border-info{border-color:#0dcaf0!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#212529!important}.border-white{border-color:#fff!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:.2rem!important}.rounded-2{border-radius:.25rem!important}.rounded-3{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-end{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-start{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css.br b/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css.br new file mode 100644 index 0000000..c982990 Binary files /dev/null and b/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css.br differ diff --git a/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css.gz b/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css.gz new file mode 100644 index 0000000..60335ba Binary files /dev/null and b/publish/wwwroot/lib/bootstrap/css/bootstrap.min.css.gz differ diff --git a/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js b/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js new file mode 100644 index 0000000..cc0a255 --- /dev/null +++ b/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(", ");return this.find(e,t).filter((t=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Rt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ie={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.br b/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.br new file mode 100644 index 0000000..62c7bae Binary files /dev/null and b/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.br differ diff --git a/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.gz b/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.gz new file mode 100644 index 0000000..2cc0a8a Binary files /dev/null and b/publish/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.gz differ diff --git a/publish/wwwroot/lib/fontawesome/css/all.min.css b/publish/wwwroot/lib/fontawesome/css/all.min.css new file mode 100644 index 0000000..0a2cf52 --- /dev/null +++ b/publish/wwwroot/lib/fontawesome/css/all.min.css @@ -0,0 +1,6 @@ +/*! + * Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2022 Fonticons, Inc. + */ +.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-duotone,.fa-light,.fa-regular,.fa-solid,.fa-thin,.fab,.fad,.fal,.far,.fas,.fat{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{-webkit-animation-name:fa-beat;animation-name:fa-beat;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{-webkit-animation-name:fa-bounce;animation-name:fa-bounce;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{-webkit-animation-name:fa-fade;animation-name:fa-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{-webkit-animation-name:fa-beat-fade;animation-name:fa-beat-fade;-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1));animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{-webkit-animation-name:fa-flip;animation-name:fa-flip;-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,ease-in-out);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{-webkit-animation-name:fa-shake;animation-name:fa-shake;-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{-webkit-animation-delay:var(--fa-animation-delay,0);animation-delay:var(--fa-animation-delay,0);-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-duration:var(--fa-animation-duration,2s);animation-duration:var(--fa-animation-duration,2s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,linear);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{-webkit-animation-name:fa-spin;animation-name:fa-spin;-webkit-animation-direction:var(--fa-animation-direction,normal);animation-direction:var(--fa-animation-direction,normal);-webkit-animation-duration:var(--fa-animation-duration,1s);animation-duration:var(--fa-animation-duration,1s);-webkit-animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-iteration-count:var(--fa-animation-iteration-count,infinite);-webkit-animation-timing-function:var(--fa-animation-timing,steps(8));animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{-webkit-animation-delay:-1ms;animation-delay:-1ms;-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-iteration-count:1;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@-webkit-keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-beat{0%,90%{-webkit-transform:scale(1);transform:scale(1)}45%{-webkit-transform:scale(var(--fa-beat-scale,1.25));transform:scale(var(--fa-beat-scale,1.25))}}@-webkit-keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@keyframes fa-bounce{0%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}10%{-webkit-transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0);transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{-webkit-transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em));transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{-webkit-transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0);transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{-webkit-transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em));transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}to{-webkit-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}}@-webkit-keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@-webkit-keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);-webkit-transform:scale(1);transform:scale(1)}50%{opacity:1;-webkit-transform:scale(var(--fa-beat-fade-scale,1.125));transform:scale(var(--fa-beat-fade-scale,1.125))}}@-webkit-keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-flip{50%{-webkit-transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg));transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@-webkit-keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes fa-shake{0%{-webkit-transform:rotate(-15deg);transform:rotate(-15deg)}4%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}8%,24%{-webkit-transform:rotate(-18deg);transform:rotate(-18deg)}12%,28%{-webkit-transform:rotate(18deg);transform:rotate(18deg)}16%{-webkit-transform:rotate(-22deg);transform:rotate(-22deg)}20%{-webkit-transform:rotate(22deg);transform:rotate(22deg)}32%{-webkit-transform:rotate(-12deg);transform:rotate(-12deg)}36%{-webkit-transform:rotate(12deg);transform:rotate(12deg)}40%,to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}.fa-rotate-by{-webkit-transform:rotate(var(--fa-rotate-angle,none));transform:rotate(var(--fa-rotate-angle,none))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-0:before{content:"\30"}.fa-1:before{content:"\31"}.fa-2:before{content:"\32"}.fa-3:before{content:"\33"}.fa-4:before{content:"\34"}.fa-5:before{content:"\35"}.fa-6:before{content:"\36"}.fa-7:before{content:"\37"}.fa-8:before{content:"\38"}.fa-9:before{content:"\39"}.fa-a:before{content:"\41"}.fa-address-book:before,.fa-contact-book:before{content:"\f2b9"}.fa-address-card:before,.fa-contact-card:before,.fa-vcard:before{content:"\f2bb"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-anchor:before{content:"\f13d"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-double-down:before,.fa-angles-down:before{content:"\f103"}.fa-angle-double-left:before,.fa-angles-left:before{content:"\f100"}.fa-angle-double-right:before,.fa-angles-right:before{content:"\f101"}.fa-angle-double-up:before,.fa-angles-up:before{content:"\f102"}.fa-ankh:before{content:"\f644"}.fa-apple-alt:before,.fa-apple-whole:before{content:"\f5d1"}.fa-archway:before{content:"\f557"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-down-1-9:before,.fa-sort-numeric-asc:before,.fa-sort-numeric-down:before{content:"\f162"}.fa-arrow-down-9-1:before,.fa-sort-numeric-desc:before,.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-arrow-down-a-z:before,.fa-sort-alpha-asc:before,.fa-sort-alpha-down:before{content:"\f15d"}.fa-arrow-down-long:before,.fa-long-arrow-down:before{content:"\f175"}.fa-arrow-down-short-wide:before,.fa-sort-amount-desc:before,.fa-sort-amount-down-alt:before{content:"\f884"}.fa-arrow-down-wide-short:before,.fa-sort-amount-asc:before,.fa-sort-amount-down:before{content:"\f160"}.fa-arrow-down-z-a:before,.fa-sort-alpha-desc:before,.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-left-long:before,.fa-long-arrow-left:before{content:"\f177"}.fa-arrow-pointer:before,.fa-mouse-pointer:before{content:"\f245"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-right-arrow-left:before,.fa-exchange:before{content:"\f0ec"}.fa-arrow-right-from-bracket:before,.fa-sign-out:before{content:"\f08b"}.fa-arrow-right-long:before,.fa-long-arrow-right:before{content:"\f178"}.fa-arrow-right-to-bracket:before,.fa-sign-in:before{content:"\f090"}.fa-arrow-left-rotate:before,.fa-arrow-rotate-back:before,.fa-arrow-rotate-backward:before,.fa-arrow-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-arrow-right-rotate:before,.fa-arrow-rotate-forward:before,.fa-arrow-rotate-right:before,.fa-redo:before{content:"\f01e"}.fa-arrow-trend-down:before{content:"\e097"}.fa-arrow-trend-up:before{content:"\e098"}.fa-arrow-turn-down:before,.fa-level-down:before{content:"\f149"}.fa-arrow-turn-up:before,.fa-level-up:before{content:"\f148"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-up-1-9:before,.fa-sort-numeric-up:before{content:"\f163"}.fa-arrow-up-9-1:before,.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-arrow-up-a-z:before,.fa-sort-alpha-up:before{content:"\f15e"}.fa-arrow-up-from-bracket:before{content:"\e09a"}.fa-arrow-up-long:before,.fa-long-arrow-up:before{content:"\f176"}.fa-arrow-up-right-from-square:before,.fa-external-link:before{content:"\f08e"}.fa-arrow-up-short-wide:before,.fa-sort-amount-up-alt:before{content:"\f885"}.fa-arrow-up-wide-short:before,.fa-sort-amount-up:before{content:"\f161"}.fa-arrow-up-z-a:before,.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-arrows-h:before,.fa-arrows-left-right:before{content:"\f07e"}.fa-arrows-rotate:before,.fa-refresh:before,.fa-sync:before{content:"\f021"}.fa-arrows-up-down:before,.fa-arrows-v:before{content:"\f07d"}.fa-arrows-up-down-left-right:before,.fa-arrows:before{content:"\f047"}.fa-asterisk:before{content:"\2a"}.fa-at:before{content:"\40"}.fa-atom:before{content:"\f5d2"}.fa-audio-description:before{content:"\f29e"}.fa-austral-sign:before{content:"\e0a9"}.fa-award:before{content:"\f559"}.fa-b:before{content:"\42"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before,.fa-carriage-baby:before{content:"\f77d"}.fa-backward:before{content:"\f04a"}.fa-backward-fast:before,.fa-fast-backward:before{content:"\f049"}.fa-backward-step:before,.fa-step-backward:before{content:"\f048"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bag-shopping:before,.fa-shopping-bag:before{content:"\f290"}.fa-bahai:before{content:"\f666"}.fa-baht-sign:before{content:"\e0ac"}.fa-ban:before,.fa-cancel:before{content:"\f05e"}.fa-ban-smoking:before,.fa-smoking-ban:before{content:"\f54d"}.fa-band-aid:before,.fa-bandage:before{content:"\f462"}.fa-barcode:before{content:"\f02a"}.fa-bars:before,.fa-navicon:before{content:"\f0c9"}.fa-bars-progress:before,.fa-tasks-alt:before{content:"\f828"}.fa-bars-staggered:before,.fa-reorder:before,.fa-stream:before{content:"\f550"}.fa-baseball-ball:before,.fa-baseball:before{content:"\f433"}.fa-baseball-bat-ball:before{content:"\f432"}.fa-basket-shopping:before,.fa-shopping-basket:before{content:"\f291"}.fa-basketball-ball:before,.fa-basketball:before{content:"\f434"}.fa-bath:before,.fa-bathtub:before{content:"\f2cd"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-battery-5:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-battery-3:before,.fa-battery-half:before{content:"\f242"}.fa-battery-2:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-4:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-bed-pulse:before,.fa-procedures:before{content:"\f487"}.fa-beer-mug-empty:before,.fa-beer:before{content:"\f0fc"}.fa-bell:before{content:"\f0f3"}.fa-bell-concierge:before,.fa-concierge-bell:before{content:"\f562"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bicycle:before{content:"\f206"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-bitcoin-sign:before{content:"\e0b4"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blog:before{content:"\f781"}.fa-bold:before{content:"\f032"}.fa-bolt:before,.fa-zap:before{content:"\f0e7"}.fa-bolt-lightning:before{content:"\e0b7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-atlas:before,.fa-book-atlas:before{content:"\f558"}.fa-bible:before,.fa-book-bible:before{content:"\f647"}.fa-book-journal-whills:before,.fa-journal-whills:before{content:"\f66a"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-open-reader:before,.fa-book-reader:before{content:"\f5da"}.fa-book-quran:before,.fa-quran:before{content:"\f687"}.fa-book-dead:before,.fa-book-skull:before{content:"\f6b7"}.fa-bookmark:before{content:"\f02e"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before,.fa-border-top-left:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-archive:before,.fa-box-archive:before{content:"\f187"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes-alt:before,.fa-boxes-stacked:before,.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-brazilian-real-sign:before{content:"\e46c"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broom:before{content:"\f51a"}.fa-broom-ball:before,.fa-quidditch-broom-ball:before,.fa-quidditch:before{content:"\f458"}.fa-brush:before{content:"\f55d"}.fa-bug:before{content:"\f188"}.fa-bug-slash:before{content:"\e490"}.fa-building:before{content:"\f1ad"}.fa-bank:before,.fa-building-columns:before,.fa-institution:before,.fa-museum:before,.fa-university:before{content:"\f19c"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burger:before,.fa-hamburger:before{content:"\f805"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before,.fa-bus-simple:before{content:"\f55e"}.fa-briefcase-clock:before,.fa-business-time:before{content:"\f64a"}.fa-c:before{content:"\43"}.fa-birthday-cake:before,.fa-cake-candles:before,.fa-cake:before{content:"\f1fd"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-alt:before,.fa-calendar-days:before{content:"\f073"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-week:before{content:"\f784"}.fa-calendar-times:before,.fa-calendar-xmark:before{content:"\f273"}.fa-camera-alt:before,.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-camera-rotate:before{content:"\e0d8"}.fa-campground:before{content:"\f6bb"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-battery-car:before,.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-alt:before,.fa-car-rear:before{content:"\f5de"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-flatbed:before,.fa-dolly-flatbed:before{content:"\f474"}.fa-cart-flatbed-suitcase:before,.fa-luggage-cart:before{content:"\f59d"}.fa-cart-plus:before{content:"\f217"}.fa-cart-shopping:before,.fa-shopping-cart:before{content:"\f07a"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cedi-sign:before{content:"\e0df"}.fa-cent-sign:before{content:"\e3f5"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-blackboard:before,.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before,.fa-chalkboard-user:before{content:"\f51c"}.fa-champagne-glasses:before,.fa-glass-cheers:before{content:"\f79f"}.fa-charging-station:before{content:"\f5e7"}.fa-area-chart:before,.fa-chart-area:before{content:"\f1fe"}.fa-bar-chart:before,.fa-chart-bar:before{content:"\f080"}.fa-chart-column:before{content:"\e0e3"}.fa-chart-gantt:before{content:"\e0e4"}.fa-chart-line:before,.fa-line-chart:before{content:"\f201"}.fa-chart-pie:before,.fa-pie-chart:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-double:before{content:"\f560"}.fa-check-to-slot:before,.fa-vote-yea:before{content:"\f772"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-arrow-circle-down:before,.fa-circle-arrow-down:before{content:"\f0ab"}.fa-arrow-circle-left:before,.fa-circle-arrow-left:before{content:"\f0a8"}.fa-arrow-circle-right:before,.fa-circle-arrow-right:before{content:"\f0a9"}.fa-arrow-circle-up:before,.fa-circle-arrow-up:before{content:"\f0aa"}.fa-check-circle:before,.fa-circle-check:before{content:"\f058"}.fa-chevron-circle-down:before,.fa-circle-chevron-down:before{content:"\f13a"}.fa-chevron-circle-left:before,.fa-circle-chevron-left:before{content:"\f137"}.fa-chevron-circle-right:before,.fa-circle-chevron-right:before{content:"\f138"}.fa-chevron-circle-up:before,.fa-circle-chevron-up:before{content:"\f139"}.fa-circle-dollar-to-slot:before,.fa-donate:before{content:"\f4b9"}.fa-circle-dot:before,.fa-dot-circle:before{content:"\f192"}.fa-arrow-alt-circle-down:before,.fa-circle-down:before{content:"\f358"}.fa-circle-exclamation:before,.fa-exclamation-circle:before{content:"\f06a"}.fa-circle-h:before,.fa-hospital-symbol:before{content:"\f47e"}.fa-adjust:before,.fa-circle-half-stroke:before{content:"\f042"}.fa-circle-info:before,.fa-info-circle:before{content:"\f05a"}.fa-arrow-alt-circle-left:before,.fa-circle-left:before{content:"\f359"}.fa-circle-minus:before,.fa-minus-circle:before{content:"\f056"}.fa-circle-notch:before{content:"\f1ce"}.fa-circle-pause:before,.fa-pause-circle:before{content:"\f28b"}.fa-circle-play:before,.fa-play-circle:before{content:"\f144"}.fa-circle-plus:before,.fa-plus-circle:before{content:"\f055"}.fa-circle-question:before,.fa-question-circle:before{content:"\f059"}.fa-circle-radiation:before,.fa-radiation-alt:before{content:"\f7ba"}.fa-arrow-alt-circle-right:before,.fa-circle-right:before{content:"\f35a"}.fa-circle-stop:before,.fa-stop-circle:before{content:"\f28d"}.fa-arrow-alt-circle-up:before,.fa-circle-up:before{content:"\f35b"}.fa-circle-user:before,.fa-user-circle:before{content:"\f2bd"}.fa-circle-xmark:before,.fa-times-circle:before,.fa-xmark-circle:before{content:"\f057"}.fa-city:before{content:"\f64f"}.fa-clapperboard:before{content:"\e131"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock-four:before,.fa-clock:before{content:"\f017"}.fa-clock-rotate-left:before,.fa-history:before{content:"\f1da"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-arrow-down:before,.fa-cloud-download-alt:before,.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-arrow-up:before,.fa-cloud-upload-alt:before,.fa-cloud-upload:before{content:"\f0ee"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-clover:before{content:"\e139"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-code-commit:before{content:"\f386"}.fa-code-compare:before{content:"\e13a"}.fa-code-fork:before{content:"\e13b"}.fa-code-merge:before{content:"\f387"}.fa-code-pull-request:before{content:"\e13c"}.fa-coins:before{content:"\f51e"}.fa-colon-sign:before{content:"\e140"}.fa-comment:before{content:"\f075"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before,.fa-commenting:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comment-sms:before,.fa-sms:before{content:"\f7cd"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compass-drafting:before,.fa-drafting-compass:before{content:"\f568"}.fa-compress:before{content:"\f066"}.fa-computer-mouse:before,.fa-mouse:before{content:"\f8cc"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-credit-card-alt:before,.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before,.fa-crop-simple:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-cruzeiro-sign:before{content:"\e152"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-d:before{content:"\44"}.fa-database:before{content:"\f1c0"}.fa-backspace:before,.fa-delete-left:before{content:"\f55a"}.fa-democrat:before{content:"\f747"}.fa-desktop-alt:before,.fa-desktop:before{content:"\f390"}.fa-dharmachakra:before{content:"\f655"}.fa-diagram-next:before{content:"\e476"}.fa-diagram-predecessor:before{content:"\e477"}.fa-diagram-project:before,.fa-project-diagram:before{content:"\f542"}.fa-diagram-successor:before{content:"\e47a"}.fa-diamond:before{content:"\f219"}.fa-diamond-turn-right:before,.fa-directions:before{content:"\f5eb"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dna:before{content:"\f471"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before,.fa-dollar:before,.fa-usd:before{content:"\24"}.fa-dolly-box:before,.fa-dolly:before{content:"\f472"}.fa-dong-sign:before{content:"\e169"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dove:before{content:"\f4ba"}.fa-compress-alt:before,.fa-down-left-and-up-right-to-center:before{content:"\f422"}.fa-down-long:before,.fa-long-arrow-alt-down:before{content:"\f309"}.fa-download:before{content:"\f019"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-droplet:before,.fa-tint:before{content:"\f043"}.fa-droplet-slash:before,.fa-tint-slash:before{content:"\f5c7"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-e:before{content:"\45"}.fa-deaf:before,.fa-deafness:before,.fa-ear-deaf:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-assistive-listening-systems:before,.fa-ear-listen:before{content:"\f2a2"}.fa-earth-africa:before,.fa-globe-africa:before{content:"\f57c"}.fa-earth-america:before,.fa-earth-americas:before,.fa-earth:before,.fa-globe-americas:before{content:"\f57d"}.fa-earth-asia:before,.fa-globe-asia:before{content:"\f57e"}.fa-earth-europe:before,.fa-globe-europe:before{content:"\f7a2"}.fa-earth-oceania:before,.fa-globe-oceania:before{content:"\e47b"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elevator:before{content:"\e16d"}.fa-ellipsis-h:before,.fa-ellipsis:before{content:"\f141"}.fa-ellipsis-v:before,.fa-ellipsis-vertical:before{content:"\f142"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelopes-bulk:before,.fa-mail-bulk:before{content:"\f674"}.fa-equals:before{content:"\3d"}.fa-eraser:before{content:"\f12d"}.fa-ethernet:before{content:"\f796"}.fa-eur:before,.fa-euro-sign:before,.fa-euro:before{content:"\f153"}.fa-exclamation:before{content:"\21"}.fa-expand:before{content:"\f065"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper-empty:before,.fa-eye-dropper:before,.fa-eyedropper:before{content:"\f1fb"}.fa-eye-low-vision:before,.fa-low-vision:before{content:"\f2a8"}.fa-eye-slash:before{content:"\f070"}.fa-f:before{content:"\46"}.fa-angry:before,.fa-face-angry:before{content:"\f556"}.fa-dizzy:before,.fa-face-dizzy:before{content:"\f567"}.fa-face-flushed:before,.fa-flushed:before{content:"\f579"}.fa-face-frown:before,.fa-frown:before{content:"\f119"}.fa-face-frown-open:before,.fa-frown-open:before{content:"\f57a"}.fa-face-grimace:before,.fa-grimace:before{content:"\f57f"}.fa-face-grin:before,.fa-grin:before{content:"\f580"}.fa-face-grin-beam:before,.fa-grin-beam:before{content:"\f582"}.fa-face-grin-beam-sweat:before,.fa-grin-beam-sweat:before{content:"\f583"}.fa-face-grin-hearts:before,.fa-grin-hearts:before{content:"\f584"}.fa-face-grin-squint:before,.fa-grin-squint:before{content:"\f585"}.fa-face-grin-squint-tears:before,.fa-grin-squint-tears:before{content:"\f586"}.fa-face-grin-stars:before,.fa-grin-stars:before{content:"\f587"}.fa-face-grin-tears:before,.fa-grin-tears:before{content:"\f588"}.fa-face-grin-tongue:before,.fa-grin-tongue:before{content:"\f589"}.fa-face-grin-tongue-squint:before,.fa-grin-tongue-squint:before{content:"\f58a"}.fa-face-grin-tongue-wink:before,.fa-grin-tongue-wink:before{content:"\f58b"}.fa-face-grin-wide:before,.fa-grin-alt:before{content:"\f581"}.fa-face-grin-wink:before,.fa-grin-wink:before{content:"\f58c"}.fa-face-kiss:before,.fa-kiss:before{content:"\f596"}.fa-face-kiss-beam:before,.fa-kiss-beam:before{content:"\f597"}.fa-face-kiss-wink-heart:before,.fa-kiss-wink-heart:before{content:"\f598"}.fa-face-laugh:before,.fa-laugh:before{content:"\f599"}.fa-face-laugh-beam:before,.fa-laugh-beam:before{content:"\f59a"}.fa-face-laugh-squint:before,.fa-laugh-squint:before{content:"\f59b"}.fa-face-laugh-wink:before,.fa-laugh-wink:before{content:"\f59c"}.fa-face-meh:before,.fa-meh:before{content:"\f11a"}.fa-face-meh-blank:before,.fa-meh-blank:before{content:"\f5a4"}.fa-face-rolling-eyes:before,.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-face-sad-cry:before,.fa-sad-cry:before{content:"\f5b3"}.fa-face-sad-tear:before,.fa-sad-tear:before{content:"\f5b4"}.fa-face-smile:before,.fa-smile:before{content:"\f118"}.fa-face-smile-beam:before,.fa-smile-beam:before{content:"\f5b8"}.fa-face-smile-wink:before,.fa-smile-wink:before{content:"\f4da"}.fa-face-surprise:before,.fa-surprise:before{content:"\f5c2"}.fa-face-tired:before,.fa-tired:before{content:"\f5c8"}.fa-fan:before{content:"\f863"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before,.fa-feather-pointed:before{content:"\f56b"}.fa-file:before{content:"\f15b"}.fa-file-arrow-down:before,.fa-file-download:before{content:"\f56d"}.fa-file-arrow-up:before,.fa-file-upload:before{content:"\f574"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-excel:before{content:"\f1c3"}.fa-arrow-right-from-file:before,.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-arrow-right-to-file:before,.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-alt:before,.fa-file-lines:before,.fa-file-text:before{content:"\f15c"}.fa-file-medical:before{content:"\f477"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-video:before{content:"\f1c8"}.fa-file-medical-alt:before,.fa-file-waveform:before{content:"\f478"}.fa-file-word:before{content:"\f1c2"}.fa-file-archive:before,.fa-file-zipper:before{content:"\f1c6"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-filter-circle-dollar:before,.fa-funnel-dollar:before{content:"\f662"}.fa-filter-circle-xmark:before{content:"\e17b"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-extinguisher:before{content:"\f134"}.fa-fire-alt:before,.fa-fire-flame-curved:before{content:"\f7e4"}.fa-burn:before,.fa-fire-flame-simple:before{content:"\f46a"}.fa-fish:before{content:"\f578"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-floppy-disk:before,.fa-save:before{content:"\f0c7"}.fa-florin-sign:before{content:"\e184"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-folder-tree:before{content:"\f802"}.fa-font:before{content:"\f031"}.fa-football-ball:before,.fa-football:before{content:"\f44e"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before,.fa-forward-fast:before{content:"\f050"}.fa-forward-step:before,.fa-step-forward:before{content:"\f051"}.fa-franc-sign:before{content:"\e18f"}.fa-frog:before{content:"\f52e"}.fa-futbol-ball:before,.fa-futbol:before,.fa-soccer-ball:before{content:"\f1e3"}.fa-g:before{content:"\47"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-dashboard:before,.fa-gauge-med:before,.fa-gauge:before,.fa-tachometer-alt-average:before{content:"\f624"}.fa-gauge-high:before,.fa-tachometer-alt-fast:before,.fa-tachometer-alt:before{content:"\f625"}.fa-gauge-simple-med:before,.fa-gauge-simple:before,.fa-tachometer-average:before{content:"\f629"}.fa-gauge-simple-high:before,.fa-tachometer-fast:before,.fa-tachometer:before{content:"\f62a"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-glasses:before{content:"\f530"}.fa-globe:before{content:"\f0ac"}.fa-golf-ball-tee:before,.fa-golf-ball:before{content:"\f450"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-greater-than:before{content:"\3e"}.fa-greater-than-equal:before{content:"\f532"}.fa-grip-horizontal:before,.fa-grip:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-guarani-sign:before{content:"\e19a"}.fa-guitar:before{content:"\f7a6"}.fa-gun:before{content:"\e19b"}.fa-h:before{content:"\48"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-paper:before,.fa-hand:before{content:"\f256"}.fa-hand-back-fist:before,.fa-hand-rock:before{content:"\f255"}.fa-allergies:before,.fa-hand-dots:before{content:"\f461"}.fa-fist-raised:before,.fa-hand-fist:before{content:"\f6de"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-dollar:before,.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-droplet:before,.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before,.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before,.fa-hands-american-sign-language-interpreting:before,.fa-hands-asl-interpreting:before{content:"\f2a3"}.fa-hands-bubbles:before,.fa-hands-wash:before{content:"\e05e"}.fa-hands-clapping:before{content:"\e1a8"}.fa-hands-holding:before{content:"\f4c2"}.fa-hands-praying:before,.fa-praying-hands:before{content:"\f684"}.fa-handshake:before{content:"\f2b5"}.fa-hands-helping:before,.fa-handshake-angle:before{content:"\f4c4"}.fa-handshake-alt-slash:before,.fa-handshake-simple-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-drive:before,.fa-hdd:before{content:"\f0a0"}.fa-hashtag:before{content:"\23"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-header:before,.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before,.fa-headphones-simple:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before,.fa-heart-crack:before{content:"\f7a9"}.fa-heart-pulse:before,.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-hard-hat:before,.fa-hat-hard:before,.fa-helmet-safety:before{content:"\f807"}.fa-highlighter:before{content:"\f591"}.fa-hippo:before{content:"\f6ed"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital-alt:before,.fa-hospital-wide:before,.fa-hospital:before{content:"\f0f8"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub-person:before,.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hourglass-2:before,.fa-hourglass-half:before,.fa-hourglass:before{content:"\f254"}.fa-hourglass-empty:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-home-alt:before,.fa-home-lg-alt:before,.fa-home:before,.fa-house:before{content:"\f015"}.fa-home-lg:before,.fa-house-chimney:before{content:"\e3af"}.fa-house-chimney-crack:before,.fa-house-damage:before{content:"\f6f1"}.fa-clinic-medical:before,.fa-house-chimney-medical:before{content:"\f7f2"}.fa-house-chimney-user:before{content:"\e065"}.fa-house-chimney-window:before{content:"\e00d"}.fa-house-crack:before{content:"\e3b1"}.fa-house-laptop:before,.fa-laptop-house:before{content:"\e066"}.fa-house-medical:before{content:"\e3b2"}.fa-home-user:before,.fa-house-user:before{content:"\e1b0"}.fa-hryvnia-sign:before,.fa-hryvnia:before{content:"\f6f2"}.fa-i:before{content:"\49"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-heart-music-camera-bolt:before,.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before,.fa-id-card-clip:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-image-portrait:before,.fa-portrait:before{content:"\f3e0"}.fa-images:before{content:"\f302"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-indian-rupee-sign:before,.fa-indian-rupee:before,.fa-inr:before{content:"\e1bc"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-italic:before{content:"\f033"}.fa-j:before{content:"\4a"}.fa-jedi:before{content:"\f669"}.fa-fighter-jet:before,.fa-jet-fighter:before{content:"\f0fb"}.fa-joint:before{content:"\f595"}.fa-k:before{content:"\4b"}.fa-kaaba:before{content:"\f66b"}.fa-key:before{content:"\f084"}.fa-keyboard:before{content:"\f11c"}.fa-khanda:before{content:"\f66d"}.fa-kip-sign:before{content:"\e1c4"}.fa-first-aid:before,.fa-kit-medical:before{content:"\f479"}.fa-kiwi-bird:before{content:"\f535"}.fa-l:before{content:"\4c"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-lari-sign:before{content:"\e1c8"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-left-long:before,.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-arrows-alt-h:before,.fa-left-right:before{content:"\f337"}.fa-lemon:before{content:"\f094"}.fa-less-than:before{content:"\3c"}.fa-less-than-equal:before{content:"\f537"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-chain-broken:before,.fa-chain-slash:before,.fa-link-slash:before,.fa-unlink:before{content:"\f127"}.fa-lira-sign:before{content:"\f195"}.fa-list-squares:before,.fa-list:before{content:"\f03a"}.fa-list-check:before,.fa-tasks:before{content:"\f0ae"}.fa-list-1-2:before,.fa-list-numeric:before,.fa-list-ol:before{content:"\f0cb"}.fa-list-dots:before,.fa-list-ul:before{content:"\f0ca"}.fa-litecoin-sign:before{content:"\e1d3"}.fa-location-arrow:before{content:"\f124"}.fa-location-crosshairs:before,.fa-location:before{content:"\f601"}.fa-location-dot:before,.fa-map-marker-alt:before{content:"\f3c5"}.fa-location-pin:before,.fa-map-marker:before{content:"\f041"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-m:before{content:"\4d"}.fa-magnet:before{content:"\f076"}.fa-magnifying-glass:before,.fa-search:before{content:"\f002"}.fa-magnifying-glass-dollar:before,.fa-search-dollar:before{content:"\f688"}.fa-magnifying-glass-location:before,.fa-search-location:before{content:"\f689"}.fa-magnifying-glass-minus:before,.fa-search-minus:before{content:"\f010"}.fa-magnifying-glass-plus:before,.fa-search-plus:before{content:"\f00e"}.fa-manat-sign:before{content:"\e1d5"}.fa-map:before{content:"\f279"}.fa-map-location:before,.fa-map-marked:before{content:"\f59f"}.fa-map-location-dot:before,.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-pin:before{content:"\f276"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-and-venus:before{content:"\f224"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before,.fa-mars-stroke-right:before{content:"\f22b"}.fa-mars-stroke-up:before,.fa-mars-stroke-v:before{content:"\f22a"}.fa-glass-martini-alt:before,.fa-martini-glass:before{content:"\f57b"}.fa-cocktail:before,.fa-martini-glass-citrus:before{content:"\f561"}.fa-glass-martini:before,.fa-martini-glass-empty:before{content:"\f000"}.fa-mask:before{content:"\f6fa"}.fa-mask-face:before{content:"\e1d7"}.fa-masks-theater:before,.fa-theater-masks:before{content:"\f630"}.fa-expand-arrows-alt:before,.fa-maximize:before{content:"\f31e"}.fa-medal:before{content:"\f5a2"}.fa-memory:before{content:"\f538"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-comment-alt:before,.fa-message:before{content:"\f27a"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before,.fa-microphone-lines:before{content:"\f3c9"}.fa-microphone-alt-slash:before,.fa-microphone-lines-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-mill-sign:before{content:"\e1ed"}.fa-compress-arrows-alt:before,.fa-minimize:before{content:"\f78c"}.fa-minus:before,.fa-subtract:before{content:"\f068"}.fa-mitten:before{content:"\f7b5"}.fa-mobile-android:before,.fa-mobile-phone:before,.fa-mobile:before{content:"\f3ce"}.fa-mobile-button:before{content:"\f10b"}.fa-mobile-alt:before,.fa-mobile-screen-button:before{content:"\f3cd"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-1:before,.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-1-wave:before,.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before,.fa-money-check-dollar:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mug-hot:before{content:"\f7b6"}.fa-coffee:before,.fa-mug-saucer:before{content:"\f0f4"}.fa-music:before{content:"\f001"}.fa-n:before{content:"\4e"}.fa-naira-sign:before{content:"\e1f6"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-not-equal:before{content:"\f53e"}.fa-note-sticky:before,.fa-sticky-note:before{content:"\f249"}.fa-notes-medical:before{content:"\f481"}.fa-o:before{content:"\4f"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-oil-can:before{content:"\f613"}.fa-om:before{content:"\f679"}.fa-otter:before{content:"\f700"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-p:before{content:"\50"}.fa-pager:before{content:"\f815"}.fa-paint-roller:before{content:"\f5aa"}.fa-paint-brush:before,.fa-paintbrush:before{content:"\f1fc"}.fa-palette:before{content:"\f53f"}.fa-pallet:before{content:"\f482"}.fa-panorama:before{content:"\e209"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-passport:before{content:"\f5ab"}.fa-file-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-pause:before{content:"\f04c"}.fa-paw:before{content:"\f1b0"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before,.fa-pen-clip:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-ruler:before,.fa-pencil-ruler:before{content:"\f5ae"}.fa-edit:before,.fa-pen-to-square:before{content:"\f044"}.fa-pencil-alt:before,.fa-pencil:before{content:"\f303"}.fa-people-arrows-left-right:before,.fa-people-arrows:before{content:"\e068"}.fa-people-carry-box:before,.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before,.fa-percentage:before{content:"\25"}.fa-male:before,.fa-person:before{content:"\f183"}.fa-biking:before,.fa-person-biking:before{content:"\f84a"}.fa-person-booth:before{content:"\f756"}.fa-diagnoses:before,.fa-person-dots-from-line:before{content:"\f470"}.fa-female:before,.fa-person-dress:before{content:"\f182"}.fa-hiking:before,.fa-person-hiking:before{content:"\f6ec"}.fa-person-praying:before,.fa-pray:before{content:"\f683"}.fa-person-running:before,.fa-running:before{content:"\f70c"}.fa-person-skating:before,.fa-skating:before{content:"\f7c5"}.fa-person-skiing:before,.fa-skiing:before{content:"\f7c9"}.fa-person-skiing-nordic:before,.fa-skiing-nordic:before{content:"\f7ca"}.fa-person-snowboarding:before,.fa-snowboarding:before{content:"\f7ce"}.fa-person-swimming:before,.fa-swimmer:before{content:"\f5c4"}.fa-person-walking:before,.fa-walking:before{content:"\f554"}.fa-blind:before,.fa-person-walking-with-cane:before{content:"\f29d"}.fa-peseta-sign:before{content:"\e221"}.fa-peso-sign:before{content:"\e222"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before,.fa-phone-flip:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-volume:before,.fa-volume-control-phone:before{content:"\f2a0"}.fa-photo-film:before,.fa-photo-video:before{content:"\f87c"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-plug:before{content:"\f1e6"}.fa-add:before,.fa-plus:before{content:"\2b"}.fa-plus-minus:before{content:"\e43c"}.fa-podcast:before{content:"\f2ce"}.fa-poo:before{content:"\f2fe"}.fa-poo-bolt:before,.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-power-off:before{content:"\f011"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before,.fa-prescription-bottle-medical:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-puzzle-piece:before{content:"\f12e"}.fa-q:before{content:"\51"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\3f"}.fa-quote-left-alt:before,.fa-quote-left:before{content:"\f10d"}.fa-quote-right-alt:before,.fa-quote-right:before{content:"\f10e"}.fa-r:before{content:"\52"}.fa-radiation:before{content:"\f7b9"}.fa-rainbow:before{content:"\f75b"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-ad:before,.fa-rectangle-ad:before{content:"\f641"}.fa-list-alt:before,.fa-rectangle-list:before{content:"\f022"}.fa-rectangle-times:before,.fa-rectangle-xmark:before,.fa-times-rectangle:before,.fa-window-close:before{content:"\f410"}.fa-recycle:before{content:"\f1b8"}.fa-registered:before{content:"\f25d"}.fa-repeat:before{content:"\f363"}.fa-mail-reply:before,.fa-reply:before{content:"\f3e5"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-republican:before{content:"\f75e"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-ribbon:before{content:"\f4d6"}.fa-right-from-bracket:before,.fa-sign-out-alt:before{content:"\f2f5"}.fa-exchange-alt:before,.fa-right-left:before{content:"\f362"}.fa-long-arrow-alt-right:before,.fa-right-long:before{content:"\f30b"}.fa-right-to-bracket:before,.fa-sign-in-alt:before{content:"\f2f6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rotate:before,.fa-sync-alt:before{content:"\f2f1"}.fa-rotate-back:before,.fa-rotate-backward:before,.fa-rotate-left:before,.fa-undo-alt:before{content:"\f2ea"}.fa-redo-alt:before,.fa-rotate-forward:before,.fa-rotate-right:before{content:"\f2f9"}.fa-route:before{content:"\f4d7"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-rouble:before,.fa-rub:before,.fa-ruble-sign:before,.fa-ruble:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-rupee-sign:before,.fa-rupee:before{content:"\f156"}.fa-rupiah-sign:before{content:"\e23d"}.fa-s:before{content:"\53"}.fa-sailboat:before{content:"\e445"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-balance-scale:before,.fa-scale-balanced:before{content:"\f24e"}.fa-balance-scale-left:before,.fa-scale-unbalanced:before{content:"\f515"}.fa-balance-scale-right:before,.fa-scale-unbalanced-flip:before{content:"\f516"}.fa-school:before{content:"\f549"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-screwdriver:before{content:"\f54a"}.fa-screwdriver-wrench:before,.fa-tools:before{content:"\f7d9"}.fa-scroll:before{content:"\f70e"}.fa-scroll-torah:before,.fa-torah:before{content:"\f6a0"}.fa-sd-card:before{content:"\f7c2"}.fa-section:before{content:"\e447"}.fa-seedling:before,.fa-sprout:before{content:"\f4d8"}.fa-server:before{content:"\f233"}.fa-shapes:before,.fa-triangle-circle-square:before{content:"\f61f"}.fa-arrow-turn-right:before,.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-share-from-square:before,.fa-share-square:before{content:"\f14d"}.fa-share-alt:before,.fa-share-nodes:before{content:"\f1e0"}.fa-ils:before,.fa-shekel-sign:before,.fa-shekel:before,.fa-sheqel-sign:before,.fa-sheqel:before{content:"\f20b"}.fa-shield:before{content:"\f132"}.fa-shield-alt:before,.fa-shield-blank:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shirt:before,.fa-t-shirt:before,.fa-tshirt:before{content:"\f553"}.fa-shoe-prints:before{content:"\f54b"}.fa-shop:before,.fa-store-alt:before{content:"\f54f"}.fa-shop-slash:before,.fa-store-alt-slash:before{content:"\e070"}.fa-shower:before{content:"\f2cc"}.fa-shrimp:before{content:"\e448"}.fa-random:before,.fa-shuffle:before{content:"\f074"}.fa-shuttle-space:before,.fa-space-shuttle:before{content:"\f197"}.fa-sign-hanging:before,.fa-sign:before{content:"\f4d9"}.fa-signal-5:before,.fa-signal-perfect:before,.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-map-signs:before,.fa-signs-post:before{content:"\f277"}.fa-sim-card:before{content:"\f7c4"}.fa-sink:before{content:"\e06d"}.fa-sitemap:before{content:"\f0e8"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before,.fa-sliders:before{content:"\f1de"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-spa:before{content:"\f5bb"}.fa-pastafarianism:before,.fa-spaghetti-monster-flying:before{content:"\f67b"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spoon:before,.fa-utensil-spoon:before{content:"\f2e5"}.fa-spray-can:before{content:"\f5bd"}.fa-air-freshener:before,.fa-spray-can-sparkles:before{content:"\f5d0"}.fa-square:before{content:"\f0c8"}.fa-external-link-square:before,.fa-square-arrow-up-right:before{content:"\f14c"}.fa-caret-square-down:before,.fa-square-caret-down:before{content:"\f150"}.fa-caret-square-left:before,.fa-square-caret-left:before{content:"\f191"}.fa-caret-square-right:before,.fa-square-caret-right:before{content:"\f152"}.fa-caret-square-up:before,.fa-square-caret-up:before{content:"\f151"}.fa-check-square:before,.fa-square-check:before{content:"\f14a"}.fa-envelope-square:before,.fa-square-envelope:before{content:"\f199"}.fa-square-full:before{content:"\f45c"}.fa-h-square:before,.fa-square-h:before{content:"\f0fd"}.fa-minus-square:before,.fa-square-minus:before{content:"\f146"}.fa-parking:before,.fa-square-parking:before{content:"\f540"}.fa-pen-square:before,.fa-pencil-square:before,.fa-square-pen:before{content:"\f14b"}.fa-phone-square:before,.fa-square-phone:before{content:"\f098"}.fa-phone-square-alt:before,.fa-square-phone-flip:before{content:"\f87b"}.fa-plus-square:before,.fa-square-plus:before{content:"\f0fe"}.fa-poll-h:before,.fa-square-poll-horizontal:before{content:"\f682"}.fa-poll:before,.fa-square-poll-vertical:before{content:"\f681"}.fa-square-root-alt:before,.fa-square-root-variable:before{content:"\f698"}.fa-rss-square:before,.fa-square-rss:before{content:"\f143"}.fa-share-alt-square:before,.fa-square-share-nodes:before{content:"\f1e1"}.fa-external-link-square-alt:before,.fa-square-up-right:before{content:"\f360"}.fa-square-xmark:before,.fa-times-square:before,.fa-xmark-square:before{content:"\f2d3"}.fa-stairs:before{content:"\e289"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before,.fa-star-half-stroke:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-gbp:before,.fa-pound-sign:before,.fa-sterling-sign:before{content:"\f154"}.fa-stethoscope:before{content:"\f0f1"}.fa-stop:before{content:"\f04d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-slash:before{content:"\e071"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stroopwafel:before{content:"\f551"}.fa-subscript:before{content:"\f12c"}.fa-suitcase:before{content:"\f0f2"}.fa-medkit:before,.fa-suitcase-medical:before{content:"\f0fa"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superscript:before{content:"\f12b"}.fa-swatchbook:before{content:"\f5c3"}.fa-synagogue:before{content:"\f69b"}.fa-syringe:before{content:"\f48e"}.fa-t:before{content:"\54"}.fa-table:before{content:"\f0ce"}.fa-table-cells:before,.fa-th:before{content:"\f00a"}.fa-table-cells-large:before,.fa-th-large:before{content:"\f009"}.fa-columns:before,.fa-table-columns:before{content:"\f0db"}.fa-table-list:before,.fa-th-list:before{content:"\f00b"}.fa-ping-pong-paddle-ball:before,.fa-table-tennis-paddle-ball:before,.fa-table-tennis:before{content:"\f45d"}.fa-tablet-android:before,.fa-tablet:before{content:"\f3fb"}.fa-tablet-button:before{content:"\f10a"}.fa-tablet-alt:before,.fa-tablet-screen-button:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-digital-tachograph:before,.fa-tachograph-digital:before{content:"\f566"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-temperature-0:before,.fa-temperature-empty:before,.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-temperature-4:before,.fa-temperature-full:before,.fa-thermometer-4:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-temperature-2:before,.fa-temperature-half:before,.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-temperature-1:before,.fa-temperature-quarter:before,.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-temperature-3:before,.fa-temperature-three-quarters:before,.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-tenge-sign:before,.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-remove-format:before,.fa-text-slash:before{content:"\f87d"}.fa-text-width:before{content:"\f035"}.fa-thermometer:before{content:"\f491"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumb-tack:before,.fa-thumbtack:before{content:"\f08d"}.fa-ticket:before{content:"\f145"}.fa-ticket-alt:before,.fa-ticket-simple:before{content:"\f3ff"}.fa-timeline:before{content:"\e29c"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tooth:before{content:"\f5c9"}.fa-torii-gate:before{content:"\f6a1"}.fa-broadcast-tower:before,.fa-tower-broadcast:before{content:"\f519"}.fa-tractor:before{content:"\f722"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-subway:before,.fa-train-subway:before{content:"\f239"}.fa-train-tram:before,.fa-tram:before{content:"\f7da"}.fa-transgender-alt:before,.fa-transgender:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-arrow-up:before,.fa-trash-restore:before{content:"\f829"}.fa-trash-alt:before,.fa-trash-can:before{content:"\f2ed"}.fa-trash-can-arrow-up:before,.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-exclamation-triangle:before,.fa-triangle-exclamation:before,.fa-warning:before{content:"\f071"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-shipping-fast:before,.fa-truck-fast:before{content:"\f48b"}.fa-ambulance:before,.fa-truck-medical:before{content:"\f0f9"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-truck-loading:before,.fa-truck-ramp-box:before{content:"\f4de"}.fa-teletype:before,.fa-tty:before{content:"\f1e4"}.fa-try:before,.fa-turkish-lira-sign:before,.fa-turkish-lira:before{content:"\e2bb"}.fa-level-down-alt:before,.fa-turn-down:before{content:"\f3be"}.fa-level-up-alt:before,.fa-turn-up:before{content:"\f3bf"}.fa-television:before,.fa-tv-alt:before,.fa-tv:before{content:"\f26c"}.fa-u:before{content:"\55"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-universal-access:before{content:"\f29a"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before,.fa-unlock-keyhole:before{content:"\f13e"}.fa-arrows-alt-v:before,.fa-up-down:before{content:"\f338"}.fa-arrows-alt:before,.fa-up-down-left-right:before{content:"\f0b2"}.fa-long-arrow-alt-up:before,.fa-up-long:before{content:"\f30c"}.fa-expand-alt:before,.fa-up-right-and-down-left-from-center:before{content:"\f424"}.fa-external-link-alt:before,.fa-up-right-from-square:before{content:"\f35d"}.fa-upload:before{content:"\f093"}.fa-user:before{content:"\f007"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-clock:before{content:"\f4fd"}.fa-user-doctor:before,.fa-user-md:before{content:"\f0f0"}.fa-user-cog:before,.fa-user-gear:before{content:"\f4fe"}.fa-user-graduate:before{content:"\f501"}.fa-user-friends:before,.fa-user-group:before{content:"\f500"}.fa-user-injured:before{content:"\f728"}.fa-user-alt:before,.fa-user-large:before{content:"\f406"}.fa-user-alt-slash:before,.fa-user-large-slash:before{content:"\f4fa"}.fa-user-lock:before{content:"\f502"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-edit:before,.fa-user-pen:before{content:"\f4ff"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before,.fa-user-xmark:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before,.fa-users-gear:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-cutlery:before,.fa-utensils:before{content:"\f2e7"}.fa-v:before{content:"\56"}.fa-shuttle-van:before,.fa-van-shuttle:before{content:"\f5b6"}.fa-vault:before{content:"\e2c5"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-video-camera:before,.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-virus:before{content:"\e074"}.fa-virus-covid:before{content:"\e4a8"}.fa-virus-covid-slash:before{content:"\e4a9"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before,.fa-volleyball:before{content:"\f45f"}.fa-volume-high:before,.fa-volume-up:before{content:"\f028"}.fa-volume-down:before,.fa-volume-low:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-mute:before,.fa-volume-times:before,.fa-volume-xmark:before{content:"\f6a9"}.fa-vr-cardboard:before{content:"\f729"}.fa-w:before{content:"\57"}.fa-wallet:before{content:"\f555"}.fa-magic:before,.fa-wand-magic:before{content:"\f0d0"}.fa-magic-wand-sparkles:before,.fa-wand-magic-sparkles:before{content:"\e2ca"}.fa-wand-sparkles:before{content:"\f72b"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-ladder-water:before,.fa-swimming-pool:before,.fa-water-ladder:before{content:"\f5c5"}.fa-wave-square:before{content:"\f83e"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weight-scale:before,.fa-weight:before{content:"\f496"}.fa-wheelchair:before{content:"\f193"}.fa-glass-whiskey:before,.fa-whiskey-glass:before{content:"\f7a0"}.fa-wifi-3:before,.fa-wifi-strong:before,.fa-wifi:before{content:"\f1eb"}.fa-wind:before{content:"\f72e"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before,.fa-wine-glass-empty:before{content:"\f5ce"}.fa-krw:before,.fa-won-sign:before,.fa-won:before{content:"\f159"}.fa-wrench:before{content:"\f0ad"}.fa-x:before{content:"\58"}.fa-x-ray:before{content:"\f497"}.fa-close:before,.fa-multiply:before,.fa-remove:before,.fa-times:before,.fa-xmark:before{content:"\f00d"}.fa-y:before{content:"\59"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen-sign:before,.fa-yen:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-z:before{content:"\5a"}.fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-family:"Font Awesome 6 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}.fa-brands,.fab{font-family:"Font Awesome 6 Brands";font-weight:400}.fa-42-group:before,.fa-innosoft:before{content:"\e080"}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-alipay:before{content:"\f642"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-amilia:before{content:"\f36d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-artstation:before{content:"\f77a"}.fa-asymmetrik:before{content:"\f372"}.fa-atlassian:before{content:"\f77b"}.fa-audible:before{content:"\f373"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-bandcamp:before{content:"\f2d5"}.fa-battle-net:before{content:"\f835"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bilibili:before{content:"\e3d9"}.fa-bimobject:before{content:"\f378"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bootstrap:before{content:"\f836"}.fa-bots:before{content:"\e340"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-buromobelexperte:before{content:"\f37f"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cmplid:before{content:"\e360"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cotton-bureau:before{content:"\f89e"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-critical-role:before{content:"\f6c9"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dhl:before{content:"\f790"}.fa-diaspora:before{content:"\f791"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-elementor:before{content:"\f430"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-etsy:before{content:"\f2d7"}.fa-evernote:before{content:"\f839"}.fa-expeditedssl:before{content:"\f23e"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-figma:before{content:"\f799"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-fly:before{content:"\f417"}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:"\f2b4"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-fulcrum:before{content:"\f50b"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-gofore:before{content:"\f3a7"}.fa-golang:before{content:"\e40f"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-gulp:before{content:"\f3ae"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hashnode:before{content:"\e499"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-hive:before{content:"\e07f"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-hotjar:before{content:"\f3b1"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-ideal:before{content:"\e013"}.fa-imdb:before{content:"\f2d8"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaggle:before{content:"\f5fa"}.fa-keybase:before{content:"\f4f5"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-korvue:before{content:"\f42f"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-leanpub:before{content:"\f212"}.fa-less:before{content:"\f41d"}.fa-line:before{content:"\f3c0"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-mailchimp:before{content:"\f59e"}.fa-mandalorian:before{content:"\f50f"}.fa-markdown:before{content:"\f60f"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medapps:before{content:"\f3c6"}.fa-medium-m:before,.fa-medium:before{content:"\f23a"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-mendeley:before{content:"\f7b3"}.fa-microblog:before{content:"\e01a"}.fa-microsoft:before{content:"\f3ca"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-old-republic:before{content:"\f510"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-padlet:before{content:"\e4a0"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-palfed:before{content:"\f3d8"}.fa-patreon:before{content:"\f3d9"}.fa-paypal:before{content:"\f1ed"}.fa-perbyte:before{content:"\e083"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pix:before{content:"\e43a"}.fa-playstation:before{content:"\f3df"}.fa-product-hunt:before{content:"\f288"}.fa-pushed:before{content:"\f3e1"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-r-project:before{content:"\f4f7"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-renren:before{content:"\f18b"}.fa-replyd:before{content:"\f3e6"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-rev:before{content:"\f5b2"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rust:before{content:"\e07a"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-schlix:before{content:"\f3ea"}.fa-scribd:before{content:"\f28a"}.fa-searchengin:before{content:"\f3eb"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-servicestack:before{content:"\f3ec"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shopify:before{content:"\e057"}.fa-shopware:before{content:"\f5b5"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sith:before{content:"\f512"}.fa-sitrox:before{content:"\e44a"}.fa-sketch:before{content:"\f7c6"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack-hash:before,.fa-slack:before{content:"\f198"}.fa-slideshare:before{content:"\f1e7"}.fa-snapchat-ghost:before,.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-square:before{content:"\f2ad"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spotify:before{content:"\f1bc"}.fa-square-font-awesome:before{content:"\f425"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-sticker-mule:before{content:"\f3f7"}.fa-strava:before{content:"\f428"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-superpowers:before{content:"\f2dd"}.fa-supple:before{content:"\f3f9"}.fa-suse:before{content:"\f7d6"}.fa-swift:before{content:"\f8e1"}.fa-symfony:before{content:"\f83d"}.fa-teamspeak:before{content:"\f4f9"}.fa-telegram-plane:before,.fa-telegram:before{content:"\f2c6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-the-red-yeti:before{content:"\f69d"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-think-peaks:before{content:"\f731"}.fa-tiktok:before{content:"\e07b"}.fa-trade-federation:before{content:"\f513"}.fa-trello:before{content:"\f181"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-uncharted:before{content:"\e084"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-vaadin:before{content:"\f408"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-viber:before{content:"\f409"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-vuejs:before{content:"\f41f"}.fa-watchman-monitoring:before{content:"\e087"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-whmcs:before{content:"\f40d"}.fa-wikipedia-w:before{content:"\f266"}.fa-windows:before{content:"\f17a"}.fa-wirsindhandwerk:before,.fa-wsh:before{content:"\e2d0"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}:host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400}:host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900}@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f250,u+f252,u+f27a} \ No newline at end of file diff --git a/publish/wwwroot/lib/fontawesome/css/all.min.css.br b/publish/wwwroot/lib/fontawesome/css/all.min.css.br new file mode 100644 index 0000000..6be4473 Binary files /dev/null and b/publish/wwwroot/lib/fontawesome/css/all.min.css.br differ diff --git a/publish/wwwroot/lib/fontawesome/css/all.min.css.gz b/publish/wwwroot/lib/fontawesome/css/all.min.css.gz new file mode 100644 index 0000000..f121fcd Binary files /dev/null and b/publish/wwwroot/lib/fontawesome/css/all.min.css.gz differ diff --git a/publish/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff2 b/publish/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff2 new file mode 100644 index 0000000..73c5c12 Binary files /dev/null and b/publish/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff2 differ diff --git a/publish/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff2 b/publish/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000..c7bd59c Binary files /dev/null and b/publish/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff2 differ diff --git a/publish/wwwroot/lib/jquery/jquery.min.js b/publish/wwwroot/lib/jquery/jquery.min.js new file mode 100644 index 0000000..c4c6022 --- /dev/null +++ b/publish/wwwroot/lib/jquery/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0