Browse Source

changes for the title creator and background remover

VISHAL BHANUSHALI 1 tháng trước cách đây
mục cha
commit
c502e61032
54 tập tin đã thay đổi với 22293 bổ sung165 xóa
  1. 4 1
      README.md
  2. 28 0
      bg_remover/migrations/0001_initial.py
  3. 18 1
      bg_remover/models.py
  4. 81 0
      bg_remover/tasks.py
  5. 188 0
      bg_remover/templates/bg_remover_history.html
  6. 80 6
      bg_remover/templates/bg_remover_index.html
  7. 15380 0
      bg_remover/templates/static/css/adminlte.css
  8. 134 0
      bg_remover/templates/static/css/custom.css
  9. 309 0
      bg_remover/templates/static/css/login.css
  10. 8 0
      bg_remover/templates/static/css/overlayscrollbars.min.css
  11. 0 0
      bg_remover/templates/static/css/select2-bootstrap4.min.css
  12. BIN
      bg_remover/templates/static/fonts/aptos-font/Aptos.eot
  13. BIN
      bg_remover/templates/static/fonts/aptos-font/Aptos.woff
  14. BIN
      bg_remover/templates/static/fonts/aptos-font/Aptos.woff2
  15. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-black-italic.ttf
  16. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-black.ttf
  17. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-bold.ttf
  18. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-extrabold-italic 2.ttf
  19. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-extrabold-italic.ttf
  20. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-extrabold.ttf
  21. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-italic.ttf
  22. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-light-italic.ttf
  23. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-light.ttf
  24. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-semibold.ttf
  25. BIN
      bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos.ttf
  26. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-black-italic.ttf
  27. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-black.ttf
  28. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-bold.ttf
  29. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-extrabold-italic 2.ttf
  30. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-extrabold-italic.ttf
  31. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-extrabold.ttf
  32. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-italic.ttf
  33. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-light-italic.ttf
  34. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-light.ttf
  35. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos-semibold.ttf
  36. BIN
      bg_remover/templates/static/fonts/aptos-font/aptos.ttf
  37. BIN
      bg_remover/templates/static/images/45.jpg
  38. BIN
      bg_remover/templates/static/images/bg.png
  39. BIN
      bg_remover/templates/static/images/left.png
  40. BIN
      bg_remover/templates/static/images/logo-mini.png
  41. BIN
      bg_remover/templates/static/images/logo.png
  42. BIN
      bg_remover/templates/static/images/user2-160x160.jpg
  43. 715 0
      bg_remover/templates/static/js/adminlte.js
  44. 1214 0
      bg_remover/templates/static/js/attr-extraction-bkp.js
  45. 3471 0
      bg_remover/templates/static/js/attr-extraction.js
  46. 3 0
      bg_remover/urls.py
  47. 255 65
      bg_remover/views.py
  48. 3 0
      content_quality_tool/settings.py
  49. 2 2
      content_quality_tool_public/templates/sidebar.html
  50. 162 0
      title_creator_app/templates/title_creator_history.html
  51. 99 34
      title_creator_app/templates/title_creator_index.html
  52. 1 1
      title_creator_app/templates/title_creator_master.html
  53. 3 1
      title_creator_app/urls.py
  54. 135 54
      title_creator_app/views.py

+ 4 - 1
README.md

@@ -1,3 +1,6 @@
 # content_quality_tool
 
-content_quality_tool
+content_quality_tool
+
+pip install cloudscraper
+pip install einops kornia timm

+ 28 - 0
bg_remover/migrations/0001_initial.py

@@ -0,0 +1,28 @@
+# Generated by Django 5.2.7 on 2025-12-24 13:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='BackgroundTask',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('task_id', models.UUIDField(editable=False, unique=True)),
+                ('status', models.CharField(choices=[('PENDING', 'Pending'), ('PROCESSING', 'Processing'), ('COMPLETED', 'Completed'), ('FAILED', 'Failed')], default='PENDING', max_length=20)),
+                ('zip_file', models.FileField(blank=True, null=True, upload_to='bulk_results/')),
+                ('created_at', models.DateTimeField(auto_now_add=True)),
+                ('error_message', models.TextField(blank=True, null=True)),
+            ],
+            options={
+                'db_table': 'bg_remover_background_tasks',
+            },
+        ),
+    ]

+ 18 - 1
bg_remover/models.py

@@ -1,3 +1,20 @@
 from django.db import models
 
-# Create your models here.
+class BackgroundTask(models.Model):
+    class Meta:
+        db_table = 'bg_remover_background_tasks'
+
+    STATUS_CHOICES = [
+        ('PENDING', 'Pending'),
+        ('PROCESSING', 'Processing'),
+        ('COMPLETED', 'Completed'),
+        ('FAILED', 'Failed'),
+    ]
+    task_id = models.UUIDField(unique=True, editable=False)
+    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='PENDING')
+    zip_file = models.FileField(upload_to='bulk_results/', null=True, blank=True)
+    created_at = models.DateTimeField(auto_now_add=True)
+    error_message = models.TextField(null=True, blank=True)
+
+    def __str__(self):
+        return f"Task {self.task_id} - {self.status}"

+ 81 - 0
bg_remover/tasks.py

@@ -0,0 +1,81 @@
+# background_remover/tasks.py
+import os
+import io
+import zipfile
+import csv
+from celery import shared_task
+from django.conf import settings
+from PIL import Image
+from .services import BiRefNetService
+
+@shared_task
+def process_bulk_images_task(file_paths, task_id):
+    service = BiRefNetService()
+    
+    # Define paths
+    results_dir = os.path.join(settings.MEDIA_ROOT, 'bulk_results', task_id)
+    os.makedirs(results_dir, exist_ok=True)
+    
+    zip_output_path = os.path.join(results_dir, f"processed_{task_id}.zip")
+    log_file_path = os.path.join(results_dir, "report.csv")
+    
+    log_data = [] # To store rows: [Filename, Status, Error]
+
+    with zipfile.ZipFile(zip_output_path, "w", zipfile.ZIP_DEFLATED) as master_zip:
+        for file_path in file_paths:
+            full_path = os.path.join(settings.MEDIA_ROOT, file_path)
+            original_name = os.path.basename(file_path)
+
+            try:
+                # CASE 1: INPUT IS A ZIP
+                if original_name.lower().endswith('.zip'):
+                    with zipfile.ZipFile(full_path, 'r') as user_zip:
+                        for inner_name in user_zip.namelist():
+                            if inner_name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
+                                try:
+                                    with user_zip.open(inner_name) as inner_file:
+                                        img = Image.open(io.BytesIO(inner_file.read())).convert("RGB")
+                                        output = service.remove_background(img)
+                                        
+                                        img_io = io.BytesIO()
+                                        output.save(img_io, format="PNG")
+                                        
+                                        clean_name = inner_name.split('/')[-1].rsplit('.', 1)[0] + "_no_bg.png"
+                                        master_zip.writestr(clean_name, img_io.getvalue())
+                                        log_data.append([inner_name, "SUCCESS", ""])
+                                except Exception as e:
+                                    log_data.append([inner_name, "FAILED", str(e)])
+
+                # CASE 2: INPUT IS AN IMAGE
+                else:
+                    try:
+                        img = Image.open(full_path).convert("RGB")
+                        output = service.remove_background(img)
+                        
+                        img_io = io.BytesIO()
+                        output.save(img_io, format="PNG")
+                        
+                        name = original_name.rsplit(".", 1)[0] + "_no_bg.png"
+                        master_zip.writestr(name, img_io.getvalue())
+                        log_data.append([original_name, "SUCCESS", ""])
+                    except Exception as e:
+                        log_data.append([original_name, "FAILED", str(e)])
+
+            finally:
+                # Cleanup temporary uploaded files
+                if os.path.exists(full_path):
+                    os.remove(full_path)
+
+        # Create the CSV log inside the task folder
+        with open(log_file_path, mode='w', newline='') as csvfile:
+            writer = csv.writer(csvfile)
+            writer.writerow(["Filename", "Status", "Error Message"])
+            writer.writerows(log_data)
+        
+        # Add the log file into the zip too
+        master_zip.write(log_file_path, "report.csv")
+
+    return {
+        "zip_url": f"{settings.MEDIA_URL}bulk_results/{task_id}/processed_{task_id}.zip",
+        "log_url": f"{settings.MEDIA_URL}bulk_results/{task_id}/report.csv"
+    }

+ 188 - 0
bg_remover/templates/bg_remover_history.html

@@ -0,0 +1,188 @@
+{% load static %}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Task History | AI Background Remover</title>
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
+<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css"
+        integrity="sha256-tXJfXfp6Ewt1ilPzLDtQnJV4hclT9XuaZUKyUvmyr+Q=" crossorigin="anonymous">
+    <!--end::Fonts--><!--begin::Third Party Plugin(OverlayScrollbars)-->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/styles/overlayscrollbars.min.css"
+        integrity="sha256-dSokZseQNT08wYEWiz5iLI8QPlKxG+TswNRD8k35cpg=" crossorigin="anonymous">
+    <!--end::Third Party Plugin(OverlayScrollbars)--><!--begin::Third Party Plugin(Bootstrap Icons)-->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.min.css"
+        integrity="sha256-Qsx5lrStHZyR9REqhUF8iQt73X06c8LGIUPzpOhwRrI=" crossorigin="anonymous">
+    <!--end::Third Party Plugin(Bootstrap Icons)--><!--begin::Required Plugin(AdminLTE)-->
+    <link rel="stylesheet" href="{% static './css/adminlte.css' %}"><!--end::Required Plugin(AdminLTE)--><!-- apexcharts -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/apexcharts@3.37.1/dist/apexcharts.css"
+        integrity="sha256-4MX+61mt9NVvvuPjUWdUdyfZfxSB1/Rf9WtqRHgG5S0=" crossorigin="anonymous">
+    <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
+    <link rel="stylesheet" href="{% static './css/select2-bootstrap4.min.css' %}">
+    <link rel="stylesheet" href="{% static './css/custom.css' %}">
+    <script src="https://cdn.tailwindcss.com"></script>
+    <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;800&display=swap" rel="stylesheet">
+    
+    <style>
+        body { font-family: 'Plus Jakarta Sans', sans-serif; background-color: #f8fafc; }
+        .table-container { background: white; border-radius: 24px; border: 1px solid #e2e8f0; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05); }
+        .status-badge { font-weight: 700; font-size: 0.7rem; letter-spacing: 0.05em; padding: 6px 12px; border-radius: 10px; text-transform: uppercase; }
+        .btn-new { background: #2563eb; color: white; padding: 10px 24px; border-radius: 14px; font-weight: 700; transition: all 0.3s; }
+        .btn-new:hover { background: #1d4ed8; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2); }
+    </style>
+</head>
+
+<body class="layout-fixed sidebar-expand-lg sidebar-mini app-loaded sidebar-collapse">
+    <div class="app-wrapper">
+        {% include 'header.html' %}
+        {% include 'sidebar.html' %}
+
+        <main class="app-main">
+            <div class="app-content pt-10 px-4">
+                <div class="max-w-6xl mx-auto">
+                    
+                    <div class="mb-8 flex flex-col md:flex-row md:items-center justify-between gap-4">
+                        <div>
+                            <nav class="flex mb-2 text-[10px] font-bold uppercase tracking-[0.2em] text-blue-600">
+                                <a href="{% url 'remove_bg' %}" class="hover:text-blue-800">Image Background Remover</a>
+                                <span class="mx-2 text-gray-300">/</span>
+                                <span class="text-gray-400">Processing History</span>
+                            </nav>
+                            <h1 class="text-3xl font-black text-gray-900 tracking-tight">Batch History</h1>
+                            <p class="text-gray-500 font-medium">Manage and download your recently processed image archives.</p>
+                        </div>
+                        
+                        <a href="{% url 'remove_bg' %}" class="btn-new inline-flex items-center gap-2">
+                            <i class="bi bi-plus-lg"></i>
+                            New Batch Task
+                        </a>
+                    </div>
+
+                    <div class="table-container overflow-hidden">
+                        <table class="table table-hover align-middle mb-0">
+                            <thead class="bg-gray-50/50 border-b border-gray-100">
+                                <tr>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest">Date & Time</th>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest">Task Identifier</th>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest text-center">Status</th>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest text-end">Action</th>
+                                </tr>
+                            </thead>
+                            <tbody id="history-table-body" class="divide-y divide-gray-50">
+                                <tr>
+                                    <td colspan="4" class="py-20 text-center">
+                                        <div class="flex flex-col items-center">
+                                            <div class="w-10 h-10 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mb-4"></div>
+                                            <p class="text-gray-400 font-bold uppercase tracking-widest text-xs">Syncing Tasks...</p>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+
+                    <p class="mt-6 text-center text-xs text-gray-400 font-medium">
+                        <i class="bi bi-info-circle mr-1"></i> 
+                        Tasks are automatically removed after 24 hours to optimize storage.
+                    </p>
+                </div>
+            </div>
+        </main>
+        {% include 'footer.html' %}
+    </div>
+    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/browser/overlayscrollbars.browser.es6.min.js"></script>
+    <script src="{% static './js/adminlte.js' %}"></script>
+    <script>
+        async function fetchHistory() {
+            try {
+                // Fetching from the API we built earlier
+                const res = await fetch('{% url "bg_tasks_json" %}'); 
+                const data = await res.json();
+                const body = document.getElementById('history-table-body');
+                
+                if (data.length === 0) {
+                    body.innerHTML = `
+                        <tr>
+                            <td colspan="4" class="text-center py-20">
+                                <i class="bi bi-inbox text-4xl text-gray-200 mb-3 block"></i>
+                                <p class="text-gray-400 font-bold">No tasks found in your history.</p>
+                            </td>
+                        </tr>`;
+                    return;
+                }
+
+                body.innerHTML = data.map(t => {
+                    let badgeStyles = "";
+                    let statusLabel = t.status;
+
+                    if(t.status === 'COMPLETED') {
+                        badgeStyles = "bg-green-100 text-green-700 border border-green-200";
+                    } else if(t.status === 'PROCESSING') {
+                        badgeStyles = "bg-blue-100 text-blue-700 border border-blue-200 animate-pulse";
+                        statusLabel = "In Progress";
+                    } else {
+                        badgeStyles = "bg-red-100 text-red-700 border border-red-200";
+                    }
+
+                    return `
+                    <tr class="transition-colors hover:bg-gray-50/50">
+                        <td class="px-6 py-4">
+                            <div class="text-sm font-bold text-gray-800">${t.date}</div>
+                        </td>
+                        <td class="px-6 py-4">
+                            <div class="text-xs font-mono text-gray-400 tracking-tighter">${t.task_id}</div>
+                        </td>
+                        <td class="px-6 py-4 text-center">
+                            <span class="status-badge ${badgeStyles}">
+                                ${statusLabel}
+                            </span>
+                        </td>
+                        <td class="px-6 py-4 text-end">
+                            ${t.url ? 
+                                `<a href="${t.url}" class="inline-flex items-center gap-2 bg-slate-900 text-white px-4 py-2 rounded-xl text-xs font-bold hover:bg-slate-800 transition-all">
+                                    <i class="bi bi-download"></i> Download ZIP
+                                </a>` : 
+                                `<span class="text-[11px] font-black text-gray-300 uppercase italic">Working...</span>`
+                            }
+                        </td>
+                    </tr>`;
+                }).join('');
+            } catch (err) {
+                console.error("History fetch error:", err);
+            }
+        }
+
+        // Auto-refresh every 5 seconds to update "Processing" tasks
+        fetchHistory();
+        // setInterval(fetchHistory, 5000);
+    </script>
+    <script>
+        const SELECTOR_SIDEBAR_WRAPPER = ".sidebar-wrapper";
+        const Default = {
+            scrollbarTheme: "os-theme-light",
+            scrollbarAutoHide: "leave",
+            scrollbarClickScroll: true,
+        };
+        document.addEventListener("DOMContentLoaded", function () {
+            const sidebarWrapper = document.querySelector(SELECTOR_SIDEBAR_WRAPPER);
+            if (
+                sidebarWrapper &&
+                typeof OverlayScrollbarsGlobal?.OverlayScrollbars !== "undefined"
+            ) {
+                OverlayScrollbarsGlobal.OverlayScrollbars(sidebarWrapper, {
+                    scrollbars: {
+                        theme: Default.scrollbarTheme,
+                        autoHide: Default.scrollbarAutoHide,
+                        clickScroll: Default.scrollbarClickScroll,
+                    },
+                });
+            }
+        });
+    </script>
+</body>
+</html>

+ 80 - 6
bg_remover/templates/bg_remover_index.html

@@ -4,7 +4,7 @@
 <head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<title>Column Mapping</title>
+<title>Background Remover</title>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
 <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css"
@@ -23,7 +23,7 @@
     <link rel="stylesheet" href="{% static './css/select2-bootstrap4.min.css' %}">
     <link rel="stylesheet" href="{% static './css/custom.css' %}">
     <script src="https://cdn.tailwindcss.com"></script>
-    <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;800&display=swap" rel="stylesheet">
+    <!-- <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;800&display=swap" rel="stylesheet"> -->
     <style>
         .bg-remover-container .nav-pills .nav-link { color: #64748b; font-weight: 600; border-radius: 12px; padding: 10px 25px; transition: all 0.3s; border: none; background: none; }
         .bg-remover-container .nav-pills .nav-link.active { background-color: #3b82f6 !important; color: white !important; box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3); }
@@ -45,12 +45,59 @@
         {% include 'sidebar.html' %}
 
         <main class="app-main">
+            <div class="app-content-header"> <!--begin::Container-->
+                <div class="container-fluid"> <!--begin::Row-->
+                    <div class="row">
+                        <div class="col-sm-6">
+                            <h3 class="mb-0">🪄 Image Background Remover
+                                
+                            </h3> 
+                            
+                        </div>
+                        <div class="col-sm-6">
+                            <ol class="breadcrumb float-sm-end">
+                                <li class="breadcrumb-item"><a href="{% url 'file-upload' %}">Home</a></li>
+                                <li class="breadcrumb-item active" aria-current="page"><a href="{% url 'product-attributes' %}"></a>
+                                   🪄 Image Background Remover</a>
+                                </li>
+                            </ol>
+                        </div>
+                    </div> <!--end::Row-->
+                </div> <!--end::Container-->
+            </div>
             <div class="app-content pt-10 bg-remover-container">
-                <div class="max-w-5xl mx-auto px-4">
-                    <div class="text-center mb-8">
+                <div class=" mx-auto px-4">
+                    <div class="mb-10 flex flex-col md:flex-row md:items-end md:justify-between gap-4 border-b border-gray-100 pb-6">
+                        <div class="text-left">
+                            <h1 class="text-4xl font-black text-gray-900 tracking-tight mb-2">
+                                Image <span class="text-blue-600">Background</span> Remover
+                            </h1>
+                            <p class="text-gray-500 font-medium ">
+                                Professional-grade background removal. Process single images or 
+                                <span class="text-gray-800 font-semibold">batch process ZIP archives </span> instantly.
+                            </p>
+                        </div>
+
+                        <div class="flex items-center">
+                            <a href="/bg-remover/tasks/history/" 
+                            class="inline-flex items-center gap-2 px-5 py-2.5 bg-white border border-gray-200 text-gray-700 text-sm font-bold rounded-xl shadow-sm hover:shadow-md hover:border-blue-300 hover:text-blue-600 transition-all duration-200 group">
+                                <i class="bi bi-clock-history text-gray-400 group-hover:text-blue-500 transition-colors"></i>
+                                Task History
+                                <span class="flex h-2 w-2 rounded-full bg-blue-500 ml-1"></span>
+                            </a>
+                        </div>
+                    </div>
+                    <!-- <div class="text-center mb-8">
                         <h1 class="text-4xl font-extrabold text-gray-900 mb-2">AI Background Remover</h1>
                         <p class="text-gray-500 font-medium">Remove image backgrounds instantly for single images, bulk uploads, or ZIP files.</p>
-                    </div>
+                        <div class="flex justify-end mb-4">
+                            <a href="/bg-remover/tasks/history/" 
+                            class="flex items-center gap-2 px-6 py-2.5 bg-white border border-gray-200 text-gray-700 font-bold rounded-xl shadow-sm hover:bg-gray-50 hover:border-blue-400 transition-all">
+                                <i class="bi bi-clock-history text-blue-600"></i>
+                                View Task History
+                            </a>
+                        </div>
+                    </div> -->
 
                     <ul class="nav nav-pills justify-content-center mb-8 gap-3" id="pills-tab" role="tablist">
                         <li class="nav-item" role="presentation">
@@ -217,7 +264,7 @@
             };
         }
 
-        if (startBulkBtn) {
+        /*if (startBulkBtn) {
             startBulkBtn.onclick = async () => {
                 const files = bulkInput.files;
                 if (!files || files.length === 0) return;
@@ -236,7 +283,34 @@
                     }
                 } finally { if (bulkLoader) bulkLoader.classList.add('hidden'); }
             };
+        }*/
+
+        if (startBulkBtn) {
+    startBulkBtn.onclick = async () => {
+        const files = document.getElementById('bulk-file-input').files;
+        if (!files.length) return;
+        const formData = new FormData();
+        for (let i = 0; i < files.length; i++) formData.append('images', files[i]);
+        
+        document.getElementById('bulk-loader').classList.remove('hidden');
+        try {
+            const response = await fetch('/bg-remover/remove-bg/bulk/', { 
+                method: 'POST', 
+                body: formData, 
+                headers: {'X-CSRFToken': '{{ csrf_token }}'} 
+            });
+            if (response.ok) {
+                // REDIRECT TO THE NEW HISTORY PAGE
+                window.location.href = "{% url 'bg_history_page' %}";
+            }
+        } catch (err) { 
+            alert("Upload failed"); 
+            document.getElementById('bulk-loader').classList.add('hidden');
         }
+    };
+}
+    
+    
     </script>
     <script>
         const SELECTOR_SIDEBAR_WRAPPER = ".sidebar-wrapper";

+ 15380 - 0
bg_remover/templates/static/css/adminlte.css

@@ -0,0 +1,15380 @@
+@charset "UTF-8";
+/*!
+ *   AdminLTE v4.0.0-beta2
+ *   Author: Colorlib
+ *   Website: AdminLTE.io <https://adminlte.io>
+ *   License: Open source - MIT <https://opensource.org/licenses/MIT>
+ */
+:root,
+[data-bs-theme=light] {
+  --bs-blue: #01445E;
+  --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-black: #000;
+  --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: #01445E;
+  --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-primary-text-emphasis: #052c65;
+  --bs-secondary-text-emphasis: #2b2f32;
+  --bs-success-text-emphasis: #0a3622;
+  --bs-info-text-emphasis: #055160;
+  --bs-warning-text-emphasis: #664d03;
+  --bs-danger-text-emphasis: #58151c;
+  --bs-light-text-emphasis: #495057;
+  --bs-dark-text-emphasis: #495057;
+  --bs-primary-bg-subtle: #cfe2ff;
+  --bs-secondary-bg-subtle: #e2e3e5;
+  --bs-success-bg-subtle: #d1e7dd;
+  --bs-info-bg-subtle: #cff4fc;
+  --bs-warning-bg-subtle: #fff3cd;
+  --bs-danger-bg-subtle: #f8d7da;
+  --bs-light-bg-subtle: #fcfcfd;
+  --bs-dark-bg-subtle: #ced4da;
+  --bs-primary-border-subtle: #9ec5fe;
+  --bs-secondary-border-subtle: #c4c8cb;
+  --bs-success-border-subtle: #a3cfbb;
+  --bs-info-border-subtle: #9eeaf9;
+  --bs-warning-border-subtle: #ffe69c;
+  --bs-danger-border-subtle: #f1aeb5;
+  --bs-light-border-subtle: #e9ecef;
+  --bs-dark-border-subtle: #adb5bd;
+  --bs-white-rgb: 255, 255, 255;
+  --bs-black-rgb: 0, 0, 0;
+  --bs-font-sans-serif: "aptos", "Noto Sans", "Liberation Sans", Arial, 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: 14px;
+  --bs-body-font-weight: 400;
+  --bs-body-line-height: 1.5;
+  --bs-body-color: #212529;
+  --bs-body-color-rgb: 33, 37, 41;
+  --bs-body-bg: #fff;
+  --bs-body-bg-rgb: 255, 255, 255;
+  --bs-emphasis-color: #000;
+  --bs-emphasis-color-rgb: 0, 0, 0;
+  --bs-secondary-color: rgba(33, 37, 41, 0.75);
+  --bs-secondary-color-rgb: 33, 37, 41;
+  --bs-secondary-bg: #e9ecef;
+  --bs-secondary-bg-rgb: 233, 236, 239;
+  --bs-tertiary-color: rgba(33, 37, 41, 0.5);
+  --bs-tertiary-color-rgb: 33, 37, 41;
+  --bs-tertiary-bg: #f8f9fa;
+  --bs-tertiary-bg-rgb: 248, 249, 250;
+  --bs-heading-color: inherit;
+  --bs-link-color: #01445E;
+  --bs-link-color-rgb: 13, 110, 253;
+  --bs-link-decoration: underline;
+  --bs-link-hover-color: #0a58ca;
+  --bs-link-hover-color-rgb: 10, 88, 202;
+  --bs-code-color: #d63384;
+  --bs-highlight-color: #212529;
+  --bs-highlight-bg: #fff3cd;
+  --bs-border-width: 1px;
+  --bs-border-style: solid;
+  --bs-border-color: #dee2e6;
+  --bs-border-color-translucent: rgba(0, 0, 0, 0.175);
+  --bs-border-radius: 0.375rem;
+  --bs-border-radius-sm: 0.25rem;
+  --bs-border-radius-lg: 0.5rem;
+  --bs-border-radius-xl: 1rem;
+  --bs-border-radius-xxl: 2rem;
+  --bs-border-radius-2xl: var(--bs-border-radius-xxl);
+  --bs-border-radius-pill: 50rem;
+  --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+  --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+  --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
+  --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
+  --bs-focus-ring-width: 0.25rem;
+  --bs-focus-ring-opacity: 0.25;
+  --bs-focus-ring-color: rgba(13, 110, 253, 0.25);
+  --bs-form-valid-color: #198754;
+  --bs-form-valid-border-color: #198754;
+  --bs-form-invalid-color: #dc3545;
+  --bs-form-invalid-border-color: #dc3545;
+}
+
+[data-bs-theme=dark] {
+  color-scheme: dark;
+  --bs-body-color: #dee2e6;
+  --bs-body-color-rgb: 222, 226, 230;
+  --bs-body-bg: #212529;
+  --bs-body-bg-rgb: 33, 37, 41;
+  --bs-emphasis-color: #fff;
+  --bs-emphasis-color-rgb: 255, 255, 255;
+  --bs-secondary-color: rgba(222, 226, 230, 0.75);
+  --bs-secondary-color-rgb: 222, 226, 230;
+  --bs-secondary-bg: #343a40;
+  --bs-secondary-bg-rgb: 52, 58, 64;
+  --bs-tertiary-color: rgba(222, 226, 230, 0.5);
+  --bs-tertiary-color-rgb: 222, 226, 230;
+  --bs-tertiary-bg: #2b3035;
+  --bs-tertiary-bg-rgb: 43, 48, 53;
+  --bs-primary-text-emphasis: #6ea8fe;
+  --bs-secondary-text-emphasis: #a7acb1;
+  --bs-success-text-emphasis: #75b798;
+  --bs-info-text-emphasis: #6edff6;
+  --bs-warning-text-emphasis: #ffda6a;
+  --bs-danger-text-emphasis: #ea868f;
+  --bs-light-text-emphasis: #f8f9fa;
+  --bs-dark-text-emphasis: #dee2e6;
+  --bs-primary-bg-subtle: #031633;
+  --bs-secondary-bg-subtle: #161719;
+  --bs-success-bg-subtle: #051b11;
+  --bs-info-bg-subtle: #032830;
+  --bs-warning-bg-subtle: #332701;
+  --bs-danger-bg-subtle: #2c0b0e;
+  --bs-light-bg-subtle: #343a40;
+  --bs-dark-bg-subtle: #1a1d20;
+  --bs-primary-border-subtle: #084298;
+  --bs-secondary-border-subtle: #41464b;
+  --bs-success-border-subtle: #0f5132;
+  --bs-info-border-subtle: #087990;
+  --bs-warning-border-subtle: #997404;
+  --bs-danger-border-subtle: #842029;
+  --bs-light-border-subtle: #495057;
+  --bs-dark-border-subtle: #343a40;
+  --bs-heading-color: inherit;
+  --bs-link-color: #6ea8fe;
+  --bs-link-hover-color: #8bb9fe;
+  --bs-link-color-rgb: 110, 168, 254;
+  --bs-link-hover-color-rgb: 139, 185, 254;
+  --bs-code-color: #e685b5;
+  --bs-highlight-color: #dee2e6;
+  --bs-highlight-bg: #664d03;
+  --bs-border-color: #495057;
+  --bs-border-color-translucent: rgba(255, 255, 255, 0.15);
+  --bs-form-valid-color: #75b798;
+  --bs-form-valid-border-color: #75b798;
+  --bs-form-invalid-color: #ea868f;
+  --bs-form-invalid-border-color: #ea868f;
+}
+
+*,
+*::before,
+*::after {
+  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: rgba(0, 0, 0, 0);
+}
+
+hr {
+  margin: 1rem 0;
+  color: inherit;
+  border: 0;
+  border-top: var(--bs-border-width) solid;
+  opacity: 0.25;
+}
+
+h6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 {
+  margin-top: 0;
+  margin-bottom: 0.5rem;
+  font-weight: 500;
+  line-height: 1.2;
+  color: var(--bs-heading-color);
+}
+
+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 + 0.9vw);
+}
+@media (min-width: 1200px) {
+  h2, .h2 {
+    font-size: 2rem;
+  }
+}
+
+h3, .h3 {
+  font-size: calc(1rem + 0.6vw);
+}
+@media (min-width: 1200px) {
+  h3, .h3 {
+    font-size: 1.55rem;
+  }
+}
+
+h4, .h4 {
+  font-size: calc(1.275rem + 0.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[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;
+}
+
+ol,
+ul,
+dl {
+  margin-top: 0;
+  margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+  margin-bottom: 0;
+}
+
+dt {
+  font-weight: 700;
+}
+
+dd {
+  margin-bottom: 0.5rem;
+  margin-left: 0;
+}
+
+blockquote {
+  margin: 0 0 1rem;
+}
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+small, .small {
+  font-size: 0.875em;
+}
+
+mark, .mark {
+  padding: 0.1875em;
+  color: var(--bs-highlight-color);
+  background-color: var(--bs-highlight-bg);
+}
+
+sub,
+sup {
+  position: relative;
+  font-size: 0.75em;
+  line-height: 0;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+a {
+  color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
+  text-decoration: underline;
+}
+a:hover {
+  --bs-link-color-rgb: var(--bs-link-hover-color-rgb);
+}
+
+a:not([href]):not([class]), a:not([href]):not([class]):hover {
+  color: inherit;
+  text-decoration: none;
+}
+
+pre,
+code,
+kbd,
+samp {
+  font-family: var(--bs-font-monospace);
+  font-size: 1em;
+}
+
+pre {
+  display: block;
+  margin-top: 0;
+  margin-bottom: 1rem;
+  overflow: auto;
+  font-size: 0.875em;
+}
+pre code {
+  font-size: inherit;
+  color: inherit;
+  word-break: normal;
+}
+
+code {
+  font-size: 0.875em;
+  color: var(--bs-code-color);
+  word-wrap: break-word;
+}
+a > code {
+  color: inherit;
+}
+
+kbd {
+  padding: 0.1875rem 0.375rem;
+  font-size: 0.875em;
+  color: var(--bs-body-bg);
+  background-color: var(--bs-body-color);
+  border-radius: 0.25rem;
+}
+kbd kbd {
+  padding: 0;
+  font-size: 1em;
+}
+
+figure {
+  margin: 0 0 1rem;
+}
+
+img,
+svg {
+  vertical-align: middle;
+}
+
+table {
+  caption-side: bottom;
+  border-collapse: collapse;
+}
+
+caption {
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+  color: var(--bs-secondary-color);
+  text-align: left;
+}
+
+th {
+  text-align: inherit;
+  text-align: -webkit-match-parent;
+}
+
+thead,
+tbody,
+tfoot,
+tr,
+td,
+th {
+  border-color: inherit;
+  border-style: solid;
+  border-width: 0;
+}
+
+label {
+  display: inline-block;
+}
+
+button {
+  border-radius: 0;
+}
+
+button:focus:not(:focus-visible) {
+  outline: 0;
+}
+
+input,
+button,
+select,
+optgroup,
+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]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
+  display: none !important;
+}
+
+button,
+[type=button],
+[type=reset],
+[type=submit] {
+  -webkit-appearance: button;
+}
+button:not(:disabled),
+[type=button]:not(:disabled),
+[type=reset]:not(:disabled),
+[type=submit]: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: 0.5rem;
+  font-size: calc(1.275rem + 0.3vw);
+  line-height: inherit;
+}
+@media (min-width: 1200px) {
+  legend {
+    font-size: 1.5rem;
+  }
+}
+legend + * {
+  clear: left;
+}
+
+::-webkit-datetime-edit-fields-wrapper,
+::-webkit-datetime-edit-text,
+::-webkit-datetime-edit-minute,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-year-field {
+  padding: 0;
+}
+
+::-webkit-inner-spin-button {
+  height: auto;
+}
+
+[type=search] {
+  -webkit-appearance: textfield;
+  outline-offset: -2px;
+}
+
+/* rtl:raw:
+[type="tel"],
+[type="url"],
+[type="email"],
+[type="number"] {
+  direction: ltr;
+}
+*/
+::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+::-webkit-color-swatch-wrapper {
+  padding: 0;
+}
+
+::-webkit-file-upload-button {
+  font: inherit;
+  -webkit-appearance: button;
+}
+
+::file-selector-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: 0.5rem;
+}
+
+.initialism {
+  font-size: 0.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: 0.875em;
+  color: #6c757d;
+}
+.blockquote-footer::before {
+  content: "— ";
+}
+
+.img-fluid {
+  max-width: 100%;
+  height: auto;
+}
+
+.img-thumbnail {
+  padding: 0.25rem;
+  background-color: var(--bs-body-bg);
+  border: var(--bs-border-width) solid var(--bs-border-color);
+  border-radius: var(--bs-border-radius);
+  box-shadow: var(--bs-box-shadow-sm);
+  max-width: 100%;
+  height: auto;
+}
+
+.figure {
+  display: inline-block;
+}
+
+.figure-img {
+  margin-bottom: 0.5rem;
+  line-height: 1;
+}
+
+.figure-caption {
+  font-size: 0.875em;
+  color: var(--bs-secondary-color);
+}
+
+.container,
+.container-fluid,
+.container-xxl,
+.container-xl,
+.container-lg,
+.container-md,
+.container-sm {
+  --bs-gutter-x: 1.5rem;
+  --bs-gutter-y: 0;
+  width: 100%;
+  padding-right: calc(var(--bs-gutter-x) * 0.5);
+  padding-left: calc(var(--bs-gutter-x) * 0.5);
+  margin-right: auto;
+  margin-left: auto;
+}
+
+@media (min-width: 576px) {
+  .container-sm, .container {
+    max-width: 540px;
+  }
+}
+@media (min-width: 768px) {
+  .container-md, .container-sm, .container {
+    max-width: 720px;
+  }
+}
+@media (min-width: 992px) {
+  .container-lg, .container-md, .container-sm, .container {
+    max-width: 960px;
+  }
+}
+@media (min-width: 1200px) {
+  .container-xl, .container-lg, .container-md, .container-sm, .container {
+    max-width: 1140px;
+  }
+}
+@media (min-width: 1400px) {
+  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {
+    max-width: 1320px;
+  }
+}
+:root {
+  --bs-breakpoint-xs: 0;
+  --bs-breakpoint-sm: 576px;
+  --bs-breakpoint-md: 768px;
+  --bs-breakpoint-lg: 992px;
+  --bs-breakpoint-xl: 1200px;
+  --bs-breakpoint-xxl: 1400px;
+}
+
+.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(-0.5 * var(--bs-gutter-x));
+  margin-left: calc(-0.5 * var(--bs-gutter-x));
+}
+.row > * {
+  flex-shrink: 0;
+  width: 100%;
+  max-width: 100%;
+  padding-right: calc(var(--bs-gutter-x) * 0.5);
+  padding-left: calc(var(--bs-gutter-x) * 0.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.33333333%;
+}
+
+.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.66666667%;
+}
+
+.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.33333333%;
+  }
+  .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.66666667%;
+  }
+  .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.33333333%;
+  }
+  .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.66666667%;
+  }
+  .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.33333333%;
+  }
+  .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.66666667%;
+  }
+  .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.33333333%;
+  }
+  .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.66666667%;
+  }
+  .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.33333333%;
+  }
+  .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.66666667%;
+  }
+  .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-color-type: initial;
+  --bs-table-bg-type: initial;
+  --bs-table-color-state: initial;
+  --bs-table-bg-state: initial;
+  --bs-table-color: var(--bs-emphasis-color);
+  --bs-table-bg: var(--bs-body-bg);
+  --bs-table-border-color: var(--bs-border-color);
+  --bs-table-accent-bg: transparent;
+  --bs-table-striped-color: var(--bs-emphasis-color);
+  --bs-table-striped-bg: rgba(var(--bs-emphasis-color-rgb), 0.05);
+  --bs-table-active-color: var(--bs-emphasis-color);
+  --bs-table-active-bg: rgba(var(--bs-emphasis-color-rgb), 0.1);
+  --bs-table-hover-color: var(--bs-emphasis-color);
+  --bs-table-hover-bg: rgba(var(--bs-emphasis-color-rgb), 0.075);
+  width: 100%;
+  margin-bottom: 1rem;
+  vertical-align: top;
+  border-color: var(--bs-table-border-color);
+}
+.table > :not(caption) > * > * {
+  padding: 0.5rem 0.5rem;
+  color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));
+  background-color: var(--bs-table-bg);
+  border-bottom-width: var(--bs-border-width);
+  box-shadow: inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg)));
+}
+.table > tbody {
+  vertical-align: inherit;
+}
+.table > thead {
+  vertical-align: bottom;
+}
+
+.table-group-divider {
+  border-top: calc(var(--bs-border-width) * 2) solid currentcolor;
+}
+
+.caption-top {
+  caption-side: top;
+}
+
+.table-sm > :not(caption) > * > * {
+  padding: 0.25rem 0.25rem;
+}
+
+.table-bordered > :not(caption) > * {
+  border-width: var(--bs-border-width) 0;
+}
+.table-bordered > :not(caption) > * > * {
+  border-width: 0 var(--bs-border-width);
+}
+
+.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-color-type: var(--bs-table-striped-color);
+  --bs-table-bg-type: var(--bs-table-striped-bg);
+}
+
+.table-striped-columns > :not(caption) > tr > :nth-child(even) {
+  --bs-table-color-type: var(--bs-table-striped-color);
+  --bs-table-bg-type: var(--bs-table-striped-bg);
+}
+
+.table-active {
+  --bs-table-color-state: var(--bs-table-active-color);
+  --bs-table-bg-state: var(--bs-table-active-bg);
+}
+
+.table-hover > tbody > tr:hover > * {
+  --bs-table-color-state: var(--bs-table-hover-color);
+  --bs-table-bg-state: var(--bs-table-hover-bg);
+}
+
+.table-primary {
+  --bs-table-color: #000;
+  --bs-table-bg: #cfe2ff;
+  --bs-table-border-color: #a6b5cc;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-secondary {
+  --bs-table-color: #000;
+  --bs-table-bg: #e2e3e5;
+  --bs-table-border-color: #b5b6b7;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-success {
+  --bs-table-color: #000;
+  --bs-table-bg: #d1e7dd;
+  --bs-table-border-color: #a7b9b1;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-info {
+  --bs-table-color: #000;
+  --bs-table-bg: #cff4fc;
+  --bs-table-border-color: #a6c3ca;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-warning {
+  --bs-table-color: #000;
+  --bs-table-bg: #fff3cd;
+  --bs-table-border-color: #ccc2a4;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-danger {
+  --bs-table-color: #000;
+  --bs-table-bg: #f8d7da;
+  --bs-table-border-color: #c6acae;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-light {
+  --bs-table-color: #000;
+  --bs-table-bg: #f8f9fa;
+  --bs-table-border-color: #c6c7c8;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.table-dark {
+  --bs-table-color: #fff;
+  --bs-table-bg: #212529;
+  --bs-table-border-color: #4d5154;
+  --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: var(--bs-table-color);
+  border-color: var(--bs-table-border-color);
+}
+
+.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: 0.5rem;
+}
+
+.col-form-label {
+  padding-top: calc(0.375rem + var(--bs-border-width));
+  padding-bottom: calc(0.375rem + var(--bs-border-width));
+  margin-bottom: 0;
+  font-size: inherit;
+  line-height: 1.5;
+}
+
+.col-form-label-lg {
+  padding-top: calc(0.5rem + var(--bs-border-width));
+  padding-bottom: calc(0.5rem + var(--bs-border-width));
+  font-size: 1.25rem;
+}
+
+.col-form-label-sm {
+  padding-top: calc(0.25rem + var(--bs-border-width));
+  padding-bottom: calc(0.25rem + var(--bs-border-width));
+  font-size: 0.875rem;
+}
+
+.form-text {
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: var(--bs-secondary-color);
+}
+
+.form-control {
+  display: block;
+  width: 100%;
+  padding: 0.375rem 0.75rem;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 1.5;
+  color: var(--bs-body-color);
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background-color: var(--bs-body-bg);
+  background-clip: padding-box;
+  border: var(--bs-border-width) solid var(--bs-border-color);
+  border-radius: var(--bs-border-radius);
+  box-shadow: var(--bs-box-shadow-inset);
+  transition: border-color 0.15s ease-in-out, box-shadow 0.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: var(--bs-body-color);
+  background-color: var(--bs-body-bg);
+  border-color: #86b7fe;
+  outline: 0;
+  box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-control::-webkit-date-and-time-value {
+  min-width: 85px;
+  height: 1.5em;
+  margin: 0;
+}
+.form-control::-webkit-datetime-edit {
+  display: block;
+  padding: 0;
+}
+.form-control::-moz-placeholder {
+  color: var(--bs-secondary-color);
+  opacity: 1;
+}
+.form-control::placeholder {
+  color: var(--bs-secondary-color);
+  opacity: 1;
+}
+.form-control:disabled {
+  background-color: var(--bs-secondary-bg);
+  opacity: 1;
+}
+.form-control::-webkit-file-upload-button {
+  padding: 0.375rem 0.75rem;
+  margin: -0.375rem -0.75rem;
+  -webkit-margin-end: 0.75rem;
+  margin-inline-end: 0.75rem;
+  color: var(--bs-body-color);
+  background-color: var(--bs-tertiary-bg);
+  pointer-events: none;
+  border-color: inherit;
+  border-style: solid;
+  border-width: 0;
+  border-inline-end-width: var(--bs-border-width);
+  border-radius: 0;
+  -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+.form-control::file-selector-button {
+  padding: 0.375rem 0.75rem;
+  margin: -0.375rem -0.75rem;
+  -webkit-margin-end: 0.75rem;
+  margin-inline-end: 0.75rem;
+  color: var(--bs-body-color);
+  background-color: var(--bs-tertiary-bg);
+  pointer-events: none;
+  border-color: inherit;
+  border-style: solid;
+  border-width: 0;
+  border-inline-end-width: var(--bs-border-width);
+  border-radius: 0;
+  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.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: var(--bs-secondary-bg);
+}
+.form-control:hover:not(:disabled):not([readonly])::file-selector-button {
+  background-color: var(--bs-secondary-bg);
+}
+
+.form-control-plaintext {
+  display: block;
+  width: 100%;
+  padding: 0.375rem 0;
+  margin-bottom: 0;
+  line-height: 1.5;
+  color: var(--bs-body-color);
+  background-color: transparent;
+  border: solid transparent;
+  border-width: var(--bs-border-width) 0;
+}
+.form-control-plaintext:focus {
+  outline: 0;
+}
+.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {
+  padding-right: 0;
+  padding-left: 0;
+}
+
+.form-control-sm {
+  min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));
+  padding: 0.25rem 0.5rem;
+  font-size: 0.875rem;
+  border-radius: var(--bs-border-radius-sm);
+}
+.form-control-sm::-webkit-file-upload-button {
+  padding: 0.25rem 0.5rem;
+  margin: -0.25rem -0.5rem;
+  -webkit-margin-end: 0.5rem;
+  margin-inline-end: 0.5rem;
+}
+.form-control-sm::file-selector-button {
+  padding: 0.25rem 0.5rem;
+  margin: -0.25rem -0.5rem;
+  -webkit-margin-end: 0.5rem;
+  margin-inline-end: 0.5rem;
+}
+
+.form-control-lg {
+  min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));
+  padding: 0.5rem 1rem;
+  font-size: 1.25rem;
+  border-radius: var(--bs-border-radius-lg);
+}
+.form-control-lg::-webkit-file-upload-button {
+  padding: 0.5rem 1rem;
+  margin: -0.5rem -1rem;
+  -webkit-margin-end: 1rem;
+  margin-inline-end: 1rem;
+}
+.form-control-lg::file-selector-button {
+  padding: 0.5rem 1rem;
+  margin: -0.5rem -1rem;
+  -webkit-margin-end: 1rem;
+  margin-inline-end: 1rem;
+}
+
+textarea.form-control {
+  min-height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
+}
+textarea.form-control-sm {
+  min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));
+}
+textarea.form-control-lg {
+  min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));
+}
+
+.form-control-color {
+  width: 3rem;
+  height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
+  padding: 0.375rem;
+}
+.form-control-color:not(:disabled):not([readonly]) {
+  cursor: pointer;
+}
+.form-control-color::-moz-color-swatch {
+  border: 0 !important;
+  border-radius: var(--bs-border-radius);
+}
+.form-control-color::-webkit-color-swatch {
+  border: 0 !important;
+  border-radius: var(--bs-border-radius);
+}
+.form-control-color.form-control-sm {
+  height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));
+}
+.form-control-color.form-control-lg {
+  height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));
+}
+
+.form-select {
+  --bs-form-select-bg-img: 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 5 6 6 6-6'/%3e%3c/svg%3e");
+  display: block;
+  width: 100%;
+  padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1.5;
+  color: var(--bs-body-color);
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background-color: var(--bs-body-bg);
+  background-image: var(--bs-form-select-bg-img), var(--bs-form-select-bg-icon, none);
+  background-repeat: no-repeat;
+  background-position: right 0.75rem center;
+  background-size: 16px 12px;
+  border: var(--bs-border-width) solid var(--bs-border-color);
+  border-radius: var(--bs-border-radius);
+  box-shadow: var(--bs-box-shadow-inset);
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .form-select {
+    transition: none;
+  }
+}
+.form-select:focus {
+  border-color: #86b7fe;
+  outline: 0;
+  box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-select[multiple], .form-select[size]:not([size="1"]) {
+  padding-right: 0.75rem;
+  background-image: none;
+}
+.form-select:disabled {
+  background-color: var(--bs-secondary-bg);
+}
+.form-select:-moz-focusring {
+  color: transparent;
+  text-shadow: 0 0 0 var(--bs-body-color);
+}
+
+.form-select-sm {
+  padding-top: 0.25rem;
+  padding-bottom: 0.25rem;
+  padding-left: 0.5rem;
+  font-size: 0.875rem;
+  border-radius: var(--bs-border-radius-sm);
+}
+
+.form-select-lg {
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+  padding-left: 1rem;
+  font-size: 1.25rem;
+  border-radius: var(--bs-border-radius-lg);
+}
+
+[data-bs-theme=dark] .form-select {
+  --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
+}
+
+.form-check {
+  display: block;
+  min-height: 1.5rem;
+  padding-left: 1.5em;
+  margin-bottom: 0.125rem;
+}
+.form-check .form-check-input {
+  float: left;
+  margin-left: -1.5em;
+}
+
+.form-check-reverse {
+  padding-right: 1.5em;
+  padding-left: 0;
+  text-align: right;
+}
+.form-check-reverse .form-check-input {
+  float: right;
+  margin-right: -1.5em;
+  margin-left: 0;
+}
+
+.form-check-input {
+  --bs-form-check-bg: var(--bs-body-bg);
+  flex-shrink: 0;
+  width: 1em;
+  height: 1em;
+  margin-top: 0.25em;
+  vertical-align: top;
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background-color: var(--bs-form-check-bg);
+  background-image: var(--bs-form-check-bg-image);
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: contain;
+  border: var(--bs-border-width) solid var(--bs-border-color);
+  -webkit-print-color-adjust: exact;
+  color-adjust: exact;
+  print-color-adjust: exact;
+}
+.form-check-input[type=checkbox] {
+  border-radius: 0.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 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-check-input:checked {
+  background-color: #01445E;
+  border-color: #01445E;
+}
+.form-check-input:checked[type=checkbox] {
+  --bs-form-check-bg-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 10 3 3 6-6'/%3e%3c/svg%3e");
+}
+.form-check-input:checked[type=radio] {
+  --bs-form-check-bg-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: #01445E;
+  border-color: #01445E;
+  --bs-form-check-bg-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: 0.5;
+}
+.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label {
+  cursor: default;
+  opacity: 0.5;
+}
+
+.form-switch {
+  padding-left: 2.5em;
+}
+.form-switch .form-check-input {
+  --bs-form-switch-bg: 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");
+  width: 2em;
+  margin-left: -2.5em;
+  background-image: var(--bs-form-switch-bg);
+  background-position: left center;
+  border-radius: 2em;
+  transition: background-position 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .form-switch .form-check-input {
+    transition: none;
+  }
+}
+.form-switch .form-check-input:focus {
+  --bs-form-switch-bg: 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;
+  --bs-form-switch-bg: 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-switch.form-check-reverse {
+  padding-right: 2.5em;
+  padding-left: 0;
+}
+.form-switch.form-check-reverse .form-check-input {
+  margin-right: -2.5em;
+  margin-left: 0;
+}
+
+.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: 0.65;
+}
+
+[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus) {
+  --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e");
+}
+
+.form-range {
+  width: 100%;
+  height: 1.5rem;
+  padding: 0;
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background-color: transparent;
+}
+.form-range:focus {
+  outline: 0;
+}
+.form-range:focus::-webkit-slider-thumb {
+  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-range:focus::-moz-range-thumb {
+  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-range::-moz-focus-outer {
+  border: 0;
+}
+.form-range::-webkit-slider-thumb {
+  width: 1rem;
+  height: 1rem;
+  margin-top: -0.25rem;
+  -webkit-appearance: none;
+  appearance: none;
+  background-color: #01445E;
+  border: 0;
+  border-radius: 1rem;
+  box-shadow: 0 0.1rem 0.25rem rgba(0, 0, 0, 0.1);
+  -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@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: 0.5rem;
+  color: transparent;
+  cursor: pointer;
+  background-color: var(--bs-secondary-bg);
+  border-color: transparent;
+  border-radius: 1rem;
+  box-shadow: var(--bs-box-shadow-inset);
+}
+.form-range::-moz-range-thumb {
+  width: 1rem;
+  height: 1rem;
+  -moz-appearance: none;
+  appearance: none;
+  background-color: #01445E;
+  border: 0;
+  border-radius: 1rem;
+  box-shadow: 0 0.1rem 0.25rem rgba(0, 0, 0, 0.1);
+  -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@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: 0.5rem;
+  color: transparent;
+  cursor: pointer;
+  background-color: var(--bs-secondary-bg);
+  border-color: transparent;
+  border-radius: 1rem;
+  box-shadow: var(--bs-box-shadow-inset);
+}
+.form-range:disabled {
+  pointer-events: none;
+}
+.form-range:disabled::-webkit-slider-thumb {
+  background-color: var(--bs-secondary-color);
+}
+.form-range:disabled::-moz-range-thumb {
+  background-color: var(--bs-secondary-color);
+}
+
+.form-floating {
+  position: relative;
+}
+.form-floating > .form-control,
+.form-floating > .form-control-plaintext,
+.form-floating > .form-select {
+  height: calc(3.5rem + calc(var(--bs-border-width) * 2));
+  min-height: calc(3.5rem + calc(var(--bs-border-width) * 2));
+  line-height: 1.25;
+}
+.form-floating > label {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 2;
+  height: 100%;
+  padding: 1rem 0.75rem;
+  overflow: hidden;
+  text-align: start;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  pointer-events: none;
+  border: var(--bs-border-width) solid transparent;
+  transform-origin: 0 0;
+  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .form-floating > label {
+    transition: none;
+  }
+}
+.form-floating > .form-control,
+.form-floating > .form-control-plaintext {
+  padding: 1rem 0.75rem;
+}
+.form-floating > .form-control::-moz-placeholder, .form-floating > .form-control-plaintext::-moz-placeholder {
+  color: transparent;
+}
+.form-floating > .form-control::placeholder,
+.form-floating > .form-control-plaintext::placeholder {
+  color: transparent;
+}
+.form-floating > .form-control:not(:-moz-placeholder-shown), .form-floating > .form-control-plaintext:not(:-moz-placeholder-shown) {
+  padding-top: 1.625rem;
+  padding-bottom: 0.625rem;
+}
+.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown),
+.form-floating > .form-control-plaintext:focus,
+.form-floating > .form-control-plaintext:not(:placeholder-shown) {
+  padding-top: 1.625rem;
+  padding-bottom: 0.625rem;
+}
+.form-floating > .form-control:-webkit-autofill,
+.form-floating > .form-control-plaintext:-webkit-autofill {
+  padding-top: 1.625rem;
+  padding-bottom: 0.625rem;
+}
+.form-floating > .form-select {
+  padding-top: 1.625rem;
+  padding-bottom: 0.625rem;
+}
+.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {
+  color: rgba(var(--bs-body-color-rgb), 0.65);
+  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+.form-floating > .form-control:focus ~ label,
+.form-floating > .form-control:not(:placeholder-shown) ~ label,
+.form-floating > .form-control-plaintext ~ label,
+.form-floating > .form-select ~ label {
+  color: rgba(var(--bs-body-color-rgb), 0.65);
+  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label::after {
+  position: absolute;
+  inset: 1rem 0.375rem;
+  z-index: -1;
+  height: 1.5em;
+  content: "";
+  background-color: var(--bs-body-bg);
+  border-radius: var(--bs-border-radius);
+}
+.form-floating > .form-control:focus ~ label::after,
+.form-floating > .form-control:not(:placeholder-shown) ~ label::after,
+.form-floating > .form-control-plaintext ~ label::after,
+.form-floating > .form-select ~ label::after {
+  position: absolute;
+  inset: 1rem 0.375rem;
+  z-index: -1;
+  height: 1.5em;
+  content: "";
+  background-color: var(--bs-body-bg);
+  border-radius: var(--bs-border-radius);
+}
+.form-floating > .form-control:-webkit-autofill ~ label {
+  color: rgba(var(--bs-body-color-rgb), 0.65);
+  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+.form-floating > .form-control-plaintext ~ label {
+  border-width: var(--bs-border-width) 0;
+}
+.form-floating > :disabled ~ label,
+.form-floating > .form-control:disabled ~ label {
+  color: #6c757d;
+}
+.form-floating > :disabled ~ label::after,
+.form-floating > .form-control:disabled ~ label::after {
+  background-color: var(--bs-secondary-bg);
+}
+
+.input-group {
+  position: relative;
+  display: flex;
+  flex-wrap: wrap;
+  align-items: stretch;
+  width: 100%;
+}
+.input-group > .form-control,
+.input-group > .form-select,
+.input-group > .form-floating {
+  position: relative;
+  flex: 1 1 auto;
+  width: 1%;
+  min-width: 0;
+}
+.input-group > .form-control:focus,
+.input-group > .form-select:focus,
+.input-group > .form-floating:focus-within {
+  z-index: 5;
+}
+.input-group .btn {
+  position: relative;
+  z-index: 2;
+}
+.input-group .btn:focus {
+  z-index: 5;
+}
+
+.input-group-text {
+  display: flex;
+  align-items: center;
+  padding: 0.375rem 0.75rem;
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1.5;
+  color: var(--bs-body-color);
+  text-align: center;
+  white-space: nowrap;
+  background-color: var(--bs-tertiary-bg);
+  border: var(--bs-border-width) solid var(--bs-border-color);
+  border-radius: var(--bs-border-radius);
+}
+
+.input-group-lg > .form-control,
+.input-group-lg > .form-select,
+.input-group-lg > .input-group-text,
+.input-group-lg > .btn {
+  padding: 0.5rem 1rem;
+  font-size: 1.25rem;
+  border-radius: var(--bs-border-radius-lg);
+}
+
+.input-group-sm > .form-control,
+.input-group-sm > .form-select,
+.input-group-sm > .input-group-text,
+.input-group-sm > .btn {
+  padding: 0.25rem 0.5rem;
+  font-size: 0.875rem;
+  border-radius: var(--bs-border-radius-sm);
+}
+
+.input-group-lg > .form-select,
+.input-group-sm > .form-select {
+  padding-right: 3rem;
+}
+
+.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
+.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3),
+.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control,
+.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
+.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4),
+.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control,
+.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select {
+  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: calc(var(--bs-border-width) * -1);
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.input-group > .form-floating:not(:first-child) > .form-control,
+.input-group > .form-floating:not(:first-child) > .form-select {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.valid-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: var(--bs-form-valid-color);
+}
+
+.valid-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #fff;
+  background-color: var(--bs-success);
+  border-radius: var(--bs-border-radius);
+}
+
+.was-validated :valid ~ .valid-feedback,
+.was-validated :valid ~ .valid-tooltip,
+.is-valid ~ .valid-feedback,
+.is-valid ~ .valid-tooltip {
+  display: block;
+}
+
+.was-validated .form-control:valid, .form-control.is-valid {
+  border-color: var(--bs-form-valid-border-color);
+  padding-right: calc(1.5em + 0.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.73.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(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.was-validated .form-control:valid:focus, .form-control.is-valid:focus {
+  border-color: var(--bs-form-valid-border-color);
+  box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);
+}
+
+.was-validated textarea.form-control:valid, textarea.form-control.is-valid {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+
+.was-validated .form-select:valid, .form-select.is-valid {
+  border-color: var(--bs-form-valid-border-color);
+}
+.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] {
+  --bs-form-select-bg-icon: 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.73.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");
+  padding-right: 4.125rem;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.was-validated .form-select:valid:focus, .form-select.is-valid:focus {
+  border-color: var(--bs-form-valid-border-color);
+  box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);
+}
+
+.was-validated .form-control-color:valid, .form-control-color.is-valid {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+
+.was-validated .form-check-input:valid, .form-check-input.is-valid {
+  border-color: var(--bs-form-valid-border-color);
+}
+.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked {
+  background-color: var(--bs-form-valid-color);
+}
+.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus {
+  box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);
+}
+.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {
+  color: var(--bs-form-valid-color);
+}
+
+.form-check-inline .form-check-input ~ .valid-feedback {
+  margin-left: 0.5em;
+}
+
+.was-validated .input-group > .form-control:not(:focus):valid, .input-group > .form-control:not(:focus).is-valid,
+.was-validated .input-group > .form-select:not(:focus):valid,
+.input-group > .form-select:not(:focus).is-valid,
+.was-validated .input-group > .form-floating:not(:focus-within):valid,
+.input-group > .form-floating:not(:focus-within).is-valid {
+  z-index: 3;
+}
+
+.invalid-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: var(--bs-form-invalid-color);
+}
+
+.invalid-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #fff;
+  background-color: var(--bs-danger);
+  border-radius: var(--bs-border-radius);
+}
+
+.was-validated :invalid ~ .invalid-feedback,
+.was-validated :invalid ~ .invalid-tooltip,
+.is-invalid ~ .invalid-feedback,
+.is-invalid ~ .invalid-tooltip {
+  display: block;
+}
+
+.was-validated .form-control:invalid, .form-control.is-invalid {
+  border-color: var(--bs-form-invalid-border-color);
+  padding-right: calc(1.5em + 0.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(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {
+  border-color: var(--bs-form-invalid-border-color);
+  box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25);
+}
+
+.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+
+.was-validated .form-select:invalid, .form-select.is-invalid {
+  border-color: var(--bs-form-invalid-border-color);
+}
+.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] {
+  --bs-form-select-bg-icon: 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");
+  padding-right: 4.125rem;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus {
+  border-color: var(--bs-form-invalid-border-color);
+  box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25);
+}
+
+.was-validated .form-control-color:invalid, .form-control-color.is-invalid {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+
+.was-validated .form-check-input:invalid, .form-check-input.is-invalid {
+  border-color: var(--bs-form-invalid-border-color);
+}
+.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked {
+  background-color: var(--bs-form-invalid-color);
+}
+.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus {
+  box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25);
+}
+.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {
+  color: var(--bs-form-invalid-color);
+}
+
+.form-check-inline .form-check-input ~ .invalid-feedback {
+  margin-left: 0.5em;
+}
+
+.was-validated .input-group > .form-control:not(:focus):invalid, .input-group > .form-control:not(:focus).is-invalid,
+.was-validated .input-group > .form-select:not(:focus):invalid,
+.input-group > .form-select:not(:focus).is-invalid,
+.was-validated .input-group > .form-floating:not(:focus-within):invalid,
+.input-group > .form-floating:not(:focus-within).is-invalid {
+  z-index: 4;
+}
+
+.btn {
+  --bs-btn-padding-x: 0.75rem;
+  --bs-btn-padding-y: 0.375rem;
+  --bs-btn-font-family: ;
+  --bs-btn-font-size: 1rem;
+  --bs-btn-font-weight: 400;
+  --bs-btn-line-height: 1.5;
+  --bs-btn-color: var(--bs-body-color);
+  --bs-btn-bg: transparent;
+  --bs-btn-border-width: var(--bs-border-width);
+  --bs-btn-border-color: transparent;
+  --bs-btn-border-radius: var(--bs-border-radius);
+  --bs-btn-hover-border-color: transparent;
+  --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+  --bs-btn-disabled-opacity: 0.65;
+  --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);
+  display: inline-block;
+  padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);
+  font-family: var(--bs-btn-font-family);
+  font-size: var(--bs-btn-font-size);
+  font-weight: var(--bs-btn-font-weight);
+  line-height: var(--bs-btn-line-height);
+  color: var(--bs-btn-color);
+  text-align: center;
+  text-decoration: none;
+  vertical-align: middle;
+  cursor: pointer;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
+  border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);
+  border-radius: var(--bs-btn-border-radius);
+  background-color: var(--bs-btn-bg);
+  box-shadow: var(--bs-btn-box-shadow);
+  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .btn {
+    transition: none;
+  }
+}
+.btn:hover {
+  color: var(--bs-btn-hover-color);
+  background-color: var(--bs-btn-hover-bg);
+  border-color: var(--bs-btn-hover-border-color);
+}
+.btn-check + .btn:hover {
+  color: var(--bs-btn-color);
+  background-color: var(--bs-btn-bg);
+  border-color: var(--bs-btn-border-color);
+}
+.btn:focus-visible {
+  color: var(--bs-btn-hover-color);
+  background-color: var(--bs-btn-hover-bg);
+  border-color: var(--bs-btn-hover-border-color);
+  outline: 0;
+  box-shadow: var(--bs-btn-box-shadow), var(--bs-btn-focus-box-shadow);
+}
+.btn-check:focus-visible + .btn {
+  border-color: var(--bs-btn-hover-border-color);
+  outline: 0;
+  box-shadow: var(--bs-btn-box-shadow), var(--bs-btn-focus-box-shadow);
+}
+.btn-check:checked + .btn, :not(.btn-check) + .btn:active, .btn:first-child:active, .btn.active, .btn.show {
+  color: var(--bs-btn-active-color);
+  background-color: var(--bs-btn-active-bg);
+  border-color: var(--bs-btn-active-border-color);
+  box-shadow: var(--bs-btn-active-shadow);
+}
+.btn-check:checked + .btn:focus-visible, :not(.btn-check) + .btn:active:focus-visible, .btn:first-child:active:focus-visible, .btn.active:focus-visible, .btn.show:focus-visible {
+  box-shadow: var(--bs-btn-active-shadow), var(--bs-btn-focus-box-shadow);
+}
+.btn-check:checked:focus-visible + .btn {
+  box-shadow: var(--bs-btn-active-shadow), var(--bs-btn-focus-box-shadow);
+}
+.btn:disabled, .btn.disabled, fieldset:disabled .btn {
+  color: var(--bs-btn-disabled-color);
+  pointer-events: none;
+  background-color: var(--bs-btn-disabled-bg);
+  border-color: var(--bs-btn-disabled-border-color);
+  opacity: var(--bs-btn-disabled-opacity);
+  box-shadow: none;
+}
+
+.btn-primary {
+  --bs-btn-color: #fff;
+  --bs-btn-bg: #01445E;
+  --bs-btn-border-color: #01445E;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #0b5ed7;
+  --bs-btn-hover-border-color: #0a58ca;
+  --bs-btn-focus-shadow-rgb: 49, 132, 253;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #0a58ca;
+  --bs-btn-active-border-color: #0a53be;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #fff;
+  --bs-btn-disabled-bg: #01445E;
+  --bs-btn-disabled-border-color: #01445E;
+}
+
+.btn-secondary {
+  --bs-btn-color: #fff;
+  --bs-btn-bg: #6c757d;
+  --bs-btn-border-color: #6c757d;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #5c636a;
+  --bs-btn-hover-border-color: #565e64;
+  --bs-btn-focus-shadow-rgb: 130, 138, 145;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #565e64;
+  --bs-btn-active-border-color: #51585e;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #fff;
+  --bs-btn-disabled-bg: #6c757d;
+  --bs-btn-disabled-border-color: #6c757d;
+}
+
+.btn-success {
+  --bs-btn-color: #fff;
+  --bs-btn-bg: #198754;
+  --bs-btn-border-color: #198754;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #157347;
+  --bs-btn-hover-border-color: #146c43;
+  --bs-btn-focus-shadow-rgb: 60, 153, 110;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #146c43;
+  --bs-btn-active-border-color: #13653f;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #fff;
+  --bs-btn-disabled-bg: #198754;
+  --bs-btn-disabled-border-color: #198754;
+}
+
+.btn-info {
+  --bs-btn-color: #000;
+  --bs-btn-bg: #0dcaf0;
+  --bs-btn-border-color: #0dcaf0;
+  --bs-btn-hover-color: #000;
+  --bs-btn-hover-bg: #31d2f2;
+  --bs-btn-hover-border-color: #25cff2;
+  --bs-btn-focus-shadow-rgb: 11, 172, 204;
+  --bs-btn-active-color: #000;
+  --bs-btn-active-bg: #3dd5f3;
+  --bs-btn-active-border-color: #25cff2;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #000;
+  --bs-btn-disabled-bg: #0dcaf0;
+  --bs-btn-disabled-border-color: #0dcaf0;
+}
+
+.btn-warning {
+  --bs-btn-color: #000;
+  --bs-btn-bg: #ffc107;
+  --bs-btn-border-color: #ffc107;
+  --bs-btn-hover-color: #000;
+  --bs-btn-hover-bg: #ffca2c;
+  --bs-btn-hover-border-color: #ffc720;
+  --bs-btn-focus-shadow-rgb: 217, 164, 6;
+  --bs-btn-active-color: #000;
+  --bs-btn-active-bg: #ffcd39;
+  --bs-btn-active-border-color: #ffc720;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #000;
+  --bs-btn-disabled-bg: #ffc107;
+  --bs-btn-disabled-border-color: #ffc107;
+}
+
+.btn-danger {
+  --bs-btn-color: #fff;
+  --bs-btn-bg: #dc3545;
+  --bs-btn-border-color: #dc3545;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #bb2d3b;
+  --bs-btn-hover-border-color: #b02a37;
+  --bs-btn-focus-shadow-rgb: 225, 83, 97;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #b02a37;
+  --bs-btn-active-border-color: #a52834;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #fff;
+  --bs-btn-disabled-bg: #dc3545;
+  --bs-btn-disabled-border-color: #dc3545;
+}
+
+.btn-light {
+  --bs-btn-color: #000;
+  --bs-btn-bg: #f8f9fa;
+  --bs-btn-border-color: #f8f9fa;
+  --bs-btn-hover-color: #000;
+  --bs-btn-hover-bg: #d3d4d5;
+  --bs-btn-hover-border-color: #c6c7c8;
+  --bs-btn-focus-shadow-rgb: 211, 212, 213;
+  --bs-btn-active-color: #000;
+  --bs-btn-active-bg: #c6c7c8;
+  --bs-btn-active-border-color: #babbbc;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #000;
+  --bs-btn-disabled-bg: #f8f9fa;
+  --bs-btn-disabled-border-color: #f8f9fa;
+}
+
+.btn-dark {
+  --bs-btn-color: #fff;
+  --bs-btn-bg: #212529;
+  --bs-btn-border-color: #212529;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #424649;
+  --bs-btn-hover-border-color: #373b3e;
+  --bs-btn-focus-shadow-rgb: 66, 70, 73;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #4d5154;
+  --bs-btn-active-border-color: #373b3e;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #fff;
+  --bs-btn-disabled-bg: #212529;
+  --bs-btn-disabled-border-color: #212529;
+}
+
+.btn-outline-primary {
+  --bs-btn-color: #01445E;
+  --bs-btn-border-color: #01445E;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #01445E;
+  --bs-btn-hover-border-color: #01445E;
+  --bs-btn-focus-shadow-rgb: 13, 110, 253;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #01445E;
+  --bs-btn-active-border-color: #01445E;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #01445E;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #01445E;
+  --bs-gradient: none;
+}
+
+.btn-outline-secondary {
+  --bs-btn-color: #6c757d;
+  --bs-btn-border-color: #6c757d;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #6c757d;
+  --bs-btn-hover-border-color: #6c757d;
+  --bs-btn-focus-shadow-rgb: 108, 117, 125;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #6c757d;
+  --bs-btn-active-border-color: #6c757d;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #6c757d;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #6c757d;
+  --bs-gradient: none;
+}
+
+.btn-outline-success {
+  --bs-btn-color: #198754;
+  --bs-btn-border-color: #198754;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #198754;
+  --bs-btn-hover-border-color: #198754;
+  --bs-btn-focus-shadow-rgb: 25, 135, 84;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #198754;
+  --bs-btn-active-border-color: #198754;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #198754;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #198754;
+  --bs-gradient: none;
+}
+
+.btn-outline-info {
+  --bs-btn-color: #0dcaf0;
+  --bs-btn-border-color: #0dcaf0;
+  --bs-btn-hover-color: #000;
+  --bs-btn-hover-bg: #0dcaf0;
+  --bs-btn-hover-border-color: #0dcaf0;
+  --bs-btn-focus-shadow-rgb: 13, 202, 240;
+  --bs-btn-active-color: #000;
+  --bs-btn-active-bg: #0dcaf0;
+  --bs-btn-active-border-color: #0dcaf0;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #0dcaf0;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #0dcaf0;
+  --bs-gradient: none;
+}
+
+.btn-outline-warning {
+  --bs-btn-color: #ffc107;
+  --bs-btn-border-color: #ffc107;
+  --bs-btn-hover-color: #000;
+  --bs-btn-hover-bg: #ffc107;
+  --bs-btn-hover-border-color: #ffc107;
+  --bs-btn-focus-shadow-rgb: 255, 193, 7;
+  --bs-btn-active-color: #000;
+  --bs-btn-active-bg: #ffc107;
+  --bs-btn-active-border-color: #ffc107;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #ffc107;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #ffc107;
+  --bs-gradient: none;
+}
+
+.btn-outline-danger {
+  --bs-btn-color: #dc3545;
+  --bs-btn-border-color: #dc3545;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #dc3545;
+  --bs-btn-hover-border-color: #dc3545;
+  --bs-btn-focus-shadow-rgb: 220, 53, 69;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #dc3545;
+  --bs-btn-active-border-color: #dc3545;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #dc3545;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #dc3545;
+  --bs-gradient: none;
+}
+
+.btn-outline-light {
+  --bs-btn-color: #f8f9fa;
+  --bs-btn-border-color: #f8f9fa;
+  --bs-btn-hover-color: #000;
+  --bs-btn-hover-bg: #f8f9fa;
+  --bs-btn-hover-border-color: #f8f9fa;
+  --bs-btn-focus-shadow-rgb: 248, 249, 250;
+  --bs-btn-active-color: #000;
+  --bs-btn-active-bg: #f8f9fa;
+  --bs-btn-active-border-color: #f8f9fa;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #f8f9fa;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #f8f9fa;
+  --bs-gradient: none;
+}
+
+.btn-outline-dark {
+  --bs-btn-color: #212529;
+  --bs-btn-border-color: #212529;
+  --bs-btn-hover-color: #fff;
+  --bs-btn-hover-bg: #212529;
+  --bs-btn-hover-border-color: #212529;
+  --bs-btn-focus-shadow-rgb: 33, 37, 41;
+  --bs-btn-active-color: #fff;
+  --bs-btn-active-bg: #212529;
+  --bs-btn-active-border-color: #212529;
+  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  --bs-btn-disabled-color: #212529;
+  --bs-btn-disabled-bg: transparent;
+  --bs-btn-disabled-border-color: #212529;
+  --bs-gradient: none;
+}
+
+.btn-link {
+  --bs-btn-font-weight: 400;
+  --bs-btn-color: var(--bs-link-color);
+  --bs-btn-bg: transparent;
+  --bs-btn-border-color: transparent;
+  --bs-btn-hover-color: var(--bs-link-hover-color);
+  --bs-btn-hover-border-color: transparent;
+  --bs-btn-active-color: var(--bs-link-hover-color);
+  --bs-btn-active-border-color: transparent;
+  --bs-btn-disabled-color: #6c757d;
+  --bs-btn-disabled-border-color: transparent;
+  --bs-btn-box-shadow: 0 0 0 #000;
+  --bs-btn-focus-shadow-rgb: 49, 132, 253;
+  text-decoration: underline;
+}
+.btn-link:focus-visible {
+  color: var(--bs-btn-color);
+}
+.btn-link:hover {
+  color: var(--bs-btn-hover-color);
+}
+
+.btn-lg, .btn-group-lg > .btn {
+  --bs-btn-padding-y: 0.5rem;
+  --bs-btn-padding-x: 1rem;
+  --bs-btn-font-size: 1.25rem;
+  --bs-btn-border-radius: var(--bs-border-radius-lg);
+}
+
+.btn-sm, .btn-group-sm > .btn {
+  --bs-btn-padding-y: 0.25rem;
+  --bs-btn-padding-x: 0.5rem;
+  --bs-btn-font-size: 0.875rem;
+  --bs-btn-border-radius: var(--bs-border-radius-sm);
+}
+
+.fade {
+  transition: opacity 0.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 0.35s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+  .collapsing {
+    transition: none;
+  }
+}
+.collapsing.collapse-horizontal {
+  width: 0;
+  height: auto;
+  transition: width 0.35s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+  .collapsing.collapse-horizontal {
+    transition: none;
+  }
+}
+
+.dropup,
+.dropend,
+.dropdown,
+.dropstart,
+.dropup-center,
+.dropdown-center {
+  position: relative;
+}
+
+.dropdown-toggle {
+  white-space: nowrap;
+}
+.dropdown-toggle::after {
+  display: inline-block;
+  margin-left: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+  border-top: 0.3em solid;
+  border-right: 0.3em solid transparent;
+  border-bottom: 0;
+  border-left: 0.3em solid transparent;
+}
+.dropdown-toggle:empty::after {
+  margin-left: 0;
+}
+
+.dropdown-menu {
+  --bs-dropdown-zindex: 1000;
+  --bs-dropdown-min-width: 10rem;
+  --bs-dropdown-padding-x: 0;
+  --bs-dropdown-padding-y: 0.5rem;
+  --bs-dropdown-spacer: 0.125rem;
+  --bs-dropdown-font-size: 1rem;
+  --bs-dropdown-color: var(--bs-body-color);
+  --bs-dropdown-bg: var(--bs-body-bg);
+  --bs-dropdown-border-color: var(--bs-border-color-translucent);
+  --bs-dropdown-border-radius: var(--bs-border-radius);
+  --bs-dropdown-border-width: var(--bs-border-width);
+  --bs-dropdown-inner-border-radius: calc(var(--bs-border-radius) - var(--bs-border-width));
+  --bs-dropdown-divider-bg: var(--bs-border-color-translucent);
+  --bs-dropdown-divider-margin-y: 0.5rem;
+  --bs-dropdown-box-shadow: var(--bs-box-shadow);
+  --bs-dropdown-link-color: var(--bs-body-color);
+  --bs-dropdown-link-hover-color: var(--bs-body-color);
+  --bs-dropdown-link-hover-bg: var(--bs-tertiary-bg);
+  --bs-dropdown-link-active-color: #fff;
+  --bs-dropdown-link-active-bg: #01445E;
+  --bs-dropdown-link-disabled-color: var(--bs-tertiary-color);
+  --bs-dropdown-item-padding-x: 1rem;
+  --bs-dropdown-item-padding-y: 0.25rem;
+  --bs-dropdown-header-color: #6c757d;
+  --bs-dropdown-header-padding-x: 1rem;
+  --bs-dropdown-header-padding-y: 0.5rem;
+  position: absolute;
+  z-index: var(--bs-dropdown-zindex);
+  display: none;
+  min-width: var(--bs-dropdown-min-width);
+  padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);
+  margin: 0;
+  font-size: var(--bs-dropdown-font-size);
+  color: var(--bs-dropdown-color);
+  text-align: left;
+  list-style: none;
+  background-color: var(--bs-dropdown-bg);
+  background-clip: padding-box;
+  border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);
+  border-radius: var(--bs-dropdown-border-radius);
+  box-shadow: var(--bs-dropdown-box-shadow);
+}
+.dropdown-menu[data-bs-popper] {
+  top: 100%;
+  left: 0;
+  margin-top: var(--bs-dropdown-spacer);
+}
+
+.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: var(--bs-dropdown-spacer);
+}
+.dropup .dropdown-toggle::after {
+  display: inline-block;
+  margin-left: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+  border-top: 0;
+  border-right: 0.3em solid transparent;
+  border-bottom: 0.3em solid;
+  border-left: 0.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: var(--bs-dropdown-spacer);
+}
+.dropend .dropdown-toggle::after {
+  display: inline-block;
+  margin-left: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+  border-top: 0.3em solid transparent;
+  border-right: 0;
+  border-bottom: 0.3em solid transparent;
+  border-left: 0.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: var(--bs-dropdown-spacer);
+}
+.dropstart .dropdown-toggle::after {
+  display: inline-block;
+  margin-left: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+}
+.dropstart .dropdown-toggle::after {
+  display: none;
+}
+.dropstart .dropdown-toggle::before {
+  display: inline-block;
+  margin-right: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+  border-top: 0.3em solid transparent;
+  border-right: 0.3em solid;
+  border-bottom: 0.3em solid transparent;
+}
+.dropstart .dropdown-toggle:empty::after {
+  margin-left: 0;
+}
+.dropstart .dropdown-toggle::before {
+  vertical-align: 0;
+}
+
+.dropdown-divider {
+  height: 0;
+  margin: var(--bs-dropdown-divider-margin-y) 0;
+  overflow: hidden;
+  border-top: 1px solid var(--bs-dropdown-divider-bg);
+  opacity: 1;
+}
+
+.dropdown-item {
+  display: block;
+  width: 100%;
+  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);
+  clear: both;
+  font-weight: 400;
+  color: var(--bs-dropdown-link-color);
+  text-align: inherit;
+  text-decoration: none;
+  white-space: nowrap;
+  background-color: transparent;
+  border: 0;
+  border-radius: var(--bs-dropdown-item-border-radius, 0);
+}
+.dropdown-item:hover, .dropdown-item:focus {
+  color: var(--bs-dropdown-link-hover-color);
+  background-color: var(--bs-dropdown-link-hover-bg);
+}
+.dropdown-item.active, .dropdown-item:active {
+  color: var(--bs-dropdown-link-active-color);
+  text-decoration: none;
+  background-color: var(--bs-dropdown-link-active-bg);
+}
+.dropdown-item.disabled, .dropdown-item:disabled {
+  color: var(--bs-dropdown-link-disabled-color);
+  pointer-events: none;
+  background-color: transparent;
+}
+
+.dropdown-menu.show {
+  display: block;
+}
+
+.dropdown-header {
+  display: block;
+  padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);
+  margin-bottom: 0;
+  font-size: 0.875rem;
+  color: var(--bs-dropdown-header-color);
+  white-space: nowrap;
+}
+
+.dropdown-item-text {
+  display: block;
+  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);
+  color: var(--bs-dropdown-link-color);
+}
+
+.dropdown-menu-dark {
+  --bs-dropdown-color: #dee2e6;
+  --bs-dropdown-bg: #343a40;
+  --bs-dropdown-border-color: var(--bs-border-color-translucent);
+  --bs-dropdown-box-shadow: ;
+  --bs-dropdown-link-color: #dee2e6;
+  --bs-dropdown-link-hover-color: #fff;
+  --bs-dropdown-divider-bg: var(--bs-border-color-translucent);
+  --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);
+  --bs-dropdown-link-active-color: #fff;
+  --bs-dropdown-link-active-bg: #01445E;
+  --bs-dropdown-link-disabled-color: #adb5bd;
+  --bs-dropdown-header-color: #adb5bd;
+}
+
+.btn-group,
+.btn-group-vertical {
+  position: relative;
+  display: inline-flex;
+  vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+  position: relative;
+  flex: 1 1 auto;
+}
+.btn-group > .btn-check:checked + .btn,
+.btn-group > .btn-check:focus + .btn,
+.btn-group > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn-check:checked + .btn,
+.btn-group-vertical > .btn-check:focus + .btn,
+.btn-group-vertical > .btn:hover,
+.btn-group-vertical > .btn:focus,
+.btn-group-vertical > .btn:active,
+.btn-group-vertical > .btn.active {
+  z-index: 1;
+}
+
+.btn-toolbar {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+}
+.btn-toolbar .input-group {
+  width: auto;
+}
+
+.btn-group {
+  border-radius: var(--bs-border-radius);
+}
+.btn-group > :not(.btn-check:first-child) + .btn,
+.btn-group > .btn-group:not(:first-child) {
+  margin-left: calc(var(--bs-border-width) * -1);
+}
+.btn-group > .btn:not(:last-child):not(.dropdown-toggle),
+.btn-group > .btn.dropdown-toggle-split:first-child,
+.btn-group > .btn-group:not(:last-child) > .btn {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.btn-group > .btn:nth-child(n+3),
+.btn-group > :not(.btn-check) + .btn,
+.btn-group > .btn-group:not(:first-child) > .btn {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.dropdown-toggle-split {
+  padding-right: 0.5625rem;
+  padding-left: 0.5625rem;
+}
+.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after {
+  margin-left: 0;
+}
+.dropstart .dropdown-toggle-split::before {
+  margin-right: 0;
+}
+
+.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {
+  padding-right: 0.375rem;
+  padding-left: 0.375rem;
+}
+
+.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {
+  padding-right: 0.75rem;
+  padding-left: 0.75rem;
+}
+
+.btn-group.show .dropdown-toggle {
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn-group.show .dropdown-toggle.btn-link {
+  box-shadow: none;
+}
+
+.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:not(:first-child),
+.btn-group-vertical > .btn-group:not(:first-child) {
+  margin-top: calc(var(--bs-border-width) * -1);
+}
+.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),
+.btn-group-vertical > .btn-group:not(:last-child) > .btn {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn ~ .btn,
+.btn-group-vertical > .btn-group:not(:first-child) > .btn {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
+.nav {
+  --bs-nav-link-padding-x: 1rem;
+  --bs-nav-link-padding-y: 0.5rem;
+  --bs-nav-link-font-weight: ;
+  --bs-nav-link-color: var(--bs-link-color);
+  --bs-nav-link-hover-color: var(--bs-link-hover-color);
+  --bs-nav-link-disabled-color: var(--bs-secondary-color);
+  display: flex;
+  flex-wrap: wrap;
+  padding-left: 0;
+  margin-bottom: 0;
+  list-style: none;
+}
+
+.nav-link {
+  display: block;
+  padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);
+  font-size: var(--bs-nav-link-font-size);
+  font-weight: var(--bs-nav-link-font-weight);
+  color: var(--bs-nav-link-color);
+  text-decoration: none;
+  background: none;
+  border: 0;
+  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .nav-link {
+    transition: none;
+  }
+}
+.nav-link:hover, .nav-link:focus {
+  color: var(--bs-nav-link-hover-color);
+}
+.nav-link:focus-visible {
+  outline: 0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.nav-link.disabled, .nav-link:disabled {
+  color: var(--bs-nav-link-disabled-color);
+  pointer-events: none;
+  cursor: default;
+}
+
+.nav-tabs {
+  --bs-nav-tabs-border-width: var(--bs-border-width);
+  --bs-nav-tabs-border-color: var(--bs-border-color);
+  --bs-nav-tabs-border-radius: var(--bs-border-radius);
+  --bs-nav-tabs-link-hover-border-color: var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);
+  --bs-nav-tabs-link-active-color: var(--bs-emphasis-color);
+  --bs-nav-tabs-link-active-bg: var(--bs-body-bg);
+  --bs-nav-tabs-link-active-border-color: var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);
+  border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color);
+}
+.nav-tabs .nav-link {
+  margin-bottom: calc(-1 * var(--bs-nav-tabs-border-width));
+  border: var(--bs-nav-tabs-border-width) solid transparent;
+  border-top-left-radius: var(--bs-nav-tabs-border-radius);
+  border-top-right-radius: var(--bs-nav-tabs-border-radius);
+}
+.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {
+  isolation: isolate;
+  border-color: var(--bs-nav-tabs-link-hover-border-color);
+}
+.nav-tabs .nav-link.active,
+.nav-tabs .nav-item.show .nav-link {
+  color: var(--bs-nav-tabs-link-active-color);
+  background-color: var(--bs-nav-tabs-link-active-bg);
+  border-color: var(--bs-nav-tabs-link-active-border-color);
+}
+.nav-tabs .dropdown-menu {
+  margin-top: calc(-1 * var(--bs-nav-tabs-border-width));
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
+.nav-pills {
+  --bs-nav-pills-border-radius: var(--bs-border-radius);
+  --bs-nav-pills-link-active-color: #fff;
+  --bs-nav-pills-link-active-bg: #01445E;
+}
+.nav-pills .nav-link {
+  border-radius: var(--bs-nav-pills-border-radius);
+}
+.nav-pills .nav-link.active,
+.nav-pills .show > .nav-link {
+  color: var(--bs-nav-pills-link-active-color);
+  background-color: var(--bs-nav-pills-link-active-bg);
+}
+
+.nav-underline {
+  --bs-nav-underline-gap: 1rem;
+  --bs-nav-underline-border-width: 0.125rem;
+  --bs-nav-underline-link-active-color: var(--bs-emphasis-color);
+  gap: var(--bs-nav-underline-gap);
+}
+.nav-underline .nav-link {
+  padding-right: 0;
+  padding-left: 0;
+  border-bottom: var(--bs-nav-underline-border-width) solid transparent;
+}
+.nav-underline .nav-link:hover, .nav-underline .nav-link:focus {
+  border-bottom-color: currentcolor;
+}
+.nav-underline .nav-link.active,
+.nav-underline .show > .nav-link {
+  font-weight: 700;
+  color: var(--bs-nav-underline-link-active-color);
+  border-bottom-color: currentcolor;
+}
+
+.nav-fill > .nav-link,
+.nav-fill .nav-item {
+  flex: 1 1 auto;
+  text-align: center;
+}
+
+.nav-justified > .nav-link,
+.nav-justified .nav-item {
+  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 {
+  --bs-navbar-padding-x: 0;
+  --bs-navbar-padding-y: 0.5rem;
+  --bs-navbar-color: rgba(var(--bs-emphasis-color-rgb), 0.65);
+  --bs-navbar-hover-color: rgba(var(--bs-emphasis-color-rgb), 0.8);
+  --bs-navbar-disabled-color: rgba(var(--bs-emphasis-color-rgb), 0.3);
+  --bs-navbar-active-color: rgba(var(--bs-emphasis-color-rgb), 1);
+  --bs-navbar-brand-padding-y: 0.3125rem;
+  --bs-navbar-brand-margin-end: 1rem;
+  --bs-navbar-brand-font-size: 1.25rem;
+  --bs-navbar-brand-color: rgba(var(--bs-emphasis-color-rgb), 1);
+  --bs-navbar-brand-hover-color: rgba(var(--bs-emphasis-color-rgb), 1);
+  --bs-navbar-nav-link-padding-x: 1rem;
+  --bs-navbar-toggler-padding-y: 0.25rem;
+  --bs-navbar-toggler-padding-x: 0.75rem;
+  --bs-navbar-toggler-font-size: 1.25rem;
+  --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
+  --bs-navbar-toggler-border-color: rgba(var(--bs-emphasis-color-rgb), 0.15);
+  --bs-navbar-toggler-border-radius: var(--bs-border-radius);
+  --bs-navbar-toggler-focus-width: 0.25rem;
+  --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+  position: relative;
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  justify-content: space-between;
+  padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);
+}
+.navbar > .container,
+.navbar > .container-fluid,
+.navbar > .container-sm,
+.navbar > .container-md,
+.navbar > .container-lg,
+.navbar > .container-xl,
+.navbar > .container-xxl {
+  display: flex;
+  flex-wrap: inherit;
+  align-items: center;
+  justify-content: space-between;
+}
+.navbar-brand {
+  padding-top: var(--bs-navbar-brand-padding-y);
+  padding-bottom: var(--bs-navbar-brand-padding-y);
+  margin-right: var(--bs-navbar-brand-margin-end);
+  font-size: var(--bs-navbar-brand-font-size);
+  color: var(--bs-navbar-brand-color);
+  text-decoration: none;
+  white-space: nowrap;
+}
+.navbar-brand:hover, .navbar-brand:focus {
+  color: var(--bs-navbar-brand-hover-color);
+}
+
+.navbar-nav {
+  --bs-nav-link-padding-x: 0;
+  --bs-nav-link-padding-y: 0.5rem;
+  --bs-nav-link-font-weight: ;
+  --bs-nav-link-color: var(--bs-navbar-color);
+  --bs-nav-link-hover-color: var(--bs-navbar-hover-color);
+  --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);
+  display: flex;
+  flex-direction: column;
+  padding-left: 0;
+  margin-bottom: 0;
+  list-style: none;
+}
+.navbar-nav .nav-link.active, .navbar-nav .nav-link.show {
+  color: var(--bs-navbar-active-color);
+}
+.navbar-nav .dropdown-menu {
+  position: static;
+}
+
+.navbar-text {
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+  color: var(--bs-navbar-color);
+}
+.navbar-text a,
+.navbar-text a:hover,
+.navbar-text a:focus {
+  color: var(--bs-navbar-active-color);
+}
+
+.navbar-collapse {
+  flex-basis: 100%;
+  flex-grow: 1;
+  align-items: center;
+}
+
+.navbar-toggler {
+  padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);
+  font-size: var(--bs-navbar-toggler-font-size);
+  line-height: 1;
+  color: var(--bs-navbar-color);
+  background-color: transparent;
+  border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);
+  border-radius: var(--bs-navbar-toggler-border-radius);
+  transition: var(--bs-navbar-toggler-transition);
+}
+@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 var(--bs-navbar-toggler-focus-width);
+}
+
+.navbar-toggler-icon {
+  display: inline-block;
+  width: 1.5em;
+  height: 1.5em;
+  vertical-align: middle;
+  background-image: var(--bs-navbar-toggler-icon-bg);
+  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: var(--bs-navbar-nav-link-padding-x);
+    padding-left: var(--bs-navbar-nav-link-padding-x);
+  }
+  .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 {
+    position: static;
+    z-index: auto;
+    flex-grow: 1;
+    width: auto !important;
+    height: auto !important;
+    visibility: visible !important;
+    background-color: transparent !important;
+    border: 0 !important;
+    transform: none !important;
+    box-shadow: none;
+    transition: none;
+  }
+  .navbar-expand-sm .offcanvas .offcanvas-header {
+    display: none;
+  }
+  .navbar-expand-sm .offcanvas .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: var(--bs-navbar-nav-link-padding-x);
+    padding-left: var(--bs-navbar-nav-link-padding-x);
+  }
+  .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 {
+    position: static;
+    z-index: auto;
+    flex-grow: 1;
+    width: auto !important;
+    height: auto !important;
+    visibility: visible !important;
+    background-color: transparent !important;
+    border: 0 !important;
+    transform: none !important;
+    box-shadow: none;
+    transition: none;
+  }
+  .navbar-expand-md .offcanvas .offcanvas-header {
+    display: none;
+  }
+  .navbar-expand-md .offcanvas .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: var(--bs-navbar-nav-link-padding-x);
+    padding-left: var(--bs-navbar-nav-link-padding-x);
+  }
+  .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 {
+    position: static;
+    z-index: auto;
+    flex-grow: 1;
+    width: auto !important;
+    height: auto !important;
+    visibility: visible !important;
+    background-color: transparent !important;
+    border: 0 !important;
+    transform: none !important;
+    box-shadow: none;
+    transition: none;
+  }
+  .navbar-expand-lg .offcanvas .offcanvas-header {
+    display: none;
+  }
+  .navbar-expand-lg .offcanvas .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: var(--bs-navbar-nav-link-padding-x);
+    padding-left: var(--bs-navbar-nav-link-padding-x);
+  }
+  .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 {
+    position: static;
+    z-index: auto;
+    flex-grow: 1;
+    width: auto !important;
+    height: auto !important;
+    visibility: visible !important;
+    background-color: transparent !important;
+    border: 0 !important;
+    transform: none !important;
+    box-shadow: none;
+    transition: none;
+  }
+  .navbar-expand-xl .offcanvas .offcanvas-header {
+    display: none;
+  }
+  .navbar-expand-xl .offcanvas .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: var(--bs-navbar-nav-link-padding-x);
+    padding-left: var(--bs-navbar-nav-link-padding-x);
+  }
+  .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 {
+    position: static;
+    z-index: auto;
+    flex-grow: 1;
+    width: auto !important;
+    height: auto !important;
+    visibility: visible !important;
+    background-color: transparent !important;
+    border: 0 !important;
+    transform: none !important;
+    box-shadow: none;
+    transition: none;
+  }
+  .navbar-expand-xxl .offcanvas .offcanvas-header {
+    display: none;
+  }
+  .navbar-expand-xxl .offcanvas .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: var(--bs-navbar-nav-link-padding-x);
+  padding-left: var(--bs-navbar-nav-link-padding-x);
+}
+.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 {
+  position: static;
+  z-index: auto;
+  flex-grow: 1;
+  width: auto !important;
+  height: auto !important;
+  visibility: visible !important;
+  background-color: transparent !important;
+  border: 0 !important;
+  transform: none !important;
+  box-shadow: none;
+  transition: none;
+}
+.navbar-expand .offcanvas .offcanvas-header {
+  display: none;
+}
+.navbar-expand .offcanvas .offcanvas-body {
+  display: flex;
+  flex-grow: 0;
+  padding: 0;
+  overflow-y: visible;
+}
+
+.navbar-dark,
+.navbar[data-bs-theme=dark] {
+  --bs-navbar-color: rgba(255, 255, 255, 0.55);
+  --bs-navbar-hover-color: rgba(255, 255, 255, 0.75);
+  --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25);
+  --bs-navbar-active-color: #fff;
+  --bs-navbar-brand-color: #fff;
+  --bs-navbar-brand-hover-color: #fff;
+  --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1);
+  --bs-navbar-toggler-icon-bg: 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");
+}
+
+[data-bs-theme=dark] .navbar-toggler-icon {
+  --bs-navbar-toggler-icon-bg: 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");
+}
+
+.card {
+  --bs-card-spacer-y: 1rem;
+  --bs-card-spacer-x: 1rem;
+  --bs-card-title-spacer-y: 0.5rem;
+  --bs-card-title-color: ;
+  --bs-card-subtitle-color: ;
+  --bs-card-border-width: var(--bs-border-width);
+  --bs-card-border-color: var(--bs-border-color-translucent);
+  --bs-card-border-radius: var(--bs-border-radius);
+  --bs-card-box-shadow: ;
+  --bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));
+  --bs-card-cap-padding-y: 0.5rem;
+  --bs-card-cap-padding-x: 1rem;
+  --bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03);
+  --bs-card-cap-color: ;
+  --bs-card-height: ;
+  --bs-card-color: ;
+  --bs-card-bg: var(--bs-body-bg);
+  --bs-card-img-overlay-padding: 1rem;
+  --bs-card-group-margin: 0.75rem;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  min-width: 0;
+  height: var(--bs-card-height);
+  color: var(--bs-body-color);
+  word-wrap: break-word;
+  background-color: var(--bs-card-bg);
+  background-clip: border-box;
+  border: var(--bs-card-border-width) solid var(--bs-card-border-color);
+  border-radius: var(--bs-card-border-radius);
+  box-shadow: var(--bs-card-box-shadow);
+}
+.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: var(--bs-card-inner-border-radius);
+  border-top-right-radius: var(--bs-card-inner-border-radius);
+}
+.card > .list-group:last-child {
+  border-bottom-width: 0;
+  border-bottom-right-radius: var(--bs-card-inner-border-radius);
+  border-bottom-left-radius: var(--bs-card-inner-border-radius);
+}
+.card > .card-header + .list-group,
+.card > .list-group + .card-footer {
+  border-top: 0;
+}
+
+.card-body {
+  flex: 1 1 auto;
+  padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x);
+  color: var(--bs-card-color);
+}
+
+.card-title {
+  margin-bottom: var(--bs-card-title-spacer-y);
+  color: var(--bs-card-title-color);
+}
+
+.card-subtitle {
+  margin-top: calc(-0.5 * var(--bs-card-title-spacer-y));
+  margin-bottom: 0;
+  color: var(--bs-card-subtitle-color);
+}
+
+.card-text:last-child {
+  margin-bottom: 0;
+}
+
+.card-link + .card-link {
+  margin-left: var(--bs-card-spacer-x);
+}
+
+.card-header {
+  padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x) !important;
+  margin-bottom: 0;
+  color: var(--bs-card-cap-color);
+  background-color: var(--bs-card-cap-bg);
+  border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color);
+}
+.card-header:first-child {
+  border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0;
+}
+
+.card-footer {
+  padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);
+  color: var(--bs-card-cap-color);
+  background-color: var(--bs-card-cap-bg);
+  border-top: var(--bs-card-border-width) solid var(--bs-card-border-color);
+}
+.card-footer:last-child {
+  border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius);
+}
+
+.card-header-tabs {
+  margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));
+  margin-bottom: calc(-1 * var(--bs-card-cap-padding-y));
+  margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));
+  border-bottom: 0;
+}
+.card-header-tabs .nav-link.active {
+  background-color: var(--bs-card-bg);
+  border-bottom-color: var(--bs-card-bg);
+}
+
+.card-header-pills {
+  margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));
+  margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));
+}
+
+.card-img-overlay {
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  padding: var(--bs-card-img-overlay-padding);
+  border-radius: var(--bs-card-inner-border-radius);
+}
+
+.card-img,
+.card-img-top,
+.card-img-bottom {
+  width: 100%;
+}
+
+.card-img,
+.card-img-top {
+  border-top-left-radius: var(--bs-card-inner-border-radius);
+  border-top-right-radius: var(--bs-card-inner-border-radius);
+}
+
+.card-img,
+.card-img-bottom {
+  border-bottom-right-radius: var(--bs-card-inner-border-radius);
+  border-bottom-left-radius: var(--bs-card-inner-border-radius);
+}
+
+.card-group > .card {
+  margin-bottom: var(--bs-card-group-margin);
+}
+@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-img-top,
+  .card-group > .card:not(:last-child) .card-header {
+    border-top-right-radius: 0;
+  }
+  .card-group > .card:not(:last-child) .card-img-bottom,
+  .card-group > .card:not(:last-child) .card-footer {
+    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-img-top,
+  .card-group > .card:not(:first-child) .card-header {
+    border-top-left-radius: 0;
+  }
+  .card-group > .card:not(:first-child) .card-img-bottom,
+  .card-group > .card:not(:first-child) .card-footer {
+    border-bottom-left-radius: 0;
+  }
+}
+
+.accordion {
+  --bs-accordion-color: var(--bs-body-color);
+  --bs-accordion-bg: var(--bs-body-bg);
+  --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+  --bs-accordion-border-color: var(--bs-border-color);
+  --bs-accordion-border-width: var(--bs-border-width);
+  --bs-accordion-border-radius: var(--bs-border-radius);
+  --bs-accordion-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));
+  --bs-accordion-btn-padding-x: 1.25rem;
+  --bs-accordion-btn-padding-y: 1rem;
+  --bs-accordion-btn-color: var(--bs-body-color);
+  --bs-accordion-btn-bg: var(--bs-accordion-bg);
+  --bs-accordion-btn-icon: 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");
+  --bs-accordion-btn-icon-width: 1.25rem;
+  --bs-accordion-btn-icon-transform: rotate(-180deg);
+  --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;
+  --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23052c65'%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");
+  --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+  --bs-accordion-body-padding-x: 1.25rem;
+  --bs-accordion-body-padding-y: 1rem;
+  --bs-accordion-active-color: var(--bs-primary-text-emphasis);
+  --bs-accordion-active-bg: var(--bs-primary-bg-subtle);
+}
+
+.accordion-button {
+  position: relative;
+  display: flex;
+  align-items: center;
+  width: 100%;
+  padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);
+  font-size: 1rem;
+  color: var(--bs-accordion-btn-color);
+  text-align: left;
+  background-color: var(--bs-accordion-btn-bg);
+  border: 0;
+  border-radius: 0;
+  overflow-anchor: none;
+  transition: var(--bs-accordion-transition);
+}
+@media (prefers-reduced-motion: reduce) {
+  .accordion-button {
+    transition: none;
+  }
+}
+.accordion-button:not(.collapsed) {
+  color: var(--bs-accordion-active-color);
+  background-color: var(--bs-accordion-active-bg);
+  box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color);
+}
+.accordion-button:not(.collapsed)::after {
+  background-image: var(--bs-accordion-btn-active-icon);
+  transform: var(--bs-accordion-btn-icon-transform);
+}
+.accordion-button::after {
+  flex-shrink: 0;
+  width: var(--bs-accordion-btn-icon-width);
+  height: var(--bs-accordion-btn-icon-width);
+  margin-left: auto;
+  content: "";
+  background-image: var(--bs-accordion-btn-icon);
+  background-repeat: no-repeat;
+  background-size: var(--bs-accordion-btn-icon-width);
+  transition: var(--bs-accordion-btn-icon-transition);
+}
+@media (prefers-reduced-motion: reduce) {
+  .accordion-button::after {
+    transition: none;
+  }
+}
+.accordion-button:hover {
+  z-index: 2;
+}
+.accordion-button:focus {
+  z-index: 3;
+  outline: 0;
+  box-shadow: var(--bs-accordion-btn-focus-box-shadow);
+}
+
+.accordion-header {
+  margin-bottom: 0;
+}
+
+.accordion-item {
+  color: var(--bs-accordion-color);
+  background-color: var(--bs-accordion-bg);
+  border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);
+}
+.accordion-item:first-of-type {
+  border-top-left-radius: var(--bs-accordion-border-radius);
+  border-top-right-radius: var(--bs-accordion-border-radius);
+}
+.accordion-item:first-of-type > .accordion-header .accordion-button {
+  border-top-left-radius: var(--bs-accordion-inner-border-radius);
+  border-top-right-radius: var(--bs-accordion-inner-border-radius);
+}
+.accordion-item:not(:first-of-type) {
+  border-top: 0;
+}
+.accordion-item:last-of-type {
+  border-bottom-right-radius: var(--bs-accordion-border-radius);
+  border-bottom-left-radius: var(--bs-accordion-border-radius);
+}
+.accordion-item:last-of-type > .accordion-header .accordion-button.collapsed {
+  border-bottom-right-radius: var(--bs-accordion-inner-border-radius);
+  border-bottom-left-radius: var(--bs-accordion-inner-border-radius);
+}
+.accordion-item:last-of-type > .accordion-collapse {
+  border-bottom-right-radius: var(--bs-accordion-border-radius);
+  border-bottom-left-radius: var(--bs-accordion-border-radius);
+}
+
+.accordion-body {
+  padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x);
+}
+
+.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-header .accordion-button, .accordion-flush > .accordion-item > .accordion-header .accordion-button.collapsed {
+  border-radius: 0;
+}
+.accordion-flush > .accordion-item > .accordion-collapse {
+  border-radius: 0;
+}
+
+[data-bs-theme=dark] .accordion-button::after {
+  --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%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");
+  --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%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");
+}
+
+.breadcrumb {
+  --bs-breadcrumb-padding-x: 0;
+  --bs-breadcrumb-padding-y: 0;
+  --bs-breadcrumb-margin-bottom: 1rem;
+  --bs-breadcrumb-bg: ;
+  --bs-breadcrumb-border-radius: ;
+  --bs-breadcrumb-divider-color: var(--bs-secondary-color);
+  --bs-breadcrumb-item-padding-x: 0.5rem;
+  --bs-breadcrumb-item-active-color: var(--bs-secondary-color);
+  display: flex;
+  flex-wrap: wrap;
+  padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);
+  margin-bottom: var(--bs-breadcrumb-margin-bottom);
+  font-size: var(--bs-breadcrumb-font-size);
+  list-style: none;
+  background-color: var(--bs-breadcrumb-bg);
+  border-radius: var(--bs-breadcrumb-border-radius);
+}
+
+.breadcrumb-item + .breadcrumb-item {
+  padding-left: var(--bs-breadcrumb-item-padding-x);
+}
+.breadcrumb-item + .breadcrumb-item::before {
+  float: left;
+  padding-right: var(--bs-breadcrumb-item-padding-x);
+  color: var(--bs-breadcrumb-divider-color);
+  content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */;
+}
+.breadcrumb-item.active {
+  color: var(--bs-breadcrumb-item-active-color);
+}
+
+.pagination {
+  --bs-pagination-padding-x: 0.75rem;
+  --bs-pagination-padding-y: 0.375rem;
+  --bs-pagination-font-size: 1rem;
+  --bs-pagination-color: var(--bs-link-color);
+  --bs-pagination-bg: var(--bs-body-bg);
+  --bs-pagination-border-width: var(--bs-border-width);
+  --bs-pagination-border-color: var(--bs-border-color);
+  --bs-pagination-border-radius: var(--bs-border-radius);
+  --bs-pagination-hover-color: var(--bs-link-hover-color);
+  --bs-pagination-hover-bg: var(--bs-tertiary-bg);
+  --bs-pagination-hover-border-color: var(--bs-border-color);
+  --bs-pagination-focus-color: var(--bs-link-hover-color);
+  --bs-pagination-focus-bg: var(--bs-secondary-bg);
+  --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+  --bs-pagination-active-color: #fff;
+  --bs-pagination-active-bg: #01445E;
+  --bs-pagination-active-border-color: #01445E;
+  --bs-pagination-disabled-color: var(--bs-secondary-color);
+  --bs-pagination-disabled-bg: var(--bs-secondary-bg);
+  --bs-pagination-disabled-border-color: var(--bs-border-color);
+  display: flex;
+  padding-left: 0;
+  list-style: none;
+}
+
+.page-link {
+  position: relative;
+  display: block;
+  padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);
+  font-size: var(--bs-pagination-font-size);
+  color: var(--bs-pagination-color);
+  text-decoration: none;
+  background-color: var(--bs-pagination-bg);
+  border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);
+  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .page-link {
+    transition: none;
+  }
+}
+.page-link:hover {
+  z-index: 2;
+  color: var(--bs-pagination-hover-color);
+  background-color: var(--bs-pagination-hover-bg);
+  border-color: var(--bs-pagination-hover-border-color);
+}
+.page-link:focus {
+  z-index: 3;
+  color: var(--bs-pagination-focus-color);
+  background-color: var(--bs-pagination-focus-bg);
+  outline: 0;
+  box-shadow: var(--bs-pagination-focus-box-shadow);
+}
+.page-link.active, .active > .page-link {
+  z-index: 3;
+  color: var(--bs-pagination-active-color);
+  background-color: var(--bs-pagination-active-bg);
+  border-color: var(--bs-pagination-active-border-color);
+}
+.page-link.disabled, .disabled > .page-link {
+  color: var(--bs-pagination-disabled-color);
+  pointer-events: none;
+  background-color: var(--bs-pagination-disabled-bg);
+  border-color: var(--bs-pagination-disabled-border-color);
+}
+
+.page-item:not(:first-child) .page-link {
+  margin-left: calc(var(--bs-border-width) * -1);
+}
+.page-item:first-child .page-link {
+  border-top-left-radius: var(--bs-pagination-border-radius);
+  border-bottom-left-radius: var(--bs-pagination-border-radius);
+}
+.page-item:last-child .page-link {
+  border-top-right-radius: var(--bs-pagination-border-radius);
+  border-bottom-right-radius: var(--bs-pagination-border-radius);
+}
+
+.pagination-lg {
+  --bs-pagination-padding-x: 1.5rem;
+  --bs-pagination-padding-y: 0.75rem;
+  --bs-pagination-font-size: 1.25rem;
+  --bs-pagination-border-radius: var(--bs-border-radius-lg);
+}
+
+.pagination-sm {
+  --bs-pagination-padding-x: 0.5rem;
+  --bs-pagination-padding-y: 0.25rem;
+  --bs-pagination-font-size: 0.875rem;
+  --bs-pagination-border-radius: var(--bs-border-radius-sm);
+}
+
+.badge {
+  --bs-badge-padding-x: 0.65em;
+  --bs-badge-padding-y: 0.35em;
+  --bs-badge-font-size: 0.75em;
+  --bs-badge-font-weight: 700;
+  --bs-badge-color: #fff;
+  --bs-badge-border-radius: var(--bs-border-radius);
+  display: inline-block;
+  padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x);
+  font-size: var(--bs-badge-font-size);
+  font-weight: var(--bs-badge-font-weight);
+  line-height: 1;
+  color: var(--bs-badge-color);
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  border-radius: var(--bs-badge-border-radius);
+}
+.badge:empty {
+  display: none;
+}
+
+.btn .badge {
+  position: relative;
+  top: -1px;
+}
+
+.alert {
+  --bs-alert-bg: transparent;
+  --bs-alert-padding-x: 1rem;
+  --bs-alert-padding-y: 1rem;
+  --bs-alert-margin-bottom: 1rem;
+  --bs-alert-color: inherit;
+  --bs-alert-border-color: transparent;
+  --bs-alert-border: var(--bs-border-width) solid var(--bs-alert-border-color);
+  --bs-alert-border-radius: var(--bs-border-radius);
+  --bs-alert-link-color: inherit;
+  position: relative;
+  padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);
+  margin-bottom: var(--bs-alert-margin-bottom);
+  color: var(--bs-alert-color);
+  background-color: var(--bs-alert-bg);
+  border: var(--bs-alert-border);
+  border-radius: var(--bs-alert-border-radius);
+}
+
+.alert-heading {
+  color: inherit;
+}
+
+.alert-link {
+  font-weight: 700;
+  color: var(--bs-alert-link-color);
+}
+
+.alert-dismissible {
+  padding-right: 3rem;
+}
+.alert-dismissible .btn-close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 2;
+  padding: 1.25rem 1rem;
+}
+
+.alert-primary {
+  --bs-alert-color: var(--bs-primary-text-emphasis);
+  --bs-alert-bg: var(--bs-primary-bg-subtle);
+  --bs-alert-border-color: var(--bs-primary-border-subtle);
+  --bs-alert-link-color: var(--bs-primary-text-emphasis);
+}
+
+.alert-secondary {
+  --bs-alert-color: var(--bs-secondary-text-emphasis);
+  --bs-alert-bg: var(--bs-secondary-bg-subtle);
+  --bs-alert-border-color: var(--bs-secondary-border-subtle);
+  --bs-alert-link-color: var(--bs-secondary-text-emphasis);
+}
+
+.alert-success {
+  --bs-alert-color: var(--bs-success-text-emphasis);
+  --bs-alert-bg: var(--bs-success-bg-subtle);
+  --bs-alert-border-color: var(--bs-success-border-subtle);
+  --bs-alert-link-color: var(--bs-success-text-emphasis);
+}
+
+.alert-info {
+  --bs-alert-color: var(--bs-info-text-emphasis);
+  --bs-alert-bg: var(--bs-info-bg-subtle);
+  --bs-alert-border-color: var(--bs-info-border-subtle);
+  --bs-alert-link-color: var(--bs-info-text-emphasis);
+}
+
+.alert-warning {
+  --bs-alert-color: var(--bs-warning-text-emphasis);
+  --bs-alert-bg: var(--bs-warning-bg-subtle);
+  --bs-alert-border-color: var(--bs-warning-border-subtle);
+  --bs-alert-link-color: var(--bs-warning-text-emphasis);
+}
+
+.alert-danger {
+  --bs-alert-color: var(--bs-danger-text-emphasis);
+  --bs-alert-bg: var(--bs-danger-bg-subtle);
+  --bs-alert-border-color: var(--bs-danger-border-subtle);
+  --bs-alert-link-color: var(--bs-danger-text-emphasis);
+}
+
+.alert-light {
+  --bs-alert-color: var(--bs-light-text-emphasis);
+  --bs-alert-bg: var(--bs-light-bg-subtle);
+  --bs-alert-border-color: var(--bs-light-border-subtle);
+  --bs-alert-link-color: var(--bs-light-text-emphasis);
+}
+
+.alert-dark {
+  --bs-alert-color: var(--bs-dark-text-emphasis);
+  --bs-alert-bg: var(--bs-dark-bg-subtle);
+  --bs-alert-border-color: var(--bs-dark-border-subtle);
+  --bs-alert-link-color: var(--bs-dark-text-emphasis);
+}
+
+@keyframes progress-bar-stripes {
+  0% {
+    background-position-x: 1rem;
+  }
+}
+.progress,
+.progress-stacked {
+  --bs-progress-height: 1rem;
+  --bs-progress-font-size: 0.75rem;
+  --bs-progress-bg: var(--bs-secondary-bg);
+  --bs-progress-border-radius: var(--bs-border-radius);
+  --bs-progress-box-shadow: var(--bs-box-shadow-inset);
+  --bs-progress-bar-color: #fff;
+  --bs-progress-bar-bg: #01445E;
+  --bs-progress-bar-transition: width 0.6s ease;
+  display: flex;
+  height: var(--bs-progress-height);
+  overflow: hidden;
+  font-size: var(--bs-progress-font-size);
+  background-color: var(--bs-progress-bg);
+  border-radius: var(--bs-progress-border-radius);
+  box-shadow: var(--bs-progress-box-shadow);
+}
+
+.progress-bar {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  overflow: hidden;
+  color: var(--bs-progress-bar-color);
+  text-align: center;
+  white-space: nowrap;
+  background-color: var(--bs-progress-bar-bg);
+  transition: var(--bs-progress-bar-transition);
+}
+@media (prefers-reduced-motion: reduce) {
+  .progress-bar {
+    transition: none;
+  }
+}
+
+.progress-bar-striped {
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-size: var(--bs-progress-height) var(--bs-progress-height);
+}
+
+.progress-stacked > .progress {
+  overflow: visible;
+}
+
+.progress-stacked > .progress > .progress-bar {
+  width: 100%;
+}
+
+.progress-bar-animated {
+  animation: 1s linear infinite progress-bar-stripes;
+}
+@media (prefers-reduced-motion: reduce) {
+  .progress-bar-animated {
+    animation: none;
+  }
+}
+
+.list-group {
+  --bs-list-group-color: var(--bs-body-color);
+  --bs-list-group-bg: var(--bs-body-bg);
+  --bs-list-group-border-color: var(--bs-border-color);
+  --bs-list-group-border-width: var(--bs-border-width);
+  --bs-list-group-border-radius: var(--bs-border-radius);
+  --bs-list-group-item-padding-x: 1rem;
+  --bs-list-group-item-padding-y: 0.5rem;
+  --bs-list-group-action-color: var(--bs-secondary-color);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-tertiary-bg);
+  --bs-list-group-action-active-color: var(--bs-body-color);
+  --bs-list-group-action-active-bg: var(--bs-secondary-bg);
+  --bs-list-group-disabled-color: var(--bs-secondary-color);
+  --bs-list-group-disabled-bg: var(--bs-body-bg);
+  --bs-list-group-active-color: #fff;
+  --bs-list-group-active-bg: #01445E;
+  --bs-list-group-active-border-color: #01445E;
+  display: flex;
+  flex-direction: column;
+  padding-left: 0;
+  margin-bottom: 0;
+  border-radius: var(--bs-list-group-border-radius);
+}
+
+.list-group-numbered {
+  list-style-type: none;
+  counter-reset: section;
+}
+.list-group-numbered > .list-group-item::before {
+  content: counters(section, ".") ". ";
+  counter-increment: section;
+}
+
+.list-group-item-action {
+  width: 100%;
+  color: var(--bs-list-group-action-color);
+  text-align: inherit;
+}
+.list-group-item-action:hover, .list-group-item-action:focus {
+  z-index: 1;
+  color: var(--bs-list-group-action-hover-color);
+  text-decoration: none;
+  background-color: var(--bs-list-group-action-hover-bg);
+}
+.list-group-item-action:active {
+  color: var(--bs-list-group-action-active-color);
+  background-color: var(--bs-list-group-action-active-bg);
+}
+
+.list-group-item {
+  position: relative;
+  display: block;
+  padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);
+  color: var(--bs-list-group-color);
+  text-decoration: none;
+  background-color: var(--bs-list-group-bg);
+  border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);
+}
+.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: var(--bs-list-group-disabled-color);
+  pointer-events: none;
+  background-color: var(--bs-list-group-disabled-bg);
+}
+.list-group-item.active {
+  z-index: 2;
+  color: var(--bs-list-group-active-color);
+  background-color: var(--bs-list-group-active-bg);
+  border-color: var(--bs-list-group-active-border-color);
+}
+.list-group-item + .list-group-item {
+  border-top-width: 0;
+}
+.list-group-item + .list-group-item.active {
+  margin-top: calc(-1 * var(--bs-list-group-border-width));
+  border-top-width: var(--bs-list-group-border-width);
+}
+
+.list-group-horizontal {
+  flex-direction: row;
+}
+.list-group-horizontal > .list-group-item:first-child:not(:last-child) {
+  border-bottom-left-radius: var(--bs-list-group-border-radius);
+  border-top-right-radius: 0;
+}
+.list-group-horizontal > .list-group-item:last-child:not(:first-child) {
+  border-top-right-radius: var(--bs-list-group-border-radius);
+  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: var(--bs-list-group-border-width);
+  border-left-width: 0;
+}
+.list-group-horizontal > .list-group-item + .list-group-item.active {
+  margin-left: calc(-1 * var(--bs-list-group-border-width));
+  border-left-width: var(--bs-list-group-border-width);
+}
+
+@media (min-width: 576px) {
+  .list-group-horizontal-sm {
+    flex-direction: row;
+  }
+  .list-group-horizontal-sm > .list-group-item:first-child:not(:last-child) {
+    border-bottom-left-radius: var(--bs-list-group-border-radius);
+    border-top-right-radius: 0;
+  }
+  .list-group-horizontal-sm > .list-group-item:last-child:not(:first-child) {
+    border-top-right-radius: var(--bs-list-group-border-radius);
+    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: var(--bs-list-group-border-width);
+    border-left-width: 0;
+  }
+  .list-group-horizontal-sm > .list-group-item + .list-group-item.active {
+    margin-left: calc(-1 * var(--bs-list-group-border-width));
+    border-left-width: var(--bs-list-group-border-width);
+  }
+}
+@media (min-width: 768px) {
+  .list-group-horizontal-md {
+    flex-direction: row;
+  }
+  .list-group-horizontal-md > .list-group-item:first-child:not(:last-child) {
+    border-bottom-left-radius: var(--bs-list-group-border-radius);
+    border-top-right-radius: 0;
+  }
+  .list-group-horizontal-md > .list-group-item:last-child:not(:first-child) {
+    border-top-right-radius: var(--bs-list-group-border-radius);
+    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: var(--bs-list-group-border-width);
+    border-left-width: 0;
+  }
+  .list-group-horizontal-md > .list-group-item + .list-group-item.active {
+    margin-left: calc(-1 * var(--bs-list-group-border-width));
+    border-left-width: var(--bs-list-group-border-width);
+  }
+}
+@media (min-width: 992px) {
+  .list-group-horizontal-lg {
+    flex-direction: row;
+  }
+  .list-group-horizontal-lg > .list-group-item:first-child:not(:last-child) {
+    border-bottom-left-radius: var(--bs-list-group-border-radius);
+    border-top-right-radius: 0;
+  }
+  .list-group-horizontal-lg > .list-group-item:last-child:not(:first-child) {
+    border-top-right-radius: var(--bs-list-group-border-radius);
+    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: var(--bs-list-group-border-width);
+    border-left-width: 0;
+  }
+  .list-group-horizontal-lg > .list-group-item + .list-group-item.active {
+    margin-left: calc(-1 * var(--bs-list-group-border-width));
+    border-left-width: var(--bs-list-group-border-width);
+  }
+}
+@media (min-width: 1200px) {
+  .list-group-horizontal-xl {
+    flex-direction: row;
+  }
+  .list-group-horizontal-xl > .list-group-item:first-child:not(:last-child) {
+    border-bottom-left-radius: var(--bs-list-group-border-radius);
+    border-top-right-radius: 0;
+  }
+  .list-group-horizontal-xl > .list-group-item:last-child:not(:first-child) {
+    border-top-right-radius: var(--bs-list-group-border-radius);
+    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: var(--bs-list-group-border-width);
+    border-left-width: 0;
+  }
+  .list-group-horizontal-xl > .list-group-item + .list-group-item.active {
+    margin-left: calc(-1 * var(--bs-list-group-border-width));
+    border-left-width: var(--bs-list-group-border-width);
+  }
+}
+@media (min-width: 1400px) {
+  .list-group-horizontal-xxl {
+    flex-direction: row;
+  }
+  .list-group-horizontal-xxl > .list-group-item:first-child:not(:last-child) {
+    border-bottom-left-radius: var(--bs-list-group-border-radius);
+    border-top-right-radius: 0;
+  }
+  .list-group-horizontal-xxl > .list-group-item:last-child:not(:first-child) {
+    border-top-right-radius: var(--bs-list-group-border-radius);
+    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: var(--bs-list-group-border-width);
+    border-left-width: 0;
+  }
+  .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {
+    margin-left: calc(-1 * var(--bs-list-group-border-width));
+    border-left-width: var(--bs-list-group-border-width);
+  }
+}
+.list-group-flush {
+  border-radius: 0;
+}
+.list-group-flush > .list-group-item {
+  border-width: 0 0 var(--bs-list-group-border-width);
+}
+.list-group-flush > .list-group-item:last-child {
+  border-bottom-width: 0;
+}
+
+.list-group-item-primary {
+  --bs-list-group-color: var(--bs-primary-text-emphasis);
+  --bs-list-group-bg: var(--bs-primary-bg-subtle);
+  --bs-list-group-border-color: var(--bs-primary-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-primary-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-primary-border-subtle);
+  --bs-list-group-active-color: var(--bs-primary-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-primary-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-primary-text-emphasis);
+}
+
+.list-group-item-secondary {
+  --bs-list-group-color: var(--bs-secondary-text-emphasis);
+  --bs-list-group-bg: var(--bs-secondary-bg-subtle);
+  --bs-list-group-border-color: var(--bs-secondary-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-secondary-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-secondary-border-subtle);
+  --bs-list-group-active-color: var(--bs-secondary-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-secondary-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-secondary-text-emphasis);
+}
+
+.list-group-item-success {
+  --bs-list-group-color: var(--bs-success-text-emphasis);
+  --bs-list-group-bg: var(--bs-success-bg-subtle);
+  --bs-list-group-border-color: var(--bs-success-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-success-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-success-border-subtle);
+  --bs-list-group-active-color: var(--bs-success-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-success-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-success-text-emphasis);
+}
+
+.list-group-item-info {
+  --bs-list-group-color: var(--bs-info-text-emphasis);
+  --bs-list-group-bg: var(--bs-info-bg-subtle);
+  --bs-list-group-border-color: var(--bs-info-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-info-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-info-border-subtle);
+  --bs-list-group-active-color: var(--bs-info-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-info-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-info-text-emphasis);
+}
+
+.list-group-item-warning {
+  --bs-list-group-color: var(--bs-warning-text-emphasis);
+  --bs-list-group-bg: var(--bs-warning-bg-subtle);
+  --bs-list-group-border-color: var(--bs-warning-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-warning-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-warning-border-subtle);
+  --bs-list-group-active-color: var(--bs-warning-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-warning-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-warning-text-emphasis);
+}
+
+.list-group-item-danger {
+  --bs-list-group-color: var(--bs-danger-text-emphasis);
+  --bs-list-group-bg: var(--bs-danger-bg-subtle);
+  --bs-list-group-border-color: var(--bs-danger-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-danger-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-danger-border-subtle);
+  --bs-list-group-active-color: var(--bs-danger-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-danger-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-danger-text-emphasis);
+}
+
+.list-group-item-light {
+  --bs-list-group-color: var(--bs-light-text-emphasis);
+  --bs-list-group-bg: var(--bs-light-bg-subtle);
+  --bs-list-group-border-color: var(--bs-light-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-light-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-light-border-subtle);
+  --bs-list-group-active-color: var(--bs-light-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-light-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-light-text-emphasis);
+}
+
+.list-group-item-dark {
+  --bs-list-group-color: var(--bs-dark-text-emphasis);
+  --bs-list-group-bg: var(--bs-dark-bg-subtle);
+  --bs-list-group-border-color: var(--bs-dark-border-subtle);
+  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
+  --bs-list-group-action-hover-bg: var(--bs-dark-border-subtle);
+  --bs-list-group-action-active-color: var(--bs-emphasis-color);
+  --bs-list-group-action-active-bg: var(--bs-dark-border-subtle);
+  --bs-list-group-active-color: var(--bs-dark-bg-subtle);
+  --bs-list-group-active-bg: var(--bs-dark-text-emphasis);
+  --bs-list-group-active-border-color: var(--bs-dark-text-emphasis);
+}
+
+.btn-close {
+  --bs-btn-close-color: #000;
+  --bs-btn-close-bg: 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 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");
+  --bs-btn-close-opacity: 0.5;
+  --bs-btn-close-hover-opacity: 0.75;
+  --bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+  --bs-btn-close-focus-opacity: 1;
+  --bs-btn-close-disabled-opacity: 0.25;
+  --bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%);
+  box-sizing: content-box;
+  width: 1em;
+  height: 1em;
+  padding: 0.25em 0.25em;
+  color: var(--bs-btn-close-color);
+  background: transparent var(--bs-btn-close-bg) center/1em auto no-repeat;
+  border: 0;
+  border-radius: 0.375rem;
+  opacity: var(--bs-btn-close-opacity);
+}
+.btn-close:hover {
+  color: var(--bs-btn-close-color);
+  text-decoration: none;
+  opacity: var(--bs-btn-close-hover-opacity);
+}
+.btn-close:focus {
+  outline: 0;
+  box-shadow: var(--bs-btn-close-focus-shadow);
+  opacity: var(--bs-btn-close-focus-opacity);
+}
+.btn-close:disabled, .btn-close.disabled {
+  pointer-events: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
+  opacity: var(--bs-btn-close-disabled-opacity);
+}
+
+.btn-close-white {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+[data-bs-theme=dark] .btn-close {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+.toast {
+  --bs-toast-zindex: 1090;
+  --bs-toast-padding-x: 0.75rem;
+  --bs-toast-padding-y: 0.5rem;
+  --bs-toast-spacing: 1.5rem;
+  --bs-toast-max-width: 350px;
+  --bs-toast-font-size: 0.875rem;
+  --bs-toast-color: ;
+  --bs-toast-bg: rgba(var(--bs-body-bg-rgb), 0.85);
+  --bs-toast-border-width: var(--bs-border-width);
+  --bs-toast-border-color: var(--bs-border-color-translucent);
+  --bs-toast-border-radius: var(--bs-border-radius);
+  --bs-toast-box-shadow: var(--bs-box-shadow);
+  --bs-toast-header-color: var(--bs-secondary-color);
+  --bs-toast-header-bg: rgba(var(--bs-body-bg-rgb), 0.85);
+  --bs-toast-header-border-color: var(--bs-border-color-translucent);
+  width: var(--bs-toast-max-width);
+  max-width: 100%;
+  font-size: var(--bs-toast-font-size);
+  color: var(--bs-toast-color);
+  pointer-events: auto;
+  background-color: var(--bs-toast-bg);
+  background-clip: padding-box;
+  border: var(--bs-toast-border-width) solid var(--bs-toast-border-color);
+  box-shadow: var(--bs-toast-box-shadow);
+  border-radius: var(--bs-toast-border-radius);
+}
+.toast.showing {
+  opacity: 0;
+}
+.toast:not(.show) {
+  display: none;
+}
+
+.toast-container {
+  --bs-toast-zindex: 1090;
+  position: absolute;
+  z-index: var(--bs-toast-zindex);
+  width: -webkit-max-content;
+  width: -moz-max-content;
+  width: max-content;
+  max-width: 100%;
+  pointer-events: none;
+}
+.toast-container > :not(:last-child) {
+  margin-bottom: var(--bs-toast-spacing);
+}
+
+.toast-header {
+  display: flex;
+  align-items: center;
+  padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x);
+  color: var(--bs-toast-header-color);
+  background-color: var(--bs-toast-header-bg);
+  background-clip: padding-box;
+  border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);
+  border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));
+  border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));
+}
+.toast-header .btn-close {
+  margin-right: calc(-0.5 * var(--bs-toast-padding-x));
+  margin-left: var(--bs-toast-padding-x);
+}
+
+.toast-body {
+  padding: var(--bs-toast-padding-x);
+  word-wrap: break-word;
+}
+
+.modal {
+  --bs-modal-zindex: 1055;
+  --bs-modal-width: 500px;
+  --bs-modal-padding: 1rem;
+  --bs-modal-margin: 0.5rem;
+  --bs-modal-color: ;
+  --bs-modal-bg: var(--bs-body-bg);
+  --bs-modal-border-color: var(--bs-border-color-translucent);
+  --bs-modal-border-width: var(--bs-border-width);
+  --bs-modal-border-radius: var(--bs-border-radius-lg);
+  --bs-modal-box-shadow: var(--bs-box-shadow-sm);
+  --bs-modal-inner-border-radius: calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));
+  --bs-modal-header-padding-x: 1rem;
+  --bs-modal-header-padding-y: 1rem;
+  --bs-modal-header-padding: 1rem 1rem;
+  --bs-modal-header-border-color: var(--bs-border-color);
+  --bs-modal-header-border-width: var(--bs-border-width);
+  --bs-modal-title-line-height: 1.5;
+  --bs-modal-footer-gap: 0.5rem;
+  --bs-modal-footer-bg: ;
+  --bs-modal-footer-border-color: var(--bs-border-color);
+  --bs-modal-footer-border-width: var(--bs-border-width);
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: var(--bs-modal-zindex);
+  display: none;
+  width: 100%;
+  height: 100%;
+  overflow-x: hidden;
+  overflow-y: auto;
+  outline: 0;
+}
+
+.modal-dialog {
+  position: relative;
+  width: auto;
+  margin: var(--bs-modal-margin);
+  pointer-events: none;
+}
+.modal.fade .modal-dialog {
+  transition: transform 0.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% - var(--bs-modal-margin) * 2);
+}
+.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% - var(--bs-modal-margin) * 2);
+}
+
+.modal-content {
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  color: var(--bs-modal-color);
+  pointer-events: auto;
+  background-color: var(--bs-modal-bg);
+  background-clip: padding-box;
+  border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);
+  border-radius: var(--bs-modal-border-radius);
+  box-shadow: var(--bs-modal-box-shadow);
+  outline: 0;
+}
+
+.modal-backdrop {
+  --bs-backdrop-zindex: 1050;
+  --bs-backdrop-bg: #000;
+  --bs-backdrop-opacity: 0.5;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: var(--bs-backdrop-zindex);
+  width: 100vw;
+  height: 100vh;
+  background-color: var(--bs-backdrop-bg);
+}
+.modal-backdrop.fade {
+  opacity: 0;
+}
+.modal-backdrop.show {
+  opacity: var(--bs-backdrop-opacity);
+}
+
+.modal-header {
+  display: flex;
+  flex-shrink: 0;
+  align-items: center;
+  padding: var(--bs-modal-header-padding);
+  border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);
+  border-top-left-radius: var(--bs-modal-inner-border-radius);
+  border-top-right-radius: var(--bs-modal-inner-border-radius);
+}
+.modal-header .btn-close {
+  padding: calc(var(--bs-modal-header-padding-y) * 0.5) calc(var(--bs-modal-header-padding-x) * 0.5);
+  margin: calc(-0.5 * var(--bs-modal-header-padding-y)) calc(-0.5 * var(--bs-modal-header-padding-x)) calc(-0.5 * var(--bs-modal-header-padding-y)) auto;
+}
+
+.modal-title {
+  margin-bottom: 0;
+  line-height: var(--bs-modal-title-line-height);
+}
+
+.modal-body {
+  position: relative;
+  flex: 1 1 auto;
+  padding: var(--bs-modal-padding);
+}
+
+.modal-footer {
+  display: flex;
+  flex-shrink: 0;
+  flex-wrap: wrap;
+  align-items: center;
+  justify-content: flex-end;
+  padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * 0.5);
+  background-color: var(--bs-modal-footer-bg);
+  border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);
+  border-bottom-right-radius: var(--bs-modal-inner-border-radius);
+  border-bottom-left-radius: var(--bs-modal-inner-border-radius);
+}
+.modal-footer > * {
+  margin: calc(var(--bs-modal-footer-gap) * 0.5);
+}
+
+@media (min-width: 576px) {
+  .modal {
+    --bs-modal-margin: 1.75rem;
+    --bs-modal-box-shadow: var(--bs-box-shadow);
+  }
+  .modal-dialog {
+    max-width: var(--bs-modal-width);
+    margin-right: auto;
+    margin-left: auto;
+  }
+  .modal-sm {
+    --bs-modal-width: 300px;
+  }
+}
+@media (min-width: 992px) {
+  .modal-lg,
+  .modal-xl {
+    --bs-modal-width: 800px;
+  }
+}
+@media (min-width: 1200px) {
+  .modal-xl {
+    --bs-modal-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,
+.modal-fullscreen .modal-footer {
+  border-radius: 0;
+}
+.modal-fullscreen .modal-body {
+  overflow-y: auto;
+}
+
+@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,
+  .modal-fullscreen-sm-down .modal-footer {
+    border-radius: 0;
+  }
+  .modal-fullscreen-sm-down .modal-body {
+    overflow-y: auto;
+  }
+}
+@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,
+  .modal-fullscreen-md-down .modal-footer {
+    border-radius: 0;
+  }
+  .modal-fullscreen-md-down .modal-body {
+    overflow-y: auto;
+  }
+}
+@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,
+  .modal-fullscreen-lg-down .modal-footer {
+    border-radius: 0;
+  }
+  .modal-fullscreen-lg-down .modal-body {
+    overflow-y: auto;
+  }
+}
+@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,
+  .modal-fullscreen-xl-down .modal-footer {
+    border-radius: 0;
+  }
+  .modal-fullscreen-xl-down .modal-body {
+    overflow-y: auto;
+  }
+}
+@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,
+  .modal-fullscreen-xxl-down .modal-footer {
+    border-radius: 0;
+  }
+  .modal-fullscreen-xxl-down .modal-body {
+    overflow-y: auto;
+  }
+}
+.tooltip {
+  --bs-tooltip-zindex: 1080;
+  --bs-tooltip-max-width: 200px;
+  --bs-tooltip-padding-x: 0.5rem;
+  --bs-tooltip-padding-y: 0.25rem;
+  --bs-tooltip-margin: ;
+  --bs-tooltip-font-size: 0.875rem;
+  --bs-tooltip-color: var(--bs-body-bg);
+  --bs-tooltip-bg: var(--bs-emphasis-color);
+  --bs-tooltip-border-radius: var(--bs-border-radius);
+  --bs-tooltip-opacity: 0.9;
+  --bs-tooltip-arrow-width: 0.8rem;
+  --bs-tooltip-arrow-height: 0.4rem;
+  z-index: var(--bs-tooltip-zindex);
+  display: block;
+  margin: var(--bs-tooltip-margin);
+  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;
+  white-space: normal;
+  word-spacing: normal;
+  line-break: auto;
+  font-size: var(--bs-tooltip-font-size);
+  word-wrap: break-word;
+  opacity: 0;
+}
+.tooltip.show {
+  opacity: var(--bs-tooltip-opacity);
+}
+.tooltip .tooltip-arrow {
+  display: block;
+  width: var(--bs-tooltip-arrow-width);
+  height: var(--bs-tooltip-arrow-height);
+}
+.tooltip .tooltip-arrow::before {
+  position: absolute;
+  content: "";
+  border-color: transparent;
+  border-style: solid;
+}
+
+.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {
+  bottom: calc(-1 * var(--bs-tooltip-arrow-height));
+}
+.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {
+  top: -1px;
+  border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;
+  border-top-color: var(--bs-tooltip-bg);
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {
+  left: calc(-1 * var(--bs-tooltip-arrow-height));
+  width: var(--bs-tooltip-arrow-height);
+  height: var(--bs-tooltip-arrow-width);
+}
+.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {
+  right: -1px;
+  border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;
+  border-right-color: var(--bs-tooltip-bg);
+}
+
+/* rtl:end:ignore */
+.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {
+  top: calc(-1 * var(--bs-tooltip-arrow-height));
+}
+.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {
+  bottom: -1px;
+  border-width: 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);
+  border-bottom-color: var(--bs-tooltip-bg);
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {
+  right: calc(-1 * var(--bs-tooltip-arrow-height));
+  width: var(--bs-tooltip-arrow-height);
+  height: var(--bs-tooltip-arrow-width);
+}
+.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {
+  left: -1px;
+  border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);
+  border-left-color: var(--bs-tooltip-bg);
+}
+
+/* rtl:end:ignore */
+.tooltip-inner {
+  max-width: var(--bs-tooltip-max-width);
+  padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);
+  color: var(--bs-tooltip-color);
+  text-align: center;
+  background-color: var(--bs-tooltip-bg);
+  border-radius: var(--bs-tooltip-border-radius);
+}
+
+.popover {
+  --bs-popover-zindex: 1070;
+  --bs-popover-max-width: 276px;
+  --bs-popover-font-size: 0.875rem;
+  --bs-popover-bg: var(--bs-body-bg);
+  --bs-popover-border-width: var(--bs-border-width);
+  --bs-popover-border-color: var(--bs-border-color-translucent);
+  --bs-popover-border-radius: var(--bs-border-radius-lg);
+  --bs-popover-inner-border-radius: calc(var(--bs-border-radius-lg) - var(--bs-border-width));
+  --bs-popover-box-shadow: var(--bs-box-shadow);
+  --bs-popover-header-padding-x: 1rem;
+  --bs-popover-header-padding-y: 0.5rem;
+  --bs-popover-header-font-size: 1rem;
+  --bs-popover-header-color: inherit;
+  --bs-popover-header-bg: var(--bs-secondary-bg);
+  --bs-popover-body-padding-x: 1rem;
+  --bs-popover-body-padding-y: 1rem;
+  --bs-popover-body-color: var(--bs-body-color);
+  --bs-popover-arrow-width: 1rem;
+  --bs-popover-arrow-height: 0.5rem;
+  --bs-popover-arrow-border: var(--bs-popover-border-color);
+  z-index: var(--bs-popover-zindex);
+  display: block;
+  max-width: var(--bs-popover-max-width);
+  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;
+  white-space: normal;
+  word-spacing: normal;
+  line-break: auto;
+  font-size: var(--bs-popover-font-size);
+  word-wrap: break-word;
+  background-color: var(--bs-popover-bg);
+  background-clip: padding-box;
+  border: var(--bs-popover-border-width) solid var(--bs-popover-border-color);
+  border-radius: var(--bs-popover-border-radius);
+  box-shadow: var(--bs-popover-box-shadow);
+}
+.popover .popover-arrow {
+  display: block;
+  width: var(--bs-popover-arrow-width);
+  height: var(--bs-popover-arrow-height);
+}
+.popover .popover-arrow::before, .popover .popover-arrow::after {
+  position: absolute;
+  display: block;
+  content: "";
+  border-color: transparent;
+  border-style: solid;
+  border-width: 0;
+}
+
+.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {
+  bottom: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));
+}
+.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {
+  border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;
+}
+.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {
+  bottom: 0;
+  border-top-color: var(--bs-popover-arrow-border);
+}
+.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {
+  bottom: var(--bs-popover-border-width);
+  border-top-color: var(--bs-popover-bg);
+}
+
+/* rtl:begin:ignore */
+.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {
+  left: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));
+  width: var(--bs-popover-arrow-height);
+  height: var(--bs-popover-arrow-width);
+}
+.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {
+  border-width: calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;
+}
+.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {
+  left: 0;
+  border-right-color: var(--bs-popover-arrow-border);
+}
+.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {
+  left: var(--bs-popover-border-width);
+  border-right-color: var(--bs-popover-bg);
+}
+
+/* rtl:end:ignore */
+.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {
+  top: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));
+}
+.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {
+  border-width: 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);
+}
+.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {
+  top: 0;
+  border-bottom-color: var(--bs-popover-arrow-border);
+}
+.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {
+  top: var(--bs-popover-border-width);
+  border-bottom-color: var(--bs-popover-bg);
+}
+.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  display: block;
+  width: var(--bs-popover-arrow-width);
+  margin-left: calc(-0.5 * var(--bs-popover-arrow-width));
+  content: "";
+  border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg);
+}
+
+/* rtl:begin:ignore */
+.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {
+  right: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));
+  width: var(--bs-popover-arrow-height);
+  height: var(--bs-popover-arrow-width);
+}
+.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {
+  border-width: calc(var(--bs-popover-arrow-width) * 0.5) 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);
+}
+.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {
+  right: 0;
+  border-left-color: var(--bs-popover-arrow-border);
+}
+.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {
+  right: var(--bs-popover-border-width);
+  border-left-color: var(--bs-popover-bg);
+}
+
+/* rtl:end:ignore */
+.popover-header {
+  padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);
+  margin-bottom: 0;
+  font-size: var(--bs-popover-header-font-size);
+  color: var(--bs-popover-header-color);
+  background-color: var(--bs-popover-header-bg);
+  border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color);
+  border-top-left-radius: var(--bs-popover-inner-border-radius);
+  border-top-right-radius: var(--bs-popover-inner-border-radius);
+}
+.popover-header:empty {
+  display: none;
+}
+
+.popover-body {
+  padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);
+  color: var(--bs-popover-body-color);
+}
+
+.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 0.6s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .carousel-item {
+    transition: none;
+  }
+}
+
+.carousel-item.active,
+.carousel-item-next,
+.carousel-item-prev {
+  display: block;
+}
+
+.carousel-item-next:not(.carousel-item-start),
+.active.carousel-item-end {
+  transform: translateX(100%);
+}
+
+.carousel-item-prev:not(.carousel-item-end),
+.active.carousel-item-start {
+  transform: translateX(-100%);
+}
+
+.carousel-fade .carousel-item {
+  opacity: 0;
+  transition-property: opacity;
+  transform: none;
+}
+.carousel-fade .carousel-item.active,
+.carousel-fade .carousel-item-next.carousel-item-start,
+.carousel-fade .carousel-item-prev.carousel-item-end {
+  z-index: 1;
+  opacity: 1;
+}
+.carousel-fade .active.carousel-item-start,
+.carousel-fade .active.carousel-item-end {
+  z-index: 0;
+  opacity: 0;
+  transition: opacity 0s 0.6s;
+}
+@media (prefers-reduced-motion: reduce) {
+  .carousel-fade .active.carousel-item-start,
+  .carousel-fade .active.carousel-item-end {
+    transition: none;
+  }
+}
+
+.carousel-control-prev,
+.carousel-control-next {
+  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: none;
+  border: 0;
+  opacity: 0.5;
+  transition: opacity 0.15s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+  .carousel-control-prev,
+  .carousel-control-next {
+    transition: none;
+  }
+}
+.carousel-control-prev:hover, .carousel-control-prev:focus,
+.carousel-control-next:hover,
+.carousel-control-next:focus {
+  color: #fff;
+  text-decoration: none;
+  outline: 0;
+  opacity: 0.9;
+}
+
+.carousel-control-prev {
+  left: 0;
+}
+
+.carousel-control-next {
+  right: 0;
+}
+
+.carousel-control-prev-icon,
+.carousel-control-next-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") /*rtl: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-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") /*rtl: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-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%;
+}
+.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: 0.5;
+  transition: opacity 0.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-prev-icon,
+.carousel-dark .carousel-control-next-icon {
+  filter: invert(1) grayscale(100);
+}
+.carousel-dark .carousel-indicators [data-bs-target] {
+  background-color: #000;
+}
+.carousel-dark .carousel-caption {
+  color: #000;
+}
+
+[data-bs-theme=dark] .carousel .carousel-control-prev-icon,
+[data-bs-theme=dark] .carousel .carousel-control-next-icon, [data-bs-theme=dark].carousel .carousel-control-prev-icon,
+[data-bs-theme=dark].carousel .carousel-control-next-icon {
+  filter: invert(1) grayscale(100);
+}
+[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target], [data-bs-theme=dark].carousel .carousel-indicators [data-bs-target] {
+  background-color: #000;
+}
+[data-bs-theme=dark] .carousel .carousel-caption, [data-bs-theme=dark].carousel .carousel-caption {
+  color: #000;
+}
+
+.spinner-grow,
+.spinner-border {
+  display: inline-block;
+  width: var(--bs-spinner-width);
+  height: var(--bs-spinner-height);
+  vertical-align: var(--bs-spinner-vertical-align);
+  border-radius: 50%;
+  animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);
+}
+
+@keyframes spinner-border {
+  to {
+    transform: rotate(360deg) /* rtl:ignore */;
+  }
+}
+.spinner-border {
+  --bs-spinner-width: 2rem;
+  --bs-spinner-height: 2rem;
+  --bs-spinner-vertical-align: -0.125em;
+  --bs-spinner-border-width: 0.25em;
+  --bs-spinner-animation-speed: 0.75s;
+  --bs-spinner-animation-name: spinner-border;
+  border: var(--bs-spinner-border-width) solid currentcolor;
+  border-right-color: transparent;
+}
+
+.spinner-border-sm {
+  --bs-spinner-width: 1rem;
+  --bs-spinner-height: 1rem;
+  --bs-spinner-border-width: 0.2em;
+}
+
+@keyframes spinner-grow {
+  0% {
+    transform: scale(0);
+  }
+  50% {
+    opacity: 1;
+    transform: none;
+  }
+}
+.spinner-grow {
+  --bs-spinner-width: 2rem;
+  --bs-spinner-height: 2rem;
+  --bs-spinner-vertical-align: -0.125em;
+  --bs-spinner-animation-speed: 0.75s;
+  --bs-spinner-animation-name: spinner-grow;
+  background-color: currentcolor;
+  opacity: 0;
+}
+
+.spinner-grow-sm {
+  --bs-spinner-width: 1rem;
+  --bs-spinner-height: 1rem;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  .spinner-border,
+  .spinner-grow {
+    --bs-spinner-animation-speed: 1.5s;
+  }
+}
+.offcanvas, .offcanvas-xxl, .offcanvas-xl, .offcanvas-lg, .offcanvas-md, .offcanvas-sm {
+  --bs-offcanvas-zindex: 1045;
+  --bs-offcanvas-width: 400px;
+  --bs-offcanvas-height: 30vh;
+  --bs-offcanvas-padding-x: 1rem;
+  --bs-offcanvas-padding-y: 1rem;
+  --bs-offcanvas-color: var(--bs-body-color);
+  --bs-offcanvas-bg: var(--bs-body-bg);
+  --bs-offcanvas-border-width: var(--bs-border-width);
+  --bs-offcanvas-border-color: var(--bs-border-color-translucent);
+  --bs-offcanvas-box-shadow: var(--bs-box-shadow-sm);
+  --bs-offcanvas-transition: transform 0.3s ease-in-out;
+  --bs-offcanvas-title-line-height: 1.5;
+}
+
+@media (max-width: 575.98px) {
+  .offcanvas-sm {
+    position: fixed;
+    bottom: 0;
+    z-index: var(--bs-offcanvas-zindex);
+    display: flex;
+    flex-direction: column;
+    max-width: 100%;
+    color: var(--bs-offcanvas-color);
+    visibility: hidden;
+    background-color: var(--bs-offcanvas-bg);
+    background-clip: padding-box;
+    outline: 0;
+    box-shadow: var(--bs-offcanvas-box-shadow);
+    transition: var(--bs-offcanvas-transition);
+  }
+}
+@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) {
+  .offcanvas-sm {
+    transition: none;
+  }
+}
+@media (max-width: 575.98px) {
+  .offcanvas-sm.offcanvas-start {
+    top: 0;
+    left: 0;
+    width: var(--bs-offcanvas-width);
+    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(-100%);
+  }
+  .offcanvas-sm.offcanvas-end {
+    top: 0;
+    right: 0;
+    width: var(--bs-offcanvas-width);
+    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(100%);
+  }
+  .offcanvas-sm.offcanvas-top {
+    top: 0;
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(-100%);
+  }
+  .offcanvas-sm.offcanvas-bottom {
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(100%);
+  }
+  .offcanvas-sm.showing, .offcanvas-sm.show:not(.hiding) {
+    transform: none;
+  }
+  .offcanvas-sm.showing, .offcanvas-sm.hiding, .offcanvas-sm.show {
+    visibility: visible;
+  }
+}
+@media (min-width: 576px) {
+  .offcanvas-sm {
+    --bs-offcanvas-height: auto;
+    --bs-offcanvas-border-width: 0;
+    background-color: transparent !important;
+  }
+  .offcanvas-sm .offcanvas-header {
+    display: none;
+  }
+  .offcanvas-sm .offcanvas-body {
+    display: flex;
+    flex-grow: 0;
+    padding: 0;
+    overflow-y: visible;
+    background-color: transparent !important;
+  }
+}
+
+@media (max-width: 767.98px) {
+  .offcanvas-md {
+    position: fixed;
+    bottom: 0;
+    z-index: var(--bs-offcanvas-zindex);
+    display: flex;
+    flex-direction: column;
+    max-width: 100%;
+    color: var(--bs-offcanvas-color);
+    visibility: hidden;
+    background-color: var(--bs-offcanvas-bg);
+    background-clip: padding-box;
+    outline: 0;
+    box-shadow: var(--bs-offcanvas-box-shadow);
+    transition: var(--bs-offcanvas-transition);
+  }
+}
+@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
+  .offcanvas-md {
+    transition: none;
+  }
+}
+@media (max-width: 767.98px) {
+  .offcanvas-md.offcanvas-start {
+    top: 0;
+    left: 0;
+    width: var(--bs-offcanvas-width);
+    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(-100%);
+  }
+  .offcanvas-md.offcanvas-end {
+    top: 0;
+    right: 0;
+    width: var(--bs-offcanvas-width);
+    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(100%);
+  }
+  .offcanvas-md.offcanvas-top {
+    top: 0;
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(-100%);
+  }
+  .offcanvas-md.offcanvas-bottom {
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(100%);
+  }
+  .offcanvas-md.showing, .offcanvas-md.show:not(.hiding) {
+    transform: none;
+  }
+  .offcanvas-md.showing, .offcanvas-md.hiding, .offcanvas-md.show {
+    visibility: visible;
+  }
+}
+@media (min-width: 768px) {
+  .offcanvas-md {
+    --bs-offcanvas-height: auto;
+    --bs-offcanvas-border-width: 0;
+    background-color: transparent !important;
+  }
+  .offcanvas-md .offcanvas-header {
+    display: none;
+  }
+  .offcanvas-md .offcanvas-body {
+    display: flex;
+    flex-grow: 0;
+    padding: 0;
+    overflow-y: visible;
+    background-color: transparent !important;
+  }
+}
+
+@media (max-width: 991.98px) {
+  .offcanvas-lg {
+    position: fixed;
+    bottom: 0;
+    z-index: var(--bs-offcanvas-zindex);
+    display: flex;
+    flex-direction: column;
+    max-width: 100%;
+    color: var(--bs-offcanvas-color);
+    visibility: hidden;
+    background-color: var(--bs-offcanvas-bg);
+    background-clip: padding-box;
+    outline: 0;
+    box-shadow: var(--bs-offcanvas-box-shadow);
+    transition: var(--bs-offcanvas-transition);
+  }
+}
+@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {
+  .offcanvas-lg {
+    transition: none;
+  }
+}
+@media (max-width: 991.98px) {
+  .offcanvas-lg.offcanvas-start {
+    top: 0;
+    left: 0;
+    width: var(--bs-offcanvas-width);
+    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(-100%);
+  }
+  .offcanvas-lg.offcanvas-end {
+    top: 0;
+    right: 0;
+    width: var(--bs-offcanvas-width);
+    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(100%);
+  }
+  .offcanvas-lg.offcanvas-top {
+    top: 0;
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(-100%);
+  }
+  .offcanvas-lg.offcanvas-bottom {
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(100%);
+  }
+  .offcanvas-lg.showing, .offcanvas-lg.show:not(.hiding) {
+    transform: none;
+  }
+  .offcanvas-lg.showing, .offcanvas-lg.hiding, .offcanvas-lg.show {
+    visibility: visible;
+  }
+}
+@media (min-width: 992px) {
+  .offcanvas-lg {
+    --bs-offcanvas-height: auto;
+    --bs-offcanvas-border-width: 0;
+    background-color: transparent !important;
+  }
+  .offcanvas-lg .offcanvas-header {
+    display: none;
+  }
+  .offcanvas-lg .offcanvas-body {
+    display: flex;
+    flex-grow: 0;
+    padding: 0;
+    overflow-y: visible;
+    background-color: transparent !important;
+  }
+}
+
+@media (max-width: 1199.98px) {
+  .offcanvas-xl {
+    position: fixed;
+    bottom: 0;
+    z-index: var(--bs-offcanvas-zindex);
+    display: flex;
+    flex-direction: column;
+    max-width: 100%;
+    color: var(--bs-offcanvas-color);
+    visibility: hidden;
+    background-color: var(--bs-offcanvas-bg);
+    background-clip: padding-box;
+    outline: 0;
+    box-shadow: var(--bs-offcanvas-box-shadow);
+    transition: var(--bs-offcanvas-transition);
+  }
+}
+@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) {
+  .offcanvas-xl {
+    transition: none;
+  }
+}
+@media (max-width: 1199.98px) {
+  .offcanvas-xl.offcanvas-start {
+    top: 0;
+    left: 0;
+    width: var(--bs-offcanvas-width);
+    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(-100%);
+  }
+  .offcanvas-xl.offcanvas-end {
+    top: 0;
+    right: 0;
+    width: var(--bs-offcanvas-width);
+    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(100%);
+  }
+  .offcanvas-xl.offcanvas-top {
+    top: 0;
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(-100%);
+  }
+  .offcanvas-xl.offcanvas-bottom {
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(100%);
+  }
+  .offcanvas-xl.showing, .offcanvas-xl.show:not(.hiding) {
+    transform: none;
+  }
+  .offcanvas-xl.showing, .offcanvas-xl.hiding, .offcanvas-xl.show {
+    visibility: visible;
+  }
+}
+@media (min-width: 1200px) {
+  .offcanvas-xl {
+    --bs-offcanvas-height: auto;
+    --bs-offcanvas-border-width: 0;
+    background-color: transparent !important;
+  }
+  .offcanvas-xl .offcanvas-header {
+    display: none;
+  }
+  .offcanvas-xl .offcanvas-body {
+    display: flex;
+    flex-grow: 0;
+    padding: 0;
+    overflow-y: visible;
+    background-color: transparent !important;
+  }
+}
+
+@media (max-width: 1399.98px) {
+  .offcanvas-xxl {
+    position: fixed;
+    bottom: 0;
+    z-index: var(--bs-offcanvas-zindex);
+    display: flex;
+    flex-direction: column;
+    max-width: 100%;
+    color: var(--bs-offcanvas-color);
+    visibility: hidden;
+    background-color: var(--bs-offcanvas-bg);
+    background-clip: padding-box;
+    outline: 0;
+    box-shadow: var(--bs-offcanvas-box-shadow);
+    transition: var(--bs-offcanvas-transition);
+  }
+}
+@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) {
+  .offcanvas-xxl {
+    transition: none;
+  }
+}
+@media (max-width: 1399.98px) {
+  .offcanvas-xxl.offcanvas-start {
+    top: 0;
+    left: 0;
+    width: var(--bs-offcanvas-width);
+    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(-100%);
+  }
+  .offcanvas-xxl.offcanvas-end {
+    top: 0;
+    right: 0;
+    width: var(--bs-offcanvas-width);
+    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateX(100%);
+  }
+  .offcanvas-xxl.offcanvas-top {
+    top: 0;
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(-100%);
+  }
+  .offcanvas-xxl.offcanvas-bottom {
+    right: 0;
+    left: 0;
+    height: var(--bs-offcanvas-height);
+    max-height: 100%;
+    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+    transform: translateY(100%);
+  }
+  .offcanvas-xxl.showing, .offcanvas-xxl.show:not(.hiding) {
+    transform: none;
+  }
+  .offcanvas-xxl.showing, .offcanvas-xxl.hiding, .offcanvas-xxl.show {
+    visibility: visible;
+  }
+}
+@media (min-width: 1400px) {
+  .offcanvas-xxl {
+    --bs-offcanvas-height: auto;
+    --bs-offcanvas-border-width: 0;
+    background-color: transparent !important;
+  }
+  .offcanvas-xxl .offcanvas-header {
+    display: none;
+  }
+  .offcanvas-xxl .offcanvas-body {
+    display: flex;
+    flex-grow: 0;
+    padding: 0;
+    overflow-y: visible;
+    background-color: transparent !important;
+  }
+}
+
+.offcanvas {
+  position: fixed;
+  bottom: 0;
+  z-index: var(--bs-offcanvas-zindex);
+  display: flex;
+  flex-direction: column;
+  max-width: 100%;
+  color: var(--bs-offcanvas-color);
+  visibility: hidden;
+  background-color: var(--bs-offcanvas-bg);
+  background-clip: padding-box;
+  outline: 0;
+  box-shadow: var(--bs-offcanvas-box-shadow);
+  transition: var(--bs-offcanvas-transition);
+}
+@media (prefers-reduced-motion: reduce) {
+  .offcanvas {
+    transition: none;
+  }
+}
+.offcanvas.offcanvas-start {
+  top: 0;
+  left: 0;
+  width: var(--bs-offcanvas-width);
+  border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+  transform: translateX(-100%);
+}
+.offcanvas.offcanvas-end {
+  top: 0;
+  right: 0;
+  width: var(--bs-offcanvas-width);
+  border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+  transform: translateX(100%);
+}
+.offcanvas.offcanvas-top {
+  top: 0;
+  right: 0;
+  left: 0;
+  height: var(--bs-offcanvas-height);
+  max-height: 100%;
+  border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+  transform: translateY(-100%);
+}
+.offcanvas.offcanvas-bottom {
+  right: 0;
+  left: 0;
+  height: var(--bs-offcanvas-height);
+  max-height: 100%;
+  border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
+  transform: translateY(100%);
+}
+.offcanvas.showing, .offcanvas.show:not(.hiding) {
+  transform: none;
+}
+.offcanvas.showing, .offcanvas.hiding, .offcanvas.show {
+  visibility: visible;
+}
+
+.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: 0.5;
+}
+
+.offcanvas-header {
+  display: flex;
+  align-items: center;
+  padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);
+}
+.offcanvas-header .btn-close {
+  padding: calc(var(--bs-offcanvas-padding-y) * 0.5) calc(var(--bs-offcanvas-padding-x) * 0.5);
+  margin: calc(-0.5 * var(--bs-offcanvas-padding-y)) calc(-0.5 * var(--bs-offcanvas-padding-x)) calc(-0.5 * var(--bs-offcanvas-padding-y)) auto;
+}
+
+.offcanvas-title {
+  margin-bottom: 0;
+  line-height: var(--bs-offcanvas-title-line-height);
+}
+
+.offcanvas-body {
+  flex-grow: 1;
+  padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);
+  overflow-y: auto;
+}
+
+.placeholder {
+  display: inline-block;
+  min-height: 1em;
+  vertical-align: middle;
+  cursor: wait;
+  background-color: currentcolor;
+  opacity: 0.5;
+}
+.placeholder.btn::before {
+  display: inline-block;
+  content: "";
+}
+
+.placeholder-xs {
+  min-height: 0.6em;
+}
+
+.placeholder-sm {
+  min-height: 0.8em;
+}
+
+.placeholder-lg {
+  min-height: 1.2em;
+}
+
+.placeholder-glow .placeholder {
+  animation: placeholder-glow 2s ease-in-out infinite;
+}
+
+@keyframes placeholder-glow {
+  50% {
+    opacity: 0.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%;
+  animation: placeholder-wave 2s linear infinite;
+}
+
+@keyframes placeholder-wave {
+  100% {
+    -webkit-mask-position: -200% 0%;
+    mask-position: -200% 0%;
+  }
+}
+.clearfix::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+
+.text-bg-primary {
+  color: #fff !important;
+  background-color: RGBA(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-secondary {
+  color: #fff !important;
+  background-color: RGBA(var(--bs-secondary-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-success {
+  color: #fff !important;
+  background-color: RGBA(var(--bs-success-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-info {
+  color: #000 !important;
+  background-color: RGBA(var(--bs-info-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-warning {
+  color: #000 !important;
+  background-color: RGBA(var(--bs-warning-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-danger {
+  color: #fff !important;
+  background-color: RGBA(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-light {
+  color: #000 !important;
+  background-color: RGBA(var(--bs-light-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.text-bg-dark {
+  color: #fff !important;
+  background-color: RGBA(var(--bs-dark-rgb), var(--bs-bg-opacity, 1)) !important;
+}
+
+.link-primary {
+  color: RGBA(var(--bs-primary-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-primary:hover, .link-primary:focus {
+  color: RGBA(10, 88, 202, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(10, 88, 202, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(10, 88, 202, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-secondary {
+  color: RGBA(var(--bs-secondary-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-secondary:hover, .link-secondary:focus {
+  color: RGBA(86, 94, 100, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-success {
+  color: RGBA(var(--bs-success-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-success:hover, .link-success:focus {
+  color: RGBA(20, 108, 67, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(20, 108, 67, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(20, 108, 67, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-info {
+  color: RGBA(var(--bs-info-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-info:hover, .link-info:focus {
+  color: RGBA(61, 213, 243, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(61, 213, 243, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(61, 213, 243, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-warning {
+  color: RGBA(var(--bs-warning-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-warning:hover, .link-warning:focus {
+  color: RGBA(255, 205, 57, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(255, 205, 57, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(255, 205, 57, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-danger {
+  color: RGBA(var(--bs-danger-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-danger:hover, .link-danger:focus {
+  color: RGBA(176, 42, 55, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(176, 42, 55, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(176, 42, 55, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-light {
+  color: RGBA(var(--bs-light-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-light:hover, .link-light:focus {
+  color: RGBA(249, 250, 251, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-dark {
+  color: RGBA(var(--bs-dark-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-dark:hover, .link-dark:focus {
+  color: RGBA(26, 30, 33, var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-body-emphasis {
+  color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 1)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+.link-body-emphasis:hover, .link-body-emphasis:focus {
+  color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 0.75)) !important;
+  -webkit-text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important;
+  text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important;
+}
+
+.focus-ring:focus {
+  outline: 0;
+  box-shadow: var(--bs-focus-ring-x, 0) var(--bs-focus-ring-y, 0) var(--bs-focus-ring-blur, 0) var(--bs-focus-ring-width) var(--bs-focus-ring-color);
+}
+
+.icon-link {
+  display: inline-flex;
+  gap: 0.375rem;
+  align-items: center;
+  -webkit-text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));
+  text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));
+  text-underline-offset: 0.25em;
+  -webkit-backface-visibility: hidden;
+  backface-visibility: hidden;
+}
+.icon-link > .bi {
+  flex-shrink: 0;
+  width: 1em;
+  height: 1em;
+  fill: currentcolor;
+  transition: 0.2s ease-in-out transform;
+}
+@media (prefers-reduced-motion: reduce) {
+  .icon-link > .bi {
+    transition: none;
+  }
+}
+
+.icon-link-hover:hover > .bi, .icon-link-hover:focus-visible > .bi {
+  transform: var(--bs-icon-link-transform, translate3d(0.25em, 0, 0));
+}
+
+.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;
+}
+
+.sticky-bottom {
+  position: -webkit-sticky;
+  position: sticky;
+  bottom: 0;
+  z-index: 1020;
+}
+
+@media (min-width: 576px) {
+  .sticky-sm-top {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    z-index: 1020;
+  }
+  .sticky-sm-bottom {
+    position: -webkit-sticky;
+    position: sticky;
+    bottom: 0;
+    z-index: 1020;
+  }
+}
+@media (min-width: 768px) {
+  .sticky-md-top {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    z-index: 1020;
+  }
+  .sticky-md-bottom {
+    position: -webkit-sticky;
+    position: sticky;
+    bottom: 0;
+    z-index: 1020;
+  }
+}
+@media (min-width: 992px) {
+  .sticky-lg-top {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    z-index: 1020;
+  }
+  .sticky-lg-bottom {
+    position: -webkit-sticky;
+    position: sticky;
+    bottom: 0;
+    z-index: 1020;
+  }
+}
+@media (min-width: 1200px) {
+  .sticky-xl-top {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    z-index: 1020;
+  }
+  .sticky-xl-bottom {
+    position: -webkit-sticky;
+    position: sticky;
+    bottom: 0;
+    z-index: 1020;
+  }
+}
+@media (min-width: 1400px) {
+  .sticky-xxl-top {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    z-index: 1020;
+  }
+  .sticky-xxl-bottom {
+    position: -webkit-sticky;
+    position: sticky;
+    bottom: 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) {
+  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;
+}
+.visually-hidden:not(caption),
+.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption) {
+  position: absolute !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: var(--bs-border-width);
+  min-height: 1em;
+  background-color: currentcolor;
+  opacity: 0.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;
+}
+
+.object-fit-contain {
+  -o-object-fit: contain !important;
+  object-fit: contain !important;
+}
+
+.object-fit-cover {
+  -o-object-fit: cover !important;
+  object-fit: cover !important;
+}
+
+.object-fit-fill {
+  -o-object-fit: fill !important;
+  object-fit: fill !important;
+}
+
+.object-fit-scale {
+  -o-object-fit: scale-down !important;
+  object-fit: scale-down !important;
+}
+
+.object-fit-none {
+  -o-object-fit: none !important;
+  object-fit: none !important;
+}
+
+.opacity-0 {
+  opacity: 0 !important;
+}
+
+.opacity-25 {
+  opacity: 0.25 !important;
+}
+
+.opacity-50 {
+  opacity: 0.5 !important;
+}
+
+.opacity-75 {
+  opacity: 0.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;
+}
+
+.overflow-x-auto {
+  overflow-x: auto !important;
+}
+
+.overflow-x-hidden {
+  overflow-x: hidden !important;
+}
+
+.overflow-x-visible {
+  overflow-x: visible !important;
+}
+
+.overflow-x-scroll {
+  overflow-x: scroll !important;
+}
+
+.overflow-y-auto {
+  overflow-y: auto !important;
+}
+
+.overflow-y-hidden {
+  overflow-y: hidden !important;
+}
+
+.overflow-y-visible {
+  overflow-y: visible !important;
+}
+
+.overflow-y-scroll {
+  overflow-y: 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-inline-grid {
+  display: inline-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: var(--bs-box-shadow) !important;
+}
+
+.shadow-sm {
+  box-shadow: var(--bs-box-shadow-sm) !important;
+}
+
+.shadow-lg {
+  box-shadow: var(--bs-box-shadow-lg) !important;
+}
+
+.shadow-none {
+  box-shadow: none !important;
+}
+
+.focus-ring-primary {
+  --bs-focus-ring-color: rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-secondary {
+  --bs-focus-ring-color: rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-success {
+  --bs-focus-ring-color: rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-info {
+  --bs-focus-ring-color: rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-warning {
+  --bs-focus-ring-color: rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-danger {
+  --bs-focus-ring-color: rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-light {
+  --bs-focus-ring-color: rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity));
+}
+
+.focus-ring-dark {
+  --bs-focus-ring-color: rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity));
+}
+
+.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: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+.border-0 {
+  border: 0 !important;
+}
+
+.border-top {
+  border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+.border-top-0 {
+  border-top: 0 !important;
+}
+
+.border-end {
+  border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+.border-end-0 {
+  border-right: 0 !important;
+}
+
+.border-bottom {
+  border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+.border-bottom-0 {
+  border-bottom: 0 !important;
+}
+
+.border-start {
+  border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
+}
+
+.border-start-0 {
+  border-left: 0 !important;
+}
+
+.border-primary {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-secondary {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-success {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-info {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-warning {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-danger {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-light {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-dark {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-black {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-black-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-white {
+  --bs-border-opacity: 1;
+  border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important;
+}
+
+.border-primary-subtle {
+  border-color: var(--bs-primary-border-subtle) !important;
+}
+
+.border-secondary-subtle {
+  border-color: var(--bs-secondary-border-subtle) !important;
+}
+
+.border-success-subtle {
+  border-color: var(--bs-success-border-subtle) !important;
+}
+
+.border-info-subtle {
+  border-color: var(--bs-info-border-subtle) !important;
+}
+
+.border-warning-subtle {
+  border-color: var(--bs-warning-border-subtle) !important;
+}
+
+.border-danger-subtle {
+  border-color: var(--bs-danger-border-subtle) !important;
+}
+
+.border-light-subtle {
+  border-color: var(--bs-light-border-subtle) !important;
+}
+
+.border-dark-subtle {
+  border-color: var(--bs-dark-border-subtle) !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;
+}
+
+.border-opacity-10 {
+  --bs-border-opacity: 0.1;
+}
+
+.border-opacity-25 {
+  --bs-border-opacity: 0.25;
+}
+
+.border-opacity-50 {
+  --bs-border-opacity: 0.5;
+}
+
+.border-opacity-75 {
+  --bs-border-opacity: 0.75;
+}
+
+.border-opacity-100 {
+  --bs-border-opacity: 1;
+}
+
+.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;
+}
+
+.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: 0.25rem !important;
+}
+
+.m-2 {
+  margin: 0.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: 0.25rem !important;
+  margin-left: 0.25rem !important;
+}
+
+.mx-2 {
+  margin-right: 0.5rem !important;
+  margin-left: 0.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: 0.25rem !important;
+  margin-bottom: 0.25rem !important;
+}
+
+.my-2 {
+  margin-top: 0.5rem !important;
+  margin-bottom: 0.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: 0.25rem !important;
+}
+
+.mt-2 {
+  margin-top: 0.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: 0.25rem !important;
+}
+
+.me-2 {
+  margin-right: 0.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: 0.25rem !important;
+}
+
+.mb-2 {
+  margin-bottom: 0.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: 0.25rem !important;
+}
+
+.ms-2 {
+  margin-left: 0.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;
+}
+
+.m-n1 {
+  margin: -0.25rem !important;
+}
+
+.m-n2 {
+  margin: -0.5rem !important;
+}
+
+.m-n3 {
+  margin: -1rem !important;
+}
+
+.m-n4 {
+  margin: -1.5rem !important;
+}
+
+.m-n5 {
+  margin: -3rem !important;
+}
+
+.mx-n1 {
+  margin-right: -0.25rem !important;
+  margin-left: -0.25rem !important;
+}
+
+.mx-n2 {
+  margin-right: -0.5rem !important;
+  margin-left: -0.5rem !important;
+}
+
+.mx-n3 {
+  margin-right: -1rem !important;
+  margin-left: -1rem !important;
+}
+
+.mx-n4 {
+  margin-right: -1.5rem !important;
+  margin-left: -1.5rem !important;
+}
+
+.mx-n5 {
+  margin-right: -3rem !important;
+  margin-left: -3rem !important;
+}
+
+.my-n1 {
+  margin-top: -0.25rem !important;
+  margin-bottom: -0.25rem !important;
+}
+
+.my-n2 {
+  margin-top: -0.5rem !important;
+  margin-bottom: -0.5rem !important;
+}
+
+.my-n3 {
+  margin-top: -1rem !important;
+  margin-bottom: -1rem !important;
+}
+
+.my-n4 {
+  margin-top: -1.5rem !important;
+  margin-bottom: -1.5rem !important;
+}
+
+.my-n5 {
+  margin-top: -3rem !important;
+  margin-bottom: -3rem !important;
+}
+
+.mt-n1 {
+  margin-top: -0.25rem !important;
+}
+
+.mt-n2 {
+  margin-top: -0.5rem !important;
+}
+
+.mt-n3 {
+  margin-top: -1rem !important;
+}
+
+.mt-n4 {
+  margin-top: -1.5rem !important;
+}
+
+.mt-n5 {
+  margin-top: -3rem !important;
+}
+
+.me-n1 {
+  margin-right: -0.25rem !important;
+}
+
+.me-n2 {
+  margin-right: -0.5rem !important;
+}
+
+.me-n3 {
+  margin-right: -1rem !important;
+}
+
+.me-n4 {
+  margin-right: -1.5rem !important;
+}
+
+.me-n5 {
+  margin-right: -3rem !important;
+}
+
+.mb-n1 {
+  margin-bottom: -0.25rem !important;
+}
+
+.mb-n2 {
+  margin-bottom: -0.5rem !important;
+}
+
+.mb-n3 {
+  margin-bottom: -1rem !important;
+}
+
+.mb-n4 {
+  margin-bottom: -1.5rem !important;
+}
+
+.mb-n5 {
+  margin-bottom: -3rem !important;
+}
+
+.ms-n1 {
+  margin-left: -0.25rem !important;
+}
+
+.ms-n2 {
+  margin-left: -0.5rem !important;
+}
+
+.ms-n3 {
+  margin-left: -1rem !important;
+}
+
+.ms-n4 {
+  margin-left: -1.5rem !important;
+}
+
+.ms-n5 {
+  margin-left: -3rem !important;
+}
+
+.p-0 {
+  padding: 0 !important;
+}
+
+.p-1 {
+  padding: 0.25rem !important;
+}
+
+.p-2 {
+  padding: 0.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: 0.25rem !important;
+  padding-left: 0.25rem !important;
+}
+
+.px-2 {
+  padding-right: 0.5rem !important;
+  padding-left: 0.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: 0.25rem !important;
+  padding-bottom: 0.25rem !important;
+}
+
+.py-2 {
+  padding-top: 0.5rem !important;
+  padding-bottom: 0.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: 0.25rem !important;
+}
+
+.pt-2 {
+  padding-top: 0.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: 0.25rem !important;
+}
+
+.pe-2 {
+  padding-right: 0.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: 0.25rem !important;
+}
+
+.pb-2 {
+  padding-bottom: 0.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: 0.25rem !important;
+}
+
+.ps-2 {
+  padding-left: 0.5rem !important;
+}
+
+.ps-3 {
+  padding-left: 1rem !important;
+}
+
+.ps-4 {
+  padding-left: 1.5rem !important;
+}
+
+.ps-5 {
+  padding-left: 3rem !important;
+}
+
+.gap-0 {
+  gap: 0 !important;
+}
+
+.gap-1 {
+  gap: 0.25rem !important;
+}
+
+.gap-2 {
+  gap: 0.5rem !important;
+}
+
+.gap-3 {
+  gap: 1rem !important;
+}
+
+.gap-4 {
+  gap: 1.5rem !important;
+}
+
+.gap-5 {
+  gap: 3rem !important;
+}
+
+.row-gap-0 {
+  row-gap: 0 !important;
+}
+
+.row-gap-1 {
+  row-gap: 0.25rem !important;
+}
+
+.row-gap-2 {
+  row-gap: 0.5rem !important;
+}
+
+.row-gap-3 {
+  row-gap: 1rem !important;
+}
+
+.row-gap-4 {
+  row-gap: 1.5rem !important;
+}
+
+.row-gap-5 {
+  row-gap: 3rem !important;
+}
+
+.column-gap-0 {
+  -moz-column-gap: 0 !important;
+  column-gap: 0 !important;
+}
+
+.column-gap-1 {
+  -moz-column-gap: 0.25rem !important;
+  column-gap: 0.25rem !important;
+}
+
+.column-gap-2 {
+  -moz-column-gap: 0.5rem !important;
+  column-gap: 0.5rem !important;
+}
+
+.column-gap-3 {
+  -moz-column-gap: 1rem !important;
+  column-gap: 1rem !important;
+}
+
+.column-gap-4 {
+  -moz-column-gap: 1.5rem !important;
+  column-gap: 1.5rem !important;
+}
+
+.column-gap-5 {
+  -moz-column-gap: 3rem !important;
+  column-gap: 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 + 0.9vw) !important;
+}
+
+.fs-3 {
+  font-size: calc(1.3rem + 0.6vw) !important;
+}
+
+.fs-4 {
+  font-size: calc(1.275rem + 0.3vw) !important;
+}
+
+.fs-5 {
+  font-size: 1.25rem !important;
+}
+
+.fs-6 {
+  font-size: 1rem !important;
+}
+
+.fs-7 {
+  font-size: 0.875rem !important;
+}
+
+.fs-8 {
+  font-size: 0.75rem !important;
+}
+
+.fst-italic {
+  font-style: italic !important;
+}
+
+.fst-normal {
+  font-style: normal !important;
+}
+
+.fw-lighter {
+  font-weight: lighter !important;
+}
+
+.fw-light {
+  font-weight: 300 !important;
+}
+
+.fw-normal {
+  font-weight: 400 !important;
+}
+
+.fw-medium {
+  font-weight: 500 !important;
+}
+
+.fw-semibold {
+  font-weight: 600 !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;
+}
+
+/* rtl:begin:remove */
+.text-break {
+  word-wrap: break-word !important;
+  word-break: break-word !important;
+}
+
+/* rtl:end:remove */
+.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: var(--bs-secondary-color) !important;
+}
+
+.text-black-50 {
+  --bs-text-opacity: 1;
+  color: rgba(0, 0, 0, 0.5) !important;
+}
+
+.text-white-50 {
+  --bs-text-opacity: 1;
+  color: rgba(255, 255, 255, 0.5) !important;
+}
+
+.text-body-secondary {
+  --bs-text-opacity: 1;
+  color: var(--bs-secondary-color) !important;
+}
+
+.text-body-tertiary {
+  --bs-text-opacity: 1;
+  color: var(--bs-tertiary-color) !important;
+}
+
+.text-body-emphasis {
+  --bs-text-opacity: 1;
+  color: var(--bs-emphasis-color) !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;
+}
+
+.text-primary-emphasis {
+  color: var(--bs-primary-text-emphasis) !important;
+}
+
+.text-secondary-emphasis {
+  color: var(--bs-secondary-text-emphasis) !important;
+}
+
+.text-success-emphasis {
+  color: var(--bs-success-text-emphasis) !important;
+}
+
+.text-info-emphasis {
+  color: var(--bs-info-text-emphasis) !important;
+}
+
+.text-warning-emphasis {
+  color: var(--bs-warning-text-emphasis) !important;
+}
+
+.text-danger-emphasis {
+  color: var(--bs-danger-text-emphasis) !important;
+}
+
+.text-light-emphasis {
+  color: var(--bs-light-text-emphasis) !important;
+}
+
+.text-dark-emphasis {
+  color: var(--bs-dark-text-emphasis) !important;
+}
+
+.link-opacity-10 {
+  --bs-link-opacity: 0.1;
+}
+
+.link-opacity-10-hover:hover {
+  --bs-link-opacity: 0.1;
+}
+
+.link-opacity-25 {
+  --bs-link-opacity: 0.25;
+}
+
+.link-opacity-25-hover:hover {
+  --bs-link-opacity: 0.25;
+}
+
+.link-opacity-50 {
+  --bs-link-opacity: 0.5;
+}
+
+.link-opacity-50-hover:hover {
+  --bs-link-opacity: 0.5;
+}
+
+.link-opacity-75 {
+  --bs-link-opacity: 0.75;
+}
+
+.link-opacity-75-hover:hover {
+  --bs-link-opacity: 0.75;
+}
+
+.link-opacity-100 {
+  --bs-link-opacity: 1;
+}
+
+.link-opacity-100-hover:hover {
+  --bs-link-opacity: 1;
+}
+
+.link-offset-1 {
+  text-underline-offset: 0.125em !important;
+}
+
+.link-offset-1-hover:hover {
+  text-underline-offset: 0.125em !important;
+}
+
+.link-offset-2 {
+  text-underline-offset: 0.25em !important;
+}
+
+.link-offset-2-hover:hover {
+  text-underline-offset: 0.25em !important;
+}
+
+.link-offset-3 {
+  text-underline-offset: 0.375em !important;
+}
+
+.link-offset-3-hover:hover {
+  text-underline-offset: 0.375em !important;
+}
+
+.link-underline-primary {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-secondary {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-success {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-info {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-warning {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-danger {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-light {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline-dark {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important;
+  text-decoration-color: rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important;
+}
+
+.link-underline {
+  --bs-link-underline-opacity: 1;
+  -webkit-text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important;
+  text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important;
+}
+
+.link-underline-opacity-0 {
+  --bs-link-underline-opacity: 0;
+}
+
+.link-underline-opacity-0-hover:hover {
+  --bs-link-underline-opacity: 0;
+}
+
+.link-underline-opacity-10 {
+  --bs-link-underline-opacity: 0.1;
+}
+
+.link-underline-opacity-10-hover:hover {
+  --bs-link-underline-opacity: 0.1;
+}
+
+.link-underline-opacity-25 {
+  --bs-link-underline-opacity: 0.25;
+}
+
+.link-underline-opacity-25-hover:hover {
+  --bs-link-underline-opacity: 0.25;
+}
+
+.link-underline-opacity-50 {
+  --bs-link-underline-opacity: 0.5;
+}
+
+.link-underline-opacity-50-hover:hover {
+  --bs-link-underline-opacity: 0.5;
+}
+
+.link-underline-opacity-75 {
+  --bs-link-underline-opacity: 0.75;
+}
+
+.link-underline-opacity-75-hover:hover {
+  --bs-link-underline-opacity: 0.75;
+}
+
+.link-underline-opacity-100 {
+  --bs-link-underline-opacity: 1;
+}
+
+.link-underline-opacity-100-hover:hover {
+  --bs-link-underline-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-body-secondary {
+  --bs-bg-opacity: 1;
+  background-color: rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important;
+}
+
+.bg-body-tertiary {
+  --bs-bg-opacity: 1;
+  background-color: rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !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-primary-subtle {
+  background-color: var(--bs-primary-bg-subtle) !important;
+}
+
+.bg-secondary-subtle {
+  background-color: var(--bs-secondary-bg-subtle) !important;
+}
+
+.bg-success-subtle {
+  background-color: var(--bs-success-bg-subtle) !important;
+}
+
+.bg-info-subtle {
+  background-color: var(--bs-info-bg-subtle) !important;
+}
+
+.bg-warning-subtle {
+  background-color: var(--bs-warning-bg-subtle) !important;
+}
+
+.bg-danger-subtle {
+  background-color: var(--bs-danger-bg-subtle) !important;
+}
+
+.bg-light-subtle {
+  background-color: var(--bs-light-bg-subtle) !important;
+}
+
+.bg-dark-subtle {
+  background-color: var(--bs-dark-bg-subtle) !important;
+}
+
+.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: var(--bs-border-radius) !important;
+}
+
+.rounded-0 {
+  border-radius: 0 !important;
+}
+
+.rounded-1 {
+  border-radius: var(--bs-border-radius-sm) !important;
+}
+
+.rounded-2 {
+  border-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-3 {
+  border-radius: var(--bs-border-radius-lg) !important;
+}
+
+.rounded-4 {
+  border-radius: var(--bs-border-radius-xl) !important;
+}
+
+.rounded-5 {
+  border-radius: var(--bs-border-radius-xxl) !important;
+}
+
+.rounded-circle {
+  border-radius: 50% !important;
+}
+
+.rounded-pill {
+  border-radius: var(--bs-border-radius-pill) !important;
+}
+
+.rounded-top {
+  border-top-left-radius: var(--bs-border-radius) !important;
+  border-top-right-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-top-0 {
+  border-top-left-radius: 0 !important;
+  border-top-right-radius: 0 !important;
+}
+
+.rounded-top-1 {
+  border-top-left-radius: var(--bs-border-radius-sm) !important;
+  border-top-right-radius: var(--bs-border-radius-sm) !important;
+}
+
+.rounded-top-2 {
+  border-top-left-radius: var(--bs-border-radius) !important;
+  border-top-right-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-top-3 {
+  border-top-left-radius: var(--bs-border-radius-lg) !important;
+  border-top-right-radius: var(--bs-border-radius-lg) !important;
+}
+
+.rounded-top-4 {
+  border-top-left-radius: var(--bs-border-radius-xl) !important;
+  border-top-right-radius: var(--bs-border-radius-xl) !important;
+}
+
+.rounded-top-5 {
+  border-top-left-radius: var(--bs-border-radius-xxl) !important;
+  border-top-right-radius: var(--bs-border-radius-xxl) !important;
+}
+
+.rounded-top-circle {
+  border-top-left-radius: 50% !important;
+  border-top-right-radius: 50% !important;
+}
+
+.rounded-top-pill {
+  border-top-left-radius: var(--bs-border-radius-pill) !important;
+  border-top-right-radius: var(--bs-border-radius-pill) !important;
+}
+
+.rounded-end {
+  border-top-right-radius: var(--bs-border-radius) !important;
+  border-bottom-right-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-end-0 {
+  border-top-right-radius: 0 !important;
+  border-bottom-right-radius: 0 !important;
+}
+
+.rounded-end-1 {
+  border-top-right-radius: var(--bs-border-radius-sm) !important;
+  border-bottom-right-radius: var(--bs-border-radius-sm) !important;
+}
+
+.rounded-end-2 {
+  border-top-right-radius: var(--bs-border-radius) !important;
+  border-bottom-right-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-end-3 {
+  border-top-right-radius: var(--bs-border-radius-lg) !important;
+  border-bottom-right-radius: var(--bs-border-radius-lg) !important;
+}
+
+.rounded-end-4 {
+  border-top-right-radius: var(--bs-border-radius-xl) !important;
+  border-bottom-right-radius: var(--bs-border-radius-xl) !important;
+}
+
+.rounded-end-5 {
+  border-top-right-radius: var(--bs-border-radius-xxl) !important;
+  border-bottom-right-radius: var(--bs-border-radius-xxl) !important;
+}
+
+.rounded-end-circle {
+  border-top-right-radius: 50% !important;
+  border-bottom-right-radius: 50% !important;
+}
+
+.rounded-end-pill {
+  border-top-right-radius: var(--bs-border-radius-pill) !important;
+  border-bottom-right-radius: var(--bs-border-radius-pill) !important;
+}
+
+.rounded-bottom {
+  border-bottom-right-radius: var(--bs-border-radius) !important;
+  border-bottom-left-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-bottom-0 {
+  border-bottom-right-radius: 0 !important;
+  border-bottom-left-radius: 0 !important;
+}
+
+.rounded-bottom-1 {
+  border-bottom-right-radius: var(--bs-border-radius-sm) !important;
+  border-bottom-left-radius: var(--bs-border-radius-sm) !important;
+}
+
+.rounded-bottom-2 {
+  border-bottom-right-radius: var(--bs-border-radius) !important;
+  border-bottom-left-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-bottom-3 {
+  border-bottom-right-radius: var(--bs-border-radius-lg) !important;
+  border-bottom-left-radius: var(--bs-border-radius-lg) !important;
+}
+
+.rounded-bottom-4 {
+  border-bottom-right-radius: var(--bs-border-radius-xl) !important;
+  border-bottom-left-radius: var(--bs-border-radius-xl) !important;
+}
+
+.rounded-bottom-5 {
+  border-bottom-right-radius: var(--bs-border-radius-xxl) !important;
+  border-bottom-left-radius: var(--bs-border-radius-xxl) !important;
+}
+
+.rounded-bottom-circle {
+  border-bottom-right-radius: 50% !important;
+  border-bottom-left-radius: 50% !important;
+}
+
+.rounded-bottom-pill {
+  border-bottom-right-radius: var(--bs-border-radius-pill) !important;
+  border-bottom-left-radius: var(--bs-border-radius-pill) !important;
+}
+
+.rounded-start {
+  border-bottom-left-radius: var(--bs-border-radius) !important;
+  border-top-left-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-start-0 {
+  border-bottom-left-radius: 0 !important;
+  border-top-left-radius: 0 !important;
+}
+
+.rounded-start-1 {
+  border-bottom-left-radius: var(--bs-border-radius-sm) !important;
+  border-top-left-radius: var(--bs-border-radius-sm) !important;
+}
+
+.rounded-start-2 {
+  border-bottom-left-radius: var(--bs-border-radius) !important;
+  border-top-left-radius: var(--bs-border-radius) !important;
+}
+
+.rounded-start-3 {
+  border-bottom-left-radius: var(--bs-border-radius-lg) !important;
+  border-top-left-radius: var(--bs-border-radius-lg) !important;
+}
+
+.rounded-start-4 {
+  border-bottom-left-radius: var(--bs-border-radius-xl) !important;
+  border-top-left-radius: var(--bs-border-radius-xl) !important;
+}
+
+.rounded-start-5 {
+  border-bottom-left-radius: var(--bs-border-radius-xxl) !important;
+  border-top-left-radius: var(--bs-border-radius-xxl) !important;
+}
+
+.rounded-start-circle {
+  border-bottom-left-radius: 50% !important;
+  border-top-left-radius: 50% !important;
+}
+
+.rounded-start-pill {
+  border-bottom-left-radius: var(--bs-border-radius-pill) !important;
+  border-top-left-radius: var(--bs-border-radius-pill) !important;
+}
+
+.visible {
+  visibility: visible !important;
+}
+
+.invisible {
+  visibility: hidden !important;
+}
+
+.z-n1 {
+  z-index: -1 !important;
+}
+
+.z-0 {
+  z-index: 0 !important;
+}
+
+.z-1 {
+  z-index: 1 !important;
+}
+
+.z-2 {
+  z-index: 2 !important;
+}
+
+.z-3 {
+  z-index: 3 !important;
+}
+
+@media (min-width: 576px) {
+  .float-sm-start {
+    float: left !important;
+  }
+  .float-sm-end {
+    float: right !important;
+  }
+  .float-sm-none {
+    float: none !important;
+  }
+  .object-fit-sm-contain {
+    -o-object-fit: contain !important;
+    object-fit: contain !important;
+  }
+  .object-fit-sm-cover {
+    -o-object-fit: cover !important;
+    object-fit: cover !important;
+  }
+  .object-fit-sm-fill {
+    -o-object-fit: fill !important;
+    object-fit: fill !important;
+  }
+  .object-fit-sm-scale {
+    -o-object-fit: scale-down !important;
+    object-fit: scale-down !important;
+  }
+  .object-fit-sm-none {
+    -o-object-fit: none !important;
+    object-fit: 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-inline-grid {
+    display: inline-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;
+  }
+  .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: 0.25rem !important;
+  }
+  .m-sm-2 {
+    margin: 0.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: 0.25rem !important;
+    margin-left: 0.25rem !important;
+  }
+  .mx-sm-2 {
+    margin-right: 0.5rem !important;
+    margin-left: 0.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: 0.25rem !important;
+    margin-bottom: 0.25rem !important;
+  }
+  .my-sm-2 {
+    margin-top: 0.5rem !important;
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .mt-sm-2 {
+    margin-top: 0.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: 0.25rem !important;
+  }
+  .me-sm-2 {
+    margin-right: 0.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: 0.25rem !important;
+  }
+  .mb-sm-2 {
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .ms-sm-2 {
+    margin-left: 0.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;
+  }
+  .m-sm-n1 {
+    margin: -0.25rem !important;
+  }
+  .m-sm-n2 {
+    margin: -0.5rem !important;
+  }
+  .m-sm-n3 {
+    margin: -1rem !important;
+  }
+  .m-sm-n4 {
+    margin: -1.5rem !important;
+  }
+  .m-sm-n5 {
+    margin: -3rem !important;
+  }
+  .mx-sm-n1 {
+    margin-right: -0.25rem !important;
+    margin-left: -0.25rem !important;
+  }
+  .mx-sm-n2 {
+    margin-right: -0.5rem !important;
+    margin-left: -0.5rem !important;
+  }
+  .mx-sm-n3 {
+    margin-right: -1rem !important;
+    margin-left: -1rem !important;
+  }
+  .mx-sm-n4 {
+    margin-right: -1.5rem !important;
+    margin-left: -1.5rem !important;
+  }
+  .mx-sm-n5 {
+    margin-right: -3rem !important;
+    margin-left: -3rem !important;
+  }
+  .my-sm-n1 {
+    margin-top: -0.25rem !important;
+    margin-bottom: -0.25rem !important;
+  }
+  .my-sm-n2 {
+    margin-top: -0.5rem !important;
+    margin-bottom: -0.5rem !important;
+  }
+  .my-sm-n3 {
+    margin-top: -1rem !important;
+    margin-bottom: -1rem !important;
+  }
+  .my-sm-n4 {
+    margin-top: -1.5rem !important;
+    margin-bottom: -1.5rem !important;
+  }
+  .my-sm-n5 {
+    margin-top: -3rem !important;
+    margin-bottom: -3rem !important;
+  }
+  .mt-sm-n1 {
+    margin-top: -0.25rem !important;
+  }
+  .mt-sm-n2 {
+    margin-top: -0.5rem !important;
+  }
+  .mt-sm-n3 {
+    margin-top: -1rem !important;
+  }
+  .mt-sm-n4 {
+    margin-top: -1.5rem !important;
+  }
+  .mt-sm-n5 {
+    margin-top: -3rem !important;
+  }
+  .me-sm-n1 {
+    margin-right: -0.25rem !important;
+  }
+  .me-sm-n2 {
+    margin-right: -0.5rem !important;
+  }
+  .me-sm-n3 {
+    margin-right: -1rem !important;
+  }
+  .me-sm-n4 {
+    margin-right: -1.5rem !important;
+  }
+  .me-sm-n5 {
+    margin-right: -3rem !important;
+  }
+  .mb-sm-n1 {
+    margin-bottom: -0.25rem !important;
+  }
+  .mb-sm-n2 {
+    margin-bottom: -0.5rem !important;
+  }
+  .mb-sm-n3 {
+    margin-bottom: -1rem !important;
+  }
+  .mb-sm-n4 {
+    margin-bottom: -1.5rem !important;
+  }
+  .mb-sm-n5 {
+    margin-bottom: -3rem !important;
+  }
+  .ms-sm-n1 {
+    margin-left: -0.25rem !important;
+  }
+  .ms-sm-n2 {
+    margin-left: -0.5rem !important;
+  }
+  .ms-sm-n3 {
+    margin-left: -1rem !important;
+  }
+  .ms-sm-n4 {
+    margin-left: -1.5rem !important;
+  }
+  .ms-sm-n5 {
+    margin-left: -3rem !important;
+  }
+  .p-sm-0 {
+    padding: 0 !important;
+  }
+  .p-sm-1 {
+    padding: 0.25rem !important;
+  }
+  .p-sm-2 {
+    padding: 0.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: 0.25rem !important;
+    padding-left: 0.25rem !important;
+  }
+  .px-sm-2 {
+    padding-right: 0.5rem !important;
+    padding-left: 0.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: 0.25rem !important;
+    padding-bottom: 0.25rem !important;
+  }
+  .py-sm-2 {
+    padding-top: 0.5rem !important;
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .pt-sm-2 {
+    padding-top: 0.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: 0.25rem !important;
+  }
+  .pe-sm-2 {
+    padding-right: 0.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: 0.25rem !important;
+  }
+  .pb-sm-2 {
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .ps-sm-2 {
+    padding-left: 0.5rem !important;
+  }
+  .ps-sm-3 {
+    padding-left: 1rem !important;
+  }
+  .ps-sm-4 {
+    padding-left: 1.5rem !important;
+  }
+  .ps-sm-5 {
+    padding-left: 3rem !important;
+  }
+  .gap-sm-0 {
+    gap: 0 !important;
+  }
+  .gap-sm-1 {
+    gap: 0.25rem !important;
+  }
+  .gap-sm-2 {
+    gap: 0.5rem !important;
+  }
+  .gap-sm-3 {
+    gap: 1rem !important;
+  }
+  .gap-sm-4 {
+    gap: 1.5rem !important;
+  }
+  .gap-sm-5 {
+    gap: 3rem !important;
+  }
+  .row-gap-sm-0 {
+    row-gap: 0 !important;
+  }
+  .row-gap-sm-1 {
+    row-gap: 0.25rem !important;
+  }
+  .row-gap-sm-2 {
+    row-gap: 0.5rem !important;
+  }
+  .row-gap-sm-3 {
+    row-gap: 1rem !important;
+  }
+  .row-gap-sm-4 {
+    row-gap: 1.5rem !important;
+  }
+  .row-gap-sm-5 {
+    row-gap: 3rem !important;
+  }
+  .column-gap-sm-0 {
+    -moz-column-gap: 0 !important;
+    column-gap: 0 !important;
+  }
+  .column-gap-sm-1 {
+    -moz-column-gap: 0.25rem !important;
+    column-gap: 0.25rem !important;
+  }
+  .column-gap-sm-2 {
+    -moz-column-gap: 0.5rem !important;
+    column-gap: 0.5rem !important;
+  }
+  .column-gap-sm-3 {
+    -moz-column-gap: 1rem !important;
+    column-gap: 1rem !important;
+  }
+  .column-gap-sm-4 {
+    -moz-column-gap: 1.5rem !important;
+    column-gap: 1.5rem !important;
+  }
+  .column-gap-sm-5 {
+    -moz-column-gap: 3rem !important;
+    column-gap: 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;
+  }
+  .object-fit-md-contain {
+    -o-object-fit: contain !important;
+    object-fit: contain !important;
+  }
+  .object-fit-md-cover {
+    -o-object-fit: cover !important;
+    object-fit: cover !important;
+  }
+  .object-fit-md-fill {
+    -o-object-fit: fill !important;
+    object-fit: fill !important;
+  }
+  .object-fit-md-scale {
+    -o-object-fit: scale-down !important;
+    object-fit: scale-down !important;
+  }
+  .object-fit-md-none {
+    -o-object-fit: none !important;
+    object-fit: 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-inline-grid {
+    display: inline-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;
+  }
+  .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: 0.25rem !important;
+  }
+  .m-md-2 {
+    margin: 0.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: 0.25rem !important;
+    margin-left: 0.25rem !important;
+  }
+  .mx-md-2 {
+    margin-right: 0.5rem !important;
+    margin-left: 0.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: 0.25rem !important;
+    margin-bottom: 0.25rem !important;
+  }
+  .my-md-2 {
+    margin-top: 0.5rem !important;
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .mt-md-2 {
+    margin-top: 0.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: 0.25rem !important;
+  }
+  .me-md-2 {
+    margin-right: 0.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: 0.25rem !important;
+  }
+  .mb-md-2 {
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .ms-md-2 {
+    margin-left: 0.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;
+  }
+  .m-md-n1 {
+    margin: -0.25rem !important;
+  }
+  .m-md-n2 {
+    margin: -0.5rem !important;
+  }
+  .m-md-n3 {
+    margin: -1rem !important;
+  }
+  .m-md-n4 {
+    margin: -1.5rem !important;
+  }
+  .m-md-n5 {
+    margin: -3rem !important;
+  }
+  .mx-md-n1 {
+    margin-right: -0.25rem !important;
+    margin-left: -0.25rem !important;
+  }
+  .mx-md-n2 {
+    margin-right: -0.5rem !important;
+    margin-left: -0.5rem !important;
+  }
+  .mx-md-n3 {
+    margin-right: -1rem !important;
+    margin-left: -1rem !important;
+  }
+  .mx-md-n4 {
+    margin-right: -1.5rem !important;
+    margin-left: -1.5rem !important;
+  }
+  .mx-md-n5 {
+    margin-right: -3rem !important;
+    margin-left: -3rem !important;
+  }
+  .my-md-n1 {
+    margin-top: -0.25rem !important;
+    margin-bottom: -0.25rem !important;
+  }
+  .my-md-n2 {
+    margin-top: -0.5rem !important;
+    margin-bottom: -0.5rem !important;
+  }
+  .my-md-n3 {
+    margin-top: -1rem !important;
+    margin-bottom: -1rem !important;
+  }
+  .my-md-n4 {
+    margin-top: -1.5rem !important;
+    margin-bottom: -1.5rem !important;
+  }
+  .my-md-n5 {
+    margin-top: -3rem !important;
+    margin-bottom: -3rem !important;
+  }
+  .mt-md-n1 {
+    margin-top: -0.25rem !important;
+  }
+  .mt-md-n2 {
+    margin-top: -0.5rem !important;
+  }
+  .mt-md-n3 {
+    margin-top: -1rem !important;
+  }
+  .mt-md-n4 {
+    margin-top: -1.5rem !important;
+  }
+  .mt-md-n5 {
+    margin-top: -3rem !important;
+  }
+  .me-md-n1 {
+    margin-right: -0.25rem !important;
+  }
+  .me-md-n2 {
+    margin-right: -0.5rem !important;
+  }
+  .me-md-n3 {
+    margin-right: -1rem !important;
+  }
+  .me-md-n4 {
+    margin-right: -1.5rem !important;
+  }
+  .me-md-n5 {
+    margin-right: -3rem !important;
+  }
+  .mb-md-n1 {
+    margin-bottom: -0.25rem !important;
+  }
+  .mb-md-n2 {
+    margin-bottom: -0.5rem !important;
+  }
+  .mb-md-n3 {
+    margin-bottom: -1rem !important;
+  }
+  .mb-md-n4 {
+    margin-bottom: -1.5rem !important;
+  }
+  .mb-md-n5 {
+    margin-bottom: -3rem !important;
+  }
+  .ms-md-n1 {
+    margin-left: -0.25rem !important;
+  }
+  .ms-md-n2 {
+    margin-left: -0.5rem !important;
+  }
+  .ms-md-n3 {
+    margin-left: -1rem !important;
+  }
+  .ms-md-n4 {
+    margin-left: -1.5rem !important;
+  }
+  .ms-md-n5 {
+    margin-left: -3rem !important;
+  }
+  .p-md-0 {
+    padding: 0 !important;
+  }
+  .p-md-1 {
+    padding: 0.25rem !important;
+  }
+  .p-md-2 {
+    padding: 0.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: 0.25rem !important;
+    padding-left: 0.25rem !important;
+  }
+  .px-md-2 {
+    padding-right: 0.5rem !important;
+    padding-left: 0.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: 0.25rem !important;
+    padding-bottom: 0.25rem !important;
+  }
+  .py-md-2 {
+    padding-top: 0.5rem !important;
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .pt-md-2 {
+    padding-top: 0.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: 0.25rem !important;
+  }
+  .pe-md-2 {
+    padding-right: 0.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: 0.25rem !important;
+  }
+  .pb-md-2 {
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .ps-md-2 {
+    padding-left: 0.5rem !important;
+  }
+  .ps-md-3 {
+    padding-left: 1rem !important;
+  }
+  .ps-md-4 {
+    padding-left: 1.5rem !important;
+  }
+  .ps-md-5 {
+    padding-left: 3rem !important;
+  }
+  .gap-md-0 {
+    gap: 0 !important;
+  }
+  .gap-md-1 {
+    gap: 0.25rem !important;
+  }
+  .gap-md-2 {
+    gap: 0.5rem !important;
+  }
+  .gap-md-3 {
+    gap: 1rem !important;
+  }
+  .gap-md-4 {
+    gap: 1.5rem !important;
+  }
+  .gap-md-5 {
+    gap: 3rem !important;
+  }
+  .row-gap-md-0 {
+    row-gap: 0 !important;
+  }
+  .row-gap-md-1 {
+    row-gap: 0.25rem !important;
+  }
+  .row-gap-md-2 {
+    row-gap: 0.5rem !important;
+  }
+  .row-gap-md-3 {
+    row-gap: 1rem !important;
+  }
+  .row-gap-md-4 {
+    row-gap: 1.5rem !important;
+  }
+  .row-gap-md-5 {
+    row-gap: 3rem !important;
+  }
+  .column-gap-md-0 {
+    -moz-column-gap: 0 !important;
+    column-gap: 0 !important;
+  }
+  .column-gap-md-1 {
+    -moz-column-gap: 0.25rem !important;
+    column-gap: 0.25rem !important;
+  }
+  .column-gap-md-2 {
+    -moz-column-gap: 0.5rem !important;
+    column-gap: 0.5rem !important;
+  }
+  .column-gap-md-3 {
+    -moz-column-gap: 1rem !important;
+    column-gap: 1rem !important;
+  }
+  .column-gap-md-4 {
+    -moz-column-gap: 1.5rem !important;
+    column-gap: 1.5rem !important;
+  }
+  .column-gap-md-5 {
+    -moz-column-gap: 3rem !important;
+    column-gap: 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;
+  }
+  .object-fit-lg-contain {
+    -o-object-fit: contain !important;
+    object-fit: contain !important;
+  }
+  .object-fit-lg-cover {
+    -o-object-fit: cover !important;
+    object-fit: cover !important;
+  }
+  .object-fit-lg-fill {
+    -o-object-fit: fill !important;
+    object-fit: fill !important;
+  }
+  .object-fit-lg-scale {
+    -o-object-fit: scale-down !important;
+    object-fit: scale-down !important;
+  }
+  .object-fit-lg-none {
+    -o-object-fit: none !important;
+    object-fit: 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-inline-grid {
+    display: inline-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;
+  }
+  .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: 0.25rem !important;
+  }
+  .m-lg-2 {
+    margin: 0.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: 0.25rem !important;
+    margin-left: 0.25rem !important;
+  }
+  .mx-lg-2 {
+    margin-right: 0.5rem !important;
+    margin-left: 0.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: 0.25rem !important;
+    margin-bottom: 0.25rem !important;
+  }
+  .my-lg-2 {
+    margin-top: 0.5rem !important;
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .mt-lg-2 {
+    margin-top: 0.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: 0.25rem !important;
+  }
+  .me-lg-2 {
+    margin-right: 0.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: 0.25rem !important;
+  }
+  .mb-lg-2 {
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .ms-lg-2 {
+    margin-left: 0.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;
+  }
+  .m-lg-n1 {
+    margin: -0.25rem !important;
+  }
+  .m-lg-n2 {
+    margin: -0.5rem !important;
+  }
+  .m-lg-n3 {
+    margin: -1rem !important;
+  }
+  .m-lg-n4 {
+    margin: -1.5rem !important;
+  }
+  .m-lg-n5 {
+    margin: -3rem !important;
+  }
+  .mx-lg-n1 {
+    margin-right: -0.25rem !important;
+    margin-left: -0.25rem !important;
+  }
+  .mx-lg-n2 {
+    margin-right: -0.5rem !important;
+    margin-left: -0.5rem !important;
+  }
+  .mx-lg-n3 {
+    margin-right: -1rem !important;
+    margin-left: -1rem !important;
+  }
+  .mx-lg-n4 {
+    margin-right: -1.5rem !important;
+    margin-left: -1.5rem !important;
+  }
+  .mx-lg-n5 {
+    margin-right: -3rem !important;
+    margin-left: -3rem !important;
+  }
+  .my-lg-n1 {
+    margin-top: -0.25rem !important;
+    margin-bottom: -0.25rem !important;
+  }
+  .my-lg-n2 {
+    margin-top: -0.5rem !important;
+    margin-bottom: -0.5rem !important;
+  }
+  .my-lg-n3 {
+    margin-top: -1rem !important;
+    margin-bottom: -1rem !important;
+  }
+  .my-lg-n4 {
+    margin-top: -1.5rem !important;
+    margin-bottom: -1.5rem !important;
+  }
+  .my-lg-n5 {
+    margin-top: -3rem !important;
+    margin-bottom: -3rem !important;
+  }
+  .mt-lg-n1 {
+    margin-top: -0.25rem !important;
+  }
+  .mt-lg-n2 {
+    margin-top: -0.5rem !important;
+  }
+  .mt-lg-n3 {
+    margin-top: -1rem !important;
+  }
+  .mt-lg-n4 {
+    margin-top: -1.5rem !important;
+  }
+  .mt-lg-n5 {
+    margin-top: -3rem !important;
+  }
+  .me-lg-n1 {
+    margin-right: -0.25rem !important;
+  }
+  .me-lg-n2 {
+    margin-right: -0.5rem !important;
+  }
+  .me-lg-n3 {
+    margin-right: -1rem !important;
+  }
+  .me-lg-n4 {
+    margin-right: -1.5rem !important;
+  }
+  .me-lg-n5 {
+    margin-right: -3rem !important;
+  }
+  .mb-lg-n1 {
+    margin-bottom: -0.25rem !important;
+  }
+  .mb-lg-n2 {
+    margin-bottom: -0.5rem !important;
+  }
+  .mb-lg-n3 {
+    margin-bottom: -1rem !important;
+  }
+  .mb-lg-n4 {
+    margin-bottom: -1.5rem !important;
+  }
+  .mb-lg-n5 {
+    margin-bottom: -3rem !important;
+  }
+  .ms-lg-n1 {
+    margin-left: -0.25rem !important;
+  }
+  .ms-lg-n2 {
+    margin-left: -0.5rem !important;
+  }
+  .ms-lg-n3 {
+    margin-left: -1rem !important;
+  }
+  .ms-lg-n4 {
+    margin-left: -1.5rem !important;
+  }
+  .ms-lg-n5 {
+    margin-left: -3rem !important;
+  }
+  .p-lg-0 {
+    padding: 0 !important;
+  }
+  .p-lg-1 {
+    padding: 0.25rem !important;
+  }
+  .p-lg-2 {
+    padding: 0.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: 0.25rem !important;
+    padding-left: 0.25rem !important;
+  }
+  .px-lg-2 {
+    padding-right: 0.5rem !important;
+    padding-left: 0.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: 0.25rem !important;
+    padding-bottom: 0.25rem !important;
+  }
+  .py-lg-2 {
+    padding-top: 0.5rem !important;
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .pt-lg-2 {
+    padding-top: 0.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: 0.25rem !important;
+  }
+  .pe-lg-2 {
+    padding-right: 0.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: 0.25rem !important;
+  }
+  .pb-lg-2 {
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .ps-lg-2 {
+    padding-left: 0.5rem !important;
+  }
+  .ps-lg-3 {
+    padding-left: 1rem !important;
+  }
+  .ps-lg-4 {
+    padding-left: 1.5rem !important;
+  }
+  .ps-lg-5 {
+    padding-left: 3rem !important;
+  }
+  .gap-lg-0 {
+    gap: 0 !important;
+  }
+  .gap-lg-1 {
+    gap: 0.25rem !important;
+  }
+  .gap-lg-2 {
+    gap: 0.5rem !important;
+  }
+  .gap-lg-3 {
+    gap: 1rem !important;
+  }
+  .gap-lg-4 {
+    gap: 1.5rem !important;
+  }
+  .gap-lg-5 {
+    gap: 3rem !important;
+  }
+  .row-gap-lg-0 {
+    row-gap: 0 !important;
+  }
+  .row-gap-lg-1 {
+    row-gap: 0.25rem !important;
+  }
+  .row-gap-lg-2 {
+    row-gap: 0.5rem !important;
+  }
+  .row-gap-lg-3 {
+    row-gap: 1rem !important;
+  }
+  .row-gap-lg-4 {
+    row-gap: 1.5rem !important;
+  }
+  .row-gap-lg-5 {
+    row-gap: 3rem !important;
+  }
+  .column-gap-lg-0 {
+    -moz-column-gap: 0 !important;
+    column-gap: 0 !important;
+  }
+  .column-gap-lg-1 {
+    -moz-column-gap: 0.25rem !important;
+    column-gap: 0.25rem !important;
+  }
+  .column-gap-lg-2 {
+    -moz-column-gap: 0.5rem !important;
+    column-gap: 0.5rem !important;
+  }
+  .column-gap-lg-3 {
+    -moz-column-gap: 1rem !important;
+    column-gap: 1rem !important;
+  }
+  .column-gap-lg-4 {
+    -moz-column-gap: 1.5rem !important;
+    column-gap: 1.5rem !important;
+  }
+  .column-gap-lg-5 {
+    -moz-column-gap: 3rem !important;
+    column-gap: 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;
+  }
+  .object-fit-xl-contain {
+    -o-object-fit: contain !important;
+    object-fit: contain !important;
+  }
+  .object-fit-xl-cover {
+    -o-object-fit: cover !important;
+    object-fit: cover !important;
+  }
+  .object-fit-xl-fill {
+    -o-object-fit: fill !important;
+    object-fit: fill !important;
+  }
+  .object-fit-xl-scale {
+    -o-object-fit: scale-down !important;
+    object-fit: scale-down !important;
+  }
+  .object-fit-xl-none {
+    -o-object-fit: none !important;
+    object-fit: 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-inline-grid {
+    display: inline-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;
+  }
+  .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: 0.25rem !important;
+  }
+  .m-xl-2 {
+    margin: 0.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: 0.25rem !important;
+    margin-left: 0.25rem !important;
+  }
+  .mx-xl-2 {
+    margin-right: 0.5rem !important;
+    margin-left: 0.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: 0.25rem !important;
+    margin-bottom: 0.25rem !important;
+  }
+  .my-xl-2 {
+    margin-top: 0.5rem !important;
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .mt-xl-2 {
+    margin-top: 0.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: 0.25rem !important;
+  }
+  .me-xl-2 {
+    margin-right: 0.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: 0.25rem !important;
+  }
+  .mb-xl-2 {
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .ms-xl-2 {
+    margin-left: 0.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;
+  }
+  .m-xl-n1 {
+    margin: -0.25rem !important;
+  }
+  .m-xl-n2 {
+    margin: -0.5rem !important;
+  }
+  .m-xl-n3 {
+    margin: -1rem !important;
+  }
+  .m-xl-n4 {
+    margin: -1.5rem !important;
+  }
+  .m-xl-n5 {
+    margin: -3rem !important;
+  }
+  .mx-xl-n1 {
+    margin-right: -0.25rem !important;
+    margin-left: -0.25rem !important;
+  }
+  .mx-xl-n2 {
+    margin-right: -0.5rem !important;
+    margin-left: -0.5rem !important;
+  }
+  .mx-xl-n3 {
+    margin-right: -1rem !important;
+    margin-left: -1rem !important;
+  }
+  .mx-xl-n4 {
+    margin-right: -1.5rem !important;
+    margin-left: -1.5rem !important;
+  }
+  .mx-xl-n5 {
+    margin-right: -3rem !important;
+    margin-left: -3rem !important;
+  }
+  .my-xl-n1 {
+    margin-top: -0.25rem !important;
+    margin-bottom: -0.25rem !important;
+  }
+  .my-xl-n2 {
+    margin-top: -0.5rem !important;
+    margin-bottom: -0.5rem !important;
+  }
+  .my-xl-n3 {
+    margin-top: -1rem !important;
+    margin-bottom: -1rem !important;
+  }
+  .my-xl-n4 {
+    margin-top: -1.5rem !important;
+    margin-bottom: -1.5rem !important;
+  }
+  .my-xl-n5 {
+    margin-top: -3rem !important;
+    margin-bottom: -3rem !important;
+  }
+  .mt-xl-n1 {
+    margin-top: -0.25rem !important;
+  }
+  .mt-xl-n2 {
+    margin-top: -0.5rem !important;
+  }
+  .mt-xl-n3 {
+    margin-top: -1rem !important;
+  }
+  .mt-xl-n4 {
+    margin-top: -1.5rem !important;
+  }
+  .mt-xl-n5 {
+    margin-top: -3rem !important;
+  }
+  .me-xl-n1 {
+    margin-right: -0.25rem !important;
+  }
+  .me-xl-n2 {
+    margin-right: -0.5rem !important;
+  }
+  .me-xl-n3 {
+    margin-right: -1rem !important;
+  }
+  .me-xl-n4 {
+    margin-right: -1.5rem !important;
+  }
+  .me-xl-n5 {
+    margin-right: -3rem !important;
+  }
+  .mb-xl-n1 {
+    margin-bottom: -0.25rem !important;
+  }
+  .mb-xl-n2 {
+    margin-bottom: -0.5rem !important;
+  }
+  .mb-xl-n3 {
+    margin-bottom: -1rem !important;
+  }
+  .mb-xl-n4 {
+    margin-bottom: -1.5rem !important;
+  }
+  .mb-xl-n5 {
+    margin-bottom: -3rem !important;
+  }
+  .ms-xl-n1 {
+    margin-left: -0.25rem !important;
+  }
+  .ms-xl-n2 {
+    margin-left: -0.5rem !important;
+  }
+  .ms-xl-n3 {
+    margin-left: -1rem !important;
+  }
+  .ms-xl-n4 {
+    margin-left: -1.5rem !important;
+  }
+  .ms-xl-n5 {
+    margin-left: -3rem !important;
+  }
+  .p-xl-0 {
+    padding: 0 !important;
+  }
+  .p-xl-1 {
+    padding: 0.25rem !important;
+  }
+  .p-xl-2 {
+    padding: 0.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: 0.25rem !important;
+    padding-left: 0.25rem !important;
+  }
+  .px-xl-2 {
+    padding-right: 0.5rem !important;
+    padding-left: 0.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: 0.25rem !important;
+    padding-bottom: 0.25rem !important;
+  }
+  .py-xl-2 {
+    padding-top: 0.5rem !important;
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .pt-xl-2 {
+    padding-top: 0.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: 0.25rem !important;
+  }
+  .pe-xl-2 {
+    padding-right: 0.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: 0.25rem !important;
+  }
+  .pb-xl-2 {
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .ps-xl-2 {
+    padding-left: 0.5rem !important;
+  }
+  .ps-xl-3 {
+    padding-left: 1rem !important;
+  }
+  .ps-xl-4 {
+    padding-left: 1.5rem !important;
+  }
+  .ps-xl-5 {
+    padding-left: 3rem !important;
+  }
+  .gap-xl-0 {
+    gap: 0 !important;
+  }
+  .gap-xl-1 {
+    gap: 0.25rem !important;
+  }
+  .gap-xl-2 {
+    gap: 0.5rem !important;
+  }
+  .gap-xl-3 {
+    gap: 1rem !important;
+  }
+  .gap-xl-4 {
+    gap: 1.5rem !important;
+  }
+  .gap-xl-5 {
+    gap: 3rem !important;
+  }
+  .row-gap-xl-0 {
+    row-gap: 0 !important;
+  }
+  .row-gap-xl-1 {
+    row-gap: 0.25rem !important;
+  }
+  .row-gap-xl-2 {
+    row-gap: 0.5rem !important;
+  }
+  .row-gap-xl-3 {
+    row-gap: 1rem !important;
+  }
+  .row-gap-xl-4 {
+    row-gap: 1.5rem !important;
+  }
+  .row-gap-xl-5 {
+    row-gap: 3rem !important;
+  }
+  .column-gap-xl-0 {
+    -moz-column-gap: 0 !important;
+    column-gap: 0 !important;
+  }
+  .column-gap-xl-1 {
+    -moz-column-gap: 0.25rem !important;
+    column-gap: 0.25rem !important;
+  }
+  .column-gap-xl-2 {
+    -moz-column-gap: 0.5rem !important;
+    column-gap: 0.5rem !important;
+  }
+  .column-gap-xl-3 {
+    -moz-column-gap: 1rem !important;
+    column-gap: 1rem !important;
+  }
+  .column-gap-xl-4 {
+    -moz-column-gap: 1.5rem !important;
+    column-gap: 1.5rem !important;
+  }
+  .column-gap-xl-5 {
+    -moz-column-gap: 3rem !important;
+    column-gap: 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;
+  }
+  .object-fit-xxl-contain {
+    -o-object-fit: contain !important;
+    object-fit: contain !important;
+  }
+  .object-fit-xxl-cover {
+    -o-object-fit: cover !important;
+    object-fit: cover !important;
+  }
+  .object-fit-xxl-fill {
+    -o-object-fit: fill !important;
+    object-fit: fill !important;
+  }
+  .object-fit-xxl-scale {
+    -o-object-fit: scale-down !important;
+    object-fit: scale-down !important;
+  }
+  .object-fit-xxl-none {
+    -o-object-fit: none !important;
+    object-fit: 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-inline-grid {
+    display: inline-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;
+  }
+  .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: 0.25rem !important;
+  }
+  .m-xxl-2 {
+    margin: 0.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: 0.25rem !important;
+    margin-left: 0.25rem !important;
+  }
+  .mx-xxl-2 {
+    margin-right: 0.5rem !important;
+    margin-left: 0.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: 0.25rem !important;
+    margin-bottom: 0.25rem !important;
+  }
+  .my-xxl-2 {
+    margin-top: 0.5rem !important;
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .mt-xxl-2 {
+    margin-top: 0.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: 0.25rem !important;
+  }
+  .me-xxl-2 {
+    margin-right: 0.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: 0.25rem !important;
+  }
+  .mb-xxl-2 {
+    margin-bottom: 0.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: 0.25rem !important;
+  }
+  .ms-xxl-2 {
+    margin-left: 0.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;
+  }
+  .m-xxl-n1 {
+    margin: -0.25rem !important;
+  }
+  .m-xxl-n2 {
+    margin: -0.5rem !important;
+  }
+  .m-xxl-n3 {
+    margin: -1rem !important;
+  }
+  .m-xxl-n4 {
+    margin: -1.5rem !important;
+  }
+  .m-xxl-n5 {
+    margin: -3rem !important;
+  }
+  .mx-xxl-n1 {
+    margin-right: -0.25rem !important;
+    margin-left: -0.25rem !important;
+  }
+  .mx-xxl-n2 {
+    margin-right: -0.5rem !important;
+    margin-left: -0.5rem !important;
+  }
+  .mx-xxl-n3 {
+    margin-right: -1rem !important;
+    margin-left: -1rem !important;
+  }
+  .mx-xxl-n4 {
+    margin-right: -1.5rem !important;
+    margin-left: -1.5rem !important;
+  }
+  .mx-xxl-n5 {
+    margin-right: -3rem !important;
+    margin-left: -3rem !important;
+  }
+  .my-xxl-n1 {
+    margin-top: -0.25rem !important;
+    margin-bottom: -0.25rem !important;
+  }
+  .my-xxl-n2 {
+    margin-top: -0.5rem !important;
+    margin-bottom: -0.5rem !important;
+  }
+  .my-xxl-n3 {
+    margin-top: -1rem !important;
+    margin-bottom: -1rem !important;
+  }
+  .my-xxl-n4 {
+    margin-top: -1.5rem !important;
+    margin-bottom: -1.5rem !important;
+  }
+  .my-xxl-n5 {
+    margin-top: -3rem !important;
+    margin-bottom: -3rem !important;
+  }
+  .mt-xxl-n1 {
+    margin-top: -0.25rem !important;
+  }
+  .mt-xxl-n2 {
+    margin-top: -0.5rem !important;
+  }
+  .mt-xxl-n3 {
+    margin-top: -1rem !important;
+  }
+  .mt-xxl-n4 {
+    margin-top: -1.5rem !important;
+  }
+  .mt-xxl-n5 {
+    margin-top: -3rem !important;
+  }
+  .me-xxl-n1 {
+    margin-right: -0.25rem !important;
+  }
+  .me-xxl-n2 {
+    margin-right: -0.5rem !important;
+  }
+  .me-xxl-n3 {
+    margin-right: -1rem !important;
+  }
+  .me-xxl-n4 {
+    margin-right: -1.5rem !important;
+  }
+  .me-xxl-n5 {
+    margin-right: -3rem !important;
+  }
+  .mb-xxl-n1 {
+    margin-bottom: -0.25rem !important;
+  }
+  .mb-xxl-n2 {
+    margin-bottom: -0.5rem !important;
+  }
+  .mb-xxl-n3 {
+    margin-bottom: -1rem !important;
+  }
+  .mb-xxl-n4 {
+    margin-bottom: -1.5rem !important;
+  }
+  .mb-xxl-n5 {
+    margin-bottom: -3rem !important;
+  }
+  .ms-xxl-n1 {
+    margin-left: -0.25rem !important;
+  }
+  .ms-xxl-n2 {
+    margin-left: -0.5rem !important;
+  }
+  .ms-xxl-n3 {
+    margin-left: -1rem !important;
+  }
+  .ms-xxl-n4 {
+    margin-left: -1.5rem !important;
+  }
+  .ms-xxl-n5 {
+    margin-left: -3rem !important;
+  }
+  .p-xxl-0 {
+    padding: 0 !important;
+  }
+  .p-xxl-1 {
+    padding: 0.25rem !important;
+  }
+  .p-xxl-2 {
+    padding: 0.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: 0.25rem !important;
+    padding-left: 0.25rem !important;
+  }
+  .px-xxl-2 {
+    padding-right: 0.5rem !important;
+    padding-left: 0.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: 0.25rem !important;
+    padding-bottom: 0.25rem !important;
+  }
+  .py-xxl-2 {
+    padding-top: 0.5rem !important;
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .pt-xxl-2 {
+    padding-top: 0.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: 0.25rem !important;
+  }
+  .pe-xxl-2 {
+    padding-right: 0.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: 0.25rem !important;
+  }
+  .pb-xxl-2 {
+    padding-bottom: 0.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: 0.25rem !important;
+  }
+  .ps-xxl-2 {
+    padding-left: 0.5rem !important;
+  }
+  .ps-xxl-3 {
+    padding-left: 1rem !important;
+  }
+  .ps-xxl-4 {
+    padding-left: 1.5rem !important;
+  }
+  .ps-xxl-5 {
+    padding-left: 3rem !important;
+  }
+  .gap-xxl-0 {
+    gap: 0 !important;
+  }
+  .gap-xxl-1 {
+    gap: 0.25rem !important;
+  }
+  .gap-xxl-2 {
+    gap: 0.5rem !important;
+  }
+  .gap-xxl-3 {
+    gap: 1rem !important;
+  }
+  .gap-xxl-4 {
+    gap: 1.5rem !important;
+  }
+  .gap-xxl-5 {
+    gap: 3rem !important;
+  }
+  .row-gap-xxl-0 {
+    row-gap: 0 !important;
+  }
+  .row-gap-xxl-1 {
+    row-gap: 0.25rem !important;
+  }
+  .row-gap-xxl-2 {
+    row-gap: 0.5rem !important;
+  }
+  .row-gap-xxl-3 {
+    row-gap: 1rem !important;
+  }
+  .row-gap-xxl-4 {
+    row-gap: 1.5rem !important;
+  }
+  .row-gap-xxl-5 {
+    row-gap: 3rem !important;
+  }
+  .column-gap-xxl-0 {
+    -moz-column-gap: 0 !important;
+    column-gap: 0 !important;
+  }
+  .column-gap-xxl-1 {
+    -moz-column-gap: 0.25rem !important;
+    column-gap: 0.25rem !important;
+  }
+  .column-gap-xxl-2 {
+    -moz-column-gap: 0.5rem !important;
+    column-gap: 0.5rem !important;
+  }
+  .column-gap-xxl-3 {
+    -moz-column-gap: 1rem !important;
+    column-gap: 1rem !important;
+  }
+  .column-gap-xxl-4 {
+    -moz-column-gap: 1.5rem !important;
+    column-gap: 1.5rem !important;
+  }
+  .column-gap-xxl-5 {
+    -moz-column-gap: 3rem !important;
+    column-gap: 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-inline-grid {
+    display: inline-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;
+  }
+}
+@keyframes flipInX {
+  0% {
+    opacity: 0;
+    transition-timing-function: ease-in;
+    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+  }
+  40% {
+    transition-timing-function: ease-in;
+    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+  }
+  60% {
+    opacity: 1;
+    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+  }
+  80% {
+    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+  }
+  100% {
+    transform: perspective(400px);
+  }
+}
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@keyframes fadeOut {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes shake {
+  0% {
+    transform: translate(2px, 1px) rotate(0deg);
+  }
+  10% {
+    transform: translate(-1px, -2px) rotate(-2deg);
+  }
+  20% {
+    transform: translate(-3px, 0) rotate(3deg);
+  }
+  30% {
+    transform: translate(0, 2px) rotate(0deg);
+  }
+  40% {
+    transform: translate(1px, -1px) rotate(1deg);
+  }
+  50% {
+    transform: translate(-1px, 2px) rotate(-1deg);
+  }
+  60% {
+    transform: translate(-3px, 1px) rotate(0deg);
+  }
+  70% {
+    transform: translate(2px, 1px) rotate(-2deg);
+  }
+  80% {
+    transform: translate(-1px, -1px) rotate(4deg);
+  }
+  90% {
+    transform: translate(2px, 2px) rotate(0deg);
+  }
+  100% {
+    transform: translate(1px, -2px) rotate(-1deg);
+  }
+}
+@keyframes wobble {
+  0% {
+    transform: none;
+  }
+  15% {
+    transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+  }
+  30% {
+    transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+  }
+  45% {
+    transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+  }
+  60% {
+    transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+  }
+  75% {
+    transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+  }
+  100% {
+    transform: none;
+  }
+}
+:root,
+[data-bs-theme=light] {
+  --lte-sidebar-width: 250px;
+}
+
+.app-wrapper {
+  position: relative;
+  display: grid;
+  grid-template-areas: "lte-app-sidebar lte-app-header" "lte-app-sidebar lte-app-main" "lte-app-sidebar lte-app-footer";
+  grid-template-rows: -webkit-min-content 1fr -webkit-min-content;
+  grid-template-rows: min-content 1fr min-content;
+  grid-template-columns: auto 1fr;
+  grid-gap: 0;
+  align-content: stretch;
+  align-items: stretch;
+  max-width: 100vw;
+  min-height: 100vh;
+}
+.app-wrapper > * {
+  min-width: 0;
+}
+
+.app-content {
+  padding: 0 0.5rem;
+}
+
+.app-header {
+  z-index: 1034;
+  grid-area: lte-app-header;
+  max-width: 100vw;
+  border-bottom: 1px solid var(--bs-border-color);
+  transition: 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .app-header {
+    transition: none;
+  }
+}
+.app-header .nav-link {
+  position: relative;
+  height: 2.5rem;
+}
+
+.navbar-badge {
+  position: absolute;
+  top: 9px;
+  right: 5px;
+  padding: 2px 4px;
+  font-size: 0.6rem;
+  font-weight: 400;
+}
+
+.app-sidebar {
+  --lte-sidebar-hover-bg: rgba(0, 0, 0, 0.1);
+  --lte-sidebar-color: #343a40;
+  --lte-sidebar-hover-color: #212529;
+  --lte-sidebar-active-color: #000;
+  --lte-sidebar-menu-active-bg: rgba(0, 0, 0, 0.1);
+  --lte-sidebar-menu-active-color: #000;
+  --lte-sidebar-submenu-bg: transparent;
+  --lte-sidebar-submenu-color: #777;
+  --lte-sidebar-submenu-hover-color: #000;
+  --lte-sidebar-submenu-hover-bg: rgba(0, 0, 0, 0.1);
+  --lte-sidebar-submenu-active-color: #212529;
+  --lte-sidebar-submenu-active-bg: rgba(0, 0, 0, 0.1);
+  --lte-sidebar-header-color: #31373d;
+  z-index: 1038;
+  grid-area: lte-app-sidebar;
+  min-width: var(--lte-sidebar-width);
+  max-width: var(--lte-sidebar-width);
+  transition: min-width 0.3s ease-in-out, max-width 0.3s ease-in-out, margin-left 0.3s ease-in-out, margin-right 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .app-sidebar {
+    transition: none;
+  }
+}
+
+.sidebar-brand {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 3.55rem;
+  padding: 0.8125rem 0.5rem;
+  overflow: hidden;
+  font-size: 1.25rem;
+  white-space: nowrap;
+  border-bottom: 1px solid var(--bs-border-color);
+  transition: width 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .sidebar-brand {
+    transition: none;
+  }
+}
+.sidebar-brand .brand-link {
+  display: flex;
+  align-items: center;
+  text-decoration: none;
+}
+.sidebar-brand .brand-link .brand-image {
+  float: left;
+  width: auto;
+  max-height: 33px;
+  line-height: 0.8;
+}
+.sidebar-brand .brand-link .brand-image-xs {
+  float: left;
+  width: auto;
+  max-height: 33px;
+  margin-top: -0.1rem;
+  line-height: 0.8;
+}
+.sidebar-brand .brand-link .brand-image-xl {
+  width: auto;
+  max-height: 40px;
+  line-height: 0.8;
+}
+.sidebar-brand .brand-link .brand-image-xl.single {
+  margin-top: -0.3rem;
+}
+.sidebar-brand .brand-text {
+  margin-left: 0.5rem;
+  color: rgba(var(--bs-emphasis-color-rgb), 0.8);
+  transition: flex 0.3s ease-in-out, width 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .sidebar-brand .brand-text {
+    transition: none;
+  }
+}
+.sidebar-brand .brand-text:hover {
+  color: var(--bs-emphasis-color);
+}
+
+.sidebar-wrapper {
+  padding-top: 0.5rem;
+  padding-right: 0.5rem;
+  padding-bottom: 0.5rem;
+  padding-left: 0.5rem;
+  scrollbar-color: var(--bs-secondary-bg) transparent;
+  scrollbar-width: thin;
+}
+.sidebar-wrapper::-webkit-scrollbar-thumb {
+  background-color: var(--bs-secondary-bg);
+}
+.sidebar-wrapper::-webkit-scrollbar-track {
+  background-color: transparent;
+}
+.sidebar-wrapper::-webkit-scrollbar-corner {
+  background-color: transparent;
+}
+.sidebar-wrapper::-webkit-scrollbar {
+  width: 0.5rem;
+  height: 0.5rem;
+}
+.sidebar-wrapper .nav-item {
+  max-width: 100%;
+}
+.sidebar-wrapper .nav-link {
+  display: flex;
+  justify-content: flex-start;
+}
+.sidebar-wrapper .nav-link p {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.sidebar-wrapper .nav-icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  min-width: 1.5rem;
+  max-width: 1.5rem;
+}
+.sidebar-wrapper .sidebar-menu > .nav-item.menu-open .nav-link.active:not(:hover) {
+  --lte-sidebar-menu-active-bg: transparent;
+}
+.sidebar-wrapper .sidebar-menu > .nav-item > .nav-link:active, .sidebar-wrapper .sidebar-menu > .nav-item > .nav-link:focus {
+  color: var(--lte-sidebar-color);
+}
+.sidebar-wrapper .sidebar-menu > .nav-item > .nav-link.active:not(:hover) {
+  color: var(--lte-sidebar-menu-active-color);
+  background-color: var(--lte-sidebar-menu-active-bg);
+}
+.sidebar-wrapper .sidebar-menu > .nav-item.menu-open > .nav-link, .sidebar-wrapper .sidebar-menu > .nav-item:hover > .nav-link,
+.sidebar-wrapper .sidebar-menu > .nav-item > .nav-link:focus {
+  color: var(--lte-sidebar-hover-color);
+  background-color: var(--lte-sidebar-hover-bg);
+}
+.sidebar-wrapper .sidebar-menu > .nav-item > .nav-treeview {
+  background-color: var(--lte-sidebar-submenu-bg);
+}
+.sidebar-wrapper .nav-header {
+  color: var(--lte-sidebar-header-color);
+  background-color: inherit;
+}
+.sidebar-wrapper a {
+  color: var(--lte-sidebar-color);
+}
+.sidebar-wrapper .nav-treeview > .nav-item > .nav-link {
+  color: var(--lte-sidebar-submenu-color);
+}
+.sidebar-wrapper .nav-treeview > .nav-item > .nav-link:hover, .sidebar-wrapper .nav-treeview > .nav-item > .nav-link:focus {
+  color: var(--lte-sidebar-submenu-hover-color);
+}
+.sidebar-wrapper .nav-treeview > .nav-item > .nav-link.active, .sidebar-wrapper .nav-treeview > .nav-item > .nav-link.active:hover, .sidebar-wrapper .nav-treeview > .nav-item > .nav-link.active:focus {
+  color: var(--lte-sidebar-submenu-active-color);
+  background-color: var(--lte-sidebar-submenu-active-bg);
+}
+.sidebar-wrapper .nav-treeview > .nav-item > .nav-link:hover {
+  background-color: var(--lte-sidebar-submenu-hover-bg);
+}
+
+.sidebar-menu .nav-item > .nav-link {
+  margin-bottom: 0.2rem;
+}
+.sidebar-menu .nav-item > .nav-link .nav-arrow {
+  transition: transform ease-in-out 0.3s;
+  transform: translateY(-50%) /*rtl:append:rotate(180deg)*/;
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+@media (prefers-reduced-motion: reduce) {
+  .sidebar-menu .nav-item > .nav-link .nav-arrow {
+    transition: none;
+  }
+}
+.sidebar-menu .nav-link > .nav-badge,
+.sidebar-menu .nav-link > p > .nav-badge {
+  position: absolute;
+  right: 1rem;
+}
+.sidebar-menu .nav-link > .nav-arrow,
+.sidebar-menu .nav-link > p > .nav-arrow {
+  position: absolute;
+  top: 50%;
+  right: 1rem;
+}
+.sidebar-menu .nav-link {
+  position: relative;
+  transition: width ease-in-out 0.3s;
+  border-radius: 0.375rem;
+}
+@media (prefers-reduced-motion: reduce) {
+  .sidebar-menu .nav-link {
+    transition: none;
+  }
+}
+.sidebar-menu .nav-link p {
+  display: inline;
+  padding-left: 0.5rem;
+  margin: 0;
+}
+.sidebar-menu .nav-header {
+  padding: 0.5rem 0.75rem;
+  font-size: 0.9rem;
+}
+.sidebar-menu .nav-treeview {
+  display: none;
+  padding: 0;
+  list-style: none;
+}
+.nav-indent .sidebar-menu .nav-treeview {
+  padding-left: 0.5rem;
+}
+.sidebar-menu .menu-open > .nav-treeview {
+  display: block;
+}
+.sidebar-menu .menu-open > .nav-link .nav-arrow {
+  transform: translateY(-50%) rotate(90deg) /*rtl:ignore*/;
+}
+
+.nav-compact.nav-indent .nav-treeview {
+  padding-left: 0;
+}
+.nav-compact.nav-indent .nav-treeview .nav-item {
+  padding-left: 0.5rem;
+}
+
+.sidebar-mini.sidebar-collapse.nav-indent .app-sidebar:hover .nav-treeview {
+  padding-left: 0;
+}
+.sidebar-mini.sidebar-collapse.nav-indent .app-sidebar:hover .nav-treeview .nav-item {
+  padding-left: 0.5rem;
+}
+
+.sidebar-collapse.nav-compact.nav-indent .nav-treeview .nav-item {
+  padding-left: 0;
+}
+
+.nav-compact .nav-link {
+  border-radius: 0;
+  margin-bottom: 0 !important;
+}
+
+.sidebar-menu,
+.sidebar-menu > .nav-header,
+.sidebar-menu .nav-link {
+  white-space: nowrap;
+}
+
+.logo-xs,
+.logo-xl {
+  position: absolute;
+  visibility: visible;
+  opacity: 1;
+}
+.logo-xs.brand-image-xs,
+.logo-xl.brand-image-xs {
+  top: 12px;
+  left: 18px;
+}
+.logo-xs.brand-image-xl,
+.logo-xl.brand-image-xl {
+  top: 6px;
+  left: 12px;
+}
+
+.logo-xs {
+  visibility: hidden;
+  opacity: 0;
+}
+.logo-xs.brand-image-xl {
+  top: 8px;
+  left: 16px;
+}
+
+.brand-link.logo-switch::before {
+  content: " ";
+}
+
+.sidebar-mini.sidebar-collapse .app-sidebar {
+  min-width: 4.6rem;
+  max-width: 4.6rem;
+}
+.sidebar-mini.sidebar-collapse .sidebar-menu .nav-header {
+  display: none;
+}
+.sidebar-mini.sidebar-collapse .sidebar-menu .nav-link {
+  width: 3.6rem;
+}
+.sidebar-mini.sidebar-collapse .sidebar-menu .nav-link p {
+  display: inline-block;
+  width: 0;
+  white-space: nowrap;
+}
+.sidebar-mini.sidebar-collapse .sidebar-menu .nav-badge,
+.sidebar-mini.sidebar-collapse .sidebar-menu .nav-arrow {
+  display: none;
+  animation-name: fadeOut;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+.sidebar-mini.sidebar-collapse .brand-text {
+  display: inline-block;
+  max-width: 0;
+  overflow: hidden;
+}
+.sidebar-mini.sidebar-collapse .sidebar-menu .nav-link p,
+.sidebar-mini.sidebar-collapse .brand-text,
+.sidebar-mini.sidebar-collapse .logo-xl,
+.sidebar-mini.sidebar-collapse .nav-arrow {
+  visibility: hidden;
+  animation-name: fadeOut;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+.sidebar-mini.sidebar-collapse .logo-xs {
+  display: inline-block;
+  visibility: visible;
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover {
+  min-width: var(--lte-sidebar-width);
+  max-width: var(--lte-sidebar-width);
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .sidebar-menu .nav-header {
+  display: inline-block;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .sidebar-menu .nav-link {
+  width: auto;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .sidebar-menu .nav-link p,
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .brand-text,
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .logo-xl {
+  width: auto;
+  margin-left: 0;
+  visibility: visible;
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .brand-text {
+  display: inline;
+  max-width: inherit;
+  margin-left: 0.5rem;
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .nav-badge,
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .nav-arrow {
+  display: inline-block;
+  visibility: visible;
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+  animation-delay: 0.3s;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .nav-link p {
+  padding-left: 0.5rem;
+}
+.sidebar-mini.sidebar-collapse .app-sidebar:hover .logo-xs {
+  visibility: hidden;
+  animation-name: fadeOut;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+}
+
+.sidebar-collapse:not(.sidebar-mini) .app-sidebar {
+  margin-left: calc(var(--lte-sidebar-width) * -1);
+}
+
+.sidebar-expand {
+  /* stylelint-disable-next-line scss/selector-no-union-class-name */
+  /* stylelint-disable-next-line scss/selector-no-union-class-name */
+  /* stylelint-disable-next-line scss/selector-no-union-class-name */
+  /* stylelint-disable-next-line scss/selector-no-union-class-name */
+  /* stylelint-disable-next-line scss/selector-no-union-class-name */
+  /* stylelint-disable-next-line scss/selector-no-union-class-name */
+}
+@media (min-width: 576px) {
+  .sidebar-expand-sm.layout-fixed .app-main-wrapper {
+    display: flex;
+    flex-direction: column;
+    min-height: 100vh;
+  }
+  .sidebar-expand-sm.layout-fixed .app-sidebar-wrapper {
+    position: relative;
+  }
+  .sidebar-expand-sm.layout-fixed .app-main {
+    flex: 1 1 auto;
+    overflow: auto;
+  }
+  .sidebar-expand-sm.layout-fixed .app-sidebar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+  }
+  .sidebar-expand-sm.layout-fixed .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-sm.sidebar-open .nav-link > .nav-badge,
+  .sidebar-expand-sm.sidebar-open .nav-link > p > .nav-badge {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+  .sidebar-expand-sm.sidebar-open .nav-link > .nav-arrow,
+  .sidebar-expand-sm.sidebar-open .nav-link > p > .nav-arrow {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+}
+@media (max-width: 575.98px) {
+  .sidebar-expand-sm::before {
+    display: none;
+    content: "575.98px";
+  }
+  .sidebar-expand-sm .app-sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+    margin-left: calc(var(--lte-sidebar-width) * -1);
+  }
+  .sidebar-expand-sm .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-sm.sidebar-open .app-sidebar {
+    margin-left: 0;
+  }
+  .sidebar-expand-sm.sidebar-open .sidebar-overlay {
+    position: absolute;
+    inset: 0;
+    z-index: 1037;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    visibility: visible;
+    background-color: rgba(0, 0, 0, 0.2);
+    animation-name: fadeIn;
+    animation-fill-mode: both;
+  }
+}
+@media (min-width: 768px) {
+  .sidebar-expand-md.layout-fixed .app-main-wrapper {
+    display: flex;
+    flex-direction: column;
+    min-height: 100vh;
+  }
+  .sidebar-expand-md.layout-fixed .app-sidebar-wrapper {
+    position: relative;
+  }
+  .sidebar-expand-md.layout-fixed .app-main {
+    flex: 1 1 auto;
+    overflow: auto;
+  }
+  .sidebar-expand-md.layout-fixed .app-sidebar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+  }
+  .sidebar-expand-md.layout-fixed .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-md.sidebar-open .nav-link > .nav-badge,
+  .sidebar-expand-md.sidebar-open .nav-link > p > .nav-badge {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+  .sidebar-expand-md.sidebar-open .nav-link > .nav-arrow,
+  .sidebar-expand-md.sidebar-open .nav-link > p > .nav-arrow {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+}
+@media (max-width: 767.98px) {
+  .sidebar-expand-md::before {
+    display: none;
+    content: "767.98px";
+  }
+  .sidebar-expand-md .app-sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+    margin-left: calc(var(--lte-sidebar-width) * -1);
+  }
+  .sidebar-expand-md .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-md.sidebar-open .app-sidebar {
+    margin-left: 0;
+  }
+  .sidebar-expand-md.sidebar-open .sidebar-overlay {
+    position: absolute;
+    inset: 0;
+    z-index: 1037;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    visibility: visible;
+    background-color: rgba(0, 0, 0, 0.2);
+    animation-name: fadeIn;
+    animation-fill-mode: both;
+  }
+}
+@media (min-width: 992px) {
+  .sidebar-expand-lg.layout-fixed .app-main-wrapper {
+    display: flex;
+    flex-direction: column;
+    min-height: 100vh;
+  }
+  .sidebar-expand-lg.layout-fixed .app-sidebar-wrapper {
+    position: relative;
+  }
+  .sidebar-expand-lg.layout-fixed .app-main {
+    flex: 1 1 auto;
+    overflow: auto;
+  }
+  .sidebar-expand-lg.layout-fixed .app-sidebar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+  }
+  .sidebar-expand-lg.layout-fixed .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-lg.sidebar-open .nav-link > .nav-badge,
+  .sidebar-expand-lg.sidebar-open .nav-link > p > .nav-badge {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+  .sidebar-expand-lg.sidebar-open .nav-link > .nav-arrow,
+  .sidebar-expand-lg.sidebar-open .nav-link > p > .nav-arrow {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+}
+@media (max-width: 991.98px) {
+  .sidebar-expand-lg::before {
+    display: none;
+    content: "991.98px";
+  }
+  .sidebar-expand-lg .app-sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+    margin-left: calc(var(--lte-sidebar-width) * -1);
+  }
+  .sidebar-expand-lg .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-lg.sidebar-open .app-sidebar {
+    margin-left: 0;
+  }
+  .sidebar-expand-lg.sidebar-open .sidebar-overlay {
+    position: absolute;
+    inset: 0;
+    z-index: 1037;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    visibility: visible;
+    background-color: rgba(0, 0, 0, 0.2);
+    animation-name: fadeIn;
+    animation-fill-mode: both;
+  }
+}
+@media (min-width: 1200px) {
+  .sidebar-expand-xl.layout-fixed .app-main-wrapper {
+    display: flex;
+    flex-direction: column;
+    min-height: 100vh;
+  }
+  .sidebar-expand-xl.layout-fixed .app-sidebar-wrapper {
+    position: relative;
+  }
+  .sidebar-expand-xl.layout-fixed .app-main {
+    flex: 1 1 auto;
+    overflow: auto;
+  }
+  .sidebar-expand-xl.layout-fixed .app-sidebar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+  }
+  .sidebar-expand-xl.layout-fixed .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-xl.sidebar-open .nav-link > .nav-badge,
+  .sidebar-expand-xl.sidebar-open .nav-link > p > .nav-badge {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+  .sidebar-expand-xl.sidebar-open .nav-link > .nav-arrow,
+  .sidebar-expand-xl.sidebar-open .nav-link > p > .nav-arrow {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+}
+@media (max-width: 1199.98px) {
+  .sidebar-expand-xl::before {
+    display: none;
+    content: "1199.98px";
+  }
+  .sidebar-expand-xl .app-sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+    margin-left: calc(var(--lte-sidebar-width) * -1);
+  }
+  .sidebar-expand-xl .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-xl.sidebar-open .app-sidebar {
+    margin-left: 0;
+  }
+  .sidebar-expand-xl.sidebar-open .sidebar-overlay {
+    position: absolute;
+    inset: 0;
+    z-index: 1037;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    visibility: visible;
+    background-color: rgba(0, 0, 0, 0.2);
+    animation-name: fadeIn;
+    animation-fill-mode: both;
+  }
+}
+@media (min-width: 1400px) {
+  .sidebar-expand-xxl.layout-fixed .app-main-wrapper {
+    display: flex;
+    flex-direction: column;
+    min-height: 100vh;
+  }
+  .sidebar-expand-xxl.layout-fixed .app-sidebar-wrapper {
+    position: relative;
+  }
+  .sidebar-expand-xxl.layout-fixed .app-main {
+    flex: 1 1 auto;
+    overflow: auto;
+  }
+  .sidebar-expand-xxl.layout-fixed .app-sidebar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+  }
+  .sidebar-expand-xxl.layout-fixed .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-xxl.sidebar-open .nav-link > .nav-badge,
+  .sidebar-expand-xxl.sidebar-open .nav-link > p > .nav-badge {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+  .sidebar-expand-xxl.sidebar-open .nav-link > .nav-arrow,
+  .sidebar-expand-xxl.sidebar-open .nav-link > p > .nav-arrow {
+    animation-name: fadeIn;
+    animation-duration: 0.3s;
+    animation-fill-mode: both;
+    animation-delay: 0.3s;
+  }
+}
+@media (max-width: 1399.98px) {
+  .sidebar-expand-xxl::before {
+    display: none;
+    content: "1399.98px";
+  }
+  .sidebar-expand-xxl .app-sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    max-height: 100vh;
+    margin-left: calc(var(--lte-sidebar-width) * -1);
+  }
+  .sidebar-expand-xxl .app-sidebar .sidebar-wrapper {
+    height: calc(100vh - (calc(3.5rem + 1px)));
+  }
+  .sidebar-expand-xxl.sidebar-open .app-sidebar {
+    margin-left: 0;
+  }
+  .sidebar-expand-xxl.sidebar-open .sidebar-overlay {
+    position: absolute;
+    inset: 0;
+    z-index: 1037;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    visibility: visible;
+    background-color: rgba(0, 0, 0, 0.2);
+    animation-name: fadeIn;
+    animation-fill-mode: both;
+  }
+}
+.sidebar-expand.layout-fixed .app-main-wrapper {
+  display: flex;
+  flex-direction: column;
+  min-height: 100vh;
+}
+.sidebar-expand.layout-fixed .app-sidebar-wrapper {
+  position: relative;
+}
+.sidebar-expand.layout-fixed .app-main {
+  flex: 1 1 auto;
+  overflow: auto;
+}
+.sidebar-expand.layout-fixed .app-sidebar {
+  position: -webkit-sticky;
+  position: sticky;
+  top: 0;
+  bottom: 0;
+  max-height: 100vh;
+}
+.sidebar-expand.layout-fixed .app-sidebar .sidebar-wrapper {
+  height: calc(100vh - (calc(3.5rem + 1px)));
+}
+.sidebar-expand.sidebar-open .nav-link > .nav-badge,
+.sidebar-expand.sidebar-open .nav-link > p > .nav-badge {
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+  animation-delay: 0.3s;
+}
+.sidebar-expand.sidebar-open .nav-link > .nav-arrow,
+.sidebar-expand.sidebar-open .nav-link > p > .nav-arrow {
+  animation-name: fadeIn;
+  animation-duration: 0.3s;
+  animation-fill-mode: both;
+  animation-delay: 0.3s;
+}
+.sidebar-expand::before {
+  display: none;
+  content: "";
+}
+.sidebar-expand .app-sidebar {
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  max-height: 100vh;
+  margin-left: calc(var(--lte-sidebar-width) * -1);
+}
+.sidebar-expand .app-sidebar .sidebar-wrapper {
+  height: calc(100vh - (calc(3.5rem + 1px)));
+}
+.sidebar-expand.sidebar-open .app-sidebar {
+  margin-left: 0;
+}
+.sidebar-expand.sidebar-open .sidebar-overlay {
+  position: absolute;
+  inset: 0;
+  z-index: 1037;
+  width: 100%;
+  height: 100%;
+  cursor: pointer;
+  visibility: visible;
+  background-color: rgba(0, 0, 0, 0.2);
+  animation-name: fadeIn;
+  animation-fill-mode: both;
+}
+
+.sidebar-menu .nav-link p,
+.app-sidebar .brand-text,
+.app-sidebar .logo-xs,
+.app-sidebar .logo-xl {
+  transition: margin-left 0.3s linear, opacity 0.3s ease, visibility 0.3s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+  .sidebar-menu .nav-link p,
+  .app-sidebar .brand-text,
+  .app-sidebar .logo-xs,
+  .app-sidebar .logo-xl {
+    transition: none;
+  }
+}
+
+.app-loaded.sidebar-mini.sidebar-collapse .sidebar-menu .nav-link p,
+.app-loaded.sidebar-mini.sidebar-collapse .brand-text {
+  animation-duration: 0.3s;
+}
+
+body:not(.app-loaded) .app-header,
+body:not(.app-loaded) .app-sidebar,
+body:not(.app-loaded) .app-main,
+body:not(.app-loaded) .app-footer {
+  transition: none !important;
+  animation-duration: 0s !important;
+}
+@media (prefers-reduced-motion: reduce) {
+  body:not(.app-loaded) .app-header,
+  body:not(.app-loaded) .app-sidebar,
+  body:not(.app-loaded) .app-main,
+  body:not(.app-loaded) .app-footer {
+    transition: none;
+  }
+}
+
+.hold-transition .app-header,
+.hold-transition .app-sidebar,
+.hold-transition .app-main,
+.hold-transition .app-footer,
+.hold-transition .nav-arrow,
+.hold-transition .nav-badge {
+  transition: none !important;
+  animation-duration: 0s !important;
+}
+@media (prefers-reduced-motion: reduce) {
+  .hold-transition .app-header,
+  .hold-transition .app-sidebar,
+  .hold-transition .app-main,
+  .hold-transition .app-footer,
+  .hold-transition .nav-arrow,
+  .hold-transition .nav-badge {
+    transition: none;
+  }
+}
+
+[data-bs-theme=dark].app-sidebar,
+[data-bs-theme=dark] .app-sidebar {
+  --lte-sidebar-hover-bg: rgba(255, 255, 255, 0.1);
+  --lte-sidebar-color: #c2c7d0;
+  --lte-sidebar-hover-color: #fff;
+  --lte-sidebar-active-color: #fff;
+  --lte-sidebar-menu-active-bg: rgba(255, 255, 255, 0.1);
+  --lte-sidebar-menu-active-color: #fff;
+  --lte-sidebar-submenu-bg: transparent;
+  --lte-sidebar-submenu-color: #c2c7d0;
+  --lte-sidebar-submenu-hover-color: #fff;
+  --lte-sidebar-submenu-hover-bg: rgba(255, 255, 255, 0.1);
+  --lte-sidebar-submenu-active-color: #fff;
+  --lte-sidebar-submenu-active-bg: rgba(255, 255, 255, 0.1);
+  --lte-sidebar-header-color: #c5cad2;
+}
+
+.app-main {
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  grid-area: lte-app-main;
+  max-width: 100vw;
+  padding-bottom: 0.75rem;
+  transition: 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .app-main {
+    transition: none;
+  }
+}
+.app-main .app-content-header {
+  padding: 1rem 0.5rem;
+}
+.app-main .app-content-header .breadcrumb {
+  padding: 0;
+  margin-bottom: 0;
+  line-height: 2rem;
+}
+.app-main .app-content-header .breadcrumb a {
+  text-decoration: none;
+}
+.app-main .app-content-top-area,
+.app-main .app-content-bottom-area {
+  color: var(--bs-secondary-color);
+  background-color: var(--bs-body-bg);
+}
+.app-main .app-content-top-area {
+  padding: 1rem 0;
+  border-bottom: 1px solid var(--bs-border-color);
+}
+.app-main .app-content-bottom-area {
+  padding: 1rem 0;
+  margin-top: auto;
+  margin-bottom: -0.75rem;
+  border-top: 1px solid var(--bs-border-color);
+}
+
+.app-footer {
+  grid-area: lte-app-footer;
+  width: inherit;
+  max-width: 100vw;
+  min-height: 3rem;
+  padding: 1rem;
+  color: var(--bs-secondary-color);
+  background-color: var(--bs-body-bg);
+  border-top: 1px solid var(--bs-border-color);
+  transition: 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .app-footer {
+    transition: none;
+  }
+}
+
+.fs-7 .dropdown-menu {
+  font-size: 0.875rem !important;
+}
+.fs-7 .dropdown-toggle::after {
+  vertical-align: 0.2rem;
+}
+
+.dropdown-item-title {
+  margin: 0;
+  font-size: 1rem;
+}
+
+.dropdown-icon::after {
+  margin-left: 0;
+}
+
+.dropdown-menu-lg {
+  min-width: 280px;
+  max-width: 300px;
+  padding: 0;
+}
+.dropdown-menu-lg .dropdown-divider {
+  margin: 0;
+}
+.dropdown-menu-lg .dropdown-item {
+  padding: 0.5rem 1rem;
+}
+.dropdown-menu-lg p {
+  margin: 0;
+  word-wrap: break-word;
+  white-space: normal;
+}
+
+.dropdown-submenu {
+  position: relative;
+}
+.dropdown-submenu > a::after {
+  border-top: 0.3em solid transparent;
+  border-right: 0;
+  border-bottom: 0.3em solid transparent;
+  border-left: 0.3em solid;
+  float: right;
+  margin-top: 0.5rem;
+  margin-left: 0.5rem;
+}
+.dropdown-submenu > .dropdown-menu {
+  top: 0;
+  left: 100%;
+  margin-top: 0;
+  margin-left: 0;
+}
+
+.dropdown-hover:hover > .dropdown-menu, .dropdown-hover.nav-item.dropdown:hover > .dropdown-menu,
+.dropdown-hover .dropdown-submenu:hover > .dropdown-menu, .dropdown-hover.dropdown-submenu:hover > .dropdown-menu {
+  display: block;
+}
+
+.dropdown-menu-xl {
+  min-width: 360px;
+  max-width: 420px;
+  padding: 0;
+}
+.dropdown-menu-xl .dropdown-divider {
+  margin: 0;
+}
+.dropdown-menu-xl .dropdown-item {
+  padding: 0.5rem 1rem;
+}
+.dropdown-menu-xl p {
+  margin: 0;
+  word-wrap: break-word;
+  white-space: normal;
+}
+
+.dropdown-footer,
+.dropdown-header {
+  display: block;
+  padding: 0.5rem 1rem;
+  font-size: 0.875rem;
+  text-align: center;
+}
+
+.open:not(.dropup) > .animated-dropdown-menu {
+  animation: flipInX 0.7s both;
+  -webkit-backface-visibility: visible !important;
+  backface-visibility: visible !important;
+}
+
+.navbar-custom-menu > .navbar-nav > li {
+  position: relative;
+}
+.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+
+@media (max-width: 575.98px) {
+  .navbar-custom-menu > .navbar-nav {
+    float: right;
+  }
+  .navbar-custom-menu > .navbar-nav > li {
+    position: static;
+  }
+  .navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
+    position: absolute;
+    right: 5%;
+    left: auto;
+    background-color: var(--bs-body-bg);
+    border: 1px solid var(--bs-border-color);
+  }
+}
+.navbar-nav > .user-menu > .nav-link::after {
+  content: none;
+}
+.navbar-nav > .user-menu > .dropdown-menu {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  width: 280px;
+  padding: 0;
+}
+.navbar-nav > .user-menu > .dropdown-menu,
+.navbar-nav > .user-menu > .dropdown-menu > .user-body {
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header {
+  min-height: 175px;
+  padding: 10px;
+  text-align: center;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img {
+  z-index: 5;
+  width: 90px;
+  height: 90px;
+  border: 3px solid;
+  border-color: transparent;
+  border-color: var(--bs-border-color-translucent);
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p {
+  z-index: 5;
+  margin-top: 10px;
+  font-size: 17px;
+  word-wrap: break-word;
+}
+.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small, .navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > .small {
+  display: block;
+  font-size: 12px;
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body {
+  padding: 15px;
+  border-top: 1px solid var(--bs-border-color);
+  border-bottom: 1px solid var(--bs-border-color-translucent);
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-body a {
+  text-decoration: none;
+}
+@media (min-width: 576px) {
+  .navbar-nav > .user-menu > .dropdown-menu > .user-body a {
+    color: var(--bs-body-color) !important;
+    background-color: var(--bs-body-bg) !important;
+  }
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer {
+  padding: 10px;
+  background-color: var(--bs-light-bg);
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+.navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default {
+  color: var(--bs-body-color);
+}
+@media (min-width: 576px) {
+  .navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default:hover {
+    background-color: var(--bs-body-bg);
+  }
+}
+.navbar-nav > .user-menu .user-image {
+  float: left;
+  width: 2rem;
+  height: 2rem;
+  margin-top: -2px;
+  border-radius: 50%;
+}
+@media (min-width: 576px) {
+  .navbar-nav > .user-menu .user-image {
+    float: none;
+    margin-top: -8px;
+    margin-right: 0.4rem;
+    line-height: 10px;
+  }
+}
+
+.callout {
+  --bs-link-color-rgb: var(--lte-callout-link);
+  --bs-code-color: var(--lte-callout-code-color);
+  padding: 1.25rem;
+  color: var(--lte-callout-color, inherit);
+  background-color: var(--lte-callout-bg, var(--bs-gray-100));
+  border-left: 0.25rem solid var(--lte-callout-border, var(--bs-gray-300));
+}
+.callout .callout-link {
+  font-weight: 700;
+  color: var(--bs-callout-link-color);
+}
+.callout h4, .callout .h4 {
+  margin-bottom: 0.25rem;
+}
+.callout > :last-child {
+  margin-bottom: 0;
+}
+.callout + .callout {
+  margin-top: -0.25rem;
+}
+
+.callout-primary {
+  --lte-callout-color: var(--bs-primary-text-emphasis);
+  --lte-callout-bg: var(--bs-primary-bg-subtle);
+  --lte-callout-border: var(--bs-primary-border-subtle);
+  --bs-callout-link-color: var(--bs-primary-text-emphasis);
+}
+
+.callout-secondary {
+  --lte-callout-color: var(--bs-secondary-text-emphasis);
+  --lte-callout-bg: var(--bs-secondary-bg-subtle);
+  --lte-callout-border: var(--bs-secondary-border-subtle);
+  --bs-callout-link-color: var(--bs-secondary-text-emphasis);
+}
+
+.callout-success {
+  --lte-callout-color: var(--bs-success-text-emphasis);
+  --lte-callout-bg: var(--bs-success-bg-subtle);
+  --lte-callout-border: var(--bs-success-border-subtle);
+  --bs-callout-link-color: var(--bs-success-text-emphasis);
+}
+
+.callout-info {
+  --lte-callout-color: var(--bs-info-text-emphasis);
+  --lte-callout-bg: var(--bs-info-bg-subtle);
+  --lte-callout-border: var(--bs-info-border-subtle);
+  --bs-callout-link-color: var(--bs-info-text-emphasis);
+}
+
+.callout-warning {
+  --lte-callout-color: var(--bs-warning-text-emphasis);
+  --lte-callout-bg: var(--bs-warning-bg-subtle);
+  --lte-callout-border: var(--bs-warning-border-subtle);
+  --bs-callout-link-color: var(--bs-warning-text-emphasis);
+}
+
+.callout-danger {
+  --lte-callout-color: var(--bs-danger-text-emphasis);
+  --lte-callout-bg: var(--bs-danger-bg-subtle);
+  --lte-callout-border: var(--bs-danger-border-subtle);
+  --bs-callout-link-color: var(--bs-danger-text-emphasis);
+}
+
+.callout-light {
+  --lte-callout-color: var(--bs-light-text-emphasis);
+  --lte-callout-bg: var(--bs-light-bg-subtle);
+  --lte-callout-border: var(--bs-light-border-subtle);
+  --bs-callout-link-color: var(--bs-light-text-emphasis);
+}
+
+.callout-dark {
+  --lte-callout-color: var(--bs-dark-text-emphasis);
+  --lte-callout-bg: var(--bs-dark-bg-subtle);
+  --lte-callout-border: var(--bs-dark-border-subtle);
+  --bs-callout-link-color: var(--bs-dark-text-emphasis);
+}
+
+.compact-mode .app-header {
+  max-height: 2.75rem;
+}
+.compact-mode .app-header .nav-link {
+  max-height: 1.75rem;
+}
+.compact-mode .nav-link {
+  --bs-nav-link-padding-y: .25rem;
+  --bs-nav-link-padding-x: .5rem;
+}
+.compact-mode.sidebar-mini.sidebar-collapse .app-sidebar:not(:hover) {
+  min-width: 3.1rem;
+  max-width: 3.1rem;
+}
+.compact-mode.sidebar-mini.sidebar-collapse .app-sidebar:not(:hover) .sidebar-menu .nav-link {
+  width: 2.1rem !important;
+}
+.compact-mode .logo-xs,
+.compact-mode .logo-xl {
+  max-height: 2.75rem;
+}
+.compact-mode .brand-image {
+  width: 1.75rem;
+  height: 1.75rem;
+}
+.compact-mode .sidebar-brand {
+  height: 2.75rem;
+}
+.compact-mode .app-footer {
+  padding: 0.5rem;
+}
+.compact-mode .sidebar-wrapper .nav-icon {
+  min-width: 1.1rem;
+  max-width: 1.1rem;
+}
+
+.astro-code {
+  padding: 0.75rem;
+  border-radius: 0.375rem;
+}
+
+.progress {
+  border-radius: 1px;
+}
+.progress.vertical {
+  position: relative;
+  display: inline-block;
+  width: 30px;
+  height: 200px;
+  margin-right: 10px;
+}
+.progress.vertical > .progress-bar {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+}
+.progress.vertical.sm, .progress.vertical.progress-sm {
+  width: 20px;
+}
+.progress.vertical.xs, .progress.vertical.progress-xs {
+  width: 10px;
+}
+.progress.vertical.xxs, .progress.vertical.progress-xxs {
+  width: 3px;
+}
+
+.progress-group {
+  margin-bottom: 0.5rem;
+}
+
+.progress-sm {
+  height: 10px;
+}
+
+.progress-xs {
+  height: 7px;
+}
+
+.progress-xxs {
+  height: 3px;
+}
+
+.table tr > td .progress {
+  margin: 0;
+}
+
+.card {
+  box-shadow: 0 0 1px rgba(var(--bs-body-color-rgb), 0.125), 0 1px 3px rgba(var(--bs-body-color-rgb), 0.2);
+}
+.card[class*=card-]:not(.card-outline) > .card-header, .card[class*=text-bg-]:not(.card-outline) > .card-header {
+  color: var(--lte-card-variant-color);
+  background-color: var(--lte-card-variant-bg);
+}
+.card[class*=card-]:not(.card-outline) > .card-header .btn-tool, .card[class*=text-bg-]:not(.card-outline) > .card-header .btn-tool {
+  --bs-btn-color: rgba(var(--lte-card-variant-color-rgb), .8);
+  --bs-btn-hover-color: var(--lte-card-variant-color);
+}
+.card.card-outline {
+  border-top: 3px solid var(--lte-card-variant-bg);
+}
+.card.maximized-card {
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 1050;
+  width: 100% !important;
+  max-width: 100% !important;
+  height: 100% !important;
+  max-height: 100% !important;
+}
+.card.maximized-card.was-collapsed .card-body {
+  display: block !important;
+}
+.card.maximized-card .card-body {
+  overflow: auto;
+}
+.card.maximized-card [data-lte-toggle=card-collapse] {
+  display: none;
+}
+.card.maximized-card [data-lte-icon=maximize] {
+  display: none;
+}
+.card.maximized-card .card-header,
+.card.maximized-card .card-footer {
+  border-radius: 0 !important;
+}
+.card:not(.maximized-card) [data-lte-icon=minimize] {
+  display: none;
+}
+.card.collapsed-card [data-lte-icon=collapse] {
+  display: none;
+}
+.card.collapsed-card .card-body,
+.card.collapsed-card .card-footer {
+  display: none;
+}
+.card:not(.collapsed-card) [data-lte-icon=expand] {
+  display: none;
+}
+.card .nav.flex-column > li {
+  margin: 0;
+  border-bottom: 1px solid var(--bs-border-color-translucent);
+}
+.card .nav.flex-column > li:last-of-type {
+  border-bottom: 0;
+}
+.card.height-control .card-body {
+  max-height: 300px;
+  overflow: auto;
+}
+.card .border-end {
+  border-right: 1px solid var(--bs-border-color-translucent);
+}
+.card .border-start {
+  border-left: 1px solid var(--bs-border-color-translucent);
+}
+.card.card-tabs:not(.card-outline) > .card-header {
+  border-bottom: 0;
+}
+.card.card-tabs:not(.card-outline) > .card-header .nav-item:first-child .nav-link {
+  border-left-color: transparent;
+}
+.card.card-tabs.card-outline .nav-item {
+  border-bottom: 0;
+}
+.card.card-tabs.card-outline .nav-item:first-child .nav-link {
+  margin-left: 0;
+  border-left: 0;
+}
+.card.card-tabs .card-tools {
+  margin: 0.3rem 0.5rem;
+}
+.card.card-tabs:not(.expanding-card).collapsed-card .card-header {
+  border-bottom: 0;
+}
+.card.card-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs {
+  border-bottom: 0;
+}
+.card.card-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs .nav-item {
+  margin-bottom: 0;
+}
+.card.card-tabs.expanding-card .card-header .nav-tabs .nav-item {
+  margin-bottom: -1px;
+}
+.card.card-outline-tabs {
+  border-top: 0;
+}
+.card.card-outline-tabs .card-header .nav-item:first-child .nav-link {
+  margin-left: 0;
+  border-left: 0;
+}
+.card.card-outline-tabs .card-header a {
+  text-decoration: none;
+  border-top: 3px solid transparent;
+}
+.card.card-outline-tabs .card-header a:hover {
+  border-top: 3px solid var(--bs-border-color);
+}
+.card.card-outline-tabs .card-header a.active:hover {
+  margin-top: 0;
+}
+.card.card-outline-tabs .card-tools {
+  margin: 0.5rem 0.5rem 0.3rem;
+}
+.card.card-outline-tabs:not(.expanding-card).collapsed-card .card-header {
+  border-bottom: 0;
+}
+.card.card-outline-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs {
+  border-bottom: 0;
+}
+.card.card-outline-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs .nav-item {
+  margin-bottom: 0;
+}
+.card.card-outline-tabs.expanding-card .card-header .nav-tabs .nav-item {
+  margin-bottom: -1px;
+}
+
+html.maximized-card {
+  overflow: hidden;
+}
+
+.card-header::after,
+.card-body::after,
+.card-footer::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+
+.card-header {
+  position: relative;
+  padding: 1rem 1rem;
+  background-color: transparent;
+  border-bottom: 1px solid var(--bs-border-color-translucent);
+  border-top-left-radius: 0.375rem;
+  border-top-right-radius: 0.375rem;
+}
+.collapsed-card .card-header {
+  border-bottom: 0;
+}
+.card-header > .card-tools {
+  float: right;
+  margin-right: -0.5rem;
+}
+.card-header > .card-tools .input-group,
+.card-header > .card-tools .nav,
+.card-header > .card-tools .pagination {
+  margin-top: -0.4rem;
+  margin-bottom: -0.4rem;
+}
+.card-header > .card-tools [data-bs-toggle=tooltip] {
+  position: relative;
+}
+
+.card-title {
+  float: left;
+  margin: 0;
+  font-size: 1.1rem;
+  font-weight: 400;
+  line-height: 1.9rem;
+}
+
+.btn-tool {
+  --bs-btn-padding-x: .5rem;
+  --bs-btn-padding-y: .25rem;
+  margin: -1rem 0;
+  font-size: 0.875rem;
+}
+.btn-tool:not(.btn-tool-custom) {
+  --bs-btn-color: var(--bs-tertiary-color);
+  --bs-btn-bg: transparent;
+  --bs-btn-box-shadow: none;
+  --bs-btn-hover-color: var(--bs-secondary-color);
+  --bs-btn-active-border-color: transparent;
+}
+
+.card-primary,
+.bg-primary,
+.text-bg-primary {
+  --lte-card-variant-bg: #01445E;
+  --lte-card-variant-bg-rgb: 13, 110, 253;
+  --lte-card-variant-color: #fff;
+  --lte-card-variant-color-rgb: 255, 255, 255;
+}
+
+.card-secondary,
+.bg-secondary,
+.text-bg-secondary {
+  --lte-card-variant-bg: #6c757d;
+  --lte-card-variant-bg-rgb: 108, 117, 125;
+  --lte-card-variant-color: #fff;
+  --lte-card-variant-color-rgb: 255, 255, 255;
+}
+
+.card-success,
+.bg-success,
+.text-bg-success {
+  --lte-card-variant-bg: #198754;
+  --lte-card-variant-bg-rgb: 25, 135, 84;
+  --lte-card-variant-color: #fff;
+  --lte-card-variant-color-rgb: 255, 255, 255;
+}
+
+.card-info,
+.bg-info,
+.text-bg-info {
+  --lte-card-variant-bg: #0dcaf0;
+  --lte-card-variant-bg-rgb: 13, 202, 240;
+  --lte-card-variant-color: #000;
+  --lte-card-variant-color-rgb: 0, 0, 0;
+}
+
+.card-warning,
+.bg-warning,
+.text-bg-warning {
+  --lte-card-variant-bg: #ffc107;
+  --lte-card-variant-bg-rgb: 255, 193, 7;
+  --lte-card-variant-color: #000;
+  --lte-card-variant-color-rgb: 0, 0, 0;
+}
+
+.card-danger,
+.bg-danger,
+.text-bg-danger {
+  --lte-card-variant-bg: #dc3545;
+  --lte-card-variant-bg-rgb: 220, 53, 69;
+  --lte-card-variant-color: #fff;
+  --lte-card-variant-color-rgb: 255, 255, 255;
+}
+
+.card-light,
+.bg-light,
+.text-bg-light {
+  --lte-card-variant-bg: #f8f9fa;
+  --lte-card-variant-bg-rgb: 248, 249, 250;
+  --lte-card-variant-color: #000;
+  --lte-card-variant-color-rgb: 0, 0, 0;
+}
+
+.card-dark,
+.bg-dark,
+.text-bg-dark {
+  --lte-card-variant-bg: #212529;
+  --lte-card-variant-bg-rgb: 33, 37, 41;
+  --lte-card-variant-color: #fff;
+  --lte-card-variant-color-rgb: 255, 255, 255;
+}
+
+.card-body > .table {
+  margin-bottom: 0;
+}
+.card-body > .table > thead > tr > th,
+.card-body > .table > thead > tr > td {
+  border-top-width: 0;
+}
+
+.table:not(.table-dark) {
+  color: inherit;
+}
+.table.table-head-fixed thead tr:nth-child(1) th {
+  position: -webkit-sticky;
+  position: sticky;
+  top: 0;
+  z-index: 10;
+  background-color: #fff;
+  border-bottom: 0;
+  box-shadow: inset 0 1px 0 var(--bs-border-color), inset 0 -1px 0 var(--bs-border-color);
+}
+.table.no-border,
+.table.no-border td,
+.table.no-border th {
+  border: 0;
+}
+.table.text-center,
+.table.text-center td,
+.table.text-center th {
+  text-align: center;
+}
+.table.table-valign-middle thead > tr > th,
+.table.table-valign-middle thead > tr > td,
+.table.table-valign-middle tbody > tr > th,
+.table.table-valign-middle tbody > tr > td {
+  vertical-align: middle;
+}
+.card-body.p-0 .table thead > tr > th:first-of-type,
+.card-body.p-0 .table thead > tr > td:first-of-type,
+.card-body.p-0 .table tfoot > tr > th:first-of-type,
+.card-body.p-0 .table tfoot > tr > td:first-of-type,
+.card-body.p-0 .table tbody > tr > th:first-of-type,
+.card-body.p-0 .table tbody > tr > td:first-of-type {
+  padding-left: 1.5rem;
+}
+.card-body.p-0 .table thead > tr > th:last-of-type,
+.card-body.p-0 .table thead > tr > td:last-of-type,
+.card-body.p-0 .table tfoot > tr > th:last-of-type,
+.card-body.p-0 .table tfoot > tr > td:last-of-type,
+.card-body.p-0 .table tbody > tr > th:last-of-type,
+.card-body.p-0 .table tbody > tr > td:last-of-type {
+  padding-right: 1.5rem;
+}
+
+.small-box {
+  border-radius: 0.375rem;
+  box-shadow: 0 0 1px rgba(var(--bs-body-color-rgb), 0.125), 0 1px 3px rgba(var(--bs-body-color-rgb), 0.2);
+  position: relative;
+  display: block;
+  margin-bottom: 1.25rem;
+  --bs-link-color-rgb: none;
+  --bs-link-hover-color-rgb: none;
+  --bs-heading-color: none;
+}
+.small-box > .inner {
+  padding: 10px;
+}
+.small-box > .small-box-footer {
+  position: relative;
+  z-index: 10;
+  display: block;
+  padding: 3px 0;
+  text-align: center;
+  background-color: rgba(0, 0, 0, 0.07);
+}
+.small-box > .small-box-footer:hover {
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.small-box h3, .small-box .h3 {
+  font-size: calc(1.345rem + 1.14vw);
+  padding: 0;
+  margin: 0 0 10px;
+  font-weight: 700;
+  white-space: nowrap;
+}
+@media (min-width: 1200px) {
+  .small-box h3, .small-box .h3 {
+    font-size: 2.2rem;
+  }
+}
+@media (min-width: 992px) {
+  .col-xl-2 .small-box h3, .col-xl-2 .small-box .h3, .col-lg-2 .small-box h3, .col-lg-2 .small-box .h3, .col-md-2 .small-box h3, .col-md-2 .small-box .h3 {
+    font-size: calc(1.285rem + 0.42vw);
+  }
+}
+@media (min-width: 992px) and (min-width: 1200px) {
+  .col-xl-2 .small-box h3, .col-xl-2 .small-box .h3, .col-lg-2 .small-box h3, .col-lg-2 .small-box .h3, .col-md-2 .small-box h3, .col-md-2 .small-box .h3 {
+    font-size: 1.6rem;
+  }
+}
+@media (min-width: 992px) {
+  .col-xl-3 .small-box h3, .col-xl-3 .small-box .h3, .col-lg-3 .small-box h3, .col-lg-3 .small-box .h3, .col-md-3 .small-box h3, .col-md-3 .small-box .h3 {
+    font-size: calc(1.285rem + 0.42vw);
+  }
+}
+@media (min-width: 992px) and (min-width: 1200px) {
+  .col-xl-3 .small-box h3, .col-xl-3 .small-box .h3, .col-lg-3 .small-box h3, .col-lg-3 .small-box .h3, .col-md-3 .small-box h3, .col-md-3 .small-box .h3 {
+    font-size: 1.6rem;
+  }
+}
+@media (min-width: 1200px) {
+  .col-xl-2 .small-box h3, .col-xl-2 .small-box .h3, .col-lg-2 .small-box h3, .col-lg-2 .small-box .h3, .col-md-2 .small-box h3, .col-md-2 .small-box .h3 {
+    font-size: calc(1.345rem + 1.14vw);
+  }
+}
+@media (min-width: 1200px) and (min-width: 1200px) {
+  .col-xl-2 .small-box h3, .col-xl-2 .small-box .h3, .col-lg-2 .small-box h3, .col-lg-2 .small-box .h3, .col-md-2 .small-box h3, .col-md-2 .small-box .h3 {
+    font-size: 2.2rem;
+  }
+}
+@media (min-width: 1200px) {
+  .col-xl-3 .small-box h3, .col-xl-3 .small-box .h3, .col-lg-3 .small-box h3, .col-lg-3 .small-box .h3, .col-md-3 .small-box h3, .col-md-3 .small-box .h3 {
+    font-size: calc(1.345rem + 1.14vw);
+  }
+}
+@media (min-width: 1200px) and (min-width: 1200px) {
+  .col-xl-3 .small-box h3, .col-xl-3 .small-box .h3, .col-lg-3 .small-box h3, .col-lg-3 .small-box .h3, .col-md-3 .small-box h3, .col-md-3 .small-box .h3 {
+    font-size: 2.2rem;
+  }
+}
+.small-box p {
+  font-size: 1rem;
+}
+.small-box p > small, .small-box p > .small {
+  display: block;
+  margin-top: 5px;
+  font-size: 0.9rem;
+  color: #f8f9fa;
+}
+.small-box h3, .small-box .h3,
+.small-box p {
+  z-index: 5;
+}
+.small-box .small-box-icon {
+  position: absolute;
+  top: 15px;
+  right: 15px;
+  z-index: 0;
+  height: 70px;
+  font-size: 70px;
+  color: rgba(0, 0, 0, 0.15);
+  transition: transform 0.3s linear;
+}
+@media (prefers-reduced-motion: reduce) {
+  .small-box .small-box-icon {
+    transition: none;
+  }
+}
+.small-box:hover .small-box-icon {
+  transform: scale(1.1);
+}
+
+@media (max-width: 575.98px) {
+  .small-box {
+    text-align: center;
+  }
+  .small-box .small-box-icon {
+    display: none;
+  }
+  .small-box p {
+    font-size: 12px;
+  }
+}
+.info-box {
+  box-shadow: 0 0 1px rgba(var(--bs-body-color-rgb), 0.125), 0 1px 3px rgba(var(--bs-body-color-rgb), 0.2);
+  border-radius: 0.375rem;
+  position: relative;
+  display: flex;
+  width: 100%;
+  min-height: 80px;
+  padding: 0.5rem;
+  margin-bottom: 1rem;
+  color: var(--bs-body-color);
+  background-color: var(--bs-body-bg);
+}
+.info-box .progress {
+  height: 2px;
+  margin: 5px 0;
+  background-color: rgba(var(--lte-card-variant-color-rgb), 0.125);
+}
+.info-box .progress .progress-bar {
+  background-color: var(--lte-card-variant-color);
+}
+.info-box .info-box-icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 70px;
+  font-size: 1.875rem;
+  text-align: center;
+  border-radius: 0.375rem;
+}
+.info-box .info-box-icon > img {
+  max-width: 100%;
+}
+.info-box .info-box-content {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  justify-content: center;
+  padding: 0 10px;
+  line-height: 1.8;
+}
+.info-box .info-box-number {
+  display: block;
+  margin-top: 0.25rem;
+  font-weight: 700;
+}
+.info-box .progress-description,
+.info-box .info-box-text {
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.info-box .info-box-more {
+  display: block;
+}
+.info-box .progress-description {
+  margin: 0;
+}
+@media (min-width: 768px) {
+  .col-xl-2 .info-box .progress-description, .col-lg-2 .info-box .progress-description, .col-md-2 .info-box .progress-description {
+    display: none;
+  }
+  .col-xl-3 .info-box .progress-description, .col-lg-3 .info-box .progress-description, .col-md-3 .info-box .progress-description {
+    display: none;
+  }
+}
+@media (min-width: 992px) {
+  .col-xl-2 .info-box .progress-description, .col-lg-2 .info-box .progress-description, .col-md-2 .info-box .progress-description {
+    font-size: 0.75rem;
+    display: block;
+  }
+  .col-xl-3 .info-box .progress-description, .col-lg-3 .info-box .progress-description, .col-md-3 .info-box .progress-description {
+    font-size: 0.75rem;
+    display: block;
+  }
+}
+@media (min-width: 1200px) {
+  .col-xl-2 .info-box .progress-description, .col-lg-2 .info-box .progress-description, .col-md-2 .info-box .progress-description {
+    font-size: 1rem;
+    display: block;
+  }
+  .col-xl-3 .info-box .progress-description, .col-lg-3 .info-box .progress-description, .col-md-3 .info-box .progress-description {
+    font-size: 1rem;
+    display: block;
+  }
+}
+
+.timeline {
+  position: relative;
+  padding: 0;
+  margin: 0 0 45px;
+}
+.timeline::before {
+  border-radius: 0.375rem;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 31px;
+  width: 4px;
+  margin: 0;
+  content: "";
+  background-color: var(--bs-border-color);
+}
+.timeline > div {
+  position: relative;
+  margin-right: 10px;
+  margin-bottom: 15px;
+}
+.timeline > div::before, .timeline > div::after {
+  display: table;
+  content: "";
+}
+.timeline > div > .timeline-item {
+  box-shadow: 0 0 1px rgba(var(--bs-body-color-rgb), 0.125), 0 1px 3px rgba(var(--bs-body-color-rgb), 0.2);
+  border-radius: 0.375rem;
+  position: relative;
+  padding: 0;
+  margin-top: 0;
+  margin-right: 15px;
+  margin-left: 60px;
+  color: var(--bs-body-color);
+  background-color: var(--bs-body-bg);
+}
+.timeline > div > .timeline-item > .time {
+  float: right;
+  padding: 10px;
+  font-size: 12px;
+  color: var(--bs-secondary-color);
+}
+.timeline > div > .timeline-item > .timeline-header {
+  padding: 10px;
+  margin: 0;
+  font-size: 16px;
+  line-height: 1.1;
+  color: var(--bs-secondary-color);
+  border-bottom: 1px solid var(--bs-border-color);
+}
+.timeline > div > .timeline-item > .timeline-header > a {
+  font-weight: 600;
+  text-decoration: none;
+}
+.timeline > div > .timeline-item > .timeline-body,
+.timeline > div > .timeline-item > .timeline-footer {
+  padding: 10px;
+}
+.timeline > div > .timeline-item > .timeline-body > img {
+  margin: 10px;
+}
+.timeline > div > .timeline-item > .timeline-body > dl,
+.timeline > div > .timeline-item > .timeline-body ol,
+.timeline > div > .timeline-item > .timeline-body ul {
+  margin: 0;
+}
+.timeline > div .timeline-icon {
+  position: absolute;
+  top: 0;
+  left: 18px;
+  width: 30px;
+  height: 30px;
+  font-size: 16px;
+  line-height: 30px;
+  text-align: center;
+  background-color: var(--bs-secondary-bg);
+  border-radius: 50%;
+}
+.timeline > .time-label > span {
+  border-radius: 4px;
+  display: inline-block;
+  padding: 5px;
+  font-weight: 600;
+  background-color: var(--bs-body-bg);
+}
+
+.timeline-inverse > div > .timeline-item {
+  box-shadow: none;
+  background-color: var(--bs-tertiary-bg);
+  border: 1px solid var(--bs-border-color);
+}
+.timeline-inverse > div > .timeline-item > .timeline-header {
+  border-bottom-color: var(--bs-border-color);
+}
+
+.direct-chat .card-body {
+  position: relative;
+  padding: 0;
+  overflow-x: hidden;
+}
+.direct-chat.chat-pane-open .direct-chat-contacts {
+  transform: translate(0, 0);
+}
+.direct-chat.timestamp-light .direct-chat-timestamp {
+  color: rgba(var(--bs-body-color-rgb), 0.65);
+}
+.direct-chat.timestamp-dark .direct-chat-timestamp {
+  color: rgba(var(--bs-body-color-rgb), 0.9);
+}
+
+.direct-chat-messages {
+  height: 250px;
+  padding: 10px;
+  overflow: auto;
+  transform: translate(0, 0);
+}
+
+.direct-chat-msg,
+.direct-chat-text {
+  display: block;
+}
+
+.direct-chat-msg {
+  margin-bottom: 10px;
+}
+.direct-chat-msg::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+
+.direct-chat-messages,
+.direct-chat-contacts {
+  transition: transform 0.5s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .direct-chat-messages,
+  .direct-chat-contacts {
+    transition: none;
+  }
+}
+
+.direct-chat-text {
+  border-radius: 0.5rem;
+  position: relative;
+  padding: 5px 10px;
+  margin: 5px 0 0 50px;
+  color: var(--bs-emphasis-color);
+  background-color: var(--bs-secondary-bg);
+  border: 1px solid var(--bs-border-color);
+}
+.direct-chat-text::after, .direct-chat-text::before {
+  position: absolute;
+  top: 15px;
+  right: 100%;
+  width: 0;
+  height: 0;
+  pointer-events: none;
+  content: " ";
+  border: solid transparent;
+  border-right-color: var(--bs-border-color);
+}
+.direct-chat-text::after {
+  margin-top: -5px;
+  border-width: 5px;
+}
+.direct-chat-text::before {
+  margin-top: -6px;
+  border-width: 6px;
+}
+.end .direct-chat-text {
+  margin-right: 50px;
+  margin-left: 0;
+}
+.end .direct-chat-text::after, .end .direct-chat-text::before {
+  right: auto;
+  left: 100%;
+  border-right-color: transparent;
+  border-left-color: var(--bs-border-color);
+}
+
+.direct-chat-img {
+  border-radius: 50%;
+  float: left;
+  width: 40px;
+  height: 40px;
+}
+.end .direct-chat-img {
+  float: right;
+}
+
+.direct-chat-infos {
+  display: block;
+  margin-bottom: 2px;
+  font-size: 0.875rem;
+}
+
+.direct-chat-name {
+  font-weight: 600;
+}
+
+.direct-chat-timestamp {
+  color: rgba(var(--bs-body-color-rgb), 0.75);
+}
+
+.direct-chat-contacts-open .direct-chat-contacts {
+  transform: translate(0, 0);
+}
+
+.direct-chat-contacts {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  width: 100%;
+  height: 250px;
+  overflow: auto;
+  color: var(--bs-body-bg);
+  background-color: var(--bs-body-color);
+  transform: translate(101%, 0);
+}
+
+.direct-chat-contacts-light {
+  background-color: var(--bs-light-bg-subtle);
+}
+.direct-chat-contacts-light .contacts-list-name {
+  color: var(--bs-body-color);
+}
+.direct-chat-contacts-light .contacts-list-date {
+  color: var(--bs-secondary-color);
+}
+.direct-chat-contacts-light .contacts-list-msg {
+  color: var(--bs-secondary-color);
+}
+
+.contacts-list {
+  padding-left: 0;
+  list-style: none;
+}
+.contacts-list > li {
+  padding: 10px;
+  margin: 0;
+  text-decoration: none;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+}
+.contacts-list > li::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+.contacts-list > li:last-of-type {
+  border-bottom: 0;
+}
+.contacts-list > li a {
+  text-decoration: none;
+}
+
+.contacts-list-img {
+  border-radius: 50%;
+  float: left;
+  width: 40px;
+}
+
+.contacts-list-info {
+  margin-left: 45px;
+  color: var(--bs-body-bg);
+}
+
+.contacts-list-name,
+.contacts-list-status {
+  display: block;
+}
+
+.contacts-list-name {
+  font-weight: 600;
+}
+
+.contacts-list-status {
+  font-size: 0.875rem;
+}
+
+.contacts-list-date {
+  font-weight: 400;
+  color: var(--bs-secondary-bg);
+}
+
+.contacts-list-msg {
+  color: var(--bs-secondary-bg);
+}
+
+.end > .direct-chat-text {
+  color: var(--lte-direct-chat-color);
+  background-color: var(--lte-direct-chat-bg);
+  border-color: var(--lte-direct-chat-bg);
+}
+.end > .direct-chat-text::after, .end > .direct-chat-text::before {
+  border-left-color: var(--lte-direct-chat-bg);
+}
+
+.direct-chat-primary {
+  --lte-direct-chat-color: #fff;
+  --lte-direct-chat-bg: #01445E;
+}
+
+.direct-chat-secondary {
+  --lte-direct-chat-color: #fff;
+  --lte-direct-chat-bg: #6c757d;
+}
+
+.direct-chat-success {
+  --lte-direct-chat-color: #fff;
+  --lte-direct-chat-bg: #198754;
+}
+
+.direct-chat-info {
+  --lte-direct-chat-color: #000;
+  --lte-direct-chat-bg: #0dcaf0;
+}
+
+.direct-chat-warning {
+  --lte-direct-chat-color: #000;
+  --lte-direct-chat-bg: #ffc107;
+}
+
+.direct-chat-danger {
+  --lte-direct-chat-color: #fff;
+  --lte-direct-chat-bg: #dc3545;
+}
+
+.direct-chat-light {
+  --lte-direct-chat-color: #000;
+  --lte-direct-chat-bg: #f8f9fa;
+}
+
+.direct-chat-dark {
+  --lte-direct-chat-color: #fff;
+  --lte-direct-chat-bg: #212529;
+}
+
+.toast-primary {
+  --bs-toast-header-color: #fff;
+  --bs-toast-header-bg: #01445E;
+  --bs-toast-header-border-color: #01445E;
+  --bs-toast-border-color: #01445E;
+  --bs-toast-bg: var(--bs-primary-bg-subtle);
+}
+.toast-primary .btn-close {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+.toast-secondary {
+  --bs-toast-header-color: #fff;
+  --bs-toast-header-bg: #6c757d;
+  --bs-toast-header-border-color: #6c757d;
+  --bs-toast-border-color: #6c757d;
+  --bs-toast-bg: var(--bs-secondary-bg-subtle);
+}
+.toast-secondary .btn-close {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+.toast-success {
+  --bs-toast-header-color: #fff;
+  --bs-toast-header-bg: #198754;
+  --bs-toast-header-border-color: #198754;
+  --bs-toast-border-color: #198754;
+  --bs-toast-bg: var(--bs-success-bg-subtle);
+}
+.toast-success .btn-close {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+.toast-info {
+  --bs-toast-header-color: #000;
+  --bs-toast-header-bg: #0dcaf0;
+  --bs-toast-header-border-color: #0dcaf0;
+  --bs-toast-border-color: #0dcaf0;
+  --bs-toast-bg: var(--bs-info-bg-subtle);
+}
+
+.toast-warning {
+  --bs-toast-header-color: #000;
+  --bs-toast-header-bg: #ffc107;
+  --bs-toast-header-border-color: #ffc107;
+  --bs-toast-border-color: #ffc107;
+  --bs-toast-bg: var(--bs-warning-bg-subtle);
+}
+
+.toast-danger {
+  --bs-toast-header-color: #fff;
+  --bs-toast-header-bg: #dc3545;
+  --bs-toast-header-border-color: #dc3545;
+  --bs-toast-border-color: #dc3545;
+  --bs-toast-bg: var(--bs-danger-bg-subtle);
+}
+.toast-danger .btn-close {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+.toast-light {
+  --bs-toast-header-color: #000;
+  --bs-toast-header-bg: #f8f9fa;
+  --bs-toast-header-border-color: #f8f9fa;
+  --bs-toast-border-color: #f8f9fa;
+  --bs-toast-bg: var(--bs-light-bg-subtle);
+}
+
+.toast-dark {
+  --bs-toast-header-color: #fff;
+  --bs-toast-header-bg: #212529;
+  --bs-toast-header-border-color: #212529;
+  --bs-toast-border-color: #212529;
+  --bs-toast-bg: var(--bs-dark-bg-subtle);
+}
+.toast-dark .btn-close {
+  filter: var(--bs-btn-close-white-filter);
+}
+
+[data-bs-theme=dark] .toast-info .btn-close {
+  --bs-btn-close-white-filter: none;
+}
+[data-bs-theme=dark] .toast-warning .btn-close {
+  --bs-btn-close-white-filter: none;
+}
+[data-bs-theme=dark] .toast-light .btn-close {
+  --bs-btn-close-white-filter: none;
+}
+.login-logo,
+.register-logo {
+  margin-bottom: 0.9rem;
+  font-size: 2.1rem;
+  font-weight: 300;
+  text-align: center;
+}
+.login-logo a,
+.register-logo a {
+  color: var(--bs-secondary-color);
+  text-decoration: none;
+}
+
+.login-page,
+.register-page {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  min-height: 100vh;
+}
+
+.login-box,
+.register-box {
+  width: 360px;
+}
+@media (max-width: 576px) {
+  .login-box,
+  .register-box {
+    width: 90%;
+    margin-top: 0.5rem;
+  }
+}
+.login-box .card,
+.register-box .card {
+  margin-bottom: 0;
+}
+
+.login-card-body,
+.register-card-body {
+  padding: 20px;
+  color: var(--bs-secondary-color);
+  background-color: var(--bs-body-bg);
+  border-top: 0;
+}
+.login-card-body .input-group .form-control:focus,
+.register-card-body .input-group .form-control:focus {
+  box-shadow: none;
+}
+.login-card-body .input-group .form-control:focus ~ .input-group-prepend .input-group-text,
+.login-card-body .input-group .form-control:focus ~ .input-group-append .input-group-text,
+.register-card-body .input-group .form-control:focus ~ .input-group-prepend .input-group-text,
+.register-card-body .input-group .form-control:focus ~ .input-group-append .input-group-text {
+  border-color: #86b7fe;
+}
+.login-card-body .input-group .form-control.is-valid:focus,
+.register-card-body .input-group .form-control.is-valid:focus {
+  box-shadow: none;
+}
+.login-card-body .input-group .form-control.is-valid ~ .input-group-prepend .input-group-text,
+.login-card-body .input-group .form-control.is-valid ~ .input-group-append .input-group-text,
+.register-card-body .input-group .form-control.is-valid ~ .input-group-prepend .input-group-text,
+.register-card-body .input-group .form-control.is-valid ~ .input-group-append .input-group-text {
+  border-color: #198754;
+}
+.login-card-body .input-group .form-control.is-invalid:focus,
+.register-card-body .input-group .form-control.is-invalid:focus {
+  box-shadow: none;
+}
+.login-card-body .input-group .form-control.is-invalid ~ .input-group-append .input-group-text,
+.register-card-body .input-group .form-control.is-invalid ~ .input-group-append .input-group-text {
+  border-color: #dc3545;
+}
+.login-card-body .input-group .input-group-text,
+.register-card-body .input-group .input-group-text {
+  color: var(--bs-secondary-color);
+  background-color: transparent;
+  border-top-right-radius: 0.375rem;
+  border-bottom-right-radius: 0.375rem;
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  .login-card-body .input-group .input-group-text,
+  .register-card-body .input-group .input-group-text {
+    transition: none;
+  }
+}
+
+.login-box-msg,
+.register-box-msg {
+  padding: 0 20px 20px;
+  margin: 0;
+  text-align: center;
+}
+
+.social-auth-links {
+  margin: 10px 0;
+}
+
+.lockscreen .lockscreen-name {
+  font-weight: 600;
+  text-align: center;
+}
+.lockscreen .lockscreen-logo {
+  margin-bottom: 25px;
+  font-size: 35px;
+  font-weight: 300;
+  text-align: center;
+}
+.lockscreen .lockscreen-logo a {
+  color: var(--bs-emphasis-color);
+  text-decoration: none;
+}
+.lockscreen .lockscreen-wrapper {
+  max-width: 400px;
+  margin: 0 auto;
+  margin-top: 10%;
+}
+.lockscreen .lockscreen-item {
+  position: relative;
+  width: 290px;
+  padding: 0;
+  margin: 10px auto 30px;
+  background-color: var(--bs-body-bg);
+  border-radius: 4px;
+}
+.lockscreen .lockscreen-image {
+  position: absolute;
+  top: -25px;
+  left: -10px;
+  z-index: 10;
+  padding: 5px;
+  background-color: var(--bs-body-bg);
+  border-radius: 50%;
+}
+.lockscreen .lockscreen-image > img {
+  border-radius: 50%;
+  width: 70px;
+  height: 70px;
+}
+.lockscreen .lockscreen-credentials {
+  margin-left: 70px;
+}
+.lockscreen .lockscreen-credentials .form-control {
+  border: 0;
+}
+.lockscreen .lockscreen-credentials .btn {
+  padding: 0 10px;
+  border: 0;
+}
+.lockscreen .lockscreen-footer {
+  margin-top: 10px;
+}
+
+.img-size-64,
+.img-size-50,
+.img-size-32 {
+  height: auto;
+}
+
+.img-size-64 {
+  width: 64px;
+}
+
+.img-size-50 {
+  width: 50px;
+}
+
+.img-size-32 {
+  width: 32px;
+}
+
+/*# sourceMappingURL=adminlte.css.map */

+ 134 - 0
bg_remover/templates/static/css/custom.css

@@ -0,0 +1,134 @@
+@font-face {
+    font-family: 'aptos';
+    src: url('../fonts/aptos-font/Aptos.eot');
+    src: url('../fonts/aptos-font/Aptos.eot?#iefix') format('embedded-opentype'),
+        /* IE6-IE8 */
+        url('../fonts/aptos-font/Aptos.woff') format('woff'),
+        /* Modern Browsers */
+        url('../fonts/aptos-font/aptos.ttf') format('truetype');
+    /* Safari, Android, iOS */
+}
+
+body {
+    font-family: 'aptos';
+    font-size: 14px;
+}
+
+.bg-body-secondary {
+    background-color: #414042 !important;
+}
+
+.bg-body-tertiary {
+    background-color: rgba(230, 231, 232, 0.3) !important;
+}
+
+.sidebar-brand .brand-link .brand-image {
+    max-height: 40px;
+}
+
+/* .sidebar-wrapper .sidebar-menu>.nav-item>.nav-link.active:not(:hover) {
+    background-color: #808285;
+} */
+
+.logo-mini {
+    display: none;
+}
+
+.sidebar-collapse .logo-mini {
+    display: block;
+}
+
+.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice__remove {
+    border: none !important;
+    background: white !important;
+}
+
+.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice {
+    margin-left: 7px;
+    margin-left: 7px;
+}
+
+.dropdown-menu-lg {
+    max-width: none !important;
+}
+
+.app-sidebar:hover .logo-mini {
+    display: none;
+}
+
+.app-sidebar:hover .brand-text {
+    max-width: none !important;
+}
+
+.sidebar-brand{
+    height: 3.55rem;
+}
+
+.form-control{
+    font-size: 14px;
+}
+
+.fa-angle-left.rotate {
+    transform: rotate(-90deg);
+    transition: transform 0.3s;
+}
+
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+    width: 45%;
+}
+
+.select2-container .select2-search--inline .select2-search__field {
+    position: absolute;
+    top: 3px;
+    font-size: 14px;
+}
+
+.hiddenSpan {
+    display: none;
+}
+
+.btn-outline-success i {
+    color: green;
+}
+
+.btn-outline-danger i {
+    color: red;
+}
+.sidebar-menu .nav-link>.right, .sidebar-menu .nav-link>p>.right {
+    position: absolute;
+    right: 1rem;
+    top: .7rem;
+}
+.breadcrumb li{
+    line-height: 1.9rem;
+}
+
+.overlay {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(0, 0, 0, 0.5);
+    /* semi-transparent */
+    display: none;
+    /* hidden by default */
+    align-items: center;
+    justify-content: center;
+    z-index: 1050;
+    /* above most elements */
+}
+
+.selectRight{
+    padding-left: 50px;
+    display: flex;
+    align-items: center;
+    gap: 8px;
+}
+
+
+.attributeName{
+    font-weight: 400;
+    color: black;
+}

+ 309 - 0
bg_remover/templates/static/css/login.css

@@ -0,0 +1,309 @@
+/*
+Project Name: WFM
+Date : 05-11-2020
+Author: Amar Kholambe (amar.kholambe@luminad.com)
+*/
+body {
+    background: rgb(239, 138, 227);
+    background: url('./../images/45.jpg') no-repeat center center fixed;
+    -webkit-background-size: cover;
+    -moz-background-size: cover;
+    -o-background-size: cover;
+    background-size: cover;
+}
+
+.login {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    background: #fff;
+}
+
+.login-container {
+    width: 800px;
+    margin: 0 auto;
+    height: 430px;
+    box-shadow: 0 0 178px #9b9b9b;
+    border: 1px solid #d1d1d1;
+    background: #f2f2f2;
+}
+
+.login-left {
+    /* background: #0070CD; */
+    background: url('./../images/left.png');
+    float: left;
+    width: 60%;
+    padding: 2 5px 30px 0;
+    height: 100%;
+    position: relative;
+    /* border-right: 1px solid #ddd; */
+    overflow: hidden;
+    background-size: cover;
+}
+
+.login-right {
+    float: left;
+    width: 48%;
+    padding: 45px 30px 0;
+    height: 100%;
+    position: absolute;
+    top:0;
+    right: 0;
+    bottom: 0;
+}
+
+.form-signin,
+.form-reset-password {
+    padding: 0 30px 0 0;
+    overflow: auto;
+    height: 410px;
+}
+
+.lbox {
+    width: 100%;
+    display: block;
+}
+
+.clogo {
+    /* width: 200px; */
+    margin: 25px 120px;
+    display: block;
+    text-align: center;
+    font-size: 35px;
+    color: #424242;
+    z-index: 1;
+    position: relative;
+}
+
+.llogo {
+    width: 115px;
+    position: absolute;
+    bottom: 10px;
+    right: 90px;
+}
+
+.lbox p {
+    margin: 320px auto auto;
+    color: #424242;
+    font-size: 12px;
+    text-align: right;
+}
+
+.form-signin-heading {
+    padding-bottom: 30px;
+    text-align: center;
+    color: #0070CD;
+    margin: 0;
+}
+
+.lang_label {
+    position: initial !important;
+    display: inline-block;
+    margin-right: 5px;
+}
+
+select {
+    width: 70px !important;
+    display: inline-block !important;
+}
+
+/* form starting stylings ------------------------------- */
+
+.login .group {
+    position: relative;
+    margin-bottom: 55px;
+}
+
+.login input {
+    padding: 5px;
+    display: block;
+    width: 100%;
+    border: none;
+    border-bottom: 1px solid #0070CD;
+    background-color: transparent;
+}
+
+.login input:focus {
+    outline: none;
+}
+
+/* LABEL ======================================= */
+
+.login label {
+    color: #999;
+    /* font-size: 18px; */
+    font-weight: normal;
+    position: absolute;
+    pointer-events: none;
+    left: 5px;
+    top: 15px;
+    transition: 0.2s ease all;
+    -moz-transition: 0.2s ease all;
+    -webkit-transition: 0.2s ease all;
+}
+
+/* active state */
+
+.login input:focus~label,
+.login input:valid~label {
+    top: -20px;
+    font-size: 14px;
+    color: #5264AE;
+}
+
+/* active state */
+
+.login input:focus~.highlight {
+    -webkit-animation: inputHighlighter 0.3s ease;
+    -moz-animation: inputHighlighter 0.3s ease;
+    animation: inputHighlighter 0.3s ease;
+}
+
+/* ANIMATIONS ================ */
+
+@-webkit-keyframes inputHighlighter {
+    from {
+        background: #5264AE;
+    }
+
+    to {
+        width: 0;
+        background: transparent;
+    }
+}
+
+@-moz-keyframes inputHighlighter {
+    from {
+        background: #5264AE;
+    }
+
+    to {
+        width: 0;
+        background: transparent;
+    }
+}
+
+@keyframes inputHighlighter {
+    from {
+        background: #5264AE;
+    }
+
+    to {
+        width: 0;
+        background: transparent;
+    }
+}
+
+.login button {
+    border-color: #0070CD;
+    color: #0070CD;
+    font-size: 18px;
+}
+
+.login button:hover,
+.login button:active,
+.login button:focus {
+    background-color: #0070CD !important;
+    color: #ffffff !important;
+}
+
+.forgotPass {
+    color: #55729c;
+    margin-top: 25px;
+    display: block;
+}
+
+.form-reset-password input {
+    padding: 8px 8px 8px 5px;
+}
+
+.form-reset-password label {
+    top: 10px;
+}
+
+.form-reset-password .group {
+    margin-bottom: 40px;
+}
+
+.header {
+    height: 200px;
+    background: #425464;
+}
+
+.footer {
+    height: 50px;
+    background: #425464;
+}
+
+@media only screen and (max-width: 900px) {
+
+    .login,
+    .login-container {
+        width: 100%;
+    }
+}
+
+@media only screen and (max-width: 768px) {
+    .login {
+        top: 150px;
+    }
+
+    .login-left,
+    .login-right {
+        width: 100%;
+        float: none;
+    }
+
+    .form-signin,
+    .form-reset-password {
+        height: 100%;
+        display: initial;
+    }
+}
+
+/* width */
+
+::-webkit-scrollbar {
+    width: 5px;
+}
+
+/* Track */
+
+::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px grey;
+    border-radius: 2px;
+}
+
+/* Handle */
+
+::-webkit-scrollbar-thumb {
+    background: #444;
+    border-radius: 2px;
+}
+
+/* Handle on hover */
+
+::-webkit-scrollbar-thumb:hover {
+    background: #333333;
+}
+
+.alert {
+    display: none;
+}
+
+.alert {
+    z-index: 9999;
+    position: fixed;
+    top: 10px;
+    width: auto;
+    left: 50%;
+    transform: translateX(-50%);
+}
+
+#triangle-topleft {
+    clip-path: polygon(0 0, 0% 100%, 100% 0);
+    background: #C4161C;
+    width: 100%;
+    height: 430px;
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 8 - 0
bg_remover/templates/static/css/overlayscrollbars.min.css


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
bg_remover/templates/static/css/select2-bootstrap4.min.css


BIN
bg_remover/templates/static/fonts/aptos-font/Aptos.eot


BIN
bg_remover/templates/static/fonts/aptos-font/Aptos.woff


BIN
bg_remover/templates/static/fonts/aptos-font/Aptos.woff2


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-black-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-black.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-bold.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-extrabold-italic 2.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-extrabold-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-extrabold.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-light-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-light.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos-semibold.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/__MACOSX/._aptos.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-black-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-black.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-bold.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-extrabold-italic 2.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-extrabold-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-extrabold.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-light-italic.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-light.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos-semibold.ttf


BIN
bg_remover/templates/static/fonts/aptos-font/aptos.ttf


BIN
bg_remover/templates/static/images/45.jpg


BIN
bg_remover/templates/static/images/bg.png


BIN
bg_remover/templates/static/images/left.png


BIN
bg_remover/templates/static/images/logo-mini.png


BIN
bg_remover/templates/static/images/logo.png


BIN
bg_remover/templates/static/images/user2-160x160.jpg


+ 715 - 0
bg_remover/templates/static/js/adminlte.js

@@ -0,0 +1,715 @@
+/*!
+ * AdminLTE v4.0.0-beta2 (https://adminlte.io)
+ * Copyright 2014-2024 Colorlib <https://colorlib.com>
+ * Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
+ */
+(function (global, factory) {
+    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+    typeof define === 'function' && define.amd ? define(['exports'], factory) :
+    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.adminlte = {}));
+})(this, (function (exports) { 'use strict';
+
+    const domContentLoadedCallbacks = [];
+    const onDOMContentLoaded = (callback) => {
+        if (document.readyState === 'loading') {
+            // add listener on the first call when the document is in loading state
+            if (!domContentLoadedCallbacks.length) {
+                document.addEventListener('DOMContentLoaded', () => {
+                    for (const callback of domContentLoadedCallbacks) {
+                        callback();
+                    }
+                });
+            }
+            domContentLoadedCallbacks.push(callback);
+        }
+        else {
+            callback();
+        }
+    };
+    /* SLIDE UP */
+    const slideUp = (target, duration = 500) => {
+        target.style.transitionProperty = 'height, margin, padding';
+        target.style.transitionDuration = `${duration}ms`;
+        target.style.boxSizing = 'border-box';
+        target.style.height = `${target.offsetHeight}px`;
+        target.style.overflow = 'hidden';
+        window.setTimeout(() => {
+            target.style.height = '0';
+            target.style.paddingTop = '0';
+            target.style.paddingBottom = '0';
+            target.style.marginTop = '0';
+            target.style.marginBottom = '0';
+        }, 1);
+        window.setTimeout(() => {
+            target.style.display = 'none';
+            target.style.removeProperty('height');
+            target.style.removeProperty('padding-top');
+            target.style.removeProperty('padding-bottom');
+            target.style.removeProperty('margin-top');
+            target.style.removeProperty('margin-bottom');
+            target.style.removeProperty('overflow');
+            target.style.removeProperty('transition-duration');
+            target.style.removeProperty('transition-property');
+        }, duration);
+    };
+    /* SLIDE DOWN */
+    const slideDown = (target, duration = 500) => {
+        target.style.removeProperty('display');
+        let { display } = window.getComputedStyle(target);
+        if (display === 'none') {
+            display = 'block';
+        }
+        target.style.display = display;
+        const height = target.offsetHeight;
+        target.style.overflow = 'hidden';
+        target.style.height = '0';
+        target.style.paddingTop = '0';
+        target.style.paddingBottom = '0';
+        target.style.marginTop = '0';
+        target.style.marginBottom = '0';
+        window.setTimeout(() => {
+            target.style.boxSizing = 'border-box';
+            target.style.transitionProperty = 'height, margin, padding';
+            target.style.transitionDuration = `${duration}ms`;
+            target.style.height = `${height}px`;
+            target.style.removeProperty('padding-top');
+            target.style.removeProperty('padding-bottom');
+            target.style.removeProperty('margin-top');
+            target.style.removeProperty('margin-bottom');
+        }, 1);
+        window.setTimeout(() => {
+            target.style.removeProperty('height');
+            target.style.removeProperty('overflow');
+            target.style.removeProperty('transition-duration');
+            target.style.removeProperty('transition-property');
+        }, duration);
+    };
+
+    /**
+     * --------------------------------------------
+     * @file AdminLTE layout.ts
+     * @description Layout for AdminLTE.
+     * @license MIT
+     * --------------------------------------------
+     */
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+    const CLASS_NAME_HOLD_TRANSITIONS = 'hold-transition';
+    const CLASS_NAME_APP_LOADED = 'app-loaded';
+    /**
+     * Class Definition
+     * ====================================================
+     */
+    class Layout {
+        constructor(element) {
+            this._element = element;
+        }
+        holdTransition() {
+            let resizeTimer;
+            window.addEventListener('resize', () => {
+                document.body.classList.add(CLASS_NAME_HOLD_TRANSITIONS);
+                clearTimeout(resizeTimer);
+                resizeTimer = setTimeout(() => {
+                    document.body.classList.remove(CLASS_NAME_HOLD_TRANSITIONS);
+                }, 400);
+            });
+        }
+    }
+    onDOMContentLoaded(() => {
+        const data = new Layout(document.body);
+        data.holdTransition();
+        setTimeout(() => {
+            document.body.classList.add(CLASS_NAME_APP_LOADED);
+        }, 400);
+    });
+
+    /**
+     * --------------------------------------------
+     * @file AdminLTE push-menu.ts
+     * @description Push menu for AdminLTE.
+     * @license MIT
+     * --------------------------------------------
+     */
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+    const DATA_KEY$4 = 'lte.push-menu';
+    const EVENT_KEY$4 = `.${DATA_KEY$4}`;
+    const EVENT_OPEN = `open${EVENT_KEY$4}`;
+    const EVENT_COLLAPSE = `collapse${EVENT_KEY$4}`;
+    const CLASS_NAME_SIDEBAR_MINI = 'sidebar-mini';
+    const CLASS_NAME_SIDEBAR_COLLAPSE = 'sidebar-collapse';
+    const CLASS_NAME_SIDEBAR_OPEN = 'sidebar-open';
+    const CLASS_NAME_SIDEBAR_EXPAND = 'sidebar-expand';
+    const CLASS_NAME_SIDEBAR_OVERLAY = 'sidebar-overlay';
+    const CLASS_NAME_MENU_OPEN$1 = 'menu-open';
+    const SELECTOR_APP_SIDEBAR = '.app-sidebar';
+    const SELECTOR_SIDEBAR_MENU = '.sidebar-menu';
+    const SELECTOR_NAV_ITEM$1 = '.nav-item';
+    const SELECTOR_NAV_TREEVIEW = '.nav-treeview';
+    const SELECTOR_APP_WRAPPER = '.app-wrapper';
+    const SELECTOR_SIDEBAR_EXPAND = `[class*="${CLASS_NAME_SIDEBAR_EXPAND}"]`;
+    const SELECTOR_SIDEBAR_TOGGLE = '[data-lte-toggle="sidebar"]';
+    const Defaults = {
+        sidebarBreakpoint: 992
+    };
+    /**
+     * Class Definition
+     * ====================================================
+     */
+    class PushMenu {
+        constructor(element, config) {
+            this._element = element;
+            this._config = Object.assign(Object.assign({}, Defaults), config);
+        }
+        // TODO
+        menusClose() {
+            const navTreeview = document.querySelectorAll(SELECTOR_NAV_TREEVIEW);
+            navTreeview.forEach(navTree => {
+                navTree.style.removeProperty('display');
+                navTree.style.removeProperty('height');
+            });
+            const navSidebar = document.querySelector(SELECTOR_SIDEBAR_MENU);
+            const navItem = navSidebar === null || navSidebar === void 0 ? void 0 : navSidebar.querySelectorAll(SELECTOR_NAV_ITEM$1);
+            if (navItem) {
+                navItem.forEach(navI => {
+                    navI.classList.remove(CLASS_NAME_MENU_OPEN$1);
+                });
+            }
+        }
+        expand() {
+            const event = new Event(EVENT_OPEN);
+            document.body.classList.remove(CLASS_NAME_SIDEBAR_COLLAPSE);
+            document.body.classList.add(CLASS_NAME_SIDEBAR_OPEN);
+            this._element.dispatchEvent(event);
+        }
+        collapse() {
+            const event = new Event(EVENT_COLLAPSE);
+            document.body.classList.remove(CLASS_NAME_SIDEBAR_OPEN);
+            document.body.classList.add(CLASS_NAME_SIDEBAR_COLLAPSE);
+            this._element.dispatchEvent(event);
+        }
+        addSidebarBreakPoint() {
+            var _a, _b, _c;
+            const sidebarExpandList = (_b = (_a = document.querySelector(SELECTOR_SIDEBAR_EXPAND)) === null || _a === void 0 ? void 0 : _a.classList) !== null && _b !== void 0 ? _b : [];
+            const sidebarExpand = (_c = Array.from(sidebarExpandList).find(className => className.startsWith(CLASS_NAME_SIDEBAR_EXPAND))) !== null && _c !== void 0 ? _c : '';
+            const sidebar = document.getElementsByClassName(sidebarExpand)[0];
+            const sidebarContent = window.getComputedStyle(sidebar, '::before').getPropertyValue('content');
+            this._config = Object.assign(Object.assign({}, this._config), { sidebarBreakpoint: Number(sidebarContent.replace(/[^\d.-]/g, '')) });
+            if (window.innerWidth <= this._config.sidebarBreakpoint) {
+                this.collapse();
+            }
+            else {
+                if (!document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI)) {
+                    this.expand();
+                }
+                if (document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI) && document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)) {
+                    this.collapse();
+                }
+            }
+        }
+        toggle() {
+            if (document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)) {
+                this.expand();
+            }
+            else {
+                this.collapse();
+            }
+        }
+        init() {
+            this.addSidebarBreakPoint();
+        }
+    }
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+    onDOMContentLoaded(() => {
+        var _a;
+        const sidebar = document === null || document === void 0 ? void 0 : document.querySelector(SELECTOR_APP_SIDEBAR);
+        if (sidebar) {
+            const data = new PushMenu(sidebar, Defaults);
+            data.init();
+            window.addEventListener('resize', () => {
+                data.init();
+            });
+        }
+        const sidebarOverlay = document.createElement('div');
+        sidebarOverlay.className = CLASS_NAME_SIDEBAR_OVERLAY;
+        (_a = document.querySelector(SELECTOR_APP_WRAPPER)) === null || _a === void 0 ? void 0 : _a.append(sidebarOverlay);
+        sidebarOverlay.addEventListener('touchstart', event => {
+            event.preventDefault();
+            const target = event.currentTarget;
+            const data = new PushMenu(target, Defaults);
+            data.collapse();
+        }, { passive: true });
+        sidebarOverlay.addEventListener('click', event => {
+            event.preventDefault();
+            const target = event.currentTarget;
+            const data = new PushMenu(target, Defaults);
+            data.collapse();
+        });
+        const fullBtn = document.querySelectorAll(SELECTOR_SIDEBAR_TOGGLE);
+        fullBtn.forEach(btn => {
+            btn.addEventListener('click', event => {
+                event.preventDefault();
+                let button = event.currentTarget;
+                if ((button === null || button === void 0 ? void 0 : button.dataset.lteToggle) !== 'sidebar') {
+                    button = button === null || button === void 0 ? void 0 : button.closest(SELECTOR_SIDEBAR_TOGGLE);
+                }
+                if (button) {
+                    event === null || event === void 0 ? void 0 : event.preventDefault();
+                    const data = new PushMenu(button, Defaults);
+                    data.toggle();
+                }
+            });
+        });
+    });
+
+    /**
+     * --------------------------------------------
+     * @file AdminLTE treeview.ts
+     * @description Treeview plugin for AdminLTE.
+     * @license MIT
+     * --------------------------------------------
+     */
+    /**
+     * ------------------------------------------------------------------------
+     * Constants
+     * ------------------------------------------------------------------------
+     */
+    // const NAME = 'Treeview'
+    const DATA_KEY$3 = 'lte.treeview';
+    const EVENT_KEY$3 = `.${DATA_KEY$3}`;
+    const EVENT_EXPANDED$2 = `expanded${EVENT_KEY$3}`;
+    const EVENT_COLLAPSED$2 = `collapsed${EVENT_KEY$3}`;
+    // const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
+    const CLASS_NAME_MENU_OPEN = 'menu-open';
+    const SELECTOR_NAV_ITEM = '.nav-item';
+    const SELECTOR_NAV_LINK = '.nav-link';
+    const SELECTOR_TREEVIEW_MENU = '.nav-treeview';
+    const SELECTOR_DATA_TOGGLE$1 = '[data-lte-toggle="treeview"]';
+    const Default$1 = {
+        animationSpeed: 300,
+        accordion: true
+    };
+    /**
+     * Class Definition
+     * ====================================================
+     */
+    class Treeview {
+        constructor(element, config) {
+            this._element = element;
+            this._config = Object.assign(Object.assign({}, Default$1), config);
+        }
+        open() {
+            var _a, _b;
+            const event = new Event(EVENT_EXPANDED$2);
+            if (this._config.accordion) {
+                const openMenuList = (_a = this._element.parentElement) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_NAV_ITEM}.${CLASS_NAME_MENU_OPEN}`);
+                openMenuList === null || openMenuList === void 0 ? void 0 : openMenuList.forEach(openMenu => {
+                    if (openMenu !== this._element.parentElement) {
+                        openMenu.classList.remove(CLASS_NAME_MENU_OPEN);
+                        const childElement = openMenu === null || openMenu === void 0 ? void 0 : openMenu.querySelector(SELECTOR_TREEVIEW_MENU);
+                        if (childElement) {
+                            slideUp(childElement, this._config.animationSpeed);
+                        }
+                    }
+                });
+            }
+            this._element.classList.add(CLASS_NAME_MENU_OPEN);
+            const childElement = (_b = this._element) === null || _b === void 0 ? void 0 : _b.querySelector(SELECTOR_TREEVIEW_MENU);
+            if (childElement) {
+                slideDown(childElement, this._config.animationSpeed);
+            }
+            this._element.dispatchEvent(event);
+        }
+        close() {
+            var _a;
+            const event = new Event(EVENT_COLLAPSED$2);
+            this._element.classList.remove(CLASS_NAME_MENU_OPEN);
+            const childElement = (_a = this._element) === null || _a === void 0 ? void 0 : _a.querySelector(SELECTOR_TREEVIEW_MENU);
+            if (childElement) {
+                slideUp(childElement, this._config.animationSpeed);
+            }
+            this._element.dispatchEvent(event);
+        }
+        toggle() {
+            if (this._element.classList.contains(CLASS_NAME_MENU_OPEN)) {
+                this.close();
+            }
+            else {
+                this.open();
+            }
+        }
+    }
+    /**
+     * ------------------------------------------------------------------------
+     * Data Api implementation
+     * ------------------------------------------------------------------------
+     */
+    onDOMContentLoaded(() => {
+        const button = document.querySelectorAll(SELECTOR_DATA_TOGGLE$1);
+        button.forEach(btn => {
+            btn.addEventListener('click', event => {
+                const target = event.target;
+                const targetItem = target.closest(SELECTOR_NAV_ITEM);
+                const targetLink = target.closest(SELECTOR_NAV_LINK);
+                if ((target === null || target === void 0 ? void 0 : target.getAttribute('href')) === '#' || (targetLink === null || targetLink === void 0 ? void 0 : targetLink.getAttribute('href')) === '#') {
+                    event.preventDefault();
+                }
+                if (targetItem) {
+                    const data = new Treeview(targetItem, Default$1);
+                    data.toggle();
+                }
+            });
+        });
+    });
+
+    /**
+     * --------------------------------------------
+     * @file AdminLTE direct-chat.ts
+     * @description Direct chat for AdminLTE.
+     * @license MIT
+     * --------------------------------------------
+     */
+    /**
+     * Constants
+     * ====================================================
+     */
+    const DATA_KEY$2 = 'lte.direct-chat';
+    const EVENT_KEY$2 = `.${DATA_KEY$2}`;
+    const EVENT_EXPANDED$1 = `expanded${EVENT_KEY$2}`;
+    const EVENT_COLLAPSED$1 = `collapsed${EVENT_KEY$2}`;
+    const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="chat-pane"]';
+    const SELECTOR_DIRECT_CHAT = '.direct-chat';
+    const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open';
+    /**
+     * Class Definition
+     * ====================================================
+     */
+    class DirectChat {
+        constructor(element) {
+            this._element = element;
+        }
+        toggle() {
+            if (this._element.classList.contains(CLASS_NAME_DIRECT_CHAT_OPEN)) {
+                const event = new Event(EVENT_COLLAPSED$1);
+                this._element.classList.remove(CLASS_NAME_DIRECT_CHAT_OPEN);
+                this._element.dispatchEvent(event);
+            }
+            else {
+                const event = new Event(EVENT_EXPANDED$1);
+                this._element.classList.add(CLASS_NAME_DIRECT_CHAT_OPEN);
+                this._element.dispatchEvent(event);
+            }
+        }
+    }
+    /**
+     *
+     * Data Api implementation
+     * ====================================================
+     */
+    onDOMContentLoaded(() => {
+        const button = document.querySelectorAll(SELECTOR_DATA_TOGGLE);
+        button.forEach(btn => {
+            btn.addEventListener('click', event => {
+                event.preventDefault();
+                const target = event.target;
+                const chatPane = target.closest(SELECTOR_DIRECT_CHAT);
+                if (chatPane) {
+                    const data = new DirectChat(chatPane);
+                    data.toggle();
+                }
+            });
+        });
+    });
+
+    /**
+     * --------------------------------------------
+     * @file AdminLTE card-widget.ts
+     * @description Card widget for AdminLTE.
+     * @license MIT
+     * --------------------------------------------
+     */
+    /**
+     * Constants
+     * ====================================================
+     */
+    const DATA_KEY$1 = 'lte.card-widget';
+    const EVENT_KEY$1 = `.${DATA_KEY$1}`;
+    const EVENT_COLLAPSED = `collapsed${EVENT_KEY$1}`;
+    const EVENT_EXPANDED = `expanded${EVENT_KEY$1}`;
+    const EVENT_REMOVE = `remove${EVENT_KEY$1}`;
+    const EVENT_MAXIMIZED$1 = `maximized${EVENT_KEY$1}`;
+    const EVENT_MINIMIZED$1 = `minimized${EVENT_KEY$1}`;
+    const CLASS_NAME_CARD = 'card';
+    const CLASS_NAME_COLLAPSED = 'collapsed-card';
+    const CLASS_NAME_COLLAPSING = 'collapsing-card';
+    const CLASS_NAME_EXPANDING = 'expanding-card';
+    const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed';
+    const CLASS_NAME_MAXIMIZED = 'maximized-card';
+    const SELECTOR_DATA_REMOVE = '[data-lte-toggle="card-remove"]';
+    const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]';
+    const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]';
+    const SELECTOR_CARD = `.${CLASS_NAME_CARD}`;
+    const SELECTOR_CARD_BODY = '.card-body';
+    const SELECTOR_CARD_FOOTER = '.card-footer';
+    const Default = {
+        animationSpeed: 500,
+        collapseTrigger: SELECTOR_DATA_COLLAPSE,
+        removeTrigger: SELECTOR_DATA_REMOVE,
+        maximizeTrigger: SELECTOR_DATA_MAXIMIZE
+    };
+    class CardWidget {
+        constructor(element, config) {
+            this._element = element;
+            this._parent = element.closest(SELECTOR_CARD);
+            if (element.classList.contains(CLASS_NAME_CARD)) {
+                this._parent = element;
+            }
+            this._config = Object.assign(Object.assign({}, Default), config);
+        }
+        collapse() {
+            var _a, _b;
+            const event = new Event(EVENT_COLLAPSED);
+            if (this._parent) {
+                this._parent.classList.add(CLASS_NAME_COLLAPSING);
+                const elm = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
+                elm.forEach(el => {
+                    if (el instanceof HTMLElement) {
+                        slideUp(el, this._config.animationSpeed);
+                    }
+                });
+                setTimeout(() => {
+                    if (this._parent) {
+                        this._parent.classList.add(CLASS_NAME_COLLAPSED);
+                        this._parent.classList.remove(CLASS_NAME_COLLAPSING);
+                    }
+                }, this._config.animationSpeed);
+            }
+            (_b = this._element) === null || _b === void 0 ? void 0 : _b.dispatchEvent(event);
+        }
+        expand() {
+            var _a, _b;
+            const event = new Event(EVENT_EXPANDED);
+            if (this._parent) {
+                this._parent.classList.add(CLASS_NAME_EXPANDING);
+                const elm = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
+                elm.forEach(el => {
+                    if (el instanceof HTMLElement) {
+                        slideDown(el, this._config.animationSpeed);
+                    }
+                });
+                setTimeout(() => {
+                    if (this._parent) {
+                        this._parent.classList.remove(CLASS_NAME_COLLAPSED);
+                        this._parent.classList.remove(CLASS_NAME_EXPANDING);
+                    }
+                }, this._config.animationSpeed);
+            }
+            (_b = this._element) === null || _b === void 0 ? void 0 : _b.dispatchEvent(event);
+        }
+        remove() {
+            var _a;
+            const event = new Event(EVENT_REMOVE);
+            if (this._parent) {
+                slideUp(this._parent, this._config.animationSpeed);
+            }
+            (_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
+        }
+        toggle() {
+            var _a;
+            if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_COLLAPSED)) {
+                this.expand();
+                return;
+            }
+            this.collapse();
+        }
+        maximize() {
+            var _a;
+            const event = new Event(EVENT_MAXIMIZED$1);
+            if (this._parent) {
+                this._parent.style.height = `${this._parent.offsetHeight}px`;
+                this._parent.style.width = `${this._parent.offsetWidth}px`;
+                this._parent.style.transition = 'all .15s';
+                setTimeout(() => {
+                    const htmlTag = document.querySelector('html');
+                    if (htmlTag) {
+                        htmlTag.classList.add(CLASS_NAME_MAXIMIZED);
+                    }
+                    if (this._parent) {
+                        this._parent.classList.add(CLASS_NAME_MAXIMIZED);
+                        if (this._parent.classList.contains(CLASS_NAME_COLLAPSED)) {
+                            this._parent.classList.add(CLASS_NAME_WAS_COLLAPSED);
+                        }
+                    }
+                }, 150);
+            }
+            (_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
+        }
+        minimize() {
+            var _a;
+            const event = new Event(EVENT_MINIMIZED$1);
+            if (this._parent) {
+                this._parent.style.height = 'auto';
+                this._parent.style.width = 'auto';
+                this._parent.style.transition = 'all .15s';
+                setTimeout(() => {
+                    var _a;
+                    const htmlTag = document.querySelector('html');
+                    if (htmlTag) {
+                        htmlTag.classList.remove(CLASS_NAME_MAXIMIZED);
+                    }
+                    if (this._parent) {
+                        this._parent.classList.remove(CLASS_NAME_MAXIMIZED);
+                        if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_WAS_COLLAPSED)) {
+                            this._parent.classList.remove(CLASS_NAME_WAS_COLLAPSED);
+                        }
+                    }
+                }, 10);
+            }
+            (_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
+        }
+        toggleMaximize() {
+            var _a;
+            if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_MAXIMIZED)) {
+                this.minimize();
+                return;
+            }
+            this.maximize();
+        }
+    }
+    /**
+     *
+     * Data Api implementation
+     * ====================================================
+     */
+    onDOMContentLoaded(() => {
+        const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE);
+        collapseBtn.forEach(btn => {
+            btn.addEventListener('click', event => {
+                event.preventDefault();
+                const target = event.target;
+                const data = new CardWidget(target, Default);
+                data.toggle();
+            });
+        });
+        const removeBtn = document.querySelectorAll(SELECTOR_DATA_REMOVE);
+        removeBtn.forEach(btn => {
+            btn.addEventListener('click', event => {
+                event.preventDefault();
+                const target = event.target;
+                const data = new CardWidget(target, Default);
+                data.remove();
+            });
+        });
+        const maxBtn = document.querySelectorAll(SELECTOR_DATA_MAXIMIZE);
+        maxBtn.forEach(btn => {
+            btn.addEventListener('click', event => {
+                event.preventDefault();
+                const target = event.target;
+                const data = new CardWidget(target, Default);
+                data.toggleMaximize();
+            });
+        });
+    });
+
+    /**
+     * --------------------------------------------
+     * @file AdminLTE fullscreen.ts
+     * @description Fullscreen plugin for AdminLTE.
+     * @license MIT
+     * --------------------------------------------
+     */
+    /**
+     * Constants
+     * ============================================================================
+     */
+    const DATA_KEY = 'lte.fullscreen';
+    const EVENT_KEY = `.${DATA_KEY}`;
+    const EVENT_MAXIMIZED = `maximized${EVENT_KEY}`;
+    const EVENT_MINIMIZED = `minimized${EVENT_KEY}`;
+    const SELECTOR_FULLSCREEN_TOGGLE = '[data-lte-toggle="fullscreen"]';
+    const SELECTOR_MAXIMIZE_ICON = '[data-lte-icon="maximize"]';
+    const SELECTOR_MINIMIZE_ICON = '[data-lte-icon="minimize"]';
+    /**
+     * Class Definition.
+     * ============================================================================
+     */
+    class FullScreen {
+        constructor(element, config) {
+            this._element = element;
+            this._config = config;
+        }
+        inFullScreen() {
+            const event = new Event(EVENT_MAXIMIZED);
+            const iconMaximize = document.querySelector(SELECTOR_MAXIMIZE_ICON);
+            const iconMinimize = document.querySelector(SELECTOR_MINIMIZE_ICON);
+            void document.documentElement.requestFullscreen();
+            if (iconMaximize) {
+                iconMaximize.style.display = 'none';
+            }
+            if (iconMinimize) {
+                iconMinimize.style.display = 'block';
+            }
+            this._element.dispatchEvent(event);
+        }
+        outFullscreen() {
+            const event = new Event(EVENT_MINIMIZED);
+            const iconMaximize = document.querySelector(SELECTOR_MAXIMIZE_ICON);
+            const iconMinimize = document.querySelector(SELECTOR_MINIMIZE_ICON);
+            void document.exitFullscreen();
+            if (iconMaximize) {
+                iconMaximize.style.display = 'block';
+            }
+            if (iconMinimize) {
+                iconMinimize.style.display = 'none';
+            }
+            this._element.dispatchEvent(event);
+        }
+        toggleFullScreen() {
+            if (document.fullscreenEnabled) {
+                if (document.fullscreenElement) {
+                    this.outFullscreen();
+                }
+                else {
+                    this.inFullScreen();
+                }
+            }
+        }
+    }
+    /**
+     * Data Api implementation
+     * ============================================================================
+     */
+    onDOMContentLoaded(() => {
+        const buttons = document.querySelectorAll(SELECTOR_FULLSCREEN_TOGGLE);
+        buttons.forEach(btn => {
+            btn.addEventListener('click', event => {
+                event.preventDefault();
+                const target = event.target;
+                const button = target.closest(SELECTOR_FULLSCREEN_TOGGLE);
+                if (button) {
+                    const data = new FullScreen(button, undefined);
+                    data.toggleFullScreen();
+                }
+            });
+        });
+    });
+
+    exports.CardWidget = CardWidget;
+    exports.DirectChat = DirectChat;
+    exports.FullScreen = FullScreen;
+    exports.Layout = Layout;
+    exports.PushMenu = PushMenu;
+    exports.Treeview = Treeview;
+
+}));
+//# sourceMappingURL=adminlte.js.map

+ 1214 - 0
bg_remover/templates/static/js/attr-extraction-bkp.js

@@ -0,0 +1,1214 @@
+jQuery.noConflict(); // Release $ to other libraries
+// console.log(typeof jQuery);
+// $ = jQuery;
+
+// --- Config ---
+const UPLOAD_API_URL = '/attr/products/upload-excel/'; // TODO: set to your upload endpoint
+const ACCEPT_TYPES = '*'; // e.g., 'image/*,.csv,.xlsx'
+
+
+const thresholdInput = document.getElementById('thresholdRange');
+const thresholdValueDisplay = document.getElementById('thresholdValue');
+
+
+var PRODUCT_BASE = [
+    // { id: 1, item_id: 'SKU001', product_name: "Levi's Jeans", product_long_description: 'Classic blue denim jeans with straight fit.', product_short_description: 'Blue denim jeans.', product_type: 'Clothing', image_path: 'media/products/jeans.jpg', image: 'http://127.0.0.1:8000/media/products/jeans.png' },
+    // { id: 2, item_id: 'SKU002', product_name: 'Adidas Running Shoes', product_long_description: 'Lightweight running shoes with breathable mesh and cushioned sole.', product_short_description: "Men's running shoes.", product_type: 'Footwear', image_path: 'media/products/shoes.png', image: 'http://127.0.0.1:8000/media/products/shoes.png' },
+    // { id: 3, item_id: 'SKU003', product_name: 'Nike Sports T-Shirt', product_long_description: 'Moisture-wicking sports tee ideal for training and outdoor activities.', product_short_description: 'Performance t-shirt.', product_type: 'Clothing', image_path: 'media/products/tshirt.png', image: 'http://127.0.0.1:8000/media/products/tshirt.png' },
+    // { id: 4, item_id: 'SKU004', product_name: 'Puma Hoodie', product_long_description: 'Soft fleece hoodie with kangaroo pocket and adjustable drawstring.', product_short_description: 'Casual hoodie.', product_type: 'Clothing', image_path: 'media/products/hoodie.png', image: 'http://127.0.0.1:8000/media/products/hoodie.png' },
+    // { id: 5, item_id: 'SKU005', product_name: 'Ray-Ban Sunglasses', product_long_description: 'Classic aviator sunglasses with UV protection lenses.', product_short_description: 'Aviator sunglasses.', product_type: 'Accessories', image_path: 'media/products/sunglasses.png', image: 'http://127.0.0.1:8000/media/products/sunglasses.png' }
+];
+// --- Data ---
+const mediaUrl = "./../";
+
+document.addEventListener('DOMContentLoaded', () => {
+    jQuery('#full-page-loader').show();  
+    fetch('/attr/products', {
+        method: 'GET', // or 'POST' if your API expects POST
+        headers: {
+            'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]')?.value || ''
+        }
+    })
+    .then(response => response.json())
+    .then(data => {
+        // console.log("data",data);
+        // --- Wire up ---
+        PRODUCT_BASE = data;
+        PRODUCT_BASE = PRODUCT_BASE.map((d)=>{return {...d,mandatoryAttributes:["color","size"]}});
+        // console.log("PRODUCT_BASE",PRODUCT_BASE);
+        if(PRODUCT_BASE.length > 0){
+            $('#paginationBar').style.display = 'block';
+        }
+        renderProducts();
+        getAtributeList();
+        document.getElementById('btnSubmit').addEventListener('click', submitAttributes);
+        document.getElementById('btnReset').addEventListener('click', resetAll);
+        // document.getElementById('btnSelectAll').addEventListener('click', () => {
+        // if (selectedIds.size === PRODUCT_BASE.length) { selectedIds.clear(); } else { selectedIds = new Set(PRODUCT_BASE.map(p => p.id)); }
+        // // renderProducts();
+        // });
+
+        // Replace your existing Select All listener with this:
+          document.getElementById('btnSelectAll').addEventListener('click', () => {
+            // Use the container for the active layout
+            const container = (layoutMode === 'cards')
+              ? document.getElementById('cardsContainer')
+              : document.getElementById('tableContainer');
+
+            // Collect all visible checkboxes
+            const boxes = Array.from(container.querySelectorAll('input[type="checkbox"]'));
+
+            // If every visible checkbox is already checked, we'll deselect; otherwise select all
+            const allChecked = boxes.length > 0 && boxes.every(cb => cb.checked);
+
+            boxes.forEach(cb => {
+              const target = !allChecked; // true to select, false to deselect
+              if (cb.checked !== target) {
+                cb.checked = target;
+                // Trigger your existing "change" handler so selectedIds & row .selected class update
+                cb.dispatchEvent(new Event('change', { bubbles: true }));
+              }
+            });
+
+            // Update the selection pill text (doesn't re-render the list)
+            updateSelectionInfo();
+          });
+        document.getElementById('btnCards').addEventListener('click', () => setLayout('cards'));
+        document.getElementById('btnTable').addEventListener('click', () => setLayout('table'));
+        jQuery('#full-page-loader').hide();
+        // if (data.success) {
+        // }
+    });
+});
+
+var FAKE_API_RESPONSE = {
+    // results: [
+    // { product_id: 'SKU001', mandatory: { 'Clothing Neck Style': 'V-Neck', 'Clothing Top Style': 'Pullover', 'Condition': 'New', 'T-Shirt Type': 'Classic T-Shirt' }, additional: { 'Material': 'Turkish Pima Cotton', 'Size': 'Large', 'Color': 'Blue', 'Brand': 'Sierra', 'Fabric Type': 'Soft & Breathable', 'Fabric Composition': '95% Turkish Pima cotton', 'Care Instructions': 'Machine Washable', 'Sizes Available': 'S-XL' } },
+    // { product_id: 'SKU002', mandatory: { 'Shoe Type': 'Running', 'Closure': 'Lace-Up', 'Condition': 'New', 'Gender': 'Men' }, additional: { 'Upper Material': 'Engineered Mesh', 'Midsole': 'EVA Foam', 'Outsole': 'Rubber', 'Color': 'Black/White', 'Brand': 'Adidas', 'Size': 'UK 9', 'Care Instructions': 'Surface Clean' } },
+    // { product_id: 'SKU003', mandatory: { 'Clothing Neck Style': 'Crew Neck', 'Sleeve Length': 'Short Sleeve', 'Condition': 'New', 'T-Shirt Type': 'Performance' }, additional: { 'Material': 'Polyester Blend', 'Color': 'Red', 'Brand': 'Nike', 'Size': 'Medium', 'Fabric Technology': 'Dri-FIT', 'Care Instructions': 'Machine Wash Cold' } },
+    // { product_id: 'SKU004', mandatory: { 'Clothing Top Style': 'Hoodie', 'Closure': 'Pullover', 'Condition': 'New', 'Fit': 'Relaxed' }, additional: { 'Material': 'Cotton Fleece', 'Color': 'Charcoal', 'Brand': 'Puma', 'Size': 'Large', 'Care Instructions': 'Machine Wash Warm' } },
+    // { product_id: 'SKU005', mandatory: { 'Accessory Type': 'Sunglasses', 'Frame Style': 'Aviator', 'Condition': 'New', 'Lens Protection': 'UV 400' }, additional: { 'Frame Material': 'Metal', 'Lens Color': 'Green', 'Brand': 'Ray-Ban', 'Size': 'Standard', 'Case Included': 'Yes', 'Care Instructions': 'Clean with microfiber' } }
+    // ],
+    // total_products: 5,
+    // successful: 5,
+    // failed: 0
+};
+
+// --- State ---
+let selectedIds = new Set();
+// NEW: Array of objects { item_id: string, mandatory_attrs: { [attribute_name]: string[] } }
+let selectedProductsWithAttributes = [];
+let selectedAttributes = new Array();
+const lastSeen = new Map(); // per-product memory for NEW highlighting (product_id -> maps)
+let layoutMode = 'table'; // 'cards' | 'table'
+
+// --- Helpers ---
+const $ = (sel) => document.querySelector(sel);
+const el = (tag, cls) => { const e = document.createElement(tag); if (cls) e.className = cls; return e; }
+
+function updateSelectionInfo() {
+    const pill = $('#selectionInfo');
+    const total = PRODUCT_BASE.length;
+    // const count = selectedIds.size;
+    const count = selectedProductsWithAttributes.length;
+    pill.textContent = count === 0 ? 'No products selected' : `${count} of ${total} selected`;
+}
+
+function setChecked(id, checked) { if (checked) selectedIds.add(id); else selectedIds.delete(id); updateSelectionInfo(); }
+// function setCheckedAttributes(id,attribute, checked) { if (checked) selectedAttributes.add({id: [attribute]}); else selectedIds.delete({id:[attribute]}); updateSelectionInfo(); }
+function formatString(str) {
+  return str
+    // Replace underscores with spaces
+    .replace(/_/g, ' ')
+    // Insert a space before any uppercase letter (except at the start)
+    .replace(/([a-z])([A-Z])/g, '$1 $2')
+    // Capitalize the first letter
+    .replace(/^./, char => char.toUpperCase());
+}
+
+// --- Chips rendering ---
+function renderChips(container, obj, memoryMap) {
+    container.innerHTML = '';
+    let count = 0;
+    Object.entries(obj || {}).forEach(([k, v]) => {
+    const chip = el('span', 'chip');
+    const kEl = el('span', 'k'); kEl.textContent = formatString(k) + ':';
+    // console.log("v",v);
+    let resVal = "";
+    let sourceVal = "";
+    if(v instanceof Array){
+        resVal  = String(v.map(v => formatString(v.value)).join(", "));
+        sourceVal = String(formatString(v[0]?.source));
+        const vEl = el('span', 'v'); vEl.textContent = ' ' + resVal  +' (' + sourceVal + ')';
+        chip.appendChild(kEl); chip.appendChild(vEl);
+    }
+    // console.log("k",k);
+    if(v instanceof Array){
+    const was = memoryMap.get(k);
+    if (was === undefined || was !== v) chip.classList.add('new');
+    container.appendChild(chip);
+    memoryMap.set(k, v);
+    
+    count++;
+    }
+    });
+    return count;
+}
+
+function findApiResultForProduct(p, index, api) { return api.results?.find(r => r.product_id === p.item_id) || api.results?.[index] || null; }
+
+// --- Cards layout ---
+function createProductCard(p) {
+    const row = el('div', 'product');
+    // Check selection using the new helper
+    if (isProductSelected(p.item_id)) row.classList.add('selected');
+    // if (selectedIds.has(p.item_id)) row.classList.add('selected');
+
+    const left = el('div', 'thumb');
+    const img = new Image(); img.src = p.image_path || p.image || '';
+    // console.log("image path",p.image_path);
+     img.alt = `${p.product_name} image`;
+    // console.log("img",img);
+    // img.onerror = () => { img.remove(); const fb = el('div', 'fallback'); fb.textContent = (p.product_name || 'Product').split(' ').map(w => w[0]).slice(0,2).join('').toUpperCase(); left.appendChild(fb); };
+    img.onerror = () => { img.src = mediaUrl+"media/images/no-product.png" };
+    left.appendChild(img);
+
+    const mid = el('div', 'meta');
+    const name = el('div', 'name'); name.textContent = p.product_name || '—';
+    const desc = el('div', 'desc'); desc.innerHTML = p.product_short_description || '';
+    const badges = el('div', 'badges');
+    const sku = el('span', 'pill'); sku.textContent = `SKU: ${p.item_id || '—'}`; badges.appendChild(sku);
+    const type = el('span', 'pill'); type.textContent = p.product_type || '—'; badges.appendChild(type);
+    const long = el('div', 'desc'); long.innerHTML = p.product_long_description || ''; long.style.marginTop = '4px';
+    mid.appendChild(name); mid.appendChild(desc); mid.appendChild(badges); mid.appendChild(long);
+
+    // Helper function to create the chip UI for attributes
+    function createAttributeChips(p, attr, initialSelected, isMandatory, updateCallback) {
+        const wrapper = el('div', 'attribute-chip-group');
+        wrapper.dataset.attrName = attr.attribute_name;
+        wrapper.innerHTML = `<p class="attribute-header">${attr.attribute_name} (${isMandatory ? 'Mandatory' : 'Optional'}):</p>`;
+
+        const chipContainer = el('div', 'chips-container');
+
+        attr.possible_values.forEach(value => {
+            const chip = el('label', 'attribute-chip');
+            
+            // Checkbox input is hidden, but drives the selection state
+            const checkbox = document.createElement('input');
+            checkbox.type = 'checkbox';
+            checkbox.value = value;
+            checkbox.name = `${p.item_id}-${attr.attribute_name}`;
+            
+            // Set initial state
+            checkbox.checked = initialSelected.includes(value); 
+            
+            // The visual part of the chip
+            const span = el('span');
+            span.textContent = value;
+            
+            chip.appendChild(checkbox);
+            chip.appendChild(span);
+            chipContainer.appendChild(chip);
+        });
+        
+        // Use event delegation on the container for performance
+        chipContainer.addEventListener('change', updateCallback);
+
+        wrapper.appendChild(chipContainer);
+        return wrapper;
+    }
+
+    // --- Main Select Checkbox (Product Selection) ---
+    const right = el('label', 'select');
+    const cb = document.createElement('input'); cb.type = 'checkbox';
+    cb.checked = isProductSelected(p.item_id);
+    const lbl = el('span'); lbl.textContent = 'Select Product';
+    right.appendChild(cb); right.appendChild(lbl);
+
+    
+    // --- Dynamic Attribute Selects ---
+    const attrContainer = el('div', 'attribute-selectors');
+if(p.product_type_details.length > 0){
+    // Find all mandatory and non-mandatory attributes for this product
+    const mandatoryAttributes = p.product_type_details?.filter(a => a.is_mandatory === 'Yes') || [];
+    const optionalAttributes = p.product_type_details?.filter(a => a.is_mandatory !== 'Yes') || [];
+
+    // Helper to update the main state object with all current selections
+    const updateProductState = () => {
+        const isSelected = cb.checked;
+        const currentSelections = {};
+
+        if (isSelected) {
+            // Iterate over all attribute groups (Mandatory and Optional)
+            attrContainer.querySelectorAll('.attribute-chip-group').forEach(group => {
+                const attrName = group.dataset.attrName;
+                
+                // Collect selected chip values
+                const selectedOptions = Array.from(group.querySelectorAll('input[type="checkbox"]:checked'))
+                    .map(checkbox => checkbox.value);
+
+                if (selectedOptions.length > 0) {
+                    currentSelections[attrName] = selectedOptions;
+                }
+            });
+        }
+        
+        toggleProductSelection(p.item_id, isSelected, currentSelections);
+        row.classList.toggle('selected', isSelected);
+    };
+
+    // Attach listener to main checkbox
+    cb.addEventListener('change', () => {
+        attrContainer.classList.toggle('disabled', !cb.checked);
+        updateProductState();
+    });
+    
+    // --- Render Mandatory Attributes ---
+    if (mandatoryAttributes.length > 0) {
+        const manTitle = el('p', "pSelectRight mandatory-title");
+        manTitle.innerHTML = "Mandatory Attributes:";
+        attrContainer.appendChild(manTitle);
+
+        mandatoryAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr.attribute_name] || attr.possible_values;
+            const chipGroup = createAttributeChips(p, attr, initialSelected, true, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+
+    // --- Render Optional Attributes ---
+    if (optionalAttributes.length > 0) {
+      const br = el('br');
+        const optTitle = el('p', "pSelectRight optional-title");
+        optTitle.innerHTML = "Additional Attributes:";
+        attrContainer.appendChild(br);
+        attrContainer.appendChild(optTitle);
+
+        optionalAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr.attribute_name] || attr.possible_values;
+            const chipGroup = createAttributeChips(p, attr, initialSelected, false, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+
+    // Initialize attribute selectors' enabled state and state data
+    attrContainer.classList.toggle('disabled', !cb.checked);
+    // Initial state setup if the product was already selected (e.g., after a re-render)
+    if (cb.checked) {
+        // This is important to set the initial state correctly on load
+        // We defer this until all selects are mounted, or ensure the initial state is correct.
+        // For simplicity, we assume the data from PRODUCT_BASE already includes selected attributes if a selection exists
+        // (which it won't in this case, so they default to all/empty)
+    }
+    }
+
+    const inline = el('div', 'attr-inline');
+    inline.dataset.pid = p.item_id; // use item_id for mapping
+    
+    row.appendChild(left); row.appendChild(mid);
+    if(p.product_type_details.length > 0){
+        console.log("IN ");
+        row.appendChild(attrContainer); // Append the new attribute selectors container
+    }    
+    row.appendChild(right);
+    // if (p.mandatoryAttributes && p.mandatoryAttributes.length > 0) { 
+      // const hr = el('hr');
+      // row.appendChild(hr);
+      // row.appendChild(attri);
+      // row.appendChild(secondRight);
+    // }
+
+    row.appendChild(inline);
+    
+    return row;
+}
+
+
+// Cards layout
+function renderProductsCards(items = getCurrentSlice()) {
+  const cards = document.getElementById('cardsContainer');
+  cards.innerHTML = '';
+  if(items.length > 0){
+    items.forEach(p => cards.appendChild(createProductCard(p)));
+  }else{
+      cards.innerHTML = "<p>No Products Found.</p>"
+  }
+}
+
+
+// --- Table layout ---
+function createMiniThumb(p) {
+    const mt = el('div', 'mini-thumb');
+    const img = new Image(); img.src = p.image_path || p.image || ''; img.alt = `${p.product_name} image`;
+    // console.log("image path",p.image_path);
+    // console.log("img",img);
+    img.onerror = () => { img.src = mediaUrl+"media/images/no-product.png" };
+    // img.onerror = () => { img.remove(); const fb = el('div', 'fallback'); fb.textContent = (p.product_name || 'Product').split(' ').map(w => w[0]).slice(0,2).join('').toUpperCase(); mt.appendChild(fb); };
+    mt.appendChild(img);
+    return mt;
+}
+
+
+// Table layout
+// function renderProductsTable(items = getCurrentSlice()) {
+//   const wrap = document.getElementById('tableContainer');
+//   wrap.innerHTML = '';
+//   const table = document.createElement('table');
+//   const thead = document.createElement('thead'); const trh = document.createElement('tr');
+//   ['Select', 'Image', 'Product', 'SKU', 'Type', 'Short Description'].forEach(h => {
+//     const th = document.createElement('th'); th.textContent = h; trh.appendChild(th);
+//   });
+//   thead.appendChild(trh); table.appendChild(thead);
+//   const tbody = document.createElement('tbody');
+//   if(items.length > 0 ){
+//     items.forEach(p => {
+//         const tr = document.createElement('tr'); tr.id = `row-${p.id}`;
+//         const tdSel = document.createElement('td'); tdSel.className = 'select-cell';
+//         const cb = document.createElement('input'); cb.type = 'checkbox'; cb.checked = selectedIds.has(p.item_id);
+//         cb.addEventListener('change', () => { setChecked(p.item_id, cb.checked); tr.classList.toggle('selected', cb.checked); });
+//         tdSel.appendChild(cb); tr.appendChild(tdSel);
+
+//         const tdImg = document.createElement('td'); tdImg.className = 'thumb-cell'; tdImg.appendChild(createMiniThumb(p)); tr.appendChild(tdImg);
+//         const tdName = document.createElement('td'); tdName.textContent = p.product_name || '—'; tr.appendChild(tdName);
+//         const tdSku  = document.createElement('td'); tdSku.textContent = p.item_id || '—'; tr.appendChild(tdSku);
+//         const tdType = document.createElement('td'); const b = document.createElement('span'); b.className = 'badge'; b.textContent = p.product_type || '—'; tdType.appendChild(b); tr.appendChild(tdType);
+//         const tdDesc = document.createElement('td'); tdDesc.textContent = p.product_short_description || ''; tr.appendChild(tdDesc);
+
+//         tr.addEventListener('click', (e) => { if (e.target.tagName.toLowerCase() !== 'input') { cb.checked = !cb.checked; cb.dispatchEvent(new Event('change')); } });
+//         tbody.appendChild(tr);
+//     });
+//   }else{
+//     const tr = el('tr'); 
+//     // tr.id = `row-${p.id}`;
+//     const tdName = el('td');
+//     tdName.colSpan = 6;
+//     tdName.innerHTML = "No Products Found."
+//     tr.appendChild(tdName);
+//     // tr.colspan = 6;
+//     // tr.innerHTML 
+//     tbody.appendChild(tr);
+//   }
+
+//   table.appendChild(tbody);
+//   wrap.appendChild(table);
+// }
+
+// NOTE: Ensure getProductStateUpdater and generateAttributeUI functions are defined globally or accessible here.
+
+/**
+ * Returns a closure function that updates the global selectedProductsWithAttributes state
+ * based on the current selections (chips) found in the DOM for a specific product.
+ * This is used for both card and table views.
+ * * @param {Object} p - The product object.
+ * @param {HTMLElement} cb - The main product selection checkbox element.
+ * @param {HTMLElement} tr - The main row/card element (used for toggling 'selected' class).
+ * @returns {function} A function to be used as the attribute change handler.
+ */
+const getProductStateUpdater = (p, cb, tr) => () => {
+    const isSelected = cb.checked;
+    const currentSelections = {};
+    
+    // Find the attribute container using its unique ID, which is the same structure 
+    // used in both card and table detail views (e.g., 'attr-container-124353498' or just the main card element).
+    // For card view, the container is often the attrContainer element itself. 
+    // For table view, we use the explicit ID.
+    const attrContainer = document.getElementById(`attr-container-${p.item_id}`) || tr.querySelector('.attribute-selectors');
+
+    if (isSelected && attrContainer) {
+        // Iterate over all attribute groups (Mandatory and Optional) within the container
+        attrContainer.querySelectorAll('.attribute-chip-group').forEach(group => {
+            const attrName = group.dataset.attrName;
+            
+            // Collect selected chip values
+            const selectedOptions = Array.from(group.querySelectorAll('input[type="checkbox"]:checked'))
+                .map(checkbox => checkbox.value);
+
+            // Only add to the selection if at least one option is selected
+            if (selectedOptions.length > 0) {
+                currentSelections[attrName] = selectedOptions;
+            }
+        });
+    }
+    
+    // Update the global state array (selectedProductsWithAttributes)
+    toggleProductSelection(p.item_id, isSelected, currentSelections);
+    
+    // Update the visual status of the row/card
+    tr.classList.toggle('selected', isSelected);
+};
+
+/**
+ * Generates the full attribute selection UI (chips) for a given product.
+ * NOTE: Assumes el(), createAttributeChips(), and getSelectedAttributes() are defined globally.
+ * @param {Object} p - The product object from PRODUCT_BASE.
+ * @param {function} updateProductState - The callback to run on chip changes.
+ * @param {HTMLElement} attrContainer - The container to append the UI to.
+ */
+function generateAttributeUI(p, updateProductState, attrContainer) {
+    // Clear the container first, just in case
+    attrContainer.innerHTML = ''; 
+
+    const mandatoryAttributes = p.product_type_details?.filter(a => a.is_mandatory === 'Yes') || [];
+    const optionalAttributes = p.product_type_details?.filter(a => a.is_mandatory !== 'Yes') || [];
+
+    // --- Render Mandatory Attributes ---
+    if (mandatoryAttributes.length > 0) {
+        // Use a general title for the section header
+        const manTitle = el('p', "pSelectRight mandatory-title");
+        manTitle.innerHTML = "Mandatory Attributes:";
+        attrContainer.appendChild(manTitle);
+
+        mandatoryAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr.attribute_name] || attr.possible_values;
+            // The createAttributeChips function must be globally available
+            const chipGroup = createAttributeChips(p, attr, initialSelected, true, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+
+    // --- Render Optional Attributes ---
+    if (optionalAttributes.length > 0) {
+        // Add visual separation using the optional-title class
+        const optTitle = el('p', "pSelectRight optional-title");
+        optTitle.innerHTML = "Additional Attributes:";
+        
+        // Append the title for separation
+        attrContainer.appendChild(optTitle);
+
+        optionalAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr.attribute_name] || attr.possible_values;
+            const chipGroup = createAttributeChips(p, attr, initialSelected, false, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+}
+
+/**
+ * Creates the HTML structure for a single attribute group using chip/checkbox labels.
+ * Assumes the helper function 'el' is available.
+ * * @param {Object} p - The product object.
+ * @param {Object} attr - The specific attribute detail object.
+ * @param {string[]} initialSelected - Array of values that should be pre-checked.
+ * @param {boolean} isMandatory - True if the attribute is mandatory.
+ * @param {function} updateCallback - The function to call when a chip selection changes.
+ * @returns {HTMLElement} The attribute chip group container (div).
+ */
+function createAttributeChips(p, attr, initialSelected, isMandatory, updateCallback) {
+    const wrapper = el('div', 'attribute-chip-group');
+    wrapper.dataset.attrName = attr.attribute_name;
+    
+    // Determine the header text based on structure preference (e.g., just the name)
+    const statusText = isMandatory ? ' (Mandatory)' : ' (Optional)';
+    wrapper.innerHTML = `<p class="attribute-header">${attr.attribute_name}${statusText}:</p>`;
+
+    const chipContainer = el('div', 'chips-container');
+
+    attr.possible_values.forEach(value => {
+        const chip = el('label', 'attribute-chip');
+        
+        // Checkbox input is hidden, but drives the selection state
+        const checkbox = document.createElement('input');
+        checkbox.type = 'checkbox';
+        checkbox.value = value;
+        // Ensure the name is unique per product/attribute group
+        checkbox.name = `${p.item_id}-${attr.attribute_name}`; 
+        
+        // Set initial state
+        checkbox.checked = initialSelected.includes(value); 
+        
+        // The visual part of the chip
+        const span = el('span');
+        span.textContent = value;
+        
+        chip.appendChild(checkbox);
+        chip.appendChild(span);
+        chipContainer.appendChild(chip);
+    });
+    
+    // Attach listener to the container using event delegation
+    chipContainer.addEventListener('change', updateCallback);
+
+    wrapper.appendChild(chipContainer);
+    return wrapper;
+}
+
+function renderProductsTable(items = getCurrentSlice()) {
+    const wrap = document.getElementById('tableContainer');
+    wrap.innerHTML = '';
+    const table = document.createElement('table');
+    table.classList.add('table', 'table-striped', 'table-bordered','table-responsive');
+    
+    const thead = document.createElement('thead'); 
+    const trh = document.createElement('tr');
+    
+    // Table Headers
+    ['Select', 'Image', 'Product', 'SKU', 'Type', 'Short Description', 'Attributes'].forEach(h => {
+        const th = document.createElement('th'); th.textContent = h; trh.appendChild(th);
+    });
+    thead.appendChild(trh); table.appendChild(thead);
+    
+    const tbody = document.createElement('tbody');
+    
+    if (items.length > 0) {
+        items.forEach(p => {
+            const tr = document.createElement('tr'); 
+            tr.id = `row-${p.id}`;
+            if (isProductSelected(p.item_id)) tr.classList.add('selected');
+
+            // --- Define Checkbox (cb) and State Updater ---
+            const cb = document.createElement('input'); 
+            cb.type = 'checkbox'; 
+            cb.checked = isProductSelected(p.item_id);
+            // console.log("checkkkkk")
+            
+            // The state updater function is bound to this specific row/checkbox
+            const updateProductState = getProductStateUpdater(p, cb, tr);
+
+            // --- Select Cell ---
+            const tdSel = document.createElement('td'); 
+            tdSel.className = 'select-cell';
+            tdSel.appendChild(cb); 
+            tr.appendChild(tdSel);
+
+            // --- Other Cells ---
+            const tdImg = document.createElement('td'); tdImg.className = 'thumb-cell'; tdImg.appendChild(createMiniThumb(p)); tr.appendChild(tdImg);
+            const tdName = document.createElement('td'); tdName.textContent = p.product_name || '—'; tr.appendChild(tdName);
+            const tdSku  = document.createElement('td'); tdSku.textContent = p.item_id || '—'; tr.appendChild(tdSku);
+            const tdType = document.createElement('td'); const b = document.createElement('span'); b.className = 'badge'; b.textContent = p.product_type || '—'; tdType.appendChild(b); tr.appendChild(tdType);
+            const tdDesc = document.createElement('td'); tdDesc.textContent = p.product_short_description || ''; tr.appendChild(tdDesc);
+
+            // ---------------------------------------------
+            // --- ATTRIBUTE SELECTION IMPLEMENTATION ---
+            // ---------------------------------------------
+
+            // 1. DETAIL ROW STRUCTURE
+            const detailRow = document.createElement('tr');
+            detailRow.classList.add('attribute-detail-row'); // Custom class for styling
+            detailRow.style.display = 'none'; // Initially hidden
+            detailRow.id = `detail-row-${p.id}`;
+            
+            const detailCell = document.createElement('td');
+            detailCell.colSpan = 7; // Must span all columns
+            
+            const attrContainer = document.createElement('div');
+            attrContainer.id = `attr-container-${p.item_id}`; // Unique ID for targeting by updateProductState
+            attrContainer.classList.add('attribute-selectors', 'table-selectors');
+
+            // 2. GENERATE CHIPS UI
+            generateAttributeUI(p, updateProductState, attrContainer);
+
+            // Initially disable the chips if the product is not selected
+            attrContainer.classList.toggle('disabled', !cb.checked);
+
+            detailCell.appendChild(attrContainer);
+            detailRow.appendChild(detailCell);
+
+            if(p.product_type_details.length > 0){
+                // 3. TOGGLE BUTTON (in the main row)
+                const tdAttr = document.createElement('td'); 
+                const toggleButton = document.createElement('button');
+                toggleButton.textContent = 'Configure';
+                toggleButton.classList.add('btn', 'btn-sm', 'btn-info', 'attribute-toggle-btn');
+                tdAttr.appendChild(toggleButton);
+                tr.appendChild(tdAttr);
+            
+
+
+            // 4. EVENT LISTENERS
+            
+            // a) Toggle Button Logic
+            toggleButton.addEventListener('click', (e) => {
+                e.stopPropagation(); // Stop row click event
+                const isHidden = detailRow.style.display === 'none';
+                detailRow.style.display = isHidden ? '' : 'none'; // Toggle visibility
+                toggleButton.textContent = isHidden ? 'Hide Attributes' : 'Configure';
+                toggleButton.classList.toggle('btn-info', !isHidden);
+                toggleButton.classList.toggle('btn-secondary', isHidden);
+            });
+            
+            // b) Main Checkbox Change Logic
+            cb.addEventListener('change', () => { 
+                // console.log("cheeeeeeeeee");
+                updateProductState(); // Update state on check/uncheck
+                attrContainer.classList.toggle('disabled', !cb.checked); // Enable/Disable chips
+            });
+
+            // c) Row Click Listener (Updated to ignore button clicks)
+            tr.addEventListener('click', (e) => { 
+                const tag = e.target.tagName.toLowerCase();
+                // console.log("clikk")
+                if (tag !== 'input' && tag !== 'button') { 
+                    cb.checked = !cb.checked; 
+                    cb.dispatchEvent(new Event('change')); 
+                } 
+            });
+            }else{
+                const tdAttr = document.createElement('td'); 
+                tr.appendChild(tdAttr);
+                // b) Main Checkbox Change Logic
+                cb.addEventListener('change', () => { 
+                    // console.log("cheeeeeeeeee");
+                    updateProductState(); // Update state on check/uncheck
+                    attrContainer.classList.toggle('disabled', !cb.checked); // Enable/Disable chips
+                });
+                tr.addEventListener('click', (e) => { 
+                    const tag = e.target.tagName.toLowerCase();
+                    // console.log("clikk")
+                    if (tag !== 'input' && tag !== 'button') { 
+                        cb.checked = !cb.checked; 
+                        cb.dispatchEvent(new Event('change')); 
+                    } 
+                });
+            }
+            
+            // 5. Append Rows to TBODY
+            tbody.appendChild(tr);
+            tbody.appendChild(detailRow); // Append the detail row right after the main row
+        });
+    } else {
+        const tr = el('tr'); 
+        const tdName = el('td');
+        tdName.colSpan = 7; 
+        tdName.innerHTML = "No Products Found.";
+        tr.appendChild(tdName);
+        tbody.appendChild(tr);
+    }
+
+    table.appendChild(tbody);
+    wrap.appendChild(table);
+}
+
+function renderInlineForCards() {
+    const api = FAKE_API_RESPONSE;
+    // Clear all inline sections first
+    document.querySelectorAll('.attr-inline').forEach(div => div.innerHTML = '');
+
+    PRODUCT_BASE.forEach((p, idx) => {
+        const inline = document.querySelector(`.attr-inline[data-pid="${p.item_id}"]`);
+        if (!inline) return;
+        
+        // --- CHANGE HERE: Use the new helper function ---
+        if (!isProductSelected(p.item_id)) return; // only show for selected
+        
+        const res = findApiResultForProduct(p, idx, api);
+        const pid = p.item_id;
+        if (!lastSeen.has(pid)) lastSeen.set(pid, { mandatory: new Map(), additional: new Map(), ocr_results: new Map(), visual_results: new Map() });
+        const mem = lastSeen.get(pid);
+
+        // Build sections
+        const manTitle = el('div', 'section-title'); manTitle.innerHTML = '<strong>Mandatory</strong>';
+        const manChips = el('div', 'chips');
+        const addTitle = el('div', 'section-title'); addTitle.innerHTML = '<strong>Additional</strong>';
+        const addChips = el('div', 'chips');
+
+        const addOcr = el('div', 'section-title'); addOcr.innerHTML = '<strong>Ocr</strong>';
+        const ocrChips = el('div', 'chips');
+        const addVisual = el('div', 'section-title'); addVisual.innerHTML = '<strong>Visual</strong>';
+        const visualChips = el('div', 'chips');
+        
+
+        const mandCount = renderChips(manChips, res?.mandatory || {}, mem.mandatory);
+        const addCount = renderChips(addChips, res?.additional || {}, mem.additional);
+        const ocrCount = renderChips(ocrChips, res?.ocr_results?.extracted_attributes || {}, mem?.ocr_results);
+        const visualCount = renderChips(visualChips, res?.visual_results?.visual_attributes || {}, mem?.visual_results);
+
+        const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+        const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+        const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+        const c3 = el('span', 'pill'); c3.textContent = `OCR: ${ocrCount}`;
+        const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+        counts.appendChild(c1); counts.appendChild(c2);  counts.appendChild(c3);  counts.appendChild(c4);
+
+        inline.appendChild(manTitle); inline.appendChild(manChips);
+        inline.appendChild(addTitle); inline.appendChild(addChips);
+        inline.appendChild(addOcr); inline.appendChild(ocrChips);
+        inline.appendChild(addVisual); inline.appendChild(visualChips);
+        inline.appendChild(counts);
+    });
+
+    // Update summary
+    $('#statTotal').textContent = api.total_products ?? 0;
+    $('#statOk').textContent = api.successful ?? 0;
+    $('#statKo').textContent = api.failed ?? 0;
+    $('#api-summary').style.display = 'block';
+}
+
+// -----------------------------------------------------------
+
+function renderInlineForTable() {
+    const api = FAKE_API_RESPONSE;
+    const table = $('#tableContainer');
+    if (!table) return;
+    // Remove existing detail rows
+    table.querySelectorAll('tr.detail-row').forEach(r => r.remove());
+
+    PRODUCT_BASE.forEach((p, idx) => {
+        // --- CHANGE HERE: Use the new helper function ---
+        if (!isProductSelected(p.item_id)) return;
+        
+        const res = findApiResultForProduct(p, idx, api);
+        const pid = p.item_id;
+        if (!lastSeen.has(pid)) lastSeen.set(pid, { mandatory: new Map(), additional: new Map(), ocr_results: new Map(), visual_results: new Map() });
+        const mem = lastSeen.get(pid);
+
+        const tbody = table.querySelector('tbody');
+        // NOTE: The table rendering uses p.id for the row ID: `row-${p.id}`.
+        // Assuming p.id is still valid for finding the base row, as your original code used it.
+        const baseRow = tbody.querySelector(`#row-${p.id}`); 
+        if (!baseRow) return;
+
+        const detail = el('tr', 'detail-row');
+        const td = el('td'); td.colSpan = 6; // number of columns
+        const content = el('div', 'detail-content');
+
+        const manTitle = el('div', 'section-title'); manTitle.innerHTML = '<strong>Mandatory</strong>';
+        const manChips = el('div', 'chips');
+        const addTitle = el('div', 'section-title'); addTitle.innerHTML = '<strong>Additional</strong>';
+        const addChips = el('div', 'chips');
+        const addOcr = el('div', 'section-title'); addOcr.innerHTML = '<strong>Ocr</strong>';
+        const ocrChips = el('div', 'chips');
+        const addVisuals = el('div', 'section-title'); addVisuals.innerHTML = '<strong>Visuals</strong>';
+        const visualsChips = el('div', 'chips');
+
+        const mandCount = renderChips(manChips, res?.mandatory || {}, mem.mandatory);
+        const addCount = renderChips(addChips, res?.additional || {}, mem.additional);
+        const ocrCount = renderChips(ocrChips, res?.ocr_results?.extracted_attributes || {}, mem.ocr_results);
+        const visualCount = renderChips(visualsChips, res?.visual_results?.visual_attributes || {}, mem.visual_results);
+
+        const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+        const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+        const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+        const c3 = el('span', 'pill'); c3.textContent = `Ocr: ${ocrCount}`;
+        const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+        counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+
+        content.appendChild(manTitle); content.appendChild(manChips);
+        content.appendChild(addTitle); content.appendChild(addChips);
+        content.appendChild(addOcr); content.appendChild(ocrChips);
+        content.appendChild(addVisuals); content.appendChild(visualsChips);
+        content.appendChild(counts);
+        td.appendChild(content); detail.appendChild(td);
+
+        // insert after base row
+        baseRow.insertAdjacentElement('afterend', detail);
+    });
+
+    // Update summary
+    $('#statTotal').textContent = api.total_products ?? 0;
+    $('#statOk').textContent = api.successful ?? 0;
+    $('#statKo').textContent = api.failed ?? 0;
+    $('#api-summary').style.display = 'block';
+}
+
+
+function renderInlineAttributes() {
+    if (layoutMode === 'cards') renderInlineForCards(); else renderInlineForTable();
+}
+
+// --- Main rendering ---
+function renderProducts() {
+    if (layoutMode === 'cards') {
+    $('#cardsContainer').style.display = '';
+    $('#tableContainer').style.display = 'none';
+    // console.log("PRODUCT_BASE",PRODUCT_BASE);
+    renderProductsCards();
+    } else {
+    $('#cardsContainer').style.display = 'none';
+    $('#tableContainer').style.display = '';
+    renderProductsTable();
+    }
+    updateSelectionInfo();
+    renderPagination();               
+
+    // If there is a selection, re-render inline attributes (persist across toggle)
+    if (selectedIds.size > 0) renderInlineAttributes();
+}
+
+// --- Submit & Reset ---
+function submitAttributes() {
+  // Check the length of the new array
+    if (selectedProductsWithAttributes.length === 0) { 
+        alert('Please select at least one product.'); 
+        return; 
+    } 
+    // if (selectedIds.size === 0) { alert('Please select at least one product.'); return; }
+    // console.log("selectedIds",selectedIds);
+    jQuery('#full-page-loader').show();  
+    // let inputArray = {
+    //       "product_ids" : [...selectedIds]
+    //     }
+    const extractAdditional = document.getElementById('extract_additional').checked;
+    const processImage = document.getElementById('process_image').checked;
+    // const selectedMultiples = document.getElementById('#mandatory-attributes');
+    // const selectedValues = Array.from(selectedMultiples.selectedOptions).map(option => option.value);
+    const selectElement = document.getElementById('mandatory-attributes');
+
+    const selectedValues = Array.from(selectElement.selectedOptions).map(option => option.value);
+
+    // console.log(selectedValues); // Logs an array of selected values
+    // console.log("thresholdValueDisplay",thresholdValueDisplay.value);
+    const threshold = parseFloat(document.getElementById('thresholdRange').value);
+
+
+    // Transform the new state array into the required API format
+    const itemIds = selectedProductsWithAttributes.map(p => p.item_id);
+    
+    // Create the mandatory_attrs map: { item_id: { attr_name: [values] } }
+    // NOTE: The backend API you showed expects a flattened list of "mandatory_attrs"
+    // like: { "color": ["color", "shade"], "size": ["size", "fit"] } 
+    // It seems to ignore the selected product-specific values and uses a general list of synonyms.
+    // Assuming the request needs a general map of *all unique* selected attributes across all selected products:
+    
+    let mandatoryAttrsMap = {};
+    selectedProductsWithAttributes.forEach(product => {
+        // Merge attributes from all selected products
+        Object.assign(mandatoryAttrsMap, product.mandatory_attrs);
+    });
+
+    // If the API expects the complex, product-specific payload from your Q1 example:
+    const payloadForQ1 = selectedProductsWithAttributes.map(p => ({
+        item_id: p.item_id,
+        mandatory_attrs: p.mandatory_attrs
+    }));
+
+    let inputArray = {
+              "products": payloadForQ1,
+              "model": "llama-3.1-8b-instant",
+              "extract_additional": extractAdditional,
+              "process_image": processImage,
+              "multiple": selectedValues,
+              "threshold_abs": threshold,  // Lower threshold to be more permissive
+            //   "margin": 0.3,  // Larger margin to include more candidates
+            //   "use_adaptive_margin": true,
+            //   "use_semantic_clustering": true
+            }
+    let raw = JSON.stringify(inputArray);
+     fetch('/attr/batch-extract/', {
+        method: 'POST', // or 'POST' if your API expects POST
+        headers: {
+            'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]')?.value || '',
+            'Content-Type': "application/json"
+        },
+        body: raw
+    })
+    .then(response => response.json())
+    .then(data => {
+        // console.log("response data",data); 
+        FAKE_API_RESPONSE = data;   
+        renderInlineAttributes();
+        jQuery('#full-page-loader').hide();  
+     });
+}
+
+function resetAll() {
+  selectedProductsWithAttributes = []; // Reset the main array
+    // selectedIds.clear();
+    lastSeen.clear();
+    renderProducts();
+    // Clear summary
+    document.getElementById('statTotal').textContent = '0';
+    document.getElementById('statOk').textContent = '0';
+    document.getElementById('statKo').textContent = '0';
+    $('#api-summary').style.display = 'none';
+
+    // ✅ Clear Select2 selections
+    jQuery('#mandatory-attributes').val(null).trigger('change');
+
+    // ✅ Reset threshold input (and display)
+    const thresholdInput = document.getElementById('thresholdRange');
+    const thresholdDisplay = document.getElementById('thresholdValue');
+
+    thresholdInput.value = '0.5'; // or any default value you prefer
+    if (thresholdDisplay) {
+        thresholdDisplay.textContent = '0.5';
+    }
+}
+
+function setLayout(mode) {
+    layoutMode = mode;
+    const btnCards = document.getElementById('btnCards');
+    const btnTable = document.getElementById('btnTable');
+    if (mode === 'cards') { btnCards.classList.add('active'); btnCards.setAttribute('aria-selected', 'true'); btnTable.classList.remove('active'); btnTable.setAttribute('aria-selected', 'false'); }
+    else { btnTable.classList.add('active'); btnTable.setAttribute('aria-selected', 'true'); btnCards.classList.remove('active'); btnCards.setAttribute('aria-selected', 'false'); }
+    renderProducts();
+}
+
+
+// Upload elements (Bootstrap modal version)
+const uploadModalEl = document.getElementById('uploadModal');
+const dropzone      = document.getElementById('dropzone');
+const uploadFiles   = document.getElementById('uploadFiles');
+const fileInfo      = document.getElementById('fileInfo');
+const uploadBar     = document.getElementById('uploadBar');
+const uploadStatus  = document.getElementById('uploadStatus');
+
+// Reset modal on show
+uploadModalEl.addEventListener('shown.bs.modal', () => {
+  uploadStatus.textContent = '';
+  uploadStatus.className = '';             // clear success/error class
+  uploadBar.style.width = '0%';
+  uploadBar.setAttribute('aria-valuenow', '0');
+  uploadFiles.value = '';
+  uploadFiles.setAttribute('accept', ACCEPT_TYPES);
+  fileInfo.textContent = 'No files selected.';
+});
+
+function describeFiles(list) {
+  if (!list || list.length === 0) { fileInfo.textContent = 'No files selected.'; return; }
+  const names = Array.from(list).map(f => `${f.name} (${Math.round(f.size/1024)} KB)`);
+  fileInfo.textContent = names.join(', ');
+}
+
+// Drag & drop feedback
+['dragenter','dragover'].forEach(evt => {
+  dropzone.addEventListener(evt, e => { e.preventDefault(); e.stopPropagation(); dropzone.classList.add('drag'); });
+});
+['dragleave','drop'].forEach(evt => {
+  dropzone.addEventListener(evt, e => { e.preventDefault(); e.stopPropagation(); dropzone.classList.remove('drag'); });
+});
+
+// Handle drop
+dropzone.addEventListener('drop', e => {
+  uploadFiles.files = e.dataTransfer.files;
+  describeFiles(uploadFiles.files);
+});
+
+// Click to browse
+// dropzone.addEventListener('click', () => uploadFiles.click());
+
+// Picker change
+uploadFiles.addEventListener('change', () => describeFiles(uploadFiles.files));
+
+function startUpload() {
+  const files = uploadFiles.files;
+  if (!files || files.length === 0) { alert('Please select file(s) to upload.'); return; }
+  jQuery('#full-page-loader').show();
+  uploadStatus.textContent = 'Uploading...';
+  uploadStatus.className = ''; // neutral
+  uploadBar.style.width = '0%';
+  uploadBar.setAttribute('aria-valuenow', '0');
+
+  const form = new FormData();
+  Array.from(files).forEach(f => form.append('file', f));
+  // form.append('uploaded_by', 'Vishal'); // example extra field
+
+  const xhr = new XMLHttpRequest();
+  xhr.open('POST', UPLOAD_API_URL, true);
+  // If you need auth:
+  // xhr.setRequestHeader('Authorization', 'Bearer <token>');
+
+  xhr.upload.onprogress = (e) => {
+    if (e.lengthComputable) {
+      const pct = Math.round((e.loaded / e.total) * 100);
+      uploadBar.style.width = pct + '%';
+      uploadBar.setAttribute('aria-valuenow', String(pct));
+    }
+  };
+
+  xhr.onreadystatechange = () => {
+    if (xhr.readyState === 4) {
+      const ok = (xhr.status >= 200 && xhr.status < 300);
+      try {
+        const resp = JSON.parse(xhr.responseText || '{}');
+        uploadStatus.textContent = ok ? (resp.message || 'Upload successful') : (resp.error || `Upload failed (${xhr.status})`);
+      } catch {
+        uploadStatus.textContent = ok ? 'Upload successful' : `Upload failed (${xhr.status})`;
+      }
+      uploadStatus.className = ok ? 'success' : 'error';
+      // Optional: auto-close the modal on success after 1.2s:
+      // if (ok) setTimeout(() => bootstrap.Modal.getInstance(uploadModalEl).hide(), 1200);
+    }
+  };
+
+  xhr.onerror = () => {
+    uploadStatus.textContent = 'Network error during upload.';
+    uploadStatus.className = 'error';
+  };
+
+  xhr.send(form);
+  setTimeout(()=>{
+      jQuery('#uploadModal').modal('hide');
+  },3000)
+  jQuery('#full-page-loader').hide();
+
+}
+
+// Wire Start button
+document.getElementById('uploadStart').addEventListener('click', startUpload);
+// Cancel button already closes the modal via data-bs-dismiss
+
+
+
+
+// --- Pagination state ---
+let page = 1;
+let pageSize = 50; // default rows per page
+
+function totalPages() {
+  return Math.max(1, Math.ceil(PRODUCT_BASE.length / pageSize));
+}
+
+function clampPage() {
+  page = Math.min(Math.max(1, page), totalPages());
+}
+
+function getCurrentSlice() {
+  clampPage();
+  const start = (page - 1) * pageSize;
+  return PRODUCT_BASE.slice(start, start + pageSize);
+}
+
+function renderPagination() {
+  const bar = document.getElementById('paginationBar');
+  if (!bar) return;
+
+  const tp = totalPages();
+  clampPage();
+
+  bar.innerHTML = `
+    <div class="page-size">
+      <label for="pageSizeSelect">Rows per page</label>
+      <select id="pageSizeSelect">
+        <option value="5"  ${pageSize===5  ? 'selected' : ''}>5</option>
+        <option value="10" ${pageSize===10 ? 'selected' : ''}>10</option>
+        <option value="20" ${pageSize===20 ? 'selected' : ''}>20</option>
+        <option value="50" ${pageSize===50 ? 'selected' : ''}>50</option>
+        <option value="all" ${pageSize>=PRODUCT_BASE.length ? 'selected' : ''}>All</option>
+      </select>
+    </div>
+
+    <div class="pager">
+      <button class="pager-btn" id="prevPage" ${page<=1 ? 'disabled' : ''} aria-label="Previous page">‹</button>
+      <span class="page-info">Page ${page} of ${tp}</span>
+      <button class="pager-btn" id="nextPage" ${page>=tp ? 'disabled' : ''} aria-label="Next page">›</button>
+    </div>
+  `;
+
+  // wire events
+  document.getElementById('prevPage')?.addEventListener('click', () => { if (page > 1) { page--; renderProducts(); } });
+  document.getElementById('nextPage')?.addEventListener('click', () => { if (page < tp) { page++; renderProducts(); } });
+
+  const sel = document.getElementById('pageSizeSelect');
+  if (sel) {
+    sel.addEventListener('change', () => {
+      const val = sel.value;
+      pageSize = (val === 'all') ? PRODUCT_BASE.length : parseInt(val, 10);
+      page = 1;            // reset to first page when size changes
+      renderProducts();
+    });
+  }
+}
+
+// Function to add/remove product from the state and manage its attributes
+function toggleProductSelection(itemId, isChecked, attributes = {}) {
+    const index = selectedProductsWithAttributes.findIndex(p => p.item_id === itemId);
+    // console.log("index",index);
+    if (isChecked) {
+        // If selecting, ensure the product object exists in the array
+        if (index === -1) {
+            selectedProductsWithAttributes.push({
+                item_id: itemId,
+                mandatory_attrs: attributes
+            });
+        } else {
+            // Update attributes if the product is already selected
+            selectedProductsWithAttributes[index].mandatory_attrs = attributes;
+        }
+    } else {
+        // If deselecting, remove the product object from the array
+        if (index !== -1) {
+            selectedProductsWithAttributes.splice(index, 1);
+        }
+    }
+    updateSelectionInfo();
+}
+
+// Function to get the current mandatory attributes for a selected item
+function getSelectedAttributes(itemId) {
+    const productEntry = selectedProductsWithAttributes.find(p => p.item_id === itemId);
+    return productEntry ? productEntry.mandatory_attrs : {};
+}
+
+// Helper to check if a product is selected
+function isProductSelected(itemId) {
+    return selectedProductsWithAttributes.some(p => p.item_id === itemId);
+}
+
+// Helper to check if a specific attribute/value is selected
+function isAttributeValueSelected(itemId, attrName, value) {
+    const attrs = getSelectedAttributes(itemId);
+    const values = attrs[attrName];
+    return values ? values.includes(value) : false; // Default all selected when first loaded
+}
+
+
+
+// $('.attribute-select').select2({
+//     placeholder: 'Select product attributes'
+// });
+
+function getAtributeList(){
+        jQuery('#full-page-loader').show();  
+            try{
+            fetch('/attr/products/attributes', {
+                method: 'GET', // or 'POST' if your API expects POST
+                headers: {
+                    'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]')?.value || ''
+                }
+            })
+            .then(response => response.json())
+            .then(data => {
+                // console.log("data",data);
+                let attributesData = data;
+                 // Step 1: Extract unique mandatory attribute names
+                const mandatoryAttributes = [...new Set(
+                    attributesData
+                        .filter(attr => attr.is_mandatory === "Yes")
+                        .map(attr => attr.attribute_name)
+                )];
+
+                // Step 2: Populate the select element
+                const $select = jQuery('#mandatory-attributes');
+                $select.append(new Option("Select All", "select_all")); // Add "Select All" option first
+
+                mandatoryAttributes.forEach(attr => {
+                    $select.append(new Option(attr, attr));
+                });
+
+                // Step 3: Initialize Select2 with placeholder
+                // $select.select2({
+                //     placeholder: "Select mandatory attributes",
+                //     allowClear: true
+                // });
+
+                // Step 4: Handle 'Select All' logic
+                $select.on('select2:select', function (e) {
+                    if (e.params.data.id === "select_all") {
+                        // Select all real options except "Select All"
+                        const allOptions = mandatoryAttributes;
+                        $select.val(allOptions).trigger('change');
+                    }
+                });
+
+                jQuery('#full-page-loader').hide();
+            });
+        }catch(err){
+            console.log("err",err);
+            jQuery('#full-page-loader').hide();
+
+        }
+    
+}
+document.addEventListener("DOMContentLoaded", function () {
+    // Update span when range changes
+    thresholdInput.addEventListener('input', function () {
+        // console.log("this.value",this.value);
+        thresholdValueDisplay.textContent = this.value;
+    });
+});
+
+// Get threshold value when needed
+function getThreshold() {
+    // console.log("parseFloat(thresholdInput.value)",parseFloat(thresholdInput.value));
+    return parseFloat(thresholdInput.value);
+}

+ 3471 - 0
bg_remover/templates/static/js/attr-extraction.js

@@ -0,0 +1,3471 @@
+jQuery.noConflict(); // Release $ to other libraries
+// console.log(typeof jQuery);
+// $ = jQuery;
+
+// --- Config ---
+const UPLOAD_API_URL = '/attr/products/upload-excel/'; // TODO: set to your upload endpoint
+const ACCEPT_TYPES = '*'; // e.g., 'image/*,.csv,.xlsx'
+
+
+const thresholdInput = document.getElementById('thresholdRange');
+const thresholdValueDisplay = document.getElementById('thresholdValue');
+
+var attributesFullData = [];
+
+var PRODUCT_BASE = [
+    // { id: 1, item_id: 'SKU001', product_name: "Levi's Jeans", product_long_description: 'Classic blue denim jeans with straight fit.', product_short_description: 'Blue denim jeans.', product_type: 'Clothing', image_path: 'media/products/jeans.jpg', image: 'http://127.0.0.1:8000/media/products/jeans.png' },
+    // { id: 2, item_id: 'SKU002', product_name: 'Adidas Running Shoes', product_long_description: 'Lightweight running shoes with breathable mesh and cushioned sole.', product_short_description: "Men's running shoes.", product_type: 'Footwear', image_path: 'media/products/shoes.png', image: 'http://127.0.0.1:8000/media/products/shoes.png' },
+    // { id: 3, item_id: 'SKU003', product_name: 'Nike Sports T-Shirt', product_long_description: 'Moisture-wicking sports tee ideal for training and outdoor activities.', product_short_description: 'Performance t-shirt.', product_type: 'Clothing', image_path: 'media/products/tshirt.png', image: 'http://127.0.0.1:8000/media/products/tshirt.png' },
+    // { id: 4, item_id: 'SKU004', product_name: 'Puma Hoodie', product_long_description: 'Soft fleece hoodie with kangaroo pocket and adjustable drawstring.', product_short_description: 'Casual hoodie.', product_type: 'Clothing', image_path: 'media/products/hoodie.png', image: 'http://127.0.0.1:8000/media/products/hoodie.png' },
+    // { id: 5, item_id: 'SKU005', product_name: 'Ray-Ban Sunglasses', product_long_description: 'Classic aviator sunglasses with UV protection lenses.', product_short_description: 'Aviator sunglasses.', product_type: 'Accessories', image_path: 'media/products/sunglasses.png', image: 'http://127.0.0.1:8000/media/products/sunglasses.png' }
+];
+// --- Data ---
+const mediaUrl = "./../";
+
+document.addEventListener('DOMContentLoaded', () => {
+    jQuery('#full-page-loader').show();  
+    fetch('/attr/products', {
+        method: 'GET', // or 'POST' if your API expects POST
+        headers: {
+            'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]')?.value || ''
+        }
+    })
+    .then(response => response.json())
+    .then(data => {
+        // console.log("data",data);
+        // --- Wire up ---
+        PRODUCT_BASE = data;
+        PRODUCT_BASE = PRODUCT_BASE.map((d)=>{return {...d,mandatoryAttributes:["color","size"]}});
+        // console.log("PRODUCT_BASE",PRODUCT_BASE);
+        if(PRODUCT_BASE.length > 0){
+            $('#paginationBar').style.display = 'block';
+        }
+        renderProducts();
+        getAtributeList();
+        document.getElementById('btnSubmit').addEventListener('click', submitAttributes);
+        // document.getElementById('btnReset').addEventListener('click', resetAll);
+        // document.getElementById('btnSelectAll').addEventListener('click', () => {
+        // if (selectedIds.size === PRODUCT_BASE.length) { selectedIds.clear(); } else { selectedIds = new Set(PRODUCT_BASE.map(p => p.id)); }
+        // // renderProducts();
+        // });
+
+        // Replace your existing Select All listener with this:
+          document.getElementById('btnSelectAll').addEventListener('click', () => {
+            // Use the container for the active layout
+            const container = (layoutMode === 'cards')
+              ? document.getElementById('cardsContainer')
+              : document.getElementById('tableContainer');
+
+            // Collect all visible checkboxes
+            const boxes = Array.from(container.querySelectorAll('input[type="checkbox"]'));
+
+            // If every visible checkbox is already checked, we'll deselect; otherwise select all
+            const allChecked = boxes.length > 0 && boxes.every(cb => cb.checked);
+
+            boxes.forEach(cb => {
+              const target = !allChecked; // true to select, false to deselect
+              if (cb.checked !== target) {
+                cb.checked = target;
+                // Trigger your existing "change" handler so selectedIds & row .selected class update
+                cb.dispatchEvent(new Event('change', { bubbles: true }));
+              }
+            });
+
+            // Update the selection pill text (doesn't re-render the list)
+            updateSelectionInfo();
+          });
+        document.getElementById('btnCards').addEventListener('click', () => setLayout('cards'));
+        document.getElementById('btnTable').addEventListener('click', () => setLayout('table'));
+        jQuery('#full-page-loader').hide();
+        // if (data.success) {
+        // }
+    });
+});
+
+var API_RESPONSE_AI = {
+    // results: [
+    // { product_id: 'SKU001', mandatory: { 'Clothing Neck Style': 'V-Neck', 'Clothing Top Style': 'Pullover', 'Condition': 'New', 'T-Shirt Type': 'Classic T-Shirt' }, additional: { 'Material': 'Turkish Pima Cotton', 'Size': 'Large', 'Color': 'Blue', 'Brand': 'Sierra', 'Fabric Type': 'Soft & Breathable', 'Fabric Composition': '95% Turkish Pima cotton', 'Care Instructions': 'Machine Washable', 'Sizes Available': 'S-XL' } },
+    // { product_id: 'SKU002', mandatory: { 'Shoe Type': 'Running', 'Closure': 'Lace-Up', 'Condition': 'New', 'Gender': 'Men' }, additional: { 'Upper Material': 'Engineered Mesh', 'Midsole': 'EVA Foam', 'Outsole': 'Rubber', 'Color': 'Black/White', 'Brand': 'Adidas', 'Size': 'UK 9', 'Care Instructions': 'Surface Clean' } },
+    // { product_id: 'SKU003', mandatory: { 'Clothing Neck Style': 'Crew Neck', 'Sleeve Length': 'Short Sleeve', 'Condition': 'New', 'T-Shirt Type': 'Performance' }, additional: { 'Material': 'Polyester Blend', 'Color': 'Red', 'Brand': 'Nike', 'Size': 'Medium', 'Fabric Technology': 'Dri-FIT', 'Care Instructions': 'Machine Wash Cold' } },
+    // { product_id: 'SKU004', mandatory: { 'Clothing Top Style': 'Hoodie', 'Closure': 'Pullover', 'Condition': 'New', 'Fit': 'Relaxed' }, additional: { 'Material': 'Cotton Fleece', 'Color': 'Charcoal', 'Brand': 'Puma', 'Size': 'Large', 'Care Instructions': 'Machine Wash Warm' } },
+    // { product_id: 'SKU005', mandatory: { 'Accessory Type': 'Sunglasses', 'Frame Style': 'Aviator', 'Condition': 'New', 'Lens Protection': 'UV 400' }, additional: { 'Frame Material': 'Metal', 'Lens Color': 'Green', 'Brand': 'Ray-Ban', 'Size': 'Standard', 'Case Included': 'Yes', 'Care Instructions': 'Clean with microfiber' } }
+    // ],
+    // total_products: 5,
+    // successful: 5,
+    // failed: 0
+};
+
+// --- State ---
+let selectedIds = new Set();
+// NEW: Array of objects { item_id: string, mandatory_attrs: { [attribute_name]: string[] } }
+let selectedProductsWithAttributes = [];
+let selectedAttributes = new Array();
+const lastSeen = new Map(); // per-product memory for NEW highlighting (product_id -> maps)
+let layoutMode = 'table'; // 'cards' | 'table'
+
+// --- Helpers ---
+const $ = (sel) => document.querySelector(sel);
+const el = (tag, cls) => { const e = document.createElement(tag); if (cls) e.className = cls; return e; }
+
+function updateSelectionInfo() {
+    const pill = $('#selectionInfo');
+    const total = PRODUCT_BASE.length;
+    // const count = selectedIds.size;
+    const count = selectedProductsWithAttributes.length;
+    pill.textContent = count === 0 ? 'No products selected' : `${count} of ${total} selected`;
+}
+
+function setChecked(id, checked) { if (checked) selectedIds.add(id); else selectedIds.delete(id); updateSelectionInfo(); }
+// function setCheckedAttributes(id,attribute, checked) { if (checked) selectedAttributes.add({id: [attribute]}); else selectedIds.delete({id:[attribute]}); updateSelectionInfo(); }
+function formatString(str) {
+  return str
+    // Replace underscores with spaces
+    .replace(/_/g, ' ')
+    // Insert a space before any uppercase letter (except at the start)
+    .replace(/([a-z])([A-Z])/g, '$1 $2')
+    // Capitalize the first letter
+    .replace(/^./, char => char.toUpperCase());
+}
+
+// --- Chips rendering ---
+function renderChips(container, obj, memoryMap) {
+    container.innerHTML = '';
+    let count = 0;
+    Object.entries(obj || {}).forEach(([k, v]) => {
+    const chip = el('span', 'chip');
+    const kEl = el('span', 'k'); kEl.textContent = formatString(k) + ':';
+    // console.log("v",v);
+    let resVal = "";
+    let sourceVal = "";
+    if(v instanceof Array){
+        resVal  = String(v.map(v => formatString(v.value)).join(", "));
+        sourceVal = String(formatString(v[0]?.source));
+        const vEl = el('span', 'v'); vEl.textContent = ' ' + resVal  +' (' + sourceVal + ')';
+        chip.appendChild(kEl); chip.appendChild(vEl);
+    }
+    // console.log("k",k);
+    if(v instanceof Array){
+    const was = memoryMap.get(k);
+    if (was === undefined || was !== v) chip.classList.add('new');
+    container.appendChild(chip);
+    memoryMap.set(k, v);
+    
+    count++;
+    }
+    });
+    return count;
+}
+
+function findApiResultForProduct(p, index, api) { return api.results?.find(r => r.product_id === p.item_id) || api.results?.[index] || null; }
+
+// --- Cards layout ---
+function createProductCard(p) {
+    const row = el('div', 'product');
+    // Check selection using the new helper
+    if (isProductSelected(p.item_id)) row.classList.add('selected');
+    // if (selectedIds.has(p.item_id)) row.classList.add('selected');
+
+    // const left = el('div', 'thumb');
+    // const img = new Image(); img.src = p.image_path || p.image || '';
+    // // console.log("image path",p.image_path);
+    //  img.alt = `${p.product_name} image`;
+    // // console.log("img",img);
+    // // img.onerror = () => { img.remove(); const fb = el('div', 'fallback'); fb.textContent = (p.product_name || 'Product').split(' ').map(w => w[0]).slice(0,2).join('').toUpperCase(); left.appendChild(fb); };
+    // img.onerror = () => { img.src = mediaUrl+"media/images/no-product.png" };
+    // left.appendChild(img);
+
+    // Assume 'el' is a function that creates an element (e.g., document.createElement)
+// Assume 'p' (product data) and 'mediaUrl' are available in scope.
+
+    // 1. Create the main container for the hover effect
+    const container = el('div', 'mini-thumb-container'); 
+
+    // 2. Create the visible thumbnail wrapper (your original 'left' element)
+    // This will serve as the base for the small image
+    const left = el('div', 'thumb'); 
+
+    // Get the image source (same as before)
+    const imageSrc = p.image_path || p.image || '';
+
+    // 3. Create the thumbnail image element (same as before)
+    const thumbImg = new Image(); 
+    thumbImg.src = imageSrc; 
+    thumbImg.alt = `${p.product_name} image`;
+    thumbImg.onerror = () => { thumbImg.src = mediaUrl+"media/images/no-product.png" };
+    // Use thumbImg instead of img to avoid naming conflict with other code if possible
+    // We will call it 'img' here to match your original code:
+    const img = thumbImg; 
+
+    left.appendChild(img);
+    container.appendChild(left); // Add the visible thumbnail to the main container
+
+    // 4. Create the full-size image element for hover (new part)
+    const fullImgWrapper = el('div', 'full-image-hover'); // Class for CSS control
+
+    const fullImg = new Image();
+    fullImg.src = imageSrc; // Use the same source, or p.full_image_path if available
+    fullImg.alt = `${p.product_name} full view`;
+    fullImg.onerror = () => { fullImg.src = mediaUrl + "media/images/no-product.png" }; // Same fallback
+
+    fullImgWrapper.appendChild(fullImg);
+    container.appendChild(fullImgWrapper); // Add full image wrapper to the main container
+
+    // The variable to use when appending this element to the DOM is 'container'.
+    // return container; // If this block is inside a function
+
+
+    const mid = el('div', 'meta');
+    const name = el('div', 'name'); name.textContent = p.product_name || '—';
+    const desc = el('div', 'desc'); desc.innerHTML = p.product_short_description || '';
+    const badges = el('div', 'badges');
+    const sku = el('span', 'pill'); sku.textContent = `SKU: ${p.item_id || '—'}`; badges.appendChild(sku);
+    const type = el('span', 'pill'); type.textContent = p.product_type || '—'; badges.appendChild(type);
+    const long = el('div', 'desc'); long.innerHTML = p.product_long_description || ''; long.style.marginTop = '4px';
+    mid.appendChild(name); mid.appendChild(desc); mid.appendChild(badges); mid.appendChild(long);
+
+    // Helper function to create the chip UI for attributes
+    function createAttributeChips(p, attr, initialSelected, isMandatory, updateCallback) {
+        const wrapper = el('div', 'attribute-chip-group');
+        wrapper.dataset.attrName = attr?.attribute_name;
+        wrapper.innerHTML = `<p class="attribute-header">${attr?.attribute_name} (${isMandatory ? 'Mandatory' : 'Optional'}):</p>`;
+
+        const chipContainer = el('div', 'chips-container');
+
+        attr?.possible_values.forEach(value => {
+            const chip = el('label', 'attribute-chip');
+            
+            // Checkbox input is hidden, but drives the selection state
+            const checkbox = document.createElement('input');
+            checkbox.type = 'checkbox';
+            checkbox.value = value;
+            checkbox.name = `${p.item_id}-${attr?.attribute_name}`;
+            
+            // Set initial state
+            checkbox.checked = initialSelected.includes(value); 
+            
+            // The visual part of the chip
+            const span = el('span');
+            span.textContent = value;
+            
+            chip.appendChild(checkbox);
+            chip.appendChild(span);
+            chipContainer.appendChild(chip);
+        });
+        
+        // Use event delegation on the container for performance
+        chipContainer.addEventListener('change', updateCallback);
+
+        wrapper.appendChild(chipContainer);
+        return wrapper;
+    }
+
+    // --- Main Select Checkbox (Product Selection) ---
+    const right = el('label', 'select');
+    const cb = document.createElement('input'); cb.type = 'checkbox';
+    cb.checked = isProductSelected(p.item_id);
+    const lbl = el('span'); lbl.textContent = 'Select Product';
+    right.appendChild(cb); right.appendChild(lbl);
+
+    
+    // --- Dynamic Attribute Selects ---
+    const attrContainer = el('div', 'attribute-selectors');
+if(p.product_type_details.length > 0){
+    // Find all mandatory and non-mandatory attributes for this product
+    const mandatoryAttributes = p.product_type_details?.filter(a => a.is_mandatory === 'Yes') || [];
+    const optionalAttributes = p.product_type_details?.filter(a => a.is_mandatory !== 'Yes') || [];
+
+    // Helper to update the main state object with all current selections
+    const updateProductState = () => {
+        const isSelected = cb.checked;
+        const currentSelections = {};
+
+        if (isSelected) {
+            // Iterate over all attribute groups (Mandatory and Optional)
+            attrContainer.querySelectorAll('.attribute-chip-group').forEach(group => {
+                const attrName = group.dataset.attrName;
+                
+                // Collect selected chip values
+                const selectedOptions = Array.from(group.querySelectorAll('input[type="checkbox"]:checked'))
+                    .map(checkbox => checkbox.value);
+
+                if (selectedOptions.length > 0) {
+                    currentSelections[attrName] = selectedOptions;
+                }
+            });
+        }
+        
+        toggleProductSelection(p.item_id, isSelected, currentSelections);
+        row.classList.toggle('selected', isSelected);
+    };
+
+    // Attach listener to main checkbox
+    cb.addEventListener('change', () => {
+        attrContainer.classList.toggle('disabled', !cb.checked);
+        updateProductState();
+    });
+    
+    // --- Render Mandatory Attributes ---
+    // if (mandatoryAttributes.length > 0) {
+    //     const manTitle = el('p', "pSelectRight mandatory-title");
+    //     manTitle.innerHTML = "Mandatory Attributes:";
+    //     attrContainer.appendChild(manTitle);
+
+    //     mandatoryAttributes.forEach(attr => {
+    //         const initialSelected = getSelectedAttributes(p.item_id)[attr?.attribute_name] || attr?.possible_values;
+    //         const chipGroup = createAttributeChips(p, attr, initialSelected, true, updateProductState);
+    //         attrContainer.appendChild(chipGroup);
+    //     });
+    // }
+
+    // --- Render Optional Attributes ---
+    if (optionalAttributes.length > 0) {
+      const br = el('br');
+        const optTitle = el('p', "pSelectRight optional-title");
+        optTitle.innerHTML = "Additional Attributes:";
+        attrContainer.appendChild(br);
+        attrContainer.appendChild(optTitle);
+
+        optionalAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr?.attribute_name] || attr?.possible_values;
+            const chipGroup = createAttributeChips(p, attr, initialSelected, false, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+
+    // Initialize attribute selectors' enabled state and state data
+    attrContainer.classList.toggle('disabled', !cb.checked);
+    // Initial state setup if the product was already selected (e.g., after a re-render)
+    if (cb.checked) {
+        // This is important to set the initial state correctly on load
+        // We defer this until all selects are mounted, or ensure the initial state is correct.
+        // For simplicity, we assume the data from PRODUCT_BASE already includes selected attributes if a selection exists
+        // (which it won't in this case, so they default to all/empty)
+    }
+    }
+
+    const inline = el('div', 'attr-inline');
+    inline.dataset.pid = p.item_id; // use item_id for mapping
+    
+    row.appendChild(container); row.appendChild(mid);
+    if(p.product_type_details.length > 0){
+        console.log("IN ");
+        // row.appendChild(attrContainer); // Append the new attribute selectors container
+    }    
+    row.appendChild(right);
+    // if (p.mandatoryAttributes && p.mandatoryAttributes.length > 0) { 
+      // const hr = el('hr');
+      // row.appendChild(hr);
+      // row.appendChild(attri);
+      // row.appendChild(secondRight);
+    // }
+
+    row.appendChild(inline);
+    
+    return row;
+}
+
+
+// Cards layout
+function renderProductsCards(items = getCurrentSlice()) {
+  const cards = document.getElementById('cardsContainer');
+  cards.innerHTML = '';
+  if(items.length > 0){
+    items.forEach(p => cards.appendChild(createProductCard(p)));
+  }else{
+      cards.innerHTML = "<p>No Products Found.</p>"
+  }
+}
+
+
+// --- Table layout ---
+// function createMiniThumb(p) {
+//     const mt = el('div', 'mini-thumb');
+//     const img = new Image(); img.src = p.image_path || p.image || ''; img.alt = `${p.product_name} image`;
+//     // console.log("image path",p.image_path);
+//     // console.log("img",img);
+//     img.onerror = () => { img.src = mediaUrl+"media/images/no-product.png" };
+//     // img.onerror = () => { img.remove(); const fb = el('div', 'fallback'); fb.textContent = (p.product_name || 'Product').split(' ').map(w => w[0]).slice(0,2).join('').toUpperCase(); mt.appendChild(fb); };
+//     mt.appendChild(img);
+//     return mt;
+// }
+
+function createMiniThumb(p) {
+    // 1. Create a container for the hover effect
+    const container = document.createElement('div');
+    container.className = 'mini-thumb-container';
+
+    // 2. Create the visible thumbnail (Mini Thumb)
+    const mt = document.createElement('div');
+    mt.className = 'mini-thumb';
+
+    // Get the image source
+    const imageSrc = p.image_path || p.image || '';
+
+    // 3. Create the thumbnail image element
+    const thumbImg = new Image(); 
+    thumbImg.src = imageSrc; 
+    thumbImg.alt = `${p.product_name} thumbnail`;
+    thumbImg.onerror = () => { thumbImg.src = mediaUrl + "media/images/no-product.png" };
+    
+    mt.appendChild(thumbImg);
+    container.appendChild(mt); // Add thumbnail to container
+
+    // 4. Create the full-size image element for hover
+    const fullImgWrapper = document.createElement('div');
+    fullImgWrapper.className = 'full-image-hover'; // Class for CSS control
+    
+    const fullImg = new Image();
+    // Assuming the same source is used for the full image, but you can change this 
+    // to p.full_image_path if your product object has a separate full-size URL.
+    fullImg.src = imageSrc; 
+    fullImg.alt = `${p.product_name} full view`;
+    fullImg.onerror = () => { fullImg.src = mediaUrl + "media/images/no-product.png" }; // Same fallback
+    
+    fullImgWrapper.appendChild(fullImg);
+    container.appendChild(fullImgWrapper); // Add full image wrapper to container
+
+    // Return the main container instead of just the mini-thumb
+    return container; 
+}
+
+
+
+// function createMiniThumb(p) {
+//     const container = document.createElement('div');
+//     container.className = 'mini-thumb-container';
+
+//     const mt = document.createElement('div');
+//     mt.className = 'mini-thumb';
+
+//     const imageSrc = p.image_path || p.image || '';
+//     const thumbImg = new Image();
+//     thumbImg.src = imageSrc;
+//     thumbImg.alt = `${p.product_name} thumbnail`;
+//     thumbImg.onerror = () => { thumbImg.src = mediaUrl + "media/images/no-product.png" };
+
+//     mt.appendChild(thumbImg);
+//     container.appendChild(mt);
+
+//     const fullImgWrapper = document.createElement('div');
+//     fullImgWrapper.className = 'full-image-hover';
+
+//     const fullImg = new Image();
+//     fullImg.src = imageSrc;
+//     fullImg.alt = `${p.product_name} full view`;
+//     fullImg.onerror = () => { fullImg.src = mediaUrl + "media/images/no-product.png" };
+
+//     fullImgWrapper.appendChild(fullImg);
+//     document.body.appendChild(fullImgWrapper); // Append to body, not container
+
+//     // Hover logic
+//     mt.addEventListener('mouseenter', () => {
+//         fullImgWrapper.style.display = 'block';
+//     });
+
+//     mt.addEventListener('mousemove', (e) => {
+//         fullImgWrapper.style.top = (e.clientY + 20) + 'px'; // 20px offset
+//         fullImgWrapper.style.left = (e.clientX + 20) + 'px';
+//     });
+
+//     mt.addEventListener('mouseleave', () => {
+//         fullImgWrapper.style.display = 'none';
+//     });
+
+//     return container;
+// }
+
+
+// Create one global hover container
+// const hoverContainer = document.createElement('div');
+// hoverContainer.className = 'full-image-hover';
+// const hoverImg = new Image();
+// hoverContainer.appendChild(hoverImg);
+// document.body.appendChild(hoverContainer);
+
+// let hoverActive = false;
+
+// function createMiniThumb(p) {
+//     const container = document.createElement('div');
+//     container.className = 'mini-thumb-container';
+
+//     const mt = document.createElement('div');
+//     mt.className = 'mini-thumb';
+
+//     const imageSrc = p.image_path || p.image || '';
+//     const thumbImg = new Image();
+//     thumbImg.src = imageSrc;
+//     thumbImg.alt = `${p.product_name} thumbnail`;
+//     thumbImg.onerror = () => { thumbImg.src = mediaUrl + "media/images/no-product.png" };
+
+//     mt.appendChild(thumbImg);
+//     container.appendChild(mt);
+
+//     // Hover logic
+//     mt.addEventListener('mouseenter', () => {
+//         hoverImg.src = imageSrc;
+//         hoverImg.alt = `${p.product_name} full view`;
+//         hoverContainer.style.display = 'block';
+//     });
+
+//     mt.addEventListener('mousemove', (e) => {
+//         hoverContainer.style.top = (e.clientY + 20) + 'px';
+//         hoverContainer.style.left = (e.clientX + 20) + 'px';
+//     });
+
+//     mt.addEventListener('mouseleave', () => {
+//         setTimeout(() => {
+//             if (!hoverActive) hoverContainer.style.display = 'none';
+//         }, 100);
+//     });
+
+//     hoverContainer.addEventListener('mouseenter', () => {
+//         hoverActive = true;
+//     });
+
+//     hoverContainer.addEventListener('mouseleave', () => {
+//         hoverActive = false;
+//         hoverContainer.style.display = 'none';
+//     });
+
+//     return container;
+// }
+
+
+
+// Table layout
+// function renderProductsTable(items = getCurrentSlice()) {
+//   const wrap = document.getElementById('tableContainer');
+//   wrap.innerHTML = '';
+//   const table = document.createElement('table');
+//   const thead = document.createElement('thead'); const trh = document.createElement('tr');
+//   ['Select', 'Image', 'Product', 'SKU', 'Type', 'Short Description'].forEach(h => {
+//     const th = document.createElement('th'); th.textContent = h; trh.appendChild(th);
+//   });
+//   thead.appendChild(trh); table.appendChild(thead);
+//   const tbody = document.createElement('tbody');
+//   if(items.length > 0 ){
+//     items.forEach(p => {
+//         const tr = document.createElement('tr'); tr.id = `row-${p.id}`;
+//         const tdSel = document.createElement('td'); tdSel.className = 'select-cell';
+//         const cb = document.createElement('input'); cb.type = 'checkbox'; cb.checked = selectedIds.has(p.item_id);
+//         cb.addEventListener('change', () => { setChecked(p.item_id, cb.checked); tr.classList.toggle('selected', cb.checked); });
+//         tdSel.appendChild(cb); tr.appendChild(tdSel);
+
+//         const tdImg = document.createElement('td'); tdImg.className = 'thumb-cell'; tdImg.appendChild(createMiniThumb(p)); tr.appendChild(tdImg);
+//         const tdName = document.createElement('td'); tdName.textContent = p.product_name || '—'; tr.appendChild(tdName);
+//         const tdSku  = document.createElement('td'); tdSku.textContent = p.item_id || '—'; tr.appendChild(tdSku);
+//         const tdType = document.createElement('td'); const b = document.createElement('span'); b.className = 'badge'; b.textContent = p.product_type || '—'; tdType.appendChild(b); tr.appendChild(tdType);
+//         const tdDesc = document.createElement('td'); tdDesc.textContent = p.product_short_description || ''; tr.appendChild(tdDesc);
+
+//         tr.addEventListener('click', (e) => { if (e.target.tagName.toLowerCase() !== 'input') { cb.checked = !cb.checked; cb.dispatchEvent(new Event('change')); } });
+//         tbody.appendChild(tr);
+//     });
+//   }else{
+//     const tr = el('tr'); 
+//     // tr.id = `row-${p.id}`;
+//     const tdName = el('td');
+//     tdName.colSpan = 6;
+//     tdName.innerHTML = "No Products Found."
+//     tr.appendChild(tdName);
+//     // tr.colspan = 6;
+//     // tr.innerHTML 
+//     tbody.appendChild(tr);
+//   }
+
+//   table.appendChild(tbody);
+//   wrap.appendChild(table);
+// }
+
+// NOTE: Ensure getProductStateUpdater and generateAttributeUI functions are defined globally or accessible here.
+
+/**
+ * Returns a closure function that updates the global selectedProductsWithAttributes state
+ * based on the current selections (chips) found in the DOM for a specific product.
+ * This is used for both card and table views.
+ * * @param {Object} p - The product object.
+ * @param {HTMLElement} cb - The main product selection checkbox element.
+ * @param {HTMLElement} tr - The main row/card element (used for toggling 'selected' class).
+ * @returns {function} A function to be used as the attribute change handler.
+ */
+const getProductStateUpdater = (p, cb, tr) => () => {
+    const isSelected = cb.checked;
+    const currentSelections = {};
+    
+    // Find the attribute container using its unique ID, which is the same structure 
+    // used in both card and table detail views (e.g., 'attr-container-124353498' or just the main card element).
+    // For card view, the container is often the attrContainer element itself. 
+    // For table view, we use the explicit ID.
+    const attrContainer = document.getElementById(`attr-container-${p.item_id}`) || tr.querySelector('.attribute-selectors');
+
+    if (isSelected && attrContainer) {
+        // Iterate over all attribute groups (Mandatory and Optional) within the container
+        attrContainer.querySelectorAll('.attribute-chip-group').forEach(group => {
+            const attrName = group.dataset.attrName;
+            
+            // Collect selected chip values
+            const selectedOptions = Array.from(group.querySelectorAll('input[type="checkbox"]:checked'))
+                .map(checkbox => checkbox.value);
+
+            // Only add to the selection if at least one option is selected
+            if (selectedOptions.length > 0) {
+                currentSelections[attrName] = selectedOptions;
+            }
+        });
+    }
+    
+    // Update the global state array (selectedProductsWithAttributes)
+    toggleProductSelection(p.item_id, isSelected, currentSelections);
+    
+    // Update the visual status of the row/card
+    tr.classList.toggle('selected', isSelected);
+};
+
+/**
+ * Generates the full attribute selection UI (chips) for a given product.
+ * NOTE: Assumes el(), createAttributeChips(), and getSelectedAttributes() are defined globally.
+ * @param {Object} p - The product object from PRODUCT_BASE.
+ * @param {function} updateProductState - The callback to run on chip changes.
+ * @param {HTMLElement} attrContainer - The container to append the UI to.
+ */
+function generateAttributeUI(p, updateProductState, attrContainer) {
+    // Clear the container first, just in case
+    attrContainer.innerHTML = ''; 
+
+    const mandatoryAttributes = p.product_type_details?.filter(a => a.is_mandatory === 'Yes') || [];
+    const optionalAttributes = p.product_type_details?.filter(a => a.is_mandatory !== 'Yes') || [];
+
+    // --- Render Mandatory Attributes ---
+    if (mandatoryAttributes.length > 0) {
+        // Use a general title for the section header
+        const manTitle = el('p', "pSelectRight mandatory-title");
+        manTitle.innerHTML = "Mandatory Attributes:";
+        attrContainer.appendChild(manTitle);
+
+        mandatoryAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr?.attribute_name] || attr?.possible_values;
+            // The createAttributeChips function must be globally available
+            const chipGroup = createAttributeChips(p, attr, initialSelected, true, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+
+    // --- Render Optional Attributes ---
+    if (optionalAttributes.length > 0) {
+        // Add visual separation using the optional-title class
+        const optTitle = el('p', "pSelectRight optional-title");
+        optTitle.innerHTML = "Additional Attributes:";
+        
+        // Append the title for separation
+        attrContainer.appendChild(optTitle);
+
+        optionalAttributes.forEach(attr => {
+            const initialSelected = getSelectedAttributes(p.item_id)[attr?.attribute_name] || attr?.possible_values;
+            const chipGroup = createAttributeChips(p, attr, initialSelected, false, updateProductState);
+            attrContainer.appendChild(chipGroup);
+        });
+    }
+}
+
+/**
+ * Creates the HTML structure for a single attribute group using chip/checkbox labels.
+ * Assumes the helper function 'el' is available.
+ * * @param {Object} p - The product object.
+ * @param {Object} attr - The specific attribute detail object.
+ * @param {string[]} initialSelected - Array of values that should be pre-checked.
+ * @param {boolean} isMandatory - True if the attribute is mandatory.
+ * @param {function} updateCallback - The function to call when a chip selection changes.
+ * @returns {HTMLElement} The attribute chip group container (div).
+ */
+function createAttributeChips(p, attr, initialSelected, isMandatory, updateCallback) {
+    const wrapper = el('div', 'attribute-chip-group');
+    wrapper.dataset.attrName = attr?.attribute_name;
+    
+    // Determine the header text based on structure preference (e.g., just the name)
+    const statusText = isMandatory ? ' (Mandatory)' : ' (Optional)';
+    wrapper.innerHTML = `<p class="attribute-header">${attr?.attribute_name}${statusText}:</p>`;
+
+    const chipContainer = el('div', 'chips-container');
+
+    attr?.possible_values.forEach(value => {
+        const chip = el('label', 'attribute-chip');
+        
+        // Checkbox input is hidden, but drives the selection state
+        const checkbox = document.createElement('input');
+        checkbox.type = 'checkbox';
+        checkbox.value = value;
+        // Ensure the name is unique per product/attribute group
+        checkbox.name = `${p.item_id}-${attr?.attribute_name}`; 
+        
+        // Set initial state
+        checkbox.checked = initialSelected.includes(value); 
+        
+        // The visual part of the chip
+        const span = el('span');
+        span.textContent = value;
+        
+        chip.appendChild(checkbox);
+        chip.appendChild(span);
+        chipContainer.appendChild(chip);
+    });
+    
+    // Attach listener to the container using event delegation
+    chipContainer.addEventListener('change', updateCallback);
+
+    wrapper.appendChild(chipContainer);
+    return wrapper;
+}
+
+// function renderProductsTable(items = getCurrentSlice()) {
+//     const wrap = document.getElementById('tableContainer');
+//     wrap.innerHTML = '';
+//     const table = document.createElement('table');
+//     table.classList.add('table', 'table-striped', 'table-bordered','table-responsive');
+    
+//     const thead = document.createElement('thead'); 
+//     const trh = document.createElement('tr');
+    
+//     // Table Headers
+//     ['Select', 'Image', 'Product', 'SKU', 'Type', 'Short Description'].forEach(h => {
+//         const th = document.createElement('th'); th.textContent = h; trh.appendChild(th);
+//     });
+//     thead.appendChild(trh); table.appendChild(thead);
+    
+//     const tbody = document.createElement('tbody');
+    
+//     if (items.length > 0) {
+//         items.forEach(p => {
+//             const tr = document.createElement('tr'); 
+//             tr.id = `row-${p.id}`;
+//             if (isProductSelected(p.item_id)) tr.classList.add('selected');
+
+//             // --- Define Checkbox (cb) and State Updater ---
+//             const cb = document.createElement('input'); 
+//             cb.type = 'checkbox'; 
+//             cb.checked = isProductSelected(p.item_id);
+//             // console.log("checkkkkk")
+            
+//             // The state updater function is bound to this specific row/checkbox
+//             const updateProductState = getProductStateUpdater(p, cb, tr);
+
+//             // --- Select Cell ---
+//             const tdSel = document.createElement('td'); 
+//             tdSel.className = 'select-cell';
+//             tdSel.appendChild(cb); 
+//             tr.appendChild(tdSel);
+
+//             // --- Other Cells ---
+//             const tdImg = document.createElement('td'); tdImg.className = 'thumb-cell'; tdImg.appendChild(createMiniThumb(p)); tr.appendChild(tdImg);
+//             const tdName = document.createElement('td'); tdName.textContent = p.product_name || '—'; tr.appendChild(tdName);
+//             const tdSku  = document.createElement('td'); tdSku.textContent = p.item_id || '—'; tr.appendChild(tdSku);
+//             const tdType = document.createElement('td'); const b = document.createElement('span'); b.className = 'badge'; b.textContent = p.product_type || '—'; tdType.appendChild(b); tr.appendChild(tdType);
+//             const tdDesc = document.createElement('td'); tdDesc.innerHTML = p.product_short_description || ''; tr.appendChild(tdDesc);
+
+//             // ---------------------------------------------
+//             // --- ATTRIBUTE SELECTION IMPLEMENTATION ---
+//             // ---------------------------------------------
+
+//             // 1. DETAIL ROW STRUCTURE
+//             const detailRow = document.createElement('tr');
+//             detailRow.classList.add('attribute-detail-row'); // Custom class for styling
+//             detailRow.style.display = 'none'; // Initially hidden
+//             detailRow.id = `detail-row-${p.id}`;
+            
+//             const detailCell = document.createElement('td');
+//             detailCell.colSpan = 6; // Must span all columns
+            
+//             const attrContainer = document.createElement('div');
+//             attrContainer.id = `attr-container-${p.item_id}`; // Unique ID for targeting by updateProductState
+//             attrContainer.classList.add('attribute-selectors', 'table-selectors');
+
+//             // 2. GENERATE CHIPS UI
+//             generateAttributeUI(p, updateProductState, attrContainer);
+
+//             // Initially disable the chips if the product is not selected
+//             attrContainer.classList.toggle('disabled', !cb.checked);
+
+//             detailCell.appendChild(attrContainer);
+//             detailRow.appendChild(detailCell);
+
+//             if(p.product_type_details.length > 0){
+//                 // 3. TOGGLE BUTTON (in the main row)
+//                 const tdAttr = document.createElement('td'); 
+//                 const toggleButton = document.createElement('button');
+//                 toggleButton.textContent = 'Configure';
+//                 toggleButton.classList.add('btn', 'btn-sm', 'btn-info', 'attribute-toggle-btn');
+//                 tdattr?.appendChild(toggleButton);
+//                 // tr.appendChild(tdAttr);
+            
+
+
+//             // 4. EVENT LISTENERS
+            
+//             // a) Toggle Button Logic
+//             toggleButton.addEventListener('click', (e) => {
+//                 e.stopPropagation(); // Stop row click event
+//                 const isHidden = detailRow.style.display === 'none';
+//                 detailRow.style.display = isHidden ? '' : 'none'; // Toggle visibility
+//                 toggleButton.textContent = isHidden ? 'Hide Attributes' : 'Configure';
+//                 toggleButton.classList.toggle('btn-info', !isHidden);
+//                 toggleButton.classList.toggle('btn-secondary', isHidden);
+//             });
+            
+//             // b) Main Checkbox Change Logic
+//             cb.addEventListener('change', () => { 
+//                 // console.log("cheeeeeeeeee");
+//                 updateProductState(); // Update state on check/uncheck
+//                 attrContainer.classList.toggle('disabled', !cb.checked); // Enable/Disable chips
+//             });
+
+//             // c) Row Click Listener (Updated to ignore button clicks)
+//             tr.addEventListener('click', (e) => { 
+//                 const tag = e.target.tagName.toLowerCase();
+//                 // console.log("clikk")
+//                 if (tag !== 'input' && tag !== 'button') { 
+//                     cb.checked = !cb.checked; 
+//                     cb.dispatchEvent(new Event('change')); 
+//                 } 
+//             });
+//             }else{
+//                 const tdAttr = document.createElement('td'); 
+//                 tr.appendChild(tdAttr);
+//                 // b) Main Checkbox Change Logic
+//                 cb.addEventListener('change', () => { 
+//                     // console.log("cheeeeeeeeee");
+//                     updateProductState(); // Update state on check/uncheck
+//                     attrContainer.classList.toggle('disabled', !cb.checked); // Enable/Disable chips
+//                 });
+//                 tr.addEventListener('click', (e) => { 
+//                     const tag = e.target.tagName.toLowerCase();
+//                     // console.log("clikk")
+//                     if (tag !== 'input' && tag !== 'button') { 
+//                         cb.checked = !cb.checked; 
+//                         cb.dispatchEvent(new Event('change')); 
+//                     } 
+//                 });
+//             }
+            
+//             // 5. Append Rows to TBODY
+//             tbody.appendChild(tr);
+//             tbody.appendChild(detailRow); // Append the detail row right after the main row
+//         });
+//     } else {
+//         const tr = el('tr'); 
+//         const tdName = el('td');
+//         tdName.colSpan = 6; 
+//         tdName.innerHTML = "No Products Found.";
+//         tr.appendChild(tdName);
+//         tbody.appendChild(tr);
+//     }
+
+//     table.appendChild(tbody);
+//     wrap.appendChild(table);
+// }
+
+function renderProductsTable(items = getCurrentSlice()) {
+    const wrap = document.getElementById('tableContainer');
+    wrap.innerHTML = '';
+    const table = document.createElement('table');
+    table.classList.add('table', 'table-striped', 'table-bordered', 'table-responsive');
+    table.id = 'productsTable'; // ✅ Add a unique table ID
+
+
+    const thead = document.createElement('thead');
+    const trh = document.createElement('tr');
+
+    // --- "Select All" Header with Checkbox ---
+    const thSelect = document.createElement('th');
+    const selectAllCheckbox = document.createElement('input');
+    selectAllCheckbox.type = 'checkbox';
+    selectAllCheckbox.id = 'selectAllCheckbox';
+    thSelect.appendChild(selectAllCheckbox);
+    trh.appendChild(thSelect);
+
+    // Other headers
+    ['Image', 'Product', 'SKU', 'Type', 'Description'].forEach(h => {
+        const th = document.createElement('th');
+        th.textContent = h;
+        trh.appendChild(th);
+    });
+    thead.appendChild(trh);
+    table.appendChild(thead);
+
+    const tbody = document.createElement('tbody');
+
+    if (items.length > 0) {
+        items.forEach(p => {
+            const tr = document.createElement('tr');
+            tr.id = `row-${p.id}`;
+            if (isProductSelected(p.item_id)) tr.classList.add('selected');
+
+            // Checkbox for each row
+            const cb = document.createElement('input');
+            cb.type = 'checkbox';
+            cb.classList.add('checkbox-productlist'); // ✅ correct way to add class
+            cb.checked = isProductSelected(p.item_id);
+
+            const updateProductState = getProductStateUpdater(p, cb, tr);
+
+            const tdSel = document.createElement('td');
+            tdSel.className = 'select-cell';
+            tdSel.appendChild(cb);
+            tr.appendChild(tdSel);
+
+            const tdImg = document.createElement('td');
+            tdImg.className = 'thumb-cell';
+            tdImg.appendChild(createMiniThumb(p));
+            tr.appendChild(tdImg);
+
+            const tdName = document.createElement('td');
+            tdName.textContent = p.product_name || '—';
+            tr.appendChild(tdName);
+
+            const tdSku = document.createElement('td');
+            tdSku.textContent = p.item_id || '—';
+            tr.appendChild(tdSku);
+
+            const tdType = document.createElement('td');
+            const b = document.createElement('span');
+            b.className = 'badge';
+            b.textContent = p.product_type || '—';
+            tdType.appendChild(b);
+            tr.appendChild(tdType);
+
+            // const tdDesc = document.createElement('td');
+            // tdDesc.innerHTML = p.product_short_description || '';
+            // tr.appendChild(tdDesc);
+
+            const tdDesc = document.createElement('td');
+
+            // Create a container for descriptions
+            const descContainer = document.createElement('div');
+            descContainer.classList.add('description-cell');
+
+            // Short description (always visible)
+            const shortDesc = document.createElement('div');
+            shortDesc.classList.add('short-desc');
+            shortDesc.innerHTML = `<strong>Short Description:</strong> ${p.product_short_description || 'N/A'}`;
+
+            // Long description (hidden initially)
+            const longDesc = document.createElement('div');
+            longDesc.classList.add('long-desc');
+            longDesc.innerHTML = `<strong>Long Description:</strong> ${p.product_long_description || 'N/A'}`;
+            longDesc.style.display = 'none';
+
+            // Button to toggle long description
+            const toggleBtn = document.createElement('button');
+            toggleBtn.textContent = 'Show Long Description';
+            toggleBtn.classList.add('btn');
+            toggleBtn.classList.add('btn-primary');
+            toggleBtn.classList.add('btn-sm');
+            toggleBtn.classList.add('btn-toggle-desc');
+            toggleBtn.style.fontSize = 'smaller';
+            toggleBtn.style.margin = '5px';
+
+
+            // Toggle logic
+            toggleBtn.addEventListener('click', () => {
+            const isVisible = longDesc.style.display === 'block';
+            longDesc.style.display = isVisible ? 'none' : 'block';
+            toggleBtn.textContent = isVisible ? 'Show Long Description' : 'Hide Long Description';
+            });
+
+            // Append elements in order
+            descContainer.appendChild(shortDesc);
+            descContainer.appendChild(toggleBtn);
+            descContainer.appendChild(longDesc);
+            tdDesc.appendChild(descContainer);
+            tr.appendChild(tdDesc);
+
+
+            // Handle attribute rows (kept your same logic)
+            const detailRow = document.createElement('tr');
+            detailRow.classList.add('attribute-detail-row');
+            detailRow.style.display = 'none';
+            detailRow.id = `detail-row-${p.id}`;
+
+            const detailCell = document.createElement('td');
+            detailCell.colSpan = 6;
+
+            const attrContainer = document.createElement('div');
+            attrContainer.id = `attr-container-${p.item_id}`;
+            attrContainer.classList.add('attribute-selectors', 'table-selectors');
+
+            generateAttributeUI(p, updateProductState, attrContainer);
+            attrContainer.classList.toggle('disabled', !cb.checked);
+
+            detailCell.appendChild(attrContainer);
+            detailRow.appendChild(detailCell);
+
+            // Checkbox behavior
+            cb.addEventListener('change', () => {
+                updateProductState();
+                attrContainer.classList.toggle('disabled', !cb.checked);
+            });
+
+            tr.addEventListener('click', (e) => {
+                const tag = e.target.tagName.toLowerCase();
+                if (tag !== 'input' && tag !== 'button') {
+                    cb.checked = !cb.checked;
+                    cb.dispatchEvent(new Event('change'));
+                }
+            });
+
+            tbody.appendChild(tr);
+            tbody.appendChild(detailRow);
+        });
+    } else {
+        const tr = document.createElement('tr');
+        const td = document.createElement('td');
+        td.colSpan = 6;
+        td.textContent = 'No Products Found.';
+        tr.appendChild(td);
+        tbody.appendChild(tr);
+    }
+
+    table.appendChild(tbody);
+    wrap.appendChild(table);
+
+    // --- Select All Checkbox Logic ---
+    selectAllCheckbox.addEventListener('change', () => {
+        // ✅ Only get product checkboxes inside *this* table
+        const allCheckboxes = table.querySelectorAll('tbody .checkbox-productlist');
+        console.log("allCheckboxes", allCheckboxes);
+
+        allCheckboxes.forEach(cb => {
+            cb.checked = selectAllCheckbox.checked;
+            cb.dispatchEvent(new Event('change'));
+        });
+    });
+
+    // --- Keep "Select All" synced with individual selections ---
+    tbody.addEventListener('change', (e) => {
+        if (e.target && e.target.classList.contains('checkbox-productlist')) {
+            // ✅ Again, limit scope to *this* table
+            const allCheckboxes = table.querySelectorAll('tbody .checkbox-productlist');
+            const allChecked = Array.from(allCheckboxes).every(cb => cb.checked);
+            const someChecked = Array.from(allCheckboxes).some(cb => cb.checked);
+
+            selectAllCheckbox.checked = allChecked;
+            selectAllCheckbox.indeterminate = !allChecked && someChecked;
+        }
+    });
+
+
+}
+
+
+// function renderInlineForCards() {
+//     const api = API_RESPONSE_AI;
+//     // Clear all inline sections first
+//     document.querySelectorAll('.attr-inline').forEach(div => div.innerHTML = '');
+
+//     PRODUCT_BASE.forEach((p, idx) => {
+//         const inline = document.querySelector(`.attr-inline[data-pid="${p.item_id}"]`);
+//         if (!inline) return;
+        
+//         // --- CHANGE HERE: Use the new helper function ---
+//         if (!isProductSelected(p.item_id)) return; // only show for selected
+        
+//         const res = findApiResultForProduct(p, idx, api);
+//         const pid = p.item_id;
+//         if (!lastSeen.has(pid)) lastSeen.set(pid, { mandatory: new Map(), additional: new Map(), ocr_results: new Map(), visual_results: new Map() });
+//         const mem = lastSeen.get(pid);
+
+//         // Build sections
+//         const manTitle = el('div', 'section-title'); manTitle.innerHTML = '<strong>Mandatory</strong>';
+//         const manChips = el('div', 'chips');
+//         const addTitle = el('div', 'section-title'); addTitle.innerHTML = '<strong>Additional</strong>';
+//         const addChips = el('div', 'chips');
+
+//         const addOcr = el('div', 'section-title'); addOcr.innerHTML = '<strong>Ocr</strong>';
+//         const ocrChips = el('div', 'chips');
+//         const addVisual = el('div', 'section-title'); addVisual.innerHTML = '<strong>Visual</strong>';
+//         const visualChips = el('div', 'chips');
+        
+
+//         const mandCount = renderChips(manChips, res?.mandatory || {}, mem.mandatory);
+//         const addCount = renderChips(addChips, res?.additional || {}, mem.additional);
+//         const ocrCount = renderChips(ocrChips, res?.ocr_results?.extracted_attributes || {}, mem?.ocr_results);
+//         const visualCount = renderChips(visualChips, res?.visual_results?.visual_attributes || {}, mem?.visual_results);
+
+//         const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+//         const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+//         const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+//         const c3 = el('span', 'pill'); c3.textContent = `OCR: ${ocrCount}`;
+//         const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+//         counts.appendChild(c1); counts.appendChild(c2);  counts.appendChild(c3);  counts.appendChild(c4);
+
+//         inline.appendChild(manTitle); inline.appendChild(manChips);
+//         inline.appendChild(addTitle); inline.appendChild(addChips);
+//         inline.appendChild(addOcr); inline.appendChild(ocrChips);
+//         inline.appendChild(addVisual); inline.appendChild(visualChips);
+//         inline.appendChild(counts);
+//     });
+
+//     // Update summary
+//     $('#statTotal').textContent = api.total_products ?? 0;
+//     $('#statOk').textContent = api.successful ?? 0;
+//     $('#statKo').textContent = api.failed ?? 0;
+//     $('#api-summary').style.display = 'block';
+// }
+
+// -----------------------------------------------------------
+
+// function renderInlineForTable() {
+//     const api = API_RESPONSE_AI;
+//     const table = $('#tableContainer');
+//     if (!table) return;
+//     // Remove existing detail rows
+//     table.querySelectorAll('tr.detail-row').forEach(r => r.remove());
+
+//     PRODUCT_BASE.forEach((p, idx) => {
+//         // --- CHANGE HERE: Use the new helper function ---
+//         if (!isProductSelected(p.item_id)) return;
+        
+//         const res = findApiResultForProduct(p, idx, api);
+//         const pid = p.item_id;
+//         if (!lastSeen.has(pid)) lastSeen.set(pid, { mandatory: new Map(), additional: new Map(), ocr_results: new Map(), visual_results: new Map() });
+//         const mem = lastSeen.get(pid);
+
+//         const tbody = table.querySelector('tbody');
+//         // NOTE: The table rendering uses p.id for the row ID: `row-${p.id}`.
+//         // Assuming p.id is still valid for finding the base row, as your original code used it.
+//         const baseRow = tbody.querySelector(`#row-${p.id}`); 
+//         if (!baseRow) return;
+
+//         const detail = el('tr', 'detail-row');
+//         const td = el('td'); td.colSpan = 6; // number of columns
+//         const content = el('div', 'detail-content');
+
+//         const manTitle = el('div', 'section-title'); manTitle.innerHTML = '<strong>Mandatory</strong>';
+//         const manChips = el('div', 'chips');
+//         const addTitle = el('div', 'section-title'); addTitle.innerHTML = '<strong>Additional</strong>';
+//         const addChips = el('div', 'chips');
+//         const addOcr = el('div', 'section-title'); addOcr.innerHTML = '<strong>Ocr</strong>';
+//         const ocrChips = el('div', 'chips');
+//         const addVisuals = el('div', 'section-title'); addVisuals.innerHTML = '<strong>Visuals</strong>';
+//         const visualsChips = el('div', 'chips');
+
+//         const mandCount = renderChips(manChips, res?.mandatory || {}, mem.mandatory);
+//         const addCount = renderChips(addChips, res?.additional || {}, mem.additional);
+//         const ocrCount = renderChips(ocrChips, res?.ocr_results?.extracted_attributes || {}, mem.ocr_results);
+//         const visualCount = renderChips(visualsChips, res?.visual_results?.visual_attributes || {}, mem.visual_results);
+
+//         const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+//         const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+//         const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+//         const c3 = el('span', 'pill'); c3.textContent = `Ocr: ${ocrCount}`;
+//         const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+//         counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+
+//         content.appendChild(manTitle); content.appendChild(manChips);
+//         content.appendChild(addTitle); content.appendChild(addChips);
+//         content.appendChild(addOcr); content.appendChild(ocrChips);
+//         content.appendChild(addVisuals); content.appendChild(visualsChips);
+//         content.appendChild(counts);
+//         td.appendChild(content); detail.appendChild(td);
+
+//         // insert after base row
+//         baseRow.insertAdjacentElement('afterend', detail);
+//     });
+
+//     // Update summary
+//     $('#statTotal').textContent = api.total_products ?? 0;
+//     $('#statOk').textContent = api.successful ?? 0;
+//     $('#statKo').textContent = api.failed ?? 0;
+//     $('#api-summary').style.display = 'block';
+// }
+
+function renderInlineForCards() {
+    const api = API_RESPONSE_AI;
+    document.querySelectorAll('.attr-inline').forEach(div => div.innerHTML = '');
+
+    PRODUCT_BASE.forEach((p, idx) => {
+        const inline = document.querySelector(`.attr-inline[data-pid="${p.item_id}"]`);
+        if (!inline) return;
+        
+        if (!isProductSelected(p.item_id)) return;
+        
+        const res = findApiResultForProduct(p, idx, api);
+        
+        // Clear existing content
+        inline.innerHTML = '';
+
+
+        // 1. MANDATORY SECTION: RENDER AS COMPARISON CARDS
+        const mandatorySection = renderMandatoryComparisonCards(
+            res?.mandatory || {}, 
+            'Mandatory Attributes Comparison'
+        );
+        inline.appendChild(mandatorySection);
+        const mandCount = Object.keys(res?.mandatory || {}).length;
+        
+
+        const combinedTitle = el('div', 'section-title');
+        combinedTitle.innerHTML = '<h2>Additional & AI-Driven Attributes</h2>';
+        inline.appendChild(combinedTitle);
+
+        const combinedAttributesContainer = el('div', 'combined-attributes-container');
+
+        // 2. ADDITIONAL SECTION: RENDER AS SIMPLE TABLE
+        const additionalSection = renderAttributesAsTable(
+            res?.additional || {}, 
+            'Additional Attributes'
+        );
+        // inline.appendChild(additionalSection);
+        const addCount = Object.keys(res?.additional || {}).length;
+        
+        // 3. OCR SECTION: RENDER AS SIMPLE TABLE
+        const ocrSection = renderAttributesAsTable(
+            res?.ocr_results?.extracted_attributes || {}, 
+            'OCR Results'
+        );
+        // inline.appendChild(ocrSection);
+        const ocrCount = Object.keys(res?.ocr_results?.extracted_attributes || {}).length;
+        
+        // 4. VISUAL SECTION: RENDER AS SIMPLE TABLE
+        const visualSection = renderAttributesAsTable(
+            res?.visual_results?.visual_attributes || {}, 
+            'Visual Attributes'
+        );
+        // inline.appendChild(visualSection);
+        const visualCount = Object.keys(res?.visual_results?.visual_attributes || {}).length;
+        combinedAttributesContainer.appendChild(additionalSection);
+        combinedAttributesContainer.appendChild(ocrSection);
+        combinedAttributesContainer.appendChild(visualSection);
+        inline.appendChild(combinedAttributesContainer);
+        // --- Summary Counts (Pills) ---
+        const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+        const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+        const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+        const c3 = el('span', 'pill'); c3.textContent = `OCR: ${ocrCount}`;
+        const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+        counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+
+        inline.appendChild(counts);
+    });
+
+    // Update summary
+    $('#statTotal').textContent = selectedProductsWithAttributes.length ?? api.total_products ?? 0;
+    $('#statOk').textContent = selectedProductsWithAttributes.length ?? api.successful ?? 0;
+    $('#statKo').textContent = api.failed ?? 0;
+    $('#api-summary').style.display = 'block';
+}
+
+// function renderInlineForCards() {
+//     const api = API_RESPONSE_AI;
+//     // Clear all inline sections first
+//     document.querySelectorAll('.attr-inline').forEach(div => div.innerHTML = '');
+
+//     PRODUCT_BASE.forEach((p, idx) => {
+//         const inline = document.querySelector(`.attr-inline[data-pid="${p.item_id}"]`);
+//         if (!inline) return;
+        
+//         if (!isProductSelected(p.item_id)) return;
+        
+//         const res = findApiResultForProduct(p, idx, api);
+//         const pid = p.item_id;
+//         // Memory map (mem) is no longer needed since we removed chip rendering
+//         // I'll keep the variable declarations for count consistency, but remove the memory map usage.
+
+//         // --- 1. MANDATORY SECTION: RENDER AS COMPARISON CARDS ---
+//         const mandatorySection = renderMandatoryComparisonCards(
+//             res?.mandatory || {}, 
+//             'Mandatory Attributes Comparison'
+//         );
+//         inline.appendChild(mandatorySection);
+        
+//         const mandCount = Object.keys(res?.mandatory || {}).length;
+        
+//         // --- 2. ADDITIONAL SECTION: RENDER AS SIMPLE CARDS ---
+//         const additionalSection = renderAttributesAsTable(
+//             res?.additional || {}, 
+//             'Additional Attributes'
+//         );
+//         inline.appendChild(additionalSection);
+//         const addCount = Object.keys(res?.additional || {}).length;
+        
+//         // --- 3. OCR SECTION: RENDER AS SIMPLE CARDS ---
+//         const ocrSection = renderAttributesAsTable(
+//             res?.ocr_results?.extracted_attributes || {}, 
+//             'OCR Results'
+//         );
+//         inline.appendChild(ocrSection);
+//         const ocrCount = Object.keys(res?.ocr_results?.extracted_attributes || {}).length;
+        
+//         // --- 4. VISUAL SECTION: RENDER AS SIMPLE CARDS ---
+//         const visualSection = renderAttributesAsTable(
+//             res?.visual_results?.visual_attributes || {}, 
+//             'Visual Results'
+//         );
+//         inline.appendChild(visualSection);
+//         const visualCount = Object.keys(res?.visual_results?.visual_attributes || {}).length;
+        
+//         // --- Summary Counts (Pills) ---
+//         const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+//         const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+//         const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+//         const c3 = el('span', 'pill'); c3.textContent = `OCR: ${ocrCount}`;
+//         const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+//         counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+
+//         inline.appendChild(counts);
+//     });
+
+//     // Update summary
+//     $('#statTotal').textContent = api.total_products ?? 0;
+//     $('#statOk').textContent = api.successful ?? 0;
+//     $('#statKo').textContent = api.failed ?? 0;
+//     $('#api-summary').style.display = 'block';
+// }
+
+// ----------------------------------------------------------------
+// NOTE: You MUST include renderMandatoryComparisonCards (from previous response)
+// and the necessary CSS for both card styles!
+// ----------------------------------------------------------------
+
+// ------------------------------------------------------------------
+// --- 1. MANDATORY COMPARISON HELPER (Existing vs. AI, with Highlighting) ---
+// ------------------------------------------------------------------
+
+// function renderInlineForCards() {
+//     const api = API_RESPONSE_AI;
+//     // Clear all inline sections first
+//     document.querySelectorAll('.attr-inline').forEach(div => div.innerHTML = '');
+
+//     PRODUCT_BASE.forEach((p, idx) => {
+//         const inline = document.querySelector(`.attr-inline[data-pid="${p.item_id}"]`);
+//         if (!inline) return;
+        
+//         // --- CHANGE HERE: Use the new helper function ---
+//         if (!isProductSelected(p.item_id)) return; // only show for selected
+        
+//         const res = findApiResultForProduct(p, idx, api);
+//         const pid = p.item_id;
+//         // Keep memory logic for old chip renderer, even though card renderer doesn't need it
+//         if (!lastSeen.has(pid)) lastSeen.set(pid, { mandatory: new Map(), additional: new Map(), ocr_results: new Map(), visual_results: new Map() });
+//         const mem = lastSeen.get(pid);
+
+//         // ------------------------------------------------
+//         // 1. MANDATORY SECTION: RENDER AS COMPARISON CARDS
+//         // ------------------------------------------------
+//         const mandatorySection = renderMandatoryComparisonCards(
+//             res?.mandatory || {}, 
+//             'Mandatory Attributes Comparison'
+//         );
+//         inline.appendChild(mandatorySection);
+        
+//         // Count the attributes for the summary pill
+//         const mandCount = Object.keys(res?.mandatory || {}).length;
+        
+//         // ------------------------------------------------
+//         // 2. ADDITIONAL/OCR/VISUALS: RENDER AS CHIPS (Original Logic)
+//         // ------------------------------------------------
+        
+//         // ADDITIONAL
+//         const addTitle = el('div', 'section-title'); addTitle.innerHTML = '<strong>Additional</strong>';
+//         const addChips = el('div', 'chips');
+//         const addCount = renderChips(addChips, res?.additional || {}, mem.additional);
+//         inline.appendChild(addTitle); inline.appendChild(addChips);
+        
+//         // OCR
+//         const addOcr = el('div', 'section-title'); addOcr.innerHTML = '<strong>Ocr</strong>';
+//         const ocrChips = el('div', 'chips');
+//         const ocrCount = renderChips(ocrChips, res?.ocr_results?.extracted_attributes || {}, mem?.ocr_results);
+//         inline.appendChild(addOcr); inline.appendChild(ocrChips);
+        
+//         // VISUALS
+//         const addVisual = el('div', 'section-title'); addVisual.innerHTML = '<strong>Visual</strong>';
+//         const visualChips = el('div', 'chips');
+//         const visualCount = renderChips(visualChips, res?.visual_results?.visual_attributes || {}, mem?.visual_results);
+//         inline.appendChild(addVisual); inline.appendChild(visualChips);
+        
+//         // --- Summary Counts (Pills) ---
+//         const counts = el('div'); counts.style.display = 'flex'; counts.style.gap = '8px'; counts.style.margin = '8px 0 0';
+//         const c1 = el('span', 'pill'); c1.textContent = `Mandatory: ${mandCount}`;
+//         const c2 = el('span', 'pill'); c2.textContent = `Additional: ${addCount}`;
+//         const c3 = el('span', 'pill'); c3.textContent = `OCR: ${ocrCount}`;
+//         const c4 = el('span', 'pill'); c4.textContent = `Visuals: ${visualCount}`;
+//         counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+
+//         inline.appendChild(counts);
+//     });
+
+//     // Update summary
+//     $('#statTotal').textContent = api.total_products ?? 0;
+//     $('#statOk').textContent = api.successful ?? 0;
+//     $('#statKo').textContent = api.failed ?? 0;
+//     $('#api-summary').style.display = 'block';
+// }
+
+/**
+ * Renders a table for Mandatory attributes, comparing AI-extracted value ('value') 
+ * against the existing value ('original_value'). Includes a scroll wrapper.
+ * @param {Object} attributes - The mandatory attribute data.
+ * @param {string} title - The title for the table section.
+ * @returns {HTMLElement} A div containing the comparison table.
+ */
+// function renderMandatoryComparisonTable(attributes, title) {
+//     const section = el('div', 'attribute-section');
+    
+//     let attributeEntries = [];
+
+//     Object.keys(attributes).forEach(key => {
+//         const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]]; 
+//         valuesArray.forEach(v => {
+//             const aiValue = v.value || 'N/A';
+//             const originalValue = v.original_value || 'N/A';
+//             const source = v.source || 'N/A';
+            
+//             // Comparison is case-insensitive and ignores leading/trailing whitespace
+//             const isMatch = (String(aiValue).trim().toLowerCase() === String(originalValue).trim().toLowerCase());
+
+//             attributeEntries.push({
+//                 name: key,
+//                 aiValue: aiValue,
+//                 originalValue: originalValue,
+//                 source: source,
+//                 isMatch: isMatch
+//             });
+//         });
+//     });
+
+//     const titleEl = el('div', 'section-title');
+//     titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+//     section.appendChild(titleEl);
+    
+//     if (attributeEntries.length === 0) {
+//         const msg = el('p', 'no-attributes-message');
+//         msg.textContent = `No ${title.toLowerCase()} found.`;
+//         section.appendChild(msg);
+//         return section;
+//     }
+
+//     // --- SCROLL WRAPPER ADDITION ---
+//     const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+//     const table = el('table', 'attribute-detail-table comparison-table');
+    
+//     const thead = el('thead');
+//     const headerRow = el('tr');
+    
+//     ['Attribute Name', 'Source', 'Manually Identified Value', 'AI Generated Value'].forEach(text => {
+//         const th = el('th');
+//         th.textContent = text;
+//         headerRow.appendChild(th);
+//     });
+//     thead.appendChild(headerRow);
+//     table.appendChild(thead);
+
+//     const tbody = el('tbody');
+
+//     attributeEntries.forEach(attr => {
+//         // Highlight the entire row in red if the values do not match
+//         const row = el('tr', attr?.isMatch ? 'match' : 'mismatch-row'); 
+        
+//         // 1. Attribute Name
+//         const nameTd = el('td', 'attribute-name');
+//         nameTd.textContent = attr?.name.replace(/_/g, ' '); 
+//         row.appendChild(nameTd);
+
+//         // 2. Source
+//         const sourceTd = el('td', 'attribute-source');
+//         sourceTd.textContent = formatString(attr?.source);
+//         row.appendChild(sourceTd);
+
+
+//         // 3. Existing Value
+//         const originalTd = el('td', 'original-value');
+//         originalTd.textContent = formatString(attr?.originalValue);
+//         row.appendChild(originalTd);
+
+//         // 4. AI Extracted Value (Highlight if mismatch)
+//         const aiTd = el('td', `ai-value ${attr?.aiValue ? '' : 'mismatch-value'}`);
+//         aiTd.textContent = attr?.aiValue;
+//         row.appendChild(aiTd);
+        
+
+//         // 5. Match Status
+//         // const matchTd = el('td', 'match-status');
+//         // const matchPill = el('span', `pill status-pill status-${attr?.isMatch ? 'match' : 'mismatch'}`);
+//         // matchPill.textContent = attr?.isMatch ? '✅ MATCH' : '❌ MISMATCH';
+//         // matchTd.appendChild(matchPill);
+//         // row.appendChild(matchTd);
+
+//         tbody.appendChild(row);
+//     });
+
+//     table.appendChild(tbody);
+//     scrollWrapper.appendChild(table); // Append table to wrapper
+//     section.appendChild(scrollWrapper); // Append wrapper to section
+//     return section;
+// }
+
+// ------------------------------------------------------------------
+// --- 2. GENERAL ATTRIBUTE HELPER (Name, Value, Source, with Scroll) ---
+// ------------------------------------------------------------------
+/**
+ * Renders a table for Mandatory attributes, comparing AI-extracted value ('value') 
+ * against the existing value ('original_value'). Includes a scroll wrapper and mismatch highlighting.
+ * @param {Object} attributes - The mandatory attribute data.
+ * @param {string} title - The title for the table section.
+ * @returns {HTMLElement} A div containing the comparison table.
+ */
+function renderMandatoryComparisonTable(attributes, title, productType) {
+    const section = el('div', 'attribute-section');
+
+    // --- 1. Intermediate object for merging values ---
+    let mergedAttributes = {};
+
+    // --- Build mergedAttributes ---
+    Object.keys(attributes).forEach(key => {
+        const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]];
+
+        if (!mergedAttributes[key]) {
+            mergedAttributes[key] = {
+                aiValues: new Set(),
+                originalValues: new Set(),
+                sources: new Set(),
+                reasons: new Set(),
+                // Store the first encountered config for possibleValues lookup
+                firstValue: valuesArray[0]
+            };
+        }
+
+        valuesArray.forEach(v => {
+            const aiValue = v.value || 'N/A';
+            const originalValue = v.original_value || 'N/A';
+            const source = v.source || 'N/A';
+            const reason = v.reason || 'N/A';
+
+            // Add values to sets for unique collection
+            if (aiValue !== 'N/A') mergedAttributes[key].aiValues.add(aiValue);
+            if (originalValue !== 'N/A') mergedAttributes[key].originalValues.add(originalValue);
+            if (source !== 'N/A') mergedAttributes[key].sources.add(source);
+            if (reason !== 'N/A') mergedAttributes[key].reasons.add(reason);
+        });
+    });
+    
+    // --- 2. Final attributeEntries from merged data ---
+    let attributeEntries = [];
+
+    Object.keys(mergedAttributes).forEach(key => {
+        const mergedData = mergedAttributes[key];
+        
+        // Find possible values for this attribute from full data using the stored firstValue
+        const attrConfig = attributesFullData.find(item => item.attribute_name === key);
+        
+        let possibleValues = [];
+        if (attrConfig && attrConfig.possible_values) {
+            possibleValues = attrConfig.possible_values.split(',').map(s => s.trim());
+        }
+
+        // Get merged AI Value
+        const aiValueString = Array.from(mergedData.aiValues).join(', ');
+        
+        // Determine match flag: check if ANY of the AI values are in possibleValues
+        const isFoundInPossible = Array.from(mergedData.aiValues).some(aiVal => possibleValues.includes(aiVal));
+        const matchFlag = isFoundInPossible ? true : false;
+        
+        // Get merged Original Value, Source, and Reason strings
+        const originalValueString = Array.from(mergedData.originalValues).join(', ');
+        const sourceString = Array.from(mergedData.sources).join(', ');
+        const reasonString = Array.from(mergedData.reasons).join(' | ');
+
+        attributeEntries.push({
+            name: key,
+            aiValue: aiValueString || 'N/A', // Use merged string
+            possibleValues: possibleValues,
+            originalValue: originalValueString || 'N/A',
+            source: sourceString || 'N/A',
+            isMatch: matchFlag,
+            reason: reasonString || 'N/A'
+        });
+    });
+
+    // --- Rest of the function (unchanged) ---
+    // ... (Section title, empty check, splitting into two tables, and buildTable helper) ...
+
+    // --- Section title ---
+    const titleEl = el('div', 'section-title');
+    titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+    section.appendChild(titleEl);
+
+    if (attributeEntries.length === 0) {
+        const msg = el('p', 'no-attributes-message');
+        msg.textContent = `No ${title.toLowerCase()} found.`;
+        section.appendChild(msg);
+        return section;
+    }
+
+    // --- Split attributes in half ---
+    const midIndex = Math.ceil(attributeEntries.length / 2);
+    const leftAttributes = attributeEntries.slice(0, midIndex);
+    const rightAttributes = attributeEntries.slice(midIndex);
+
+    // --- Create a container for two tables ---
+    const tableContainer = el('div', 'two-column-table-container');
+
+    // Helper function to build a table
+    function buildTable(attrArray) {
+        const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+        const table = el('table', 'attribute-detail-table comparison-table');
+
+        const thead = el('thead');
+        const headerRow = el('tr');
+        // , 'AI Generated Value'
+        ['Attribute Name', 'Recommended Attribute Value(s)'].forEach(text => {
+            const th = el('th');
+            th.textContent = text;
+            headerRow.appendChild(th);
+        });
+        thead.appendChild(headerRow);
+        table.appendChild(thead);
+
+        const tbody = el('tbody');
+
+        attrArray.forEach(attr => {
+            const row = el('tr', attr?.isMatch ? 'match-row' : 'mismatch-row');
+
+            // Attribute name
+            const nameTd = el('td', 'attribute-name');
+            nameTd.textContent = formatString(attr?.name).replace(/_/g, ' ');
+            row.appendChild(nameTd);
+
+            // Dropdown
+            const aiTd = el('td', 'attribute-source');
+
+            // Create a multi-select dropdown
+            const select = document.createElement('select');
+            select.classList.add('select2-dropdown');
+            select.name = 'manuallyUpdatedAttributes[]';
+            select.setAttribute('multiple', 'multiple');
+            select.setAttribute('data-attribute', attr?.name);
+
+            // The values selected will be the merged AI values
+            const selectedValues = attr?.aiValue.split(', ').filter(v => v !== 'N/A' && v.trim() !== '');
+
+            // Populate options
+            // Add possible values
+            // attr?.possibleValues.forEach(val => {
+            //     const option = document.createElement('option');
+            //     option.value = val;
+            //     option.textContent = val;
+            //     if (selectedValues.includes(val)) option.selected = true;
+            //     select.appendChild(option);
+            // });
+
+            // attr?.possibleValues.forEach(val => {
+            //     // Split by comma if there are multiple values, trim spaces
+            //     const values = val.split(',').map(v => v.trim());
+
+            //     values.forEach(v => {
+            //         const option = document.createElement('option');
+            //         option.value = v;
+            //         option.textContent = v;
+            //         if (selectedValues.includes(v)) option.selected = true;
+            //         select.appendChild(option);
+            //     });
+            // });
+
+            
+            // Add AI values not found in possibleValues as new selected options
+            // selectedValues.forEach(aiVal => {
+            //     if (!attr?.possibleValues.includes(aiVal)) {
+            //         const newOpt = document.createElement('option');
+            //         newOpt.value = aiVal;
+            //         newOpt.textContent = aiVal;
+            //         newOpt.selected = true;
+            //         select.appendChild(newOpt);
+            //     }
+            // });
+            // 1. Prepare and clean the selected values first, flattening the comma-separated data.
+                let allSelectedValues = new Set();
+                selectedValues.forEach(aiVal => {
+                    aiVal.split(',')
+                        .map(value => value.trim())
+                        .filter(value => value.length > 0)
+                        .forEach(singleVal => allSelectedValues.add(singleVal));
+                });
+
+                // Convert the Set back to an array for easy checking, or keep it as a Set for O(1) lookups.
+                // We'll keep it as a Set for efficient checking.
+
+                // ---
+
+                // 2. Add all default possible values.
+                attr?.possibleValues.forEach(val => {
+                    const option = document.createElement('option');
+                    option.value = val;
+                    option.textContent = val;
+
+                    // Check if the possible value is one of the cleaned selected values
+                    if (allSelectedValues.has(val)) {
+                        option.selected = true;
+                        // IMPORTANT: Remove this value from the Set so we know which ones are left over (the custom ones)
+                        allSelectedValues.delete(val);
+                    }
+                    
+                    select.appendChild(option);
+                });
+
+                // ---
+
+                // 3. Add any "custom" selected values that weren't in possibleValues.
+                // The allSelectedValues Set now only contains values that are NOT in attr?.possibleValues.
+                allSelectedValues.forEach(singleVal => {
+                    const newOpt = document.createElement('option');
+                    newOpt.value = singleVal;
+                    newOpt.textContent = singleVal;
+                    newOpt.selected = true; // These are guaranteed to be selected values
+                    select.appendChild(newOpt);
+                });
+            aiTd.appendChild(select);
+            row.appendChild(aiTd);
+
+            tbody.appendChild(row);
+
+            // Initialize Select2
+            jQuery(select).select2({
+                tags: true,
+                width: 'resolve'
+            });
+        });
+
+        table.appendChild(tbody);
+        scrollWrapper.appendChild(table);
+        return scrollWrapper;
+    }
+
+    // --- Build and append both tables ---
+    const leftTable = buildTable(leftAttributes);
+    const rightTable = buildTable(rightAttributes);
+
+    tableContainer.appendChild(leftTable);
+    tableContainer.appendChild(rightTable);
+
+    section.appendChild(tableContainer);
+    return section;
+}
+
+// function renderMandatoryComparisonTable(attributes, title, productType) {
+//     const section = el('div', 'attribute-section');
+
+//     let attributeEntries = [];
+
+//     // --- Build attributeEntries ---
+//     Object.keys(attributes).forEach(key => {
+//         const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]];
+//         valuesArray.forEach(v => {
+//             const aiValue = v.value || 'N/A';
+//             const originalValue = v.original_value || 'N/A';
+//             const source = v.source || 'N/A';
+//             const reason = v.reason || 'N/A';
+
+//             // Find possible values for this attribute from full data
+//             const attrConfig = attributesFullData.find(item => item.attribute_name === key);
+            
+//             let possibleValues = [];
+//             if (attrConfig && attrConfig.possible_values) {
+//                 possibleValues = attrConfig.possible_values.split(',').map(s => s.trim());
+//             }
+
+//             // Determine match flag
+//             const isFoundInPossible = possibleValues.includes(aiValue);
+//             const matchFlag = isFoundInPossible ? true : false;
+
+//             attributeEntries.push({
+//                 name: key,
+//                 aiValue: aiValue,
+//                 possibleValues: possibleValues,
+//                 originalValue: originalValue,
+//                 source: source,
+//                 isMatch: matchFlag,
+//                 reason: reason
+//             });
+//         });
+//     });
+
+//     // --- Section title ---
+//     const titleEl = el('div', 'section-title');
+//     titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+//     section.appendChild(titleEl);
+
+//     if (attributeEntries.length === 0) {
+//         const msg = el('p', 'no-attributes-message');
+//         msg.textContent = `No ${title.toLowerCase()} found.`;
+//         section.appendChild(msg);
+//         return section;
+//     }
+
+//     // --- Split attributes in half ---
+//     const midIndex = Math.ceil(attributeEntries.length / 2);
+//     const leftAttributes = attributeEntries.slice(0, midIndex);
+//     const rightAttributes = attributeEntries.slice(midIndex);
+
+//     // --- Create a container for two tables ---
+//     const tableContainer = el('div', 'two-column-table-container');
+
+//     // Helper function to build a table
+//     function buildTable(attrArray) {
+//         const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+//         const table = el('table', 'attribute-detail-table comparison-table');
+
+//         const thead = el('thead');
+//         const headerRow = el('tr');
+//         // , 'AI Generated Value'
+//         ['Attribute Name', 'Recommended Attribute Value(s)'].forEach(text => {
+//             const th = el('th');
+//             th.textContent = text;
+//             headerRow.appendChild(th);
+//         });
+//         thead.appendChild(headerRow);
+//         table.appendChild(thead);
+
+//         const tbody = el('tbody');
+
+//         attrArray.forEach(attr => {
+//             const row = el('tr', attr?.isMatch ? 'match-row' : 'mismatch-row');
+
+//             // Attribute name
+//             const nameTd = el('td', 'attribute-name');
+//             nameTd.textContent = formatString(attr?.name).replace(/_/g, ' ');
+//             row.appendChild(nameTd);
+
+//             // AI Value display
+//             // AI Value cell with info icon
+//             // const aiValueTd = el('td', `ai-value ${attr?.isMatch ? '' : 'mismatch-value'}`);
+
+//             // // Create a wrapper for text and icon
+//             // const aiValueWrapper = document.createElement('div');
+//             // aiValueWrapper.style.display = 'flex';
+//             // aiValueWrapper.style.alignItems = 'center';
+//             // aiValueWrapper.style.gap = '6px';
+
+//             // // Text node
+//             // const valueText = document.createElement('span');
+//             // valueText.textContent = formatString(attr?.aiValue);
+//             // aiValueWrapper.appendChild(valueText);
+
+//             // // Info icon (Bootstrap Icons)
+//             // if (attr?.reason && attr?.reason.trim() !== '') {
+//             //     const infoIcon = document.createElement('i');
+//             //     infoIcon.className = 'bi bi-info-circle';
+//             //     infoIcon.style.cursor = 'pointer';
+//             //     infoIcon.setAttribute('title', attr?.reason); // Tooltip on hover
+//             //     infoIcon.style.color = '#0d6efd'; // Bootstrap blue
+//             //     aiValueWrapper.appendChild(infoIcon);
+//             // }
+
+//             // aiValueTd.appendChild(aiValueWrapper);
+//             // row.appendChild(aiValueTd);
+
+//             // const aiValueTd = el('td', `ai-value ${attr?.isMatch ? '' : 'mismatch-value'}`);
+//             // aiValueTd.textContent = formatString(attr?.aiValue);
+//             // row.appendChild(aiValueTd);
+
+//             // Dropdown
+//             // const aiTd = el('td', 'attribute-source');
+//             // const select = document.createElement('select');
+//             // select.classList.add('select2-dropdown');
+//             // select.setAttribute('data-attribute', attr?.name);
+            
+//             const aiTd = el('td', 'attribute-source');
+
+//             // Create a multi-select dropdown
+//             const select = document.createElement('select');
+//             select.classList.add('select2-dropdown');
+//             // select.id = 'manually-attributes'; // You may want to make this unique per row
+//             select.name = 'manuallyUpdatedAttributes[]';
+//             // select.setAttribute('aria-labelledby', 'select a attribute for which multiple data required');
+//             select.setAttribute('multiple', 'multiple');
+//             // select.style.width = '100%';
+//             select.setAttribute('data-attribute', attr?.name);
+
+
+//             // Populate options
+//             attr?.possibleValues.forEach(val => {
+//                 const option = document.createElement('option');
+//                 option.value = val;
+//                 option.textContent = val;
+//                 if (val === attr?.aiValue) option.selected = true;
+//                 select.appendChild(option);
+//             });
+
+//             // if (!attr?.isMatch && attr?.aiValue !== 'N/A') {
+//             //     const newOpt = document.createElement('option');
+//             //     newOpt.value = attr?.aiValue;
+//             //     newOpt.textContent = attr?.aiValue; // + " (new)";
+//             //     newOpt.selected = true;
+//             //     select.appendChild(newOpt);
+//             // }
+
+//             aiTd.appendChild(select);
+//             row.appendChild(aiTd);
+
+//             tbody.appendChild(row);
+
+//             // Initialize Select2
+//             jQuery(select).select2({
+//                 tags: true,
+//                 width: 'resolve'
+//             });
+//         });
+
+//         table.appendChild(tbody);
+//         scrollWrapper.appendChild(table);
+//         return scrollWrapper;
+//     }
+
+//     // --- Build and append both tables ---
+//     const leftTable = buildTable(leftAttributes);
+//     const rightTable = buildTable(rightAttributes);
+
+//     tableContainer.appendChild(leftTable);
+//     tableContainer.appendChild(rightTable);
+
+//     section.appendChild(tableContainer);
+//     return section;
+// }
+
+// function renderMandatoryComparisonTable(attributes, title, productType) {
+//     const section = el('div', 'attribute-section');
+
+//     let attributeEntries = [];
+
+//     Object.keys(attributes).forEach(key => {
+//         const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]];
+//         valuesArray.forEach(v => {
+//             const aiValue = v.value || 'N/A';
+//             const originalValue = v.original_value || 'N/A';
+//             const source = v.source || 'N/A';
+
+//             // Find possible values for this attribute from `a`
+//             const attrConfig = attributesFullData.find(item => 
+//                  item.attribute_name === key
+//             );
+            
+//             let possibleValues = [];
+//             if (attrConfig && attrConfig.possible_values) {
+//                 possibleValues = attrConfig.possible_values.split(',').map(s => s.trim());
+//             }
+
+//             // Determine if AI value exists in possible values
+//             const isFoundInPossible = possibleValues.includes(aiValue);
+//             const matchFlag = isFoundInPossible ? true : false;
+
+//             attributeEntries.push({
+//                 name: key,
+//                 aiValue: aiValue,
+//                 possibleValues: possibleValues,
+//                 originalValue: originalValue,
+//                 source: source,
+//                 isMatch: matchFlag
+//             });
+//         });
+//     });
+
+//     const titleEl = el('div', 'section-title');
+//     titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+//     section.appendChild(titleEl);
+
+//     if (attributeEntries.length === 0) {
+//         const msg = el('p', 'no-attributes-message');
+//         msg.textContent = `No ${title.toLowerCase()} found.`;
+//         section.appendChild(msg);
+//         return section;
+//     }
+
+//     const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+//     const table = el('table', 'attribute-detail-table comparison-table');
+
+//     const thead = el('thead');
+//     const headerRow = el('tr');
+
+//     ['Attribute Name', 'AI Generated Value', 'Action'].forEach(text => {
+//         const th = el('th');
+//         th.textContent = text;
+//         headerRow.appendChild(th);
+//     });
+//     thead.appendChild(headerRow);
+//     table.appendChild(thead);
+
+//     const tbody = el('tbody');
+
+//     attributeEntries.forEach(attr => {
+//         const row = el('tr', attr?.isMatch ? 'match-row' : 'mismatch-row');
+
+//         // 1. Attribute Name
+//         const nameTd = el('td', 'attribute-name');
+//         nameTd.textContent = formatString(attr?.name).replace(/_/g, ' ');
+//         row.appendChild(nameTd);
+
+//         // 3. Source Column
+//         const sourceTd = el('td', `ai-value ${attr?.isMatch ? '' : 'mismatch-value'}`);
+//         sourceTd.textContent = formatString(attr?.aiValue);
+//         row.appendChild(sourceTd);
+
+
+//         // 2. AI Value Dropdown (Select2)
+//         const aiTd = el('td', 'attribute-source');
+
+//         const select = document.createElement('select');
+//         select.classList.add('select2-dropdown');
+//         select.setAttribute('data-attribute', attr?.name);
+
+//         // Populate possible values
+//         attr?.possibleValues.forEach(val => {
+//             const option = document.createElement('option');
+//             option.value = val;
+//             option.textContent = val;
+//             if (val === attr?.aiValue) option.selected = true;
+//             select.appendChild(option);
+//         });
+
+//         // If not found in possible values, add it as a new option
+//         if (!attr?.isMatch && attr?.aiValue !== 'N/A') {
+//             const newOpt = document.createElement('option');
+//             newOpt.value = attr?.aiValue;
+//             newOpt.textContent = attr?.aiValue + " (new)";
+//             newOpt.selected = true;
+//             select.appendChild(newOpt);
+//         }
+
+//         aiTd.appendChild(select);
+//         row.appendChild(aiTd);
+
+
+//         tbody.appendChild(row);
+
+//         // Initialize Select2 after element is added
+//         jQuery(select).select2({
+//             tags: true, // allows new values
+//             width: 'resolve'
+//         });
+//     });
+
+//     table.appendChild(tbody);
+//     scrollWrapper.appendChild(table);
+//     section.appendChild(scrollWrapper);
+
+//     return section;
+// }
+
+// function renderMandatoryComparisonTable(attributes, title) {
+//     const section = el('div', 'attribute-section');
+    
+//     let attributeEntries = [];
+
+//     Object.keys(attributes).forEach(key => {
+//         const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]]; 
+//         valuesArray.forEach(v => {
+//             const aiValue = v.value || 'N/A';
+//             const originalValue = v.original_value || 'N/A';
+//             const source = v.source || 'N/A';
+            
+//             // Comparison is case-insensitive and ignores leading/trailing whitespace
+//             const isMatch = (String(aiValue).trim().toLowerCase() === String(originalValue).trim().toLowerCase());
+
+//             attributeEntries.push({
+//                 name: key,
+//                 aiValue: aiValue,
+//                 originalValue: originalValue,
+//                 source: source,
+//                 isMatch: isMatch
+//             });
+//         });
+//     });
+
+//     const titleEl = el('div', 'section-title');
+//     titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+//     section.appendChild(titleEl);
+    
+//     if (attributeEntries.length === 0) {
+//         const msg = el('p', 'no-attributes-message');
+//         msg.textContent = `No ${title.toLowerCase()} found.`;
+//         section.appendChild(msg);
+//         return section;
+//     }
+
+//     // --- SCROLL WRAPPER ADDITION ---
+//     const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+//     const table = el('table', 'attribute-detail-table comparison-table');
+    
+//     const thead = el('thead');
+//     const headerRow = el('tr');
+    
+//     // Updated Headers for Comparison Table
+//     ['Attribute Name', 'AI Generated Value', 'Action'].forEach(text => {
+//         const th = el('th');
+//         th.textContent = text;
+//         headerRow.appendChild(th);
+//     });
+//     thead.appendChild(headerRow);
+//     table.appendChild(thead);
+
+//     const tbody = el('tbody');
+
+//     attributeEntries.forEach(attr => {
+//         // Highlight the entire row in red if the values do not match
+//         const row = el('tr', attr?.isMatch ? 'match-row' : 'mismatch-row'); 
+        
+//         // 1. Attribute Name
+//         const nameTd = el('td', 'attribute-name');
+//         nameTd.textContent = formatString(attr?.name).replace(/_/g, ' '); 
+//         row.appendChild(nameTd);
+
+
+//         // 3. AI Extracted Value
+//         const aiTd = el('td', `ai-value ${attr?.isMatch ? '' : 'mismatch-value'}`);
+//         aiTd.textContent = attr?.aiValue;
+//         row.appendChild(aiTd);
+        
+//         // 4. Source
+//         const sourceTd = el('td', 'attribute-source');
+//         sourceTd.textContent = formatString(attr?.source);
+//         row.appendChild(sourceTd);
+
+//         tbody.appendChild(row);
+//     });
+
+//     table.appendChild(tbody);
+//     scrollWrapper.appendChild(table); // Append table to wrapper
+//     section.appendChild(scrollWrapper); // Append wrapper to section
+//     return section;
+// }
+
+/**
+ * Renders a table for Additional, OCR, or Visual attributes (Name, Value, Source).
+ * @param {Object} attributes - The attribute data.
+ * @param {string} title - The title for the table section.
+ * @returns {HTMLElement} A div containing the table.
+ */
+function renderAttributesAsTable(attributes, title, mandatoryData = null) {
+    const section = el('div', 'attribute-section');
+    let attributeEntries = [];
+
+    // --- STEP 1: Create a Set of all Mandatory Original Values (Normalized) ---
+    // A Set is used for fast lookups. Values are normalized (trimmed, lowercase)
+    const mandatoryOriginalValuesSet = new Set();
+    if (mandatoryData) {
+        Object.values(mandatoryData).forEach(attrArray => {
+            const originalValue = attrArray[0]?.original_value;
+            if (originalValue) {
+                mandatoryOriginalValuesSet.add(String(originalValue).trim().toLowerCase());
+            }
+        });
+    }
+
+    // Helper to extract attribute entries consistently
+    const processAttribute = (key, values) => {
+        const valuesArray = Array.isArray(values) ? values : [values]; 
+        valuesArray.forEach(v => {
+            attributeEntries.push({
+                name: key,
+                value: v.value,
+                source: v.source || 'N/A'
+            });
+        });
+    };
+
+    // Iterate through attributes (OCR/Visual/Additional) and flatten them
+    Object.keys(attributes).forEach(key => {
+        const attribute = attributes[key];
+        
+        if (Array.isArray(attribute)) {
+            processAttribute(key, attribute);
+        } else if (typeof attribute === 'object' && attribute !== null) {
+            // Handle simple { "key": { "value": "X", "source": "Y" } } structure
+            if (attribute.value !== undefined) {
+                 attributeEntries.push({
+                    name: key,
+                    value: attribute.value,
+                    source: attribute.source || 'N/A'
+                });
+            } else {
+                // Handle nested objects
+                Object.keys(attribute).forEach(subKey => {
+                    const subAttribute = attribute[subKey];
+                    if (Array.isArray(subAttribute)) {
+                        processAttribute(`${key} (${subKey.replace(/_/g, ' ')})`, subAttribute);
+                    }
+                });
+            }
+        }
+    });
+
+    const titleEl = el('div', 'section-title');
+    titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+    section.appendChild(titleEl);
+    
+    if (attributeEntries.length === 0) {
+        const msg = el('p', 'no-attributes-message');
+        msg.textContent = `No ${title.toLowerCase()} found.`;
+        section.appendChild(msg);
+        return section;
+    }
+
+    const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+    const table = el('table', 'attribute-detail-table');
+
+    const thead = el('thead');
+    const headerRow = el('tr');
+    
+    ['Attribute Name', 'Value'].forEach(text => {
+        const th = el('th');
+        th.textContent = text;
+        headerRow.appendChild(th);
+    });
+    thead.appendChild(headerRow);
+    table.appendChild(thead);
+
+    const tbody = el('tbody');
+
+    attributeEntries.forEach(attr => {
+        const row = el('tr'); 
+        
+        // --- CORE COMPARISON LOGIC (Global Check) ---
+        let colorClass = '';
+        const hasMandatoryBaseline = mandatoryOriginalValuesSet.size > 0;
+        
+        if (hasMandatoryBaseline) {
+            // Normalize the current attribute's value
+            const currentValueNormalized = String(attr?.value).trim().toLowerCase();
+            
+            // Check if the current value exists ANYWHERE in the mandatory original values set
+            if (mandatoryOriginalValuesSet.has(currentValueNormalized)) {
+                colorClass = 'green-text'; // Found a match in the global mandatory set
+            } else {
+                colorClass = 'red-text'; // Did NOT find a match
+            }
+        }
+        // --- END CORE COMPARISON LOGIC ---
+        
+        const nameTd = el('td', 'attribute-name');
+        nameTd.textContent = formatString(attr?.name).replace(/_/g, ' '); 
+        row.appendChild(nameTd);
+
+        const valueTd = el('td', 'attribute-value');
+        const displayValue = formatString(attr?.value) + ' (' + formatString(attr?.source) + ')';
+        
+        valueTd.textContent = displayValue || 'N/A';
+        
+        // Apply the determined color class to the value cell
+        if (colorClass) {
+            valueTd.classList.add(colorClass);
+        }
+
+        row.appendChild(valueTd);
+        tbody.appendChild(row);
+    });
+
+    table.appendChild(tbody);
+    scrollWrapper.appendChild(table); 
+    section.appendChild(scrollWrapper); 
+    return section;
+}
+// function renderAttributesAsTable(attributes, title, mandatoryData = null) {
+//     const section = el('div', 'attribute-section');
+//     let attributeEntries = [];
+
+//     const processAttribute = (key, values) => {
+//         const valuesArray = Array.isArray(values) ? values : [values]; 
+//         valuesArray.forEach(v => {
+//             attributeEntries.push({
+//                 name: key,
+//                 value: v.value,
+//                 source: v.source || 'N/A'
+//             });
+//         });
+//     };
+
+//     Object.keys(attributes).forEach(key => {
+//         const attribute = attributes[key];
+        
+//         if (Array.isArray(attribute)) {
+//             processAttribute(key, attribute);
+//         } else if (typeof attribute === 'object' && attribute !== null) {
+//             Object.keys(attribute).forEach(subKey => {
+//                 const subAttribute = attribute[subKey];
+//                 if (Array.isArray(subAttribute)) {
+//                     // Combines parent key (e.g., 'size') and sub-key (e.g., 'waist_size')
+//                     processAttribute(`${key} (${subKey.replace(/_/g, ' ')})`, subAttribute);
+//                 }
+//             });
+//         }
+//     });
+
+//     const titleEl = el('div', 'section-title');
+//     titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+//     section.appendChild(titleEl);
+    
+//     if (attributeEntries.length === 0) {
+//         const msg = el('p', 'no-attributes-message');
+//         msg.textContent = `No ${title.toLowerCase()} found.`;
+//         section.appendChild(msg);
+//         return section;
+//     }
+
+//     // --- SCROLL WRAPPER ADDITION ---
+//     const scrollWrapper = el('div', 'attribute-scroll-wrapper');
+//     const table = el('table', 'attribute-detail-table');
+
+//     const thead = el('thead');
+//     const headerRow = el('tr');
+    
+//     ['Attribute Name', 'Value'].forEach(text => {
+//         const th = el('th');
+//         th.textContent = text;
+//         headerRow.appendChild(th);
+//     });
+//     thead.appendChild(headerRow);
+//     table.appendChild(thead);
+
+//     const tbody = el('tbody');
+
+//     attributeEntries.forEach(attr => {
+//         const row = el('tr'); 
+        
+//         const nameTd = el('td', 'attribute-name');
+//         nameTd.textContent = formatString(attr?.name).replace(/_/g, ' '); 
+//         row.appendChild(nameTd);
+
+//         const valueTd = el('td', 'attribute-value');
+//         const displayValue = Array.isArray(attr?.value) 
+//             ? (attr?.value.map(v => formatString(v.value))).join(', ') +'('+ formatString(attr?.source)+ ')' 
+//             : formatString(attr?.value) +'('+ formatString(attr?.source)+ ')';
+//         valueTd.textContent = displayValue || 'N/A';
+//         row.appendChild(valueTd);
+
+//         // const sourceTd = el('td', 'attribute-source');
+//         // sourceTd.textContent = attr?.source || 'Unknown';
+//         // row.appendChild(sourceTd);
+
+//         tbody.appendChild(row);
+//     });
+
+//     table.appendChild(tbody);
+//     scrollWrapper.appendChild(table); // Append table to wrapper
+//     section.appendChild(scrollWrapper); // Append wrapper to section
+//     return section;
+// }
+
+// ------------------------------------------------------------------
+// --- 3. MAIN RENDER FUNCTION (REPLACEMENT) ---
+// ------------------------------------------------------------------
+
+// function renderInlineForTable() {
+//     const api = API_RESPONSE_AI;
+//     const table = $('#tableContainer');
+//     if (!table) return;
+
+//     // Remove existing detail rows
+//     table.querySelectorAll('tr.detail-row').forEach(r => r.remove());
+
+//     PRODUCT_BASE.forEach((p, idx) => {
+//         if (!isProductSelected(p.item_id)) return;
+        
+//         const res = findApiResultForProduct(p, idx, api);
+        
+//         const tbody = table.querySelector('tbody');
+//         const baseRow = tbody ? tbody.querySelector(`#row-${p.id}`) : null; 
+//         if (!baseRow) return;
+
+//         // --- Detail Row Construction ---
+//         const detail = el('tr', 'detail-row');
+//         // td.colSpan must match the number of columns in your main table
+//         const td = el('td'); td.colSpan = 7; 
+//         const content = el('div', 'detail-content-tables');
+
+
+//         // // 1. MANDATORY Attributes Table (NOW USES CARD COMPARISON)
+//         // const mandatorySection = renderMandatoryComparisonCards( // <-- NEW FUNCTION NAME
+//         //     res?.mandatory || {}, 
+//         //     'Mandatory Attributes Comparison'
+//         // );
+//         // content.appendChild(mandatorySection);
+
+//         // // 2. COMBINED Attributes Section (Additional, OCR, Visuals) - REMAINS THE SAME
+//         // content.appendChild(el('hr', 'section-separator'));
+
+//         // 1. MANDATORY Attributes Table (USES COMPARISON FUNCTION)
+//         const mandatoryTable = renderMandatoryComparisonTable(
+//             res?.mandatory || {}, 
+//             'Mandatory Attributes Comparison'
+//         );
+//         content.appendChild(mandatoryTable);
+
+//         // 2. COMBINED Attributes Section (Additional, OCR, Visuals)
+//         content.appendChild(el('hr', 'section-separator')); 
+        
+//         const combinedTitle = el('div', 'section-title');
+//         combinedTitle.innerHTML = '<h2>Additional & AI-Driven Attributes</h2>';
+//         content.appendChild(combinedTitle);
+        
+//         const combinedAttributesContainer = el('div', 'combined-attributes-container');
+        
+//         // Use the general renderer for these sections
+//         const additionalTable = renderAttributesAsTable(
+//             res?.additional || {}, 
+//             'Additional Attributes'
+//         );
+        
+//         const ocrTable = renderAttributesAsTable(
+//             res?.ocr_results?.extracted_attributes || {}, 
+//             'OCR Results'
+//         );
+        
+//         const visualsTable = renderAttributesAsTable(
+//             res?.visual_results?.visual_attributes || {}, 
+//             'Visual Results'
+//         );
+
+//         // Append all sections to the combined container
+//         combinedAttributesContainer.appendChild(additionalTable);
+//         combinedAttributesContainer.appendChild(ocrTable);
+//         combinedAttributesContainer.appendChild(visualsTable);
+//         content.appendChild(combinedAttributesContainer);
+        
+//         // --- Summary Counts ---
+//         const mandCount = Object.keys(res?.mandatory || {}).length;
+//         const addCount = Object.keys(res?.additional || {}).length;
+//         const ocrExtractedCount = Object.keys(res?.ocr_results?.extracted_attributes || {}).length;
+//         const visualExtractedCount = Object.keys(res?.visual_results?.visual_attributes || {}).length;
+        
+//         const counts = el('div', 'attribute-summary-pills');
+//         const c1 = el('span', 'pill primary'); c1.textContent = `Mandatory: ${mandCount}`;
+//         const c2 = el('span', 'pill secondary'); c2.textContent = `Additional: ${addCount}`;
+//         const c3 = el('span', 'pill secondary'); c3.textContent = `OCR Keys: ${ocrExtractedCount}`;
+//         const c4 = el('span', 'pill secondary'); c4.textContent = `Visual Keys: ${visualExtractedCount}`;
+//         counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+//         content.appendChild(counts);
+        
+//         // Final assembly and insertion
+//         td.appendChild(content); 
+//         detail.appendChild(td);
+//         baseRow.insertAdjacentElement('afterend', detail);
+//     });
+
+//     // Update summary statistics
+//     $('#statTotal').textContent = api.total_products ?? 0;
+//     $('#statOk').textContent = api.successful ?? 0;
+//     $('#statKo').textContent = api.failed ?? 0;
+//     const apiSummary = $('#api-summary');
+//     if (apiSummary) apiSummary.style.display = 'block';
+// }
+
+// function highlightMatches(text, keywords) {
+//     if (!text) return '—';
+//     let highlighted = text;
+//     keywords.forEach(keyword => {
+//         const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Escape regex
+//         const regex = new RegExp(`(${escapedKeyword})`, 'gi');
+//         highlighted = highlighted.replace(regex, '<span class="highlight-text">$1</span>');
+//     });
+//     return highlighted;
+// }
+
+function highlightMatches(text, keywords) {
+    if (!text) return '—';
+
+    // 1. Process Keywords: Flatten the array and handle comma-separated strings
+    const uniqueKeywords = new Set(); 
+
+    keywords.forEach(compositeKeyword => {
+        // Split by comma, trim whitespace, and add non-empty terms to the Set
+        compositeKeyword.split(',')
+            .map(kw => kw.trim())
+            .filter(kw => kw.length > 0)
+            .forEach(singleKeyword => {
+                // Only add the keyword if it's not just an empty string
+                if (singleKeyword) {
+                    uniqueKeywords.add(singleKeyword);
+                }
+            });
+    });
+
+    let highlighted = text;
+
+    // 2. Apply Highlighting using the clean, unique keywords
+    uniqueKeywords.forEach(keyword => {
+        // We still need to check for length in case something slipped through, 
+        // though the filter and Set should handle most cases.
+        if (keyword.length > 0) {
+            const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Escape regex special characters
+            
+            // Use 'g' (global) and 'i' (case-insensitive) flags
+            const regex = new RegExp(`(${escapedKeyword})`, 'gi'); 
+            
+            // Use a function as the replacer to ensure we highlight all matches
+            highlighted = highlighted.replace(regex, '<span class="highlight-text">$1</span>');
+        }
+    });
+
+    return highlighted;
+}
+
+// WOrking ONe
+function renderInlineForTable() {
+    const api = API_RESPONSE_AI;
+    const table = $('#tableContainer');
+    if (!table) return;
+
+    // Remove existing detail rows
+    table.querySelectorAll('tr.detail-row').forEach(r => r.remove());
+
+    PRODUCT_BASE.forEach((p, idx) => {
+        if (!isProductSelected(p.item_id)) return;
+        
+        const res = findApiResultForProduct(p, idx, api);
+        
+        const tbody = table.querySelector('tbody');
+        const baseRow = tbody ? tbody.querySelector(`#row-${p.id}`) : null; 
+        if (!baseRow) return;
+
+        // --- Detail Row Construction ---
+        const detail = el('tr', 'detail-row');
+        // td.colSpan must match the number of columns in your main table
+        const td = el('td'); td.colSpan = 6; 
+        const content = el('div', 'detail-content-tables');
+
+        // 1. MANDATORY Attributes Table
+        // 🚨 Note: The color check (Requirement #2) must be implemented inside renderMandatoryComparisonTable. 
+        const mandatoryData = res?.mandatory || {};
+        if (Object.keys(mandatoryData).length > 0) {
+            const mandatoryTable = renderMandatoryComparisonTable(
+                mandatoryData, 
+                'Attributes'
+            );
+            content.appendChild(mandatoryTable);
+        }
+
+        // 2. COMBINED Attributes Section (Additional, OCR, Visuals)
+        const additionalData = res?.additional || {};
+        const ocrData = res?.ocr_results?.extracted_attributes || {};
+        const visualsData = res?.visual_results?.visual_attributes || {};
+        
+        const hasCombinedData = Object.keys(additionalData).length > 0 || 
+                                Object.keys(ocrData).length > 0 || 
+                                Object.keys(visualsData).length > 0;
+
+        if (hasCombinedData) {
+            content.appendChild(el('hr', 'section-separator')); 
+            
+            const combinedTitle = el('div', 'section-title');
+            combinedTitle.innerHTML = '<h2>Additional & AI-Driven Attributes</h2>';
+            // content.appendChild(combinedTitle);
+            
+            const combinedAttributesContainer = el('div', 'combined-attributes-container');
+            
+            // Render Additional Table (Conditional based on data existence)
+            if (Object.keys(additionalData).length > 0) {
+                const additionalTable = renderAttributesAsTable(
+                    additionalData, 
+                    'Additional Attributes',
+                    mandatoryData
+                );
+                // combinedAttributesContainer.appendChild(additionalTable);
+            }
+            
+            // Render OCR Table (Conditional based on data existence)
+            if (Object.keys(ocrData).length > 0) {
+                const ocrTable = renderAttributesAsTable(
+                    ocrData, 
+                    'OCR Results',
+                    mandatoryData
+                );
+                // combinedAttributesContainer.appendChild(ocrTable);
+            }
+            
+            // Render Visuals Table (Conditional based on data existence)
+            if (Object.keys(visualsData).length > 0) {
+                const visualsTable = renderAttributesAsTable(
+                    visualsData, 
+                    'Visual Results',
+                    mandatoryData
+                );
+                // combinedAttributesContainer.appendChild(visualsTable);
+            }
+
+            // content.appendChild(combinedAttributesContainer);
+        }
+        
+        // --- Summary Counts ---
+        const mandCount = Object.keys(mandatoryData).length;
+        const addCount = Object.keys(additionalData).length;
+        const ocrExtractedCount = Object.keys(ocrData).length;
+        const visualExtractedCount = Object.keys(visualsData).length;
+        
+        const counts = el('div', 'attribute-summary-pills');
+        const c1 = el('span', 'pill primary'); c1.textContent = `Mandatory: ${mandCount}`;
+        const c2 = el('span', 'pill secondary'); c2.textContent = `Additional: ${addCount}`;
+        const c3 = el('span', 'pill secondary'); c3.textContent = `OCR Keys: ${ocrExtractedCount}`;
+        const c4 = el('span', 'pill secondary'); c4.textContent = `Visual Keys: ${visualExtractedCount}`;
+        counts.appendChild(c1); counts.appendChild(c2); counts.appendChild(c3); counts.appendChild(c4);
+        // content.appendChild(counts);
+        
+        // Final assembly and insertion
+        td.appendChild(content); 
+        detail.appendChild(td);
+        baseRow.insertAdjacentElement('afterend', detail);
+
+        
+        // Extract mandatory values for highlighting
+        // const mandatoryValues = Object.values(mandatoryData)
+        //     .map(v => v?.value?.toString()?.trim())
+        //     .filter(Boolean);
+
+        // const attrConfig = attributesFullData.find(item => item.attribute_name === key);
+
+        const mandatoryValues = Object.values(mandatoryData)
+            // 1. Use flatMap to iterate over the outer array AND flatten the inner arrays.
+            //    'arr' here is the array like [ { value: 'Pullover', ... } ]
+            .flatMap(arr => 
+                // 2. Map the inner array. We safely assume the first element [0] 
+                //    holds the value we want.
+                arr.map(item => item?.value?.toString()?.trim())
+            )
+            // 3. Filter out any potential undefined/null/empty string results.
+            .filter(Boolean);
+
+        // Highlight in Product Name
+        const nameCell = baseRow.querySelector('td:nth-child(3)');
+        if (nameCell) {
+            nameCell.innerHTML = highlightMatches(nameCell.textContent, mandatoryValues);
+        }
+
+        // Highlight in Short Description
+        const descCell = baseRow.querySelector('td:nth-child(6)');
+        if (descCell) {
+            const shortDescDiv = descCell.querySelector('.short-desc');
+            if (shortDescDiv) {
+                shortDescDiv.innerHTML = highlightMatches(shortDescDiv.innerHTML, mandatoryValues);
+            }
+        }
+
+        const desclongCell = baseRow.querySelector('td:nth-child(6)');
+        if (desclongCell) {
+            const longDescDiv = desclongCell.querySelector('.long-desc');
+            if (longDescDiv) {
+                longDescDiv.innerHTML = highlightMatches(longDescDiv.innerHTML, mandatoryValues);
+            }
+        }
+
+    });
+
+    // Update summary statistics
+    $('#statTotal').textContent = selectedProductsWithAttributes.length ?? api.total_products ?? 0;
+    $('#statOk').textContent = selectedProductsWithAttributes.length ?? api.successful ?? 0;
+    $('#statKo').textContent = api.failed ?? 0;
+    const apiSummary = $('#api-summary');
+    if (apiSummary) apiSummary.style.display = 'block';
+}
+// working one
+function applyHighlightingToTableRow(baseRow, mandatoryValues) {
+    const nameCell = baseRow.querySelector('td:nth-child(3)');
+    if (nameCell) {
+        nameCell.innerHTML = highlightMatches(nameCell.textContent, mandatoryValues);
+    }
+
+    const descCell = baseRow.querySelector('td:nth-child(6)');
+    if (descCell) {
+        const shortDescDiv = descCell.querySelector('.short-desc');
+        if (shortDescDiv) {
+            shortDescDiv.innerHTML = highlightMatches(shortDescDiv.innerHTML, mandatoryValues);
+        }
+    }
+}
+
+function renderInlineAttributes() {
+    if (layoutMode === 'cards') renderInlineForCards(); else renderInlineForTable();
+    // renderInlineForCards(); 
+    // renderInlineForTable();
+}
+
+// --- Main rendering ---
+function renderProducts() {
+    if (layoutMode === 'cards') {
+    $('#cardsContainer').style.display = '';
+    $('#tableContainer').style.display = 'none';
+    // console.log("PRODUCT_BASE",PRODUCT_BASE);
+    renderProductsCards();
+    } else {
+    $('#cardsContainer').style.display = 'none';
+    $('#tableContainer').style.display = '';
+    renderProductsTable();
+    }
+    updateSelectionInfo();
+    renderPagination();               
+
+    // If there is a selection, re-render inline attributes (persist across toggle)
+    if (selectedProductsWithAttributes.length > 0) renderInlineAttributes();
+}
+
+// --- Submit & Reset ---
+function submitAttributes() {
+  // Check the length of the new array
+    if (selectedProductsWithAttributes.length === 0) { 
+        alert('Please select at least one product.'); 
+        return; 
+    } 
+    // if (selectedIds.size === 0) { alert('Please select at least one product.'); return; }
+    // console.log("selectedIds",selectedIds);
+    jQuery('#full-page-loader').show();  
+    // let inputArray = {
+    //       "product_ids" : [...selectedIds]
+    //     }
+    const extractAdditional = document.getElementById('extract_additional').checked;
+    const processImage = document.getElementById('process_image').checked;
+    // const selectedMultiples = document.getElementById('#mandatory-attributes');
+    // const selectedValues = Array.from(selectedMultiples.selectedOptions).map(option => option.value);
+    const selectElement = document.getElementById('mandatory-attributes');
+
+    const selectedValues = Array.from(selectElement.selectedOptions).map(option => option.value);
+
+    // console.log(selectedValues); // Logs an array of selected values
+    // console.log("thresholdValueDisplay",thresholdValueDisplay.value);
+    const threshold = parseFloat(document.getElementById('thresholdRange').value);
+
+
+    // Transform the new state array into the required API format
+    const itemIds = selectedProductsWithAttributes.map(p => p.item_id);
+    
+    // Create the mandatory_attrs map: { item_id: { attr_name: [values] } }
+    // NOTE: The backend API you showed expects a flattened list of "mandatory_attrs"
+    // like: { "color": ["color", "shade"], "size": ["size", "fit"] } 
+    // It seems to ignore the selected product-specific values and uses a general list of synonyms.
+    // Assuming the request needs a general map of *all unique* selected attributes across all selected products:
+    
+    let mandatoryAttrsMap = {};
+    selectedProductsWithAttributes.forEach(product => {
+        // Merge attributes from all selected products
+        Object.assign(mandatoryAttrsMap, product.mandatory_attrs);
+    });
+
+    // If the API expects the complex, product-specific payload from your Q1 example:
+    const payloadForQ1 = selectedProductsWithAttributes.map(p => ({
+        item_id: p.item_id,
+        mandatory_attrs: p.mandatory_attrs
+    }));
+
+    let inputArray = {
+              "products": payloadForQ1,
+              "model": "llama-3.1-8b-instant",
+              "extract_additional": extractAdditional,
+              "process_image": processImage,
+              "multiple": selectedValues,
+              "threshold_abs": 0.6,  // Lower threshold to be more permissive
+            //   "margin": 0.3,  // Larger margin to include more candidates
+            //   "use_adaptive_margin": true,
+            //   "use_semantic_clustering": true
+            }
+    let raw = JSON.stringify(inputArray);
+     fetch('/attr/batch-extract/', {
+        method: 'POST', // or 'POST' if your API expects POST
+        headers: {
+            'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]')?.value || '',
+            'Content-Type': "application/json"
+        },
+        body: raw
+    })
+    .then(response => response.json())
+    .then(async data => {
+        await delay(5000); // waits for 3 seconds
+        // console.log("response data",data); 
+        API_RESPONSE_AI = data;   
+        renderInlineAttributes();
+        jQuery('#full-page-loader').hide();  
+     });
+}
+
+function resetAll() {
+  selectedProductsWithAttributes = []; // Reset the main array
+    // selectedIds.clear();
+    lastSeen.clear();
+    renderProducts();
+    // Clear summary
+    document.getElementById('statTotal').textContent = '0';
+    document.getElementById('statOk').textContent = '0';
+    document.getElementById('statKo').textContent = '0';
+    $('#api-summary').style.display = 'none';
+
+    // ✅ Clear Select2 selections
+    jQuery('#mandatory-attributes').val(null).trigger('change');
+
+    // ✅ Reset threshold input (and display)
+    const thresholdInput = document.getElementById('thresholdRange');
+    const thresholdDisplay = document.getElementById('thresholdValue');
+
+    thresholdInput.value = '0.65'; // or any default value you prefer
+    if (thresholdDisplay) {
+        thresholdDisplay.textContent = '0.65';
+    }
+}
+
+function setLayout(mode) {
+    layoutMode = mode;
+    const btnCards = document.getElementById('btnCards');
+    const btnTable = document.getElementById('btnTable');
+    if (mode === 'cards') { btnCards.classList.add('active'); btnCards.setAttribute('aria-selected', 'true'); btnTable.classList.remove('active'); btnTable.setAttribute('aria-selected', 'false'); }
+    else { btnTable.classList.add('active'); btnTable.setAttribute('aria-selected', 'true'); btnCards.classList.remove('active'); btnCards.setAttribute('aria-selected', 'false'); }
+    renderProducts();
+}
+
+
+// Upload elements (Bootstrap modal version)
+const uploadModalEl = document.getElementById('uploadModal');
+const dropzone      = document.getElementById('dropzone');
+const uploadFiles   = document.getElementById('uploadFiles');
+const fileInfo      = document.getElementById('fileInfo');
+const uploadBar     = document.getElementById('uploadBar');
+const uploadStatus  = document.getElementById('uploadStatus');
+
+// Reset modal on show
+uploadModalEl.addEventListener('shown.bs.modal', () => {
+  uploadStatus.textContent = '';
+  uploadStatus.className = '';             // clear success/error class
+  uploadBar.style.width = '0%';
+  uploadBar.setAttribute('aria-valuenow', '0');
+  uploadFiles.value = '';
+  uploadFiles.setAttribute('accept', ACCEPT_TYPES);
+  fileInfo.textContent = 'No files selected.';
+});
+
+function describeFiles(list) {
+  if (!list || list.length === 0) { fileInfo.textContent = 'No files selected.'; return; }
+  const names = Array.from(list).map(f => `${f.name} (${Math.round(f.size/1024)} KB)`);
+  fileInfo.textContent = names.join(', ');
+}
+
+// Drag & drop feedback
+['dragenter','dragover'].forEach(evt => {
+  dropzone.addEventListener(evt, e => { e.preventDefault(); e.stopPropagation(); dropzone.classList.add('drag'); });
+});
+['dragleave','drop'].forEach(evt => {
+  dropzone.addEventListener(evt, e => { e.preventDefault(); e.stopPropagation(); dropzone.classList.remove('drag'); });
+});
+
+// Handle drop
+dropzone.addEventListener('drop', e => {
+  uploadFiles.files = e.dataTransfer.files;
+  describeFiles(uploadFiles.files);
+});
+
+// Click to browse
+// dropzone.addEventListener('click', () => uploadFiles.click());
+
+// Picker change
+uploadFiles.addEventListener('change', () => describeFiles(uploadFiles.files));
+
+function startUpload() {
+  const files = uploadFiles.files;
+  if (!files || files.length === 0) { alert('Please select file(s) to upload.'); return; }
+  jQuery('#full-page-loader').show();
+  uploadStatus.textContent = 'Uploading...';
+  uploadStatus.className = ''; // neutral
+  uploadBar.style.width = '0%';
+  uploadBar.setAttribute('aria-valuenow', '0');
+
+  const form = new FormData();
+  Array.from(files).forEach(f => form.append('file', f));
+  // form.append('uploaded_by', 'Vishal'); // example extra field
+
+  const xhr = new XMLHttpRequest();
+  xhr.open('POST', UPLOAD_API_URL, true);
+  // If you need auth:
+  // xhr.setRequestHeader('Authorization', 'Bearer <token>');
+
+  xhr.upload.onprogress = (e) => {
+    if (e.lengthComputable) {
+      const pct = Math.round((e.loaded / e.total) * 100);
+      uploadBar.style.width = pct + '%';
+      uploadBar.setAttribute('aria-valuenow', String(pct));
+    }
+  };
+
+  xhr.onreadystatechange = () => {
+    if (xhr.readyState === 4) {
+      const ok = (xhr.status >= 200 && xhr.status < 300);
+      try {
+        const resp = JSON.parse(xhr.responseText || '{}');
+        uploadStatus.textContent = ok ? (resp.message || 'Upload successful') : (resp.error || `Upload failed (${xhr.status})`);
+      } catch {
+        uploadStatus.textContent = ok ? 'Upload successful' : `Upload failed (${xhr.status})`;
+      }
+      uploadStatus.className = ok ? 'success' : 'error';
+      // Optional: auto-close the modal on success after 1.2s:
+      // if (ok) setTimeout(() => bootstrap.Modal.getInstance(uploadModalEl).hide(), 1200);
+    }
+  };
+
+  xhr.onerror = () => {
+    uploadStatus.textContent = 'Network error during upload.';
+    uploadStatus.className = 'error';
+  };
+
+  xhr.send(form);
+  setTimeout(()=>{
+      jQuery('#uploadModal').modal('hide');
+      window.location.reload();
+  },3000)
+  jQuery('#full-page-loader').hide();
+
+}
+
+// Wire Start button
+document.getElementById('uploadStart').addEventListener('click', startUpload);
+// Cancel button already closes the modal via data-bs-dismiss
+
+
+
+
+// --- Pagination state ---
+let page = 1;
+let pageSize = 50; // default rows per page
+
+function totalPages() {
+  return Math.max(1, Math.ceil(PRODUCT_BASE.length / pageSize));
+}
+
+function clampPage() {
+  page = Math.min(Math.max(1, page), totalPages());
+}
+
+function getCurrentSlice() {
+  clampPage();
+  const start = (page - 1) * pageSize;
+  return PRODUCT_BASE.slice(start, start + pageSize);
+}
+
+function renderPagination() {
+  const bar = document.getElementById('paginationBar');
+  if (!bar) return;
+
+  const tp = totalPages();
+  clampPage();
+
+  bar.innerHTML = `
+    <div class="page-size">
+      <label for="pageSizeSelect">Rows per page</label>
+      <select id="pageSizeSelect">
+        <option value="5"  ${pageSize===5  ? 'selected' : ''}>5</option>
+        <option value="10" ${pageSize===10 ? 'selected' : ''}>10</option>
+        <option value="20" ${pageSize===20 ? 'selected' : ''}>20</option>
+        <option value="50" ${pageSize===50 ? 'selected' : ''}>50</option>
+        <option value="all" ${pageSize>=PRODUCT_BASE.length ? 'selected' : ''}>All</option>
+      </select>
+    </div>
+
+    <div class="pager">
+      <button class="pager-btn" id="prevPage" ${page<=1 ? 'disabled' : ''} aria-label="Previous page">‹</button>
+      <span class="page-info">Page ${page} of ${tp}</span>
+      <button class="pager-btn" id="nextPage" ${page>=tp ? 'disabled' : ''} aria-label="Next page">›</button>
+    </div>
+  `;
+
+  // wire events
+  document.getElementById('prevPage')?.addEventListener('click', () => { if (page > 1) { page--; renderProducts(); } });
+  document.getElementById('nextPage')?.addEventListener('click', () => { if (page < tp) { page++; renderProducts(); } });
+
+  const sel = document.getElementById('pageSizeSelect');
+  if (sel) {
+    sel.addEventListener('change', () => {
+      const val = sel.value;
+      pageSize = (val === 'all') ? PRODUCT_BASE.length : parseInt(val, 10);
+      page = 1;            // reset to first page when size changes
+      renderProducts();
+    });
+  }
+}
+
+// Function to add/remove product from the state and manage its attributes
+function toggleProductSelection(itemId, isChecked, attributes = {}) {
+    const index = selectedProductsWithAttributes.findIndex(p => p.item_id === itemId);
+    // console.log("index",index);
+    if (isChecked) {
+        // If selecting, ensure the product object exists in the array
+        if (index === -1) {
+            selectedProductsWithAttributes.push({
+                item_id: itemId,
+                mandatory_attrs: attributes
+            });
+        } else {
+            // Update attributes if the product is already selected
+            selectedProductsWithAttributes[index].mandatory_attrs = attributes;
+        }
+    } else {
+        // If deselecting, remove the product object from the array
+        if (index !== -1) {
+            selectedProductsWithAttributes.splice(index, 1);
+        }
+    }
+    updateSelectionInfo();
+}
+
+// Function to get the current mandatory attributes for a selected item
+function getSelectedAttributes(itemId) {
+    const productEntry = selectedProductsWithAttributes.find(p => p.item_id === itemId);
+    return productEntry ? productEntry.mandatory_attrs : {};
+}
+
+// Helper to check if a product is selected
+function isProductSelected(itemId) {
+    return selectedProductsWithAttributes.some(p => p.item_id === itemId);
+}
+
+// Helper to check if a specific attribute/value is selected
+function isAttributeValueSelected(itemId, attrName, value) {
+    const attrs = getSelectedAttributes(itemId);
+    const values = attrs[attrName];
+    return values ? values.includes(value) : false; // Default all selected when first loaded
+}
+
+
+
+// $('.attribute-select').select2({
+//     placeholder: 'Select product attributes'
+// });
+
+function getAtributeList(){
+        jQuery('#full-page-loader').show();  
+            try{
+            fetch('/attr/products/attributes', {
+                method: 'GET', // or 'POST' if your API expects POST
+                headers: {
+                    'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]')?.value || ''
+                }
+            })
+            .then(response => response.json())
+            .then(data => {
+                // console.log("data",data);
+                attributesFullData = data;
+                let attributesData = data;
+                 // Step 1: Extract unique mandatory attribute names
+                const mandatoryAttributes = [...new Set(
+                    attributesData
+                        .filter(attr => attr?.is_mandatory === "Yes")
+                        .map(attr => attr?.attribute_name)
+                )];
+
+                // Step 2: Populate the select element
+                const $select = jQuery('#mandatory-attributes');
+                $select.append(new Option("Select All", "select_all")); // Add "Select All" option first
+
+                mandatoryAttributes.forEach(attr => {
+                    $select.append(new Option(attr, attr));
+                });
+
+                // Step 3: Initialize Select2 with placeholder
+                // $select.select2({
+                //     placeholder: "Select mandatory attributes",
+                //     allowClear: true
+                // });
+
+                // Step 4: Handle 'Select All' logic
+                $select.on('select2:select', function (e) {
+                    if (e.params.data.id === "select_all") {
+                        // Select all real options except "Select All"
+                        const allOptions = mandatoryAttributes;
+                        $select.val(allOptions).trigger('change');
+                    }
+                });
+
+                jQuery('#full-page-loader').hide();
+            });
+        }catch(err){
+            console.log("err",err);
+            jQuery('#full-page-loader').hide();
+
+        }
+    
+}
+document.addEventListener("DOMContentLoaded", function () {
+    // Update span when range changes
+    thresholdInput.addEventListener('input', function () {
+        // console.log("this.value",this.value);
+        thresholdValueDisplay.textContent = this.value;
+    });
+});
+
+// Get threshold value when needed
+function getThreshold() {
+    // console.log("parseFloat(thresholdInput.value)",parseFloat(thresholdInput.value));
+    return parseFloat(thresholdInput.value);
+}
+
+
+/**
+ * Renders Mandatory attributes using a card-based comparison layout.
+ * Highlights mismatches prominently.
+ * @param {Object} attributes - The mandatory attribute data.
+ * @param {string} title - The title for the section.
+ * @returns {HTMLElement} A div containing the comparison cards.
+ */
+function renderMandatoryComparisonCards(attributes, title) {
+    const section = el('div', 'attribute-section');
+    
+    // --- 1. Flatten Mandatory Attributes ---
+    let attributeEntries = [];
+
+    Object.keys(attributes).forEach(key => {
+        const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]]; 
+        valuesArray.forEach(v => {
+            const aiValue = v.value || 'N/A';
+            const originalValue = v.original_value || 'N/A';
+            
+            // Comparison is case-insensitive and ignores leading/trailing whitespace
+            const isMatch = (String(aiValue).trim().toLowerCase() === String(originalValue).trim().toLowerCase());
+
+            attributeEntries.push({
+                name: key,
+                aiValue: aiValue,
+                originalValue: originalValue,
+                isMatch: isMatch,
+                source: v.source || 'N/A'
+            });
+        });
+    });
+
+    // --- 2. Section Header ---
+    const titleEl = el('div', 'section-title');
+    titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+    section.appendChild(titleEl);
+    
+    if (attributeEntries.length === 0) {
+        const msg = el('p', 'no-attributes-message');
+        msg.textContent = `No ${title.toLowerCase()} found.`;
+        section.appendChild(msg);
+        return section;
+    }
+
+    // --- 3. Card Container ---
+    const cardsContainer = el('div', 'comparison-cards-container');
+
+    attributeEntries.forEach(attr => {
+        // Main Card Element
+        const card = el('div', `comparison-card ${attr?.isMatch ? 'match' : 'mismatch-card'}`);
+
+        // Card Header (Attribute Name)
+        const header = el('div', 'card-header');
+        header.textContent = attr?.name.replace(/_/g, ' ');
+        card.appendChild(header);
+
+        // Content Wrapper
+        const content = el('div', 'card-content');
+
+        // Existing Value Box
+        const originalBox = el('div', 'value-box original-box');
+        originalBox.innerHTML = `
+            <div class="value-label">Manually Identified Value</div>
+            <div class="value-text">${attr?.originalValue}</div>
+        `;
+        content.appendChild(originalBox);
+
+        // AI Value Box
+        const aiBox = el('div', `value-box ai-box ${attr?.isMatch ? 'found-value' : 'mismatch-value'}`);
+        aiBox.innerHTML = `
+            <div class="value-label">AI Generated Value <span class="value-source">(${attr?.source})</span></div>
+            <div class="value-text">${attr?.aiValue}</div>
+        `;
+        content.appendChild(aiBox);
+
+        card.appendChild(content);
+
+        // Mismatch Indicator (only visible on mismatch-card via CSS)
+        if (!attr?.isMatch) {
+            const indicator = el('div', 'mismatch-indicator');
+            // indicator.innerHTML = '❌ MISMATCH';
+            indicator.innerHTML = attr?.isMatch ? '✅ MATCH' : '❌ MISMATCH';
+            card.appendChild(indicator);
+        }
+
+        cardsContainer.appendChild(card);
+    });
+
+    section.appendChild(cardsContainer);
+    return section;
+}
+
+// Example JavaScript (Assuming you have access to API_RESPONSE_AI)
+// document.getElementById('downloadResultBtn').addEventListener('click', () => {
+//     // 1. Convert the data to a JSON string
+//     const jsonString = JSON.stringify(API_RESPONSE_AI, null, 2); 
+    
+//     // 2. Create a Blob from the JSON string
+//     const blob = new Blob([jsonString], { type: 'application/json' });
+    
+//     // 3. Create a temporary URL and link element
+//     const url = URL.createObjectURL(blob);
+//     const a = document.createElement('a');
+    
+//     // 4. Set download attributes
+//     a.href = url;
+//     a.download = 'api_generated_results.json';
+    
+//     // 5. Simulate a click to trigger download
+//     document.body.appendChild(a);
+//     a.click();
+    
+//     // 6. Clean up
+//     document.body.removeChild(a);
+//     URL.revokeObjectURL(url);
+// });
+
+
+/**
+ * Renders Mandatory attributes using a card-based comparison layout.
+ * Highlights mismatches prominently.
+ * @param {Object} attributes - The mandatory attribute data.
+ * @param {string} title - The title for the section (used for the header).
+ * @returns {HTMLElement} A div containing the comparison cards.
+ */
+// function renderMandatoryComparisonCards(attributes, title) {
+//     const section = el('div', 'attribute-section mandatory-comparison-section');
+    
+//     // --- 1. Flatten Mandatory Attributes ---
+//     let attributeEntries = [];
+
+//     Object.keys(attributes).forEach(key => {
+//         const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]]; 
+//         valuesArray.forEach(v => {
+//             const aiValue = v.value || 'N/A';
+//             const originalValue = v.original_value || 'N/A';
+            
+//             const isMatch = (String(aiValue).trim().toLowerCase() === String(originalValue).trim().toLowerCase());
+
+//             attributeEntries.push({
+//                 name: key,
+//                 aiValue: aiValue,
+//                 originalValue: originalValue,
+//                 isMatch: isMatch,
+//                 source: v.source || 'N/A'
+//             });
+//         });
+//     });
+
+//     // --- 2. Section Header ---
+//     const titleEl = el('div', 'section-title');
+//     titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+//     section.appendChild(titleEl);
+    
+//     if (attributeEntries.length === 0) {
+//         const msg = el('p', 'no-attributes-message');
+//         msg.textContent = `No ${title.toLowerCase()} found.`;
+//         section.appendChild(msg);
+//         return section;
+//     }
+
+//     // --- 3. Card Container ---
+//     const cardsContainer = el('div', 'comparison-cards-container');
+
+//     attributeEntries.forEach(attr => {
+//         const card = el('div', `comparison-card ${attr?.isMatch ? 'match' : 'mismatch-card'}`);
+
+//         const header = el('div', 'card-header');
+//         header.textContent = attr?.name.replace(/_/g, ' ');
+//         card.appendChild(header);
+
+//         const content = el('div', 'card-content');
+
+//         // Existing Value Box
+//         const originalBox = el('div', 'value-box original-box');
+//         originalBox.innerHTML = `
+//             <div class="value-label">Manually Identified Value</div>
+//             <div class="value-text">${attr?.originalValue}</div>
+//         `;
+//         content.appendChild(originalBox);
+
+//         // AI Value Box
+//         const aiBox = el('div', `value-box ai-box ${attr?.isMatch ? 'found-value' : 'mismatch-value'}`);
+//         aiBox.innerHTML = `
+//             <div class="value-label">AI Generated Value <span class="value-source">(${attr?.source})</span></div>
+//             <div class="value-text">${attr?.aiValue}</div>
+//         `;
+//         content.appendChild(aiBox);
+
+//         card.appendChild(content);
+
+//         // Mismatch Indicator
+//         if (!attr?.isMatch) {
+//             const indicator = el('div', 'mismatch-indicator');
+//             // indicator.innerHTML = '❌ MISMATCH';
+//             indicator.innerHTML = attr?.isMatch ? '✅ MATCH' : '❌ MISMATCH';
+//             card.appendChild(indicator);
+//         }
+
+//         cardsContainer.appendChild(card);
+//     });
+
+//     section.appendChild(cardsContainer);
+//     return section;
+// }
+
+function renderMandatoryComparisonCards(attributes, title) {
+    const section = el('div', 'attribute-section mandatory-comparison-section');
+    
+    // --- 1. Flatten Mandatory Attributes ---
+    let attributeEntries = [];
+
+    Object.keys(attributes).forEach(key => {
+        const valuesArray = Array.isArray(attributes[key]) ? attributes[key] : [attributes[key]]; 
+        valuesArray.forEach(v => {
+            const aiValue = v.value || 'N/A';
+            const originalValue = v.original_value || 'N/A';
+            
+            const isMatch = (String(aiValue).trim().toLowerCase() === String(originalValue).trim().toLowerCase());
+
+            attributeEntries.push({
+                name: key,
+                aiValue: aiValue,
+                originalValue: originalValue,
+                isMatch: isMatch,
+                source: v.source || 'N/A'
+            });
+        });
+    });
+
+    // --- 2. Section Header ---
+    const titleEl = el('div', 'section-title');
+    titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+    section.appendChild(titleEl);
+    
+    if (attributeEntries.length === 0) {
+        const msg = el('p', 'no-attributes-message');
+        msg.textContent = `No ${title.toLowerCase()} found.`;
+        section.appendChild(msg);
+        return section;
+    }
+
+    // --- 3. Card Container ---
+    const cardsContainer = el('div', 'comparison-cards-container');
+
+    attributeEntries.forEach(attr => {
+        // --- CHANGE 1: Apply 'match-card' or 'mismatch-card' explicitly ---
+        const cardClass = attr?.isMatch ? 'match-card' : 'mismatch-card';
+        const card = el('div', `comparison-card ${cardClass}`);
+
+        const header = el('div', 'card-header');
+        header.textContent = attr?.name.replace(/_/g, ' ');
+        card.appendChild(header);
+
+        const content = el('div', 'card-content');
+
+        // Existing Value Box
+        const originalBox = el('div', 'value-box original-box');
+        originalBox.innerHTML = `
+            <div class="value-label">Manually Identified Value</div>
+            <div class="value-text">${attr?.originalValue}</div>
+        `;
+        content.appendChild(originalBox);
+
+        // AI Value Box
+        // Removed 'found-value' class here as styling should rely on the parent card class
+        const aiBox = el('div', `value-box ai-box ${attr?.isMatch ? '' : 'mismatch-value'}`); 
+        aiBox.innerHTML = `
+            <div class="value-label">AI Generated Value <span class="value-source">(${attr?.source})</span></div>
+            <div class="value-text">${attr?.aiValue}</div>
+        `;
+        content.appendChild(aiBox);
+
+        card.appendChild(content);
+
+        // --- CHANGE 2: Display the indicator for ALL cards, controlling color via CSS ---
+        const indicator = el('div', 'match-status-indicator');
+        indicator.innerHTML = attr?.isMatch ? '✅ MATCH' : '❌ MISMATCH';
+        card.appendChild(indicator);
+
+        cardsContainer.appendChild(card);
+    });
+
+    section.appendChild(cardsContainer);
+    return section;
+}
+
+/**
+ * Renders Additional, OCR, or Visual attributes in a simple card layout.
+ * @param {Object} attributes - The attribute data (Additional, OCR, or Visual).
+ * @param {string} title - The title for the section.
+ * @returns {HTMLElement} A div containing the attribute cards.
+ */
+function renderSimpleAttributeCards(attributes, title) {
+    const section = el('div', 'attribute-section simple-attribute-section');
+    
+    // --- 1. Flatten Attributes ---
+    let attributeEntries = [];
+
+    const processAttribute = (key, values) => {
+        const valuesArray = Array.isArray(values) ? values : [values]; 
+        valuesArray.forEach(v => {
+            attributeEntries.push({
+                name: key,
+                value: v.value,
+                source: v.source || 'N/A'
+            });
+        });
+    };
+
+    Object.keys(attributes).forEach(key => {
+        const attribute = attributes[key];
+        
+        if (Array.isArray(attribute)) {
+            processAttribute(key, attribute);
+        } else if (typeof attribute === 'object' && attribute !== null) {
+            Object.keys(attribute).forEach(subKey => {
+                const subAttribute = attribute[subKey];
+                if (Array.isArray(subAttribute)) {
+                    processAttribute(`${key} (${subKey.replace(/_/g, ' ')})`, subAttribute);
+                }
+            });
+        }
+    });
+
+    // --- 2. Section Header ---
+    const titleEl = el('div', 'section-title');
+    titleEl.innerHTML = `<h3>${title} (${attributeEntries.length})</h3>`;
+    section.appendChild(titleEl);
+    
+    if (attributeEntries.length === 0) {
+        const msg = el('p', 'no-attributes-message');
+        msg.textContent = `No ${title.toLowerCase()} found.`;
+        section.appendChild(msg);
+        return section;
+    }
+
+    // --- 3. Card Container ---
+    const cardsContainer = el('div', 'comparison-cards-container simple-cards-container');
+
+    attributeEntries.forEach(attr => {
+        // Simple Card Element
+        const card = el('div', 'simple-card');
+
+        // Card Header (Attribute Name)
+        const header = el('div', 'card-header');
+        header.textContent = formatString(attr?.name).replace(/_/g, ' ');
+        card.appendChild(header);
+
+        // Content Wrapper
+        const content = el('div', 'card-content');
+        
+        // Value Box
+        const valueBox = el('div', 'value-box single-value-box');
+        const displayValue = Array.isArray(attr?.value) 
+            ? (attr?.value.map(v => formatString(v.value))).join(', ') +'('+ formatString(attr?.source)+ ')' 
+            : formatString(attr?.value) +'('+ formatString(attr?.source)+ ')'; 
+            // : attr?.value;
+            
+        valueBox.innerHTML = `
+            <div class="value-label">Extracted Value <span class="value-source">(${formatString(attr?.source)})</span></div>
+            <div class="value-text">${displayValue || 'N/A'}</div>
+        `;
+        content.appendChild(valueBox);
+
+        card.appendChild(content);
+        cardsContainer.appendChild(card);
+    });
+
+    section.appendChild(cardsContainer);
+    return section;
+}
+
+function delay(ms) {
+    return new Promise(resolve => setTimeout(resolve, ms));
+}

+ 3 - 0
bg_remover/urls.py

@@ -7,5 +7,8 @@ from django.conf.urls.static import static
 urlpatterns = [
     path('remove-bg/', views.BackgroundRemovalView.as_view(), name='remove_bg'),
     path("remove-bg/bulk/", views.BulkBackgroundRemovalAPI.as_view(), name="remove_bg_bulk"),
+    path('status/<str:task_id>/', views.TaskStatusAPI.as_view(), name='task_status'),
+    path('tasks/list/', views.TaskHistoryAPI.as_view(), name='bg_tasks_json'),
+    path('tasks/history/', views.TaskHistoryPageView.as_view(), name='bg_history_page'),
 
 ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

+ 255 - 65
bg_remover/views.py

@@ -1,13 +1,129 @@
-# background_remover/views.py
+# # background_remover/views.py
+# import io
+# from PIL import Image
+# from django.http import HttpResponse
+# from rest_framework.views import APIView
+# from rest_framework.parsers import MultiPartParser
+# from .services import BiRefNetService
+# from django.shortcuts import render
+# import zipfile
+# import time
+
+# class BackgroundRemovalView(APIView):
+#     parser_classes = [MultiPartParser]
+
+#     def get(self, request):
+#         return render(request, "bg_remover_index.html")
+
+#     def post(self, request, *args, **kwargs):
+#         if 'image' not in request.FILES:
+#             return HttpResponse("No image provided", status=400)
+
+#         # 1. Load image from request
+#         input_file = request.FILES['image']
+#         input_image = Image.open(input_file)
+
+#         # 2. Process via Service
+#         service = BiRefNetService()
+#         output_image = service.remove_background(input_image)
+
+#         # 3. Prepare response
+#         buffer = io.BytesIO()
+#         output_image.save(buffer, format="PNG")
+        
+#         return HttpResponse(buffer.getvalue(), content_type="image/png")
+    
+# class BulkBackgroundRemovalAPI(APIView):
+#     parser_classes = [MultiPartParser]
+
+#     def post(self, request):
+#         files = request.FILES.getlist("images")
+
+#         if not files:
+#             return HttpResponse({"error": "No images provided"}, status=400)
+
+#         service = BiRefNetService()
+#         start_time = time.time()
+
+#         zip_buffer = io.BytesIO()
+
+#         # with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
+#             # for file in files:
+#             #     try:
+#             #         image = Image.open(file).convert("RGB")
+#             #         output = service.remove_background(image)
+
+#             #         img_buffer = io.BytesIO()
+#             #         output.save(img_buffer, format="PNG")
+
+#             #         name = file.name.rsplit(".", 1)[0] + "_whitebg.png"
+#             #         zip_file.writestr(name, img_buffer.getvalue())
+
+#             #     except Exception as e:
+#             #         print(f"Error processing {file.name}: {e}")
+
+#         with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as master_zip:
+#             for file in files:
+#                 # CHECK IF FILE IS A ZIP
+#                 if file.name.lower().endswith('.zip'):
+#                     with zipfile.ZipFile(file, 'r') as user_zip:
+#                         for inner_file_name in user_zip.namelist():
+#                             # Skip directories and non-image files
+#                             if inner_file_name.endswith(('.png', '.jpg', '.jpeg', '.webp')):
+#                                 with user_zip.open(inner_file_name) as inner_file:
+#                                     img_data = inner_file.read()
+#                                     image = Image.open(io.BytesIO(img_data)).convert("RGB")
+#                                     output = service.remove_background(image)
+                                    
+#                                     img_io = io.BytesIO()
+#                                     output.save(img_io, format="PNG")
+                                    
+#                                     # Create clean name for the output zip
+#                                     clean_name = inner_file_name.rsplit(".", 1)[0].split('/')[-1] + "_no_bg.png"
+#                                     master_zip.writestr(clean_name, img_io.getvalue())
+                
+#                 # PROCESS INDIVIDUAL IMAGES (Existing logic)
+#                 else:
+#                     try:
+#                         image = Image.open(file).convert("RGB")
+#                         output = service.remove_background(image)
+#                         img_io = io.BytesIO()
+#                         output.save(img_io, format="PNG")
+#                         name = file.name.rsplit(".", 1)[0] + "_no_bg.png"
+#                         master_zip.writestr(name, img_io.getvalue())
+#                     except Exception as e:
+#                         print(f"Error processing {file.name}: {e}")
+#         zip_buffer.seek(0)
+#         total_time = round(time.time() - start_time, 2)
+
+#         response = HttpResponse(
+#             zip_buffer.getvalue(),
+#             content_type="application/zip"
+#         )
+#         response["Content-Disposition"] = "attachment; filename=processed_images.zip"
+#         response["X-Processing-Time"] = f"{total_time}s"
+
+#         return response    
+
+
+
+
+import uuid
+import threading
+import os
 import io
-from PIL import Image
-from django.http import HttpResponse
+import zipfile
+import csv
+from django.shortcuts import render
+from django.http import HttpResponse, JsonResponse
+from django.conf import settings
 from rest_framework.views import APIView
 from rest_framework.parsers import MultiPartParser
+from PIL import Image
+
+from .models import BackgroundTask
 from .services import BiRefNetService
-from django.shortcuts import render
-import zipfile
-import time
+
 
 class BackgroundRemovalView(APIView):
     parser_classes = [MultiPartParser]
@@ -33,74 +149,148 @@ class BackgroundRemovalView(APIView):
         
         return HttpResponse(buffer.getvalue(), content_type="image/png")
     
+
 class BulkBackgroundRemovalAPI(APIView):
     parser_classes = [MultiPartParser]
 
     def post(self, request):
         files = request.FILES.getlist("images")
-
         if not files:
-            return HttpResponse({"error": "No images provided"}, status=400)
+            return JsonResponse({"error": "No images provided"}, status=400)
 
+        # 1. Create a database record for the task
+        task_id = uuid.uuid4()
+        BackgroundTask.objects.create(task_id=task_id, status='PROCESSING')
+
+        # 2. Read files into memory to pass to the thread
+        file_list = []
+        for f in files:
+            file_list.append({
+                "name": f.name,
+                "content": f.read()
+            })
+
+        # 3. Start background thread
+        thread = threading.Thread(
+            target=self.process_images_logic, 
+            args=(task_id, file_list)
+        )
+        thread.start()
+
+        return JsonResponse({
+            "task_id": str(task_id),
+            "message": "Task started",
+            "status_url": f"/api/status/{task_id}/"
+        }, status=202)
+
+    def process_images_logic(self, task_id, file_list):
+        """Heavy AI logic running in background"""
         service = BiRefNetService()
-        start_time = time.time()
-
-        zip_buffer = io.BytesIO()
-
-        # with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as zip_file:
-            # for file in files:
-            #     try:
-            #         image = Image.open(file).convert("RGB")
-            #         output = service.remove_background(image)
-
-            #         img_buffer = io.BytesIO()
-            #         output.save(img_buffer, format="PNG")
-
-            #         name = file.name.rsplit(".", 1)[0] + "_whitebg.png"
-            #         zip_file.writestr(name, img_buffer.getvalue())
-
-            #     except Exception as e:
-            #         print(f"Error processing {file.name}: {e}")
-
-        with zipfile.ZipFile(zip_buffer, "w", zipfile.ZIP_DEFLATED) as master_zip:
-            for file in files:
-                # CHECK IF FILE IS A ZIP
-                if file.name.lower().endswith('.zip'):
-                    with zipfile.ZipFile(file, 'r') as user_zip:
-                        for inner_file_name in user_zip.namelist():
-                            # Skip directories and non-image files
-                            if inner_file_name.endswith(('.png', '.jpg', '.jpeg', '.webp')):
-                                with user_zip.open(inner_file_name) as inner_file:
-                                    img_data = inner_file.read()
-                                    image = Image.open(io.BytesIO(img_data)).convert("RGB")
-                                    output = service.remove_background(image)
-                                    
-                                    img_io = io.BytesIO()
-                                    output.save(img_io, format="PNG")
-                                    
-                                    # Create clean name for the output zip
-                                    clean_name = inner_file_name.rsplit(".", 1)[0].split('/')[-1] + "_no_bg.png"
-                                    master_zip.writestr(clean_name, img_io.getvalue())
-                
-                # PROCESS INDIVIDUAL IMAGES (Existing logic)
-                else:
+        log_data = []
+        
+        # Prepare folders
+        folder_path = os.path.join(settings.MEDIA_ROOT, 'bulk_results', str(task_id))
+        os.makedirs(folder_path, exist_ok=True)
+        zip_filename = f"result_{task_id}.zip"
+        zip_abs_path = os.path.join(folder_path, zip_filename)
+
+        try:
+            with zipfile.ZipFile(zip_abs_path, "w", zipfile.ZIP_DEFLATED) as master_zip:
+                for item in file_list:
+                    name, content = item["name"], item["content"]
+                    
                     try:
-                        image = Image.open(file).convert("RGB")
-                        output = service.remove_background(image)
-                        img_io = io.BytesIO()
-                        output.save(img_io, format="PNG")
-                        name = file.name.rsplit(".", 1)[0] + "_no_bg.png"
-                        master_zip.writestr(name, img_io.getvalue())
+                        # Process if it's a zip
+                        if name.lower().endswith('.zip'):
+                            with zipfile.ZipFile(io.BytesIO(content)) as user_zip:
+                                for inner_name in user_zip.namelist():
+                                    if inner_name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
+                                        with user_zip.open(inner_name) as inner_file:
+                                            img = Image.open(io.BytesIO(inner_file.read())).convert("RGB")
+                                            out = service.remove_background(img)
+                                            buf = io.BytesIO()
+                                            out.save(buf, format="PNG")
+                                            master_zip.writestr(f"no_bg_{inner_name.split('/')[-1]}", buf.getvalue())
+                                            log_data.append([inner_name, "SUCCESS", "Done"])
+                        
+                        # Process if it's an image
+                        else:
+                            img = Image.open(io.BytesIO(content)).convert("RGB")
+                            out = service.remove_background(img)
+                            buf = io.BytesIO()
+                            out.save(buf, format="PNG")
+                            clean_name = name.rsplit(".", 1)[0] + "_no_bg.png"
+                            master_zip.writestr(clean_name, buf.getvalue())
+                            log_data.append([name, "SUCCESS", "Done"])
+
                     except Exception as e:
-                        print(f"Error processing {file.name}: {e}")
-        zip_buffer.seek(0)
-        total_time = round(time.time() - start_time, 2)
+                        log_data.append([name, "FAIL", str(e)])
 
-        response = HttpResponse(
-            zip_buffer.getvalue(),
-            content_type="application/zip"
-        )
-        response["Content-Disposition"] = "attachment; filename=processed_images.zip"
-        response["X-Processing-Time"] = f"{total_time}s"
+                # Create CSV Log inside the Zip
+                csv_buf = io.StringIO()
+                writer = csv.writer(csv_buf)
+                writer.writerow(["Filename", "Status", "Message"])
+                writer.writerows(log_data)
+                master_zip.writestr("processing_report.csv", csv_buf.getvalue())
+
+            # 4. Update model to COMPLETED
+            task = BackgroundTask.objects.get(task_id=task_id)
+            task.status = 'COMPLETED'
+            # Save the relative path for the FileField
+            task.zip_file = f"bulk_results/{task_id}/{zip_filename}"
+            task.save()
+
+        except Exception as e:
+            task = BackgroundTask.objects.get(task_id=task_id)
+            task.status = 'FAILED'
+            task.error_message = str(e)
+            task.save()
 
-        return response    
+
+class TaskStatusAPI(APIView):
+    def get(self, request, task_id):
+        try:
+            task = BackgroundTask.objects.get(task_id=task_id)
+            return JsonResponse({
+                "task_id": task.task_id,
+                "status": task.status,
+                "download_url": task.zip_file.url if task.zip_file else None,
+                "error": task.error_message
+            })
+        except BackgroundTask.DoesNotExist:
+            return JsonResponse({"error": "Task not found"}, status=404)
+        
+class TaskHistoryListView(APIView):
+    def get(self, request):
+        # Fetch latest 20 tasks
+        tasks = BackgroundTask.objects.all().order_by('-created_at')[:20]
+        data = []
+        for t in tasks:
+            data.append({
+                "task_id": str(t.task_id),
+                "status": t.status,
+                "created_at": t.created_at.strftime("%Y-%m-%d %H:%M"),
+                "download_url": t.zip_file.url if t.zip_file else None
+            })
+        return HttpResponse(data) 
+
+# Make sure this name matches what you put in urls.py
+class TaskHistoryAPI(APIView): 
+    def get(self, request):
+        # Fetch latest 20 tasks
+        tasks = BackgroundTask.objects.all().order_by('-created_at')[:20]
+        data = []
+        for t in tasks:
+            data.append({
+                "task_id": str(t.task_id),
+                "status": t.status,
+                # Using 'date' key to match the JS 't.date' in the history page
+                "date": t.created_at.strftime("%Y-%m-%d %H:%M"), 
+                "url": t.zip_file.url if t.zip_file else None
+            })
+        # Use JsonResponse so the frontend can read it as an object
+        return JsonResponse(data, safe=False)
+
+class TaskHistoryPageView(APIView):
+    def get(self, request):
+        return render(request, "bg_remover_history.html")           

+ 3 - 0
content_quality_tool/settings.py

@@ -52,6 +52,9 @@ MIDDLEWARE = [
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 ]
+# settings.py
+TIME_ZONE = 'Asia/Kolkata'  # Change to your specific timezone
+USE_TZ = True
 ROOT_URLCONF = 'content_quality_tool.urls'
 TEMPLATES = [
     {

+ 2 - 2
content_quality_tool_public/templates/sidebar.html

@@ -63,11 +63,11 @@
                         <p>Product Attribute Column Mapping</p>
                     </a> 
                 </li>    
-                <li class="nav-item"> <a href="{% url 'remove_bg' %}" title="Image Background Remover" class="nav-link {% if request.path == '/bg-remover/remove-bg/' %}active{% endif %}"> <i
+                <li class="nav-item"> <a href="{% url 'remove_bg' %}" title="Image Background Remover" class="nav-link {% if request.path == '/bg-remover/remove-bg/' or request.path == '/bg-remover/tasks/history/' %}active{% endif %}"> <i
                             class="nav-icon bi bi-eraser-fill"></i>
                         <p>Image Background Remover</p>
                     </a> 
-                </li> 
+                </li>    
                 <!-- {{request.resolver_match.url_name}} {{request.path}} -->
                 <li class="nav-item has-treeview  {% if request.path == '/title-creator/upload/' or request.path == '/title-creator/master/' %}active{% endif %}">
                     <a href="#" class="nav-link {% if request.path == '/title-creator/upload/' or request.path == '/title-creator/master/' %}active{% endif %}">

+ 162 - 0
title_creator_app/templates/title_creator_history.html

@@ -0,0 +1,162 @@
+{% load static %}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Task History | Title Creator</title>
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
+<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
+<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css"
+        integrity="sha256-tXJfXfp6Ewt1ilPzLDtQnJV4hclT9XuaZUKyUvmyr+Q=" crossorigin="anonymous">
+    <!--end::Fonts--><!--begin::Third Party Plugin(OverlayScrollbars)-->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/styles/overlayscrollbars.min.css"
+        integrity="sha256-dSokZseQNT08wYEWiz5iLI8QPlKxG+TswNRD8k35cpg=" crossorigin="anonymous">
+    <!--end::Third Party Plugin(OverlayScrollbars)--><!--begin::Third Party Plugin(Bootstrap Icons)-->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.min.css"
+        integrity="sha256-Qsx5lrStHZyR9REqhUF8iQt73X06c8LGIUPzpOhwRrI=" crossorigin="anonymous">
+    <!--end::Third Party Plugin(Bootstrap Icons)--><!--begin::Required Plugin(AdminLTE)-->
+    <link rel="stylesheet" href="{% static './css/adminlte.css' %}"><!--end::Required Plugin(AdminLTE)--><!-- apexcharts -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/apexcharts@3.37.1/dist/apexcharts.css"
+        integrity="sha256-4MX+61mt9NVvvuPjUWdUdyfZfxSB1/Rf9WtqRHgG5S0=" crossorigin="anonymous">
+    <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
+    <link rel="stylesheet" href="{% static './css/select2-bootstrap4.min.css' %}">
+    <link rel="stylesheet" href="{% static './css/custom.css' %}">
+    <script src="https://cdn.tailwindcss.com"></script>
+    <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;800&display=swap" rel="stylesheet">
+    
+    <style>
+        body { font-family: 'Plus Jakarta Sans', sans-serif; background-color: #f8fafc; }
+        .glass-card { background: white; border-radius: 24px; border: 1px solid #e2e8f0; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05); }
+        .status-pill { font-weight: 800; font-size: 0.65rem; letter-spacing: 0.05em; padding: 5px 12px; border-radius: 8px; text-transform: uppercase; }
+    </style>
+</head>
+
+<body class="layout-fixed sidebar-expand-lg sidebar-mini app-loaded sidebar-collapse">
+    <div class="app-wrapper">
+        {% include 'header.html' %}
+        {% include 'sidebar.html' %}
+
+        <main class="app-main">
+            <div class="app-content pt-10 px-6">
+                <div class="max-w-6xl mx-auto">
+                    
+                    <div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
+                        <div>
+                            <nav class="flex mb-2 text-[10px] font-bold uppercase tracking-widest text-blue-600">
+                                <span>Automation</span>
+                                <span class="mx-2 text-gray-300">/</span>
+                                <span class="text-gray-400">Title Creator</span>
+                            </nav>
+                            <h1 class="text-3xl font-black text-gray-900 tracking-tight">Task Scheduler</h1>
+                            <p class="text-gray-500 font-medium">Monitor and download your processed Excel files.</p>
+                        </div>
+                        <a href="{% url 'title_creator_home' %}" class="inline-flex items-center gap-2 px-6 py-3 bg-blue-600 text-white rounded-2xl font-bold hover:bg-blue-700 shadow-lg shadow-blue-200 transition-all">
+                            <i class="bi bi-file-earmark-plus"></i> New Task
+                        </a>
+                    </div>
+
+                    <div class="glass-card overflow-hidden">
+                        <table class="table table-hover align-middle mb-0">
+                            <thead class="bg-gray-50/50 border-b border-gray-100">
+                                <tr>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest">Date Created</th>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest">Filename</th>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest text-center">Status</th>
+                                    <th class="px-6 py-4 text-[11px] font-black text-gray-400 uppercase tracking-widest text-end">Action</th>
+                                </tr>
+                            </thead>
+                            <tbody id="task-list" class="divide-y divide-gray-50">
+                                <tr>
+                                    <td colspan="4" class="py-20 text-center">
+                                        <div class="flex flex-col items-center">
+                                            <div class="w-10 h-10 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mb-4"></div>
+                                            <p class="text-gray-400 font-bold uppercase tracking-widest text-xs">Loading Queue...</p>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </main>
+        {% include 'footer.html' %}
+    </div>
+    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.3.0/browser/overlayscrollbars.browser.es6.min.js"></script>
+    <script src="{% static './js/adminlte.js' %}"></script>
+    <script>
+        async function loadTasks() {
+            try {
+                const response = await fetch('{% url "title_creator_tasks_json" %}');
+                const tasks = await response.json();
+                const container = document.getElementById('task-list');
+
+                if (tasks.length === 0) {
+                    container.innerHTML = `<tr><td colspan="4" class="text-center py-20 text-gray-400 font-medium">No processing tasks found.</td></tr>`;
+                    return;
+                }
+
+                container.innerHTML = tasks.map(task => {
+                    let statusClass = "";
+                    if (task.status === 'COMPLETED') statusClass = "bg-green-100 text-green-700 border border-green-200";
+                    else if (task.status === 'PENDING') statusClass = "bg-blue-100 text-blue-700 border border-blue-200 animate-pulse";
+                    else statusClass = "bg-red-100 text-red-700 border border-red-200";
+
+                    return `
+                        <tr class="hover:bg-gray-50/50 transition-colors">
+                            <td class="px-6 py-4 text-sm font-bold text-gray-700">${task.date}</td>
+                            <td class="px-6 py-4">
+                                <div class="flex items-center gap-3">
+                                    <div class="p-2 bg-gray-100 rounded-lg"><i class="bi bi-file-earmark-spreadsheet text-blue-600"></i></div>
+                                    <span class="text-sm font-semibold text-gray-800">${task.filename}</span>
+                                </div>
+                            </td>
+                            <td class="px-6 py-4 text-center">
+                                <span class="status-pill ${statusClass}">${task.status}</span>
+                            </td>
+                            <td class="px-6 py-4 text-end">
+                                ${task.url ? 
+                                    `<a href="${task.url}" class="inline-flex items-center gap-2 px-4 py-2 bg-slate-900 text-white rounded-xl text-xs font-bold hover:bg-slate-800 shadow-sm transition-all" download>
+                                        <i class="bi bi-cloud-download"></i> Download Excel
+                                    </a>` : 
+                                    `<span class="text-[10px] font-black text-gray-300 uppercase italic tracking-widest">Processing...</span>`
+                                }
+                            </td>
+                        </tr>
+                    `;
+                }).join('');
+            } catch (e) { console.error("Refresh Error:", e); }
+        }
+
+        loadTasks();
+        // setInterval(loadTasks, 5000); // Auto-refresh every 5 seconds
+    </script>
+    <script>
+        const SELECTOR_SIDEBAR_WRAPPER = ".sidebar-wrapper";
+        const Default = {
+            scrollbarTheme: "os-theme-light",
+            scrollbarAutoHide: "leave",
+            scrollbarClickScroll: true,
+        };
+        document.addEventListener("DOMContentLoaded", function () {
+            const sidebarWrapper = document.querySelector(SELECTOR_SIDEBAR_WRAPPER);
+            if (
+                sidebarWrapper &&
+                typeof OverlayScrollbarsGlobal?.OverlayScrollbars !== "undefined"
+            ) {
+                OverlayScrollbarsGlobal.OverlayScrollbars(sidebarWrapper, {
+                    scrollbars: {
+                        theme: Default.scrollbarTheme,
+                        autoHide: Default.scrollbarAutoHide,
+                        clickScroll: Default.scrollbarClickScroll,
+                    },
+                });
+            }
+        });
+    </script>
+</body>
+</html>

+ 99 - 34
title_creator_app/templates/title_creator_index.html

@@ -4,7 +4,7 @@
 <head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<title>Column Mapping</title>
+<title>Title Creator</title>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
 <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css"
@@ -145,10 +145,39 @@
                 </a>
             </div>
         </div>
-        <div class="mb-10 text-center">
-            <h1 class="text-4xl font-extrabold text-gray-900 mb-2">Title Creator </h1>
-            <p class="text-gray-500">Upload Excel URLs to generate dynamic titles from Data</p>
+        <!-- <div class="flex-shrink-0">
+            <a href="{% url 'title_creator_history' %}" 
+            class="inline-flex items-center gap-3 px-6 py-3 bg-white border border-gray-200 text-gray-700 text-sm font-bold rounded-2xl shadow-sm hover:shadow-md hover:border-blue-300 hover:text-blue-600 transition-all duration-200 group">
+                <div class="bg-gray-50 p-2 rounded-lg group-hover:bg-blue-50 transition-colors">
+                    <i class="bi bi-calendar-check text-gray-400 group-hover:text-blue-500"></i>
+                </div>
+                <span>Task Scheduler</span>
+                <i class="bi bi-chevron-right text-gray-300 group-hover:text-blue-400 text-xs"></i>
+            </a>
+        </div> -->
+        <div class="mb-10 flex flex-col md:flex-row md:items-end md:justify-between gap-4 border-b border-gray-100 pb-6">
+            <div class="text-left">
+                <h1 class="text-4xl font-black text-gray-900 tracking-tight mb-2">
+                    Title Creator
+                </h1>
+                <p class="text-gray-500 font-medium ">
+                    Upload Excel URLs to generate dynamic titles from Data.
+                </p>
+            </div>
+
+            <div class="flex items-center">
+                <a href="{% url 'title_creator_history' %}" 
+                class="inline-flex items-center gap-2 px-5 py-2.5 bg-white border border-gray-200 text-gray-700 text-sm font-bold rounded-xl shadow-sm hover:shadow-md hover:border-blue-300 hover:text-blue-600 transition-all duration-200 group">
+                    <i class="bi bi-clock-history text-gray-400 group-hover:text-blue-500 transition-colors"></i>
+                    Task History
+                    <span class="flex h-2 w-2 rounded-full bg-blue-500 ml-1"></span>
+                </a>
+            </div>
         </div>
+        <!-- <div class="mb-10 text-center">
+            <h1 class="text-4xl font-extrabold text-gray-900 mb-2"> </h1>
+            <p class="text-gray-500"></p>
+        </div> -->
 
         <div id="uploadCard" class="bg-white p-8 rounded-3xl shadow-sm border border-gray-200 mb-8 transition-all">
             <div class="mb-6">
@@ -321,51 +350,87 @@
             formData.append('file', fileInput.files[0]);
             formData.append('product_type', ptDropdown.value);
 
-            // Toggle UI
-            document.getElementById('uploadCard').classList.add('hidden');
-            document.getElementById('statusCard').classList.remove('hidden');
-            document.getElementById('statusFile').innerText = `File: ${fileInput.files[0].name}`;
+            // 1. Show a "Starting..." state on the button to prevent double-clicks
+            const uploadBtn = document.getElementById('uploadBtn'); // adjust ID to match your button
+            if(uploadBtn) {
+                uploadBtn.innerHTML = `<span class="spinner-border spinner-border-sm mr-2"></span> Initializing...`;
+                uploadBtn.disabled = true;
+            }
 
             try {
-                const response = await fetch('/title-creator/upload-async/', { // New Endpoint
+                const response = await fetch('/title-creator/upload-async/', { 
                     method: 'POST',
                     body: formData,
                     headers: {'X-CSRFToken': '{{ csrf_token }}'}
                 });
                 const data = await response.json();
 
-                if (data.task_id) {
-                    pollStatus(data.task_id);
+                // 2. CHECK FOR 'started' STATUS HERE
+                if (data.status === 'started' || data.task_id) {
+                    // REDIRECT TO HISTORY PAGE
+                    // This is the best place because the user can track the progress there
+                    window.location.href = "{% url 'title_creator_history' %}";
+                } else {
+                    alert("Error: " + (data.error || "Unknown error occurred"));
+                    location.reload(); // Reset UI
                 }
             } catch (err) {
+                console.error(err);
                 alert("Failed to start background task.");
+                location.reload();
             }
         }
 
-        function pollStatus(taskId) {
-            const msg = document.getElementById('statusMsg');
-            const interval = setInterval(async () => {
-                try {
-                    const response = await fetch(`/check-status/${taskId}/`);
-                    const data = await response.json();
+        // async function startBackgroundTask() {
+        //     const formData = new FormData();
+        //     formData.append('file', fileInput.files[0]);
+        //     formData.append('product_type', ptDropdown.value);
 
-                    if (data.status === 'COMPLETED') {
-                        clearInterval(interval);
-                        document.getElementById('statusIcon').innerHTML = "✅";
-                        document.getElementById('statusTitle').innerText = "Process Complete!";
-                        msg.innerHTML = `<a href="${data.download_url}" class="text-white bg-green-600 px-6 py-2 rounded-lg inline-block">Download Ready: ${data.file_name}</a>`;
-                    } else if (data.status === 'FAILED') {
-                        clearInterval(interval);
-                        msg.innerText = "Error: Processing failed.";
-                        msg.classList.add('text-red-600');
-                    } else {
-                        msg.innerText = "Task in progress... still scraping URLs.";
-                    }
-                } catch (e) {
-                    console.error("Polling error", e);
-                }
-            }, 4000); // Poll every 4 seconds
-        }
+        //     // Toggle UI
+        //     document.getElementById('uploadCard').classList.add('hidden');
+        //     document.getElementById('statusCard').classList.remove('hidden');
+        //     document.getElementById('statusFile').innerText = `File: ${fileInput.files[0].name}`;
+
+        //     try {
+        //         const response = await fetch('/title-creator/upload-async/', { // New Endpoint
+        //             method: 'POST',
+        //             body: formData,
+        //             headers: {'X-CSRFToken': '{{ csrf_token }}'}
+        //         });
+        //         const data = await response.json();
+
+        //         if (data.task_id) {
+        //             pollStatus(data.task_id);
+        //         }
+        //     } catch (err) {
+        //         alert("Failed to start background task.");
+        //     }
+        // }
+
+        // function pollStatus(taskId) {
+        //     const msg = document.getElementById('statusMsg');
+        //     const interval = setInterval(async () => {
+        //         try {
+        //             const response = await fetch(`/check-status/${taskId}/`);
+        //             const data = await response.json();
+
+        //             if (data.status === 'COMPLETED') {
+        //                 clearInterval(interval);
+        //                 document.getElementById('statusIcon').innerHTML = "✅";
+        //                 document.getElementById('statusTitle').innerText = "Process Complete!";
+        //                 msg.innerHTML = `<a href="${data.download_url}" class="text-white bg-green-600 px-6 py-2 rounded-lg inline-block">Download Ready: ${data.file_name}</a>`;
+        //             } else if (data.status === 'FAILED') {
+        //                 clearInterval(interval);
+        //                 msg.innerText = "Error: Processing failed.";
+        //                 msg.classList.add('text-red-600');
+        //             } else {
+        //                 msg.innerText = "Task in progress... still scraping URLs.";
+        //             }
+        //         } catch (e) {
+        //             console.error("Polling error", e);
+        //         }
+        //     }, 4000); // Poll every 4 seconds
+        // }
     </script>
  </main>
    {% include 'footer.html' %}

+ 1 - 1
title_creator_app/templates/title_creator_master.html

@@ -4,7 +4,7 @@
 <head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<title>Column Mapping</title>
+<title>Title Creator - Master</title>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
 <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/source-sans-3@5.0.12/index.css"

+ 3 - 1
title_creator_app/urls.py

@@ -11,5 +11,7 @@ urlpatterns = [
     path('upload-async/', views.title_creator_async_view, name='title_creator_async'), # New
     path('check-status/<str:task_id>/', views.check_status, name='check_status'), # Status checker
     path('master/', views.master_config_view, name='title_creator_master'),
-    path('api/save-config/', views.save_config_api, name='save_config_api')
+    path('api/save-config/', views.save_config_api, name='save_config_api'),
+    path('title-creator/history/', views.title_creator_history_page, name='title_creator_history'),
+    path('title-creator/api/tasks/', views.get_title_creator_tasks_json, name='title_creator_tasks_json'),
 ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

+ 135 - 54
title_creator_app/views.py

@@ -133,8 +133,66 @@ def save_config_api(request):
         except Exception as e:
             return JsonResponse({'success': False, 'error': str(e)})
 
-def extract_title_or_error(product,selected_pt):
-    # 1. Identify Product Type from JSON to fetch the correct Mapping
+# def extract_title_or_error(product,selected_pt):
+#     # 1. Identify Product Type from JSON to fetch the correct Mapping
+#     pt_name = selected_pt
+#     try:
+#         mapping = TitleMapping.objects.get(product_type=pt_name)
+#         config_sequence = mapping.get_sequence_list()
+#     except TitleMapping.DoesNotExist:
+#         return f"No Title Configuration found for Product Type: {pt_name}"
+
+#     # 2. Get Mandatory list from DB
+#     mandatory_fields = list(AttributeMaster.objects.filter(is_mandatory=True).values_list('name', flat=True))
+
+#     # 3. Data Extraction (Your logic)
+#     extracted_data = {
+#         "Brand": product.get("brand"),
+#         "Product Type": pt_name
+#     }
+#     dimensions = {}
+
+#     for group in product.get("attributeGroups", []):
+#         for attr in group.get("attributes", []):
+#             desc = attr.get("attributeDesc")
+#             value = attr.get("attributeValue")
+            
+#             if desc == "Capacity":
+#                 extracted_data[desc] = f"Capacity {value}"
+#             if desc in ["Door Type", "Capacity", "Color"]:
+#                 extracted_data[desc] = value
+#             elif desc in ["Width", "Depth", "Height"]:
+#                 dimensions[desc] = value
+
+#     if {"Width", "Depth", "Height"}.issubset(dimensions):
+#         # extracted_data["Dimensions"] = f'{dimensions["Width"]} x {dimensions["Depth"]} x {dimensions["Height"]}'
+#         w, d, h = dimensions["Width"], dimensions["Depth"], dimensions["Height"]
+#         extracted_data["Dimensions"] = f'{w}"w x {d}"d x {h}"h'
+
+#     # 4. Build Title and Check Mandatory Rules from DB
+#     final_title_parts = []
+#     missing_mandatory = []
+
+#     for attr_name in config_sequence:
+#         val = extracted_data.get(attr_name)
+        
+#         if not val or str(val).strip() == "":
+#             # If DB says it's mandatory, track the error
+#             if attr_name in mandatory_fields:
+#                 missing_mandatory.append(attr_name)
+#             continue 
+            
+#         final_title_parts.append(str(val))
+
+#     # 5. Result
+#     if missing_mandatory:
+#         return f"Could not found {', '.join(missing_mandatory)} on Product Details page"
+    
+#     return " ".join(final_title_parts)
+
+
+def extract_title_or_error(product, selected_pt):
+    # 1. Identify Product Type
     pt_name = selected_pt
     try:
         mapping = TitleMapping.objects.get(product_type=pt_name)
@@ -142,12 +200,11 @@ def extract_title_or_error(product,selected_pt):
     except TitleMapping.DoesNotExist:
         return f"No Title Configuration found for Product Type: {pt_name}"
 
-    # 2. Get Mandatory list from DB
     mandatory_fields = list(AttributeMaster.objects.filter(is_mandatory=True).values_list('name', flat=True))
 
-    # 3. Data Extraction (Your logic)
+    # 2. Data Extraction
     extracted_data = {
-        "Brand": product.get("brand"),
+        "Brand": product.get("brand")+"©",
         "Product Type": pt_name
     }
     dimensions = {}
@@ -155,36 +212,76 @@ def extract_title_or_error(product,selected_pt):
     for group in product.get("attributeGroups", []):
         for attr in group.get("attributes", []):
             desc = attr.get("attributeDesc")
-            value = attr.get("attributeValue")
+            val = attr.get("attributeValue")
             
-            if desc in ["Door Type", "Capacity", "Color"]:
-                extracted_data[desc] = value
+            if desc == "Capacity":
+                extracted_data[desc] = f"Capacity {val}"
+            elif desc in ["Door Type", "Color"]:
+                extracted_data[desc] = val
             elif desc in ["Width", "Depth", "Height"]:
-                dimensions[desc] = value
+                dimensions[desc] = val
 
     if {"Width", "Depth", "Height"}.issubset(dimensions):
-        extracted_data["Dimensions"] = f'{dimensions["Width"]} x {dimensions["Depth"]} x {dimensions["Height"]}'
-
-    # 4. Build Title and Check Mandatory Rules from DB
+        w, d, h = dimensions["Width"], dimensions["Depth"], dimensions["Height"]
+        # We use .replace(" in", "") to remove the existing unit before adding the " symbol
+        w = dimensions["Width"].replace(" in", "").strip()
+        d = dimensions["Depth"].replace(" in", "").strip()
+        h = dimensions["Height"].replace(" in", "").strip()
+        extracted_data["Dimensions"] = f'{w}"w x {d}"d x {h}"h'
+
+    # 3. Build Title Parts
     final_title_parts = []
     missing_mandatory = []
 
     for attr_name in config_sequence:
         val = extracted_data.get(attr_name)
-        
         if not val or str(val).strip() == "":
-            # If DB says it's mandatory, track the error
             if attr_name in mandatory_fields:
                 missing_mandatory.append(attr_name)
             continue 
-            
         final_title_parts.append(str(val))
 
-    # 5. Result
     if missing_mandatory:
         return f"Could not found {', '.join(missing_mandatory)} on Product Details page"
+
+    # Helper function to join parts: Brand PT, Param1, Param2
+    def construct_string(parts):
+        if len(parts) <= 2:
+            return " ".join(parts)
+        return f"{parts[0]} {parts[1]}, {', '.join(parts[2:])}"
+
+    current_title = construct_string(final_title_parts)
+
+    # 4. Length Reduction Logic (Step-by-Step)
     
-    return " ".join(final_title_parts)
+    # Step 1: Change "Capacity" -> "Cap."
+    if len(current_title) > 100:
+        for i, part in enumerate(final_title_parts):
+            if "Capacity" in part:
+                final_title_parts[i] = part.replace("Capacity", "Cap.")
+        current_title = construct_string(final_title_parts)
+
+    # Step 2: Shorten Product Type (e.g., Stainless Steel -> SS)
+    # Step B: Dynamic Product Type Acronym
+    if len(current_title) > 100:
+        pt_part = final_title_parts[1]
+        words = pt_part.split()
+        if len(words) > 1:
+            # Takes first letter of every word in the Product Type
+            final_title_parts[1] = "".join([w[0].upper() for w in words])
+            current_title = construct_string(final_title_parts)
+
+    # Step 3: Remove spaces from attributes starting from the back
+    # Brand (0) and Product Type (1) are skipped
+    if len(current_title) > 100:
+        for i in range(len(final_title_parts) - 1, 1, -1):
+            if len(current_title) <= 100:
+                break
+            # Remove white spaces from the current attribute part
+            final_title_parts[i] = final_title_parts[i].replace(" ", "")
+            current_title = construct_string(final_title_parts)
+
+    return current_title
 
 def construct_dynamic_title(raw_data,selected_pt):
     try:
@@ -266,42 +363,6 @@ def title_creator_view(request):
     return render(request, 'title_creator_index.html', {'product_types': product_types})
     # return render(request, 'title_creator_index.html')
 
-# def process_excel_task(file_path, selected_pt, task_id):
-#     task = ProcessingTask.objects.get(task_id=task_id)
-#     try:
-#         df = pd.read_excel(file_path)
-#         if 'New_Generated_Title' not in df.columns:
-#             df['New_Generated_Title'] = ""
-
-#         headers = {"User-Agent": "Mozilla/5.0"}
-
-#         for index, row in df.iterrows():
-#             url = row.get('URL')
-#             # ... [Insert your existing BeautifulSoup/Scraping Logic Here] ...
-#             # Example:
-#             # new_title = construct_dynamic_title(raw_data, selected_pt)
-#             # df.at[index, 'New_Generated_Title'] = new_title
-#             time.sleep(1) 
-
-#         # Save Final File
-#         output_filename = f"completed_{task.original_filename}"
-#         from django.conf import settings
-#         output_path = os.path.join(settings.MEDIA_ROOT, output_filename)
-#         df.to_excel(output_path, index=False)
-
-#         # Update Task Status
-#         task.status = 'COMPLETED'
-#         task.download_url = f"{settings.MEDIA_URL}{output_filename}"
-#         task.save()
-
-#     except Exception as e:
-#         task.status = 'FAILED'
-#         task.save()
-#         print(f"Error: {e}")
-#     finally:
-#         if os.path.exists(file_path):
-#             os.remove(file_path)
-
 def process_excel_task(file_path, selected_pt, task_id):
     # Retrieve the task record from the database
     scraper = cloudscraper.create_scraper() # This replaces requests.get
@@ -422,4 +483,24 @@ def check_status(request, task_id):
         'status': task.status,               # 'PENDING', 'COMPLETED', or 'FAILED'
         'file_name': task.original_filename,
         'download_url': task.download_url    # This will be null until status is COMPLETED
-    })
+    })
+
+@login_required
+def title_creator_history_page(request):
+    # Renders the HTML page
+    return render(request, 'title_creator_history.html')
+
+@login_required
+def get_title_creator_tasks_json(request):
+    # Returns the list of tasks as JSON for the history table
+    tasks = ProcessingTask.objects.all().order_by('-created_at')[:50]  # Latest 50 tasks
+    data = []
+    for t in tasks:
+        data.append({
+            'task_id': t.task_id,
+            'filename': t.original_filename or "Unknown File",
+            'status': t.status,
+            'url': t.download_url,
+            'date': t.created_at.strftime("%d %b %Y, %I:%M %p")
+        })
+    return JsonResponse(data, safe=False)

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác