Objective: Design and develop a mobile application or web-based dashboard for the real-time visualization of Network Survey Vehicle (NSV) data during site inspections and for remote access by engineers, auditors, or NHAI officials. 🧠 Prompt to Build the Project Build an AI- and GIS-enabled mobile/web application that can: Ingest NSV pavement condition data (including geo-stamped distress metrics like roughness, rutting, ravelling, and cracking). Play synchronized dashboard camera footage alongside the map to match the road segment being inspected. Display interactive, lane-wise maps with color-coded pavement conditions using GPS coordinates. Allow filtering by distress type, severity level, road ID, date, or segment length. Show charts or trend visualizations of pavement health across time and routes. Include a summary dashboard showing statistics like: % of road network with critical damage Top 5 damaged segments Pavement Health Index per route Enable report export (PDF/CSV) and real-time notes or tagging by field inspectors. Be optimized for use on mobile phones or tablets by highway engineers in the field. ⚙️ Technology Stack Suggestions: Frontend: React Native or Flutter (for mobile); React.js or Vue.js (for web) Mapping/GIS: Leaflet.js / Mapbox / Google Maps API Backend: Node.js or Python (Flask/Django) Database: PostgreSQL with PostGIS for spatial queries Video Syncing: HTML5 video + timeline mapping logic Optional: Machine Learning for auto-identification of damage segments from video (advanced) 📥 Input Data: Geo-stamped CSV reports (with latitude, longitude, distress type, severity, etc.) Dashboard video footage (MP4 format) 📤 Expected Deliverables: Fully functional prototype or demo app (APK or live link) Source code (well-documented) Concept note / documentation describing: Architecture Data flow Visualization logic Tools/libraries used Presentation deck for demo day (PDF/Slides) 🎯 Goals: Help NHAI engineers view and assess NSV reports in real-time in an intuitive and efficient manner. Reduce manual effort in identifying road distress during inspection. Improve response time and data interpretation for remote decision-making. 🏆 Optimize for: Innovation (UI, visualization techniques, video-data integration) Feasibility (working MVP within 7 days) Scalability (can scale to pan-India highway data) User Experience (field usability, offline mode optional) 🔗 Sample Data Reference: https://drive.google.com/drive/folders/1TZ8eVn24W-iLkBIlFR3O9PSH4mnnd8w?usp=sharing 📣 Bonus Tips for Your Hackathon Team Assign roles: Backend, frontend, data integration, presentation. Start with basic map + data point plotting → then sync with video. Keep UI clean, intuitive, mobile-friendly. Highlight unique features in your submission deck (e.g., AI tagging, heatmaps, etc.). Include a short demo video if possible during submission. - Initial Deployment
91c2a0b verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>NSV Dashboard - Road Inspection Analytics</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> | |
| <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <style> | |
| #map { height: 400px; } | |
| .video-container { position: relative; } | |
| .video-timeline { height: 4px; background: #e2e8f0; } | |
| .video-progress { height: 100%; background: #3b82f6; width: 0%; } | |
| .distress-marker { width: 12px; height: 12px; border-radius: 50%; } | |
| .lane-path { stroke-width: 8; stroke-linecap: round; } | |
| .sidebar { | |
| scrollbar-width: thin; | |
| scrollbar-color: #cbd5e0 #f1f5f9; | |
| } | |
| .sidebar::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| .sidebar::-webkit-scrollbar-track { | |
| background: #f1f5f9; | |
| } | |
| .sidebar::-webkit-scrollbar-thumb { | |
| background-color: #cbd5e0; | |
| border-radius: 3px; | |
| } | |
| @media (max-width: 768px) { | |
| .mobile-flex-col { | |
| flex-direction: column; | |
| } | |
| #map { | |
| height: 300px; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 font-sans"> | |
| <div class="flex flex-col min-h-screen"> | |
| <!-- Header --> | |
| <header class="bg-blue-800 text-white shadow-md"> | |
| <div class="container mx-auto px-4 py-3 flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" /> | |
| </svg> | |
| <h1 class="text-xl font-bold">NSV Dashboard</h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="hidden md:flex items-center space-x-2"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /> | |
| </svg> | |
| <span>Engineer</span> | |
| </div> | |
| <button class="p-1 rounded-full bg-blue-700"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="flex-1 container mx-auto px-4 py-6"> | |
| <div class="grid grid-cols-1 lg:grid-cols-4 gap-6"> | |
| <!-- Sidebar --> | |
| <div class="lg:col-span-1 bg-white rounded-lg shadow-md p-4 sidebar overflow-y-auto max-h-screen"> | |
| <h2 class="text-lg font-semibold mb-4 text-gray-800">Filters</h2> | |
| <div class="space-y-4"> | |
| <!-- Date Range --> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Date Range</label> | |
| <div class="flex space-x-2"> | |
| <input type="date" class="w-full p-2 border border-gray-300 rounded-md text-sm"> | |
| <input type="date" class="w-full p-2 border border-gray-300 rounded-md text-sm"> | |
| </div> | |
| </div> | |
| <!-- Road ID --> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Road ID</label> | |
| <select class="w-full p-2 border border-gray-300 rounded-md text-sm"> | |
| <option>All Roads</option> | |
| <option>NH-48</option> | |
| <option>NH-44</option> | |
| <option>NH-19</option> | |
| </select> | |
| </div> | |
| <!-- Distress Type --> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Distress Type</label> | |
| <select class="w-full p-2 border border-gray-300 rounded-md text-sm"> | |
| <option>All Types</option> | |
| <option>Cracking</option> | |
| <option>Rutting</option> | |
| <option>Roughness</option> | |
| <option>Ravelling</option> | |
| </select> | |
| </div> | |
| <!-- Severity Level --> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Severity Level</label> | |
| <div class="flex space-x-2"> | |
| <button class="px-3 py-1 bg-red-100 text-red-800 rounded-full text-xs">Critical</button> | |
| <button class="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs">Moderate</button> | |
| <button class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-xs">Minor</button> | |
| </div> | |
| </div> | |
| <!-- Segment Length --> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Segment Length (km)</label> | |
| <input type="range" min="0" max="10" value="5" class="w-full"> | |
| <div class="flex justify-between text-xs text-gray-500"> | |
| <span>0</span> | |
| <span>5</span> | |
| <span>10</span> | |
| </div> | |
| </div> | |
| <!-- Quick Stats --> | |
| <div class="pt-4 border-t border-gray-200"> | |
| <h3 class="text-sm font-medium text-gray-700 mb-2">Quick Stats</h3> | |
| <div class="space-y-2"> | |
| <div class="flex justify-between text-sm"> | |
| <span class="text-gray-600">Total Distance</span> | |
| <span class="font-medium">142.5 km</span> | |
| </div> | |
| <div class="flex justify-between text-sm"> | |
| <span class="text-gray-600">Critical Segments</span> | |
| <span class="font-medium text-red-600">8.2 km (5.8%)</span> | |
| </div> | |
| <div class="flex justify-between text-sm"> | |
| <span class="text-gray-600">Moderate Segments</span> | |
| <span class="font-medium text-yellow-600">24.7 km (17.3%)</span> | |
| </div> | |
| <div class="flex justify-between text-sm"> | |
| <span class="text-gray-600">Pavement Health Index</span> | |
| <span class="font-medium">76.5/100</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Export Buttons --> | |
| <div class="pt-4 border-t border-gray-200"> | |
| <h3 class="text-sm font-medium text-gray-700 mb-2">Export Data</h3> | |
| <div class="flex space-x-2"> | |
| <button class="flex-1 bg-gray-100 hover:bg-gray-200 text-gray-800 py-2 px-3 rounded-md text-sm flex items-center justify-center"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> | |
| </svg> | |
| </button> | |
| <button class="flex-1 bg-gray-100 hover:bg-gray-200 text-gray-800 py-2 px-3 rounded-md text-sm flex items-center justify-center"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> | |
| </svg> | |
| CSV | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content Area --> | |
| <div class="lg:col-span-3 space-y-6"> | |
| <!-- Map and Video Section --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-lg font-semibold text-gray-800">Road Inspection - NH-48 (KM 125 to KM 145)</h2> | |
| <div class="flex space-x-2"> | |
| <button class="p-2 bg-blue-50 text-blue-600 rounded-md"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5v-4m0 4h-4m4 0l-5-5" /> | |
| </svg> | |
| </button> | |
| <button class="p-2 bg-blue-50 text-blue-600 rounded-md"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Map --> | |
| <div id="map" class="w-full rounded-md mb-4"></div> | |
| <!-- Video Player --> | |
| <div class="video-container"> | |
| <video id="inspection-video" class="w-full rounded-md" controls> | |
| <source src="https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4" type="video/mp4"> | |
| Your browser does not support the video tag. | |
| </video> | |
| <div class="video-timeline mt-1"> | |
| <div class="video-progress"></div> | |
| </div> | |
| <div class="flex justify-between text-xs text-gray-500 mt-1"> | |
| <span>KM 125.0</span> | |
| <span>KM 145.0</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Charts and Data Section --> | |
| <div class="mobile-flex-col flex flex-col md:flex-row gap-6"> | |
| <!-- Left Column --> | |
| <div class="flex-1 space-y-6"> | |
| <!-- Distress Distribution --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <h3 class="text-md font-medium text-gray-800 mb-3">Distress Distribution</h3> | |
| <div class="h-64"> | |
| <canvas id="distressChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Top Damaged Segments --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <h3 class="text-md font-medium text-gray-800 mb-3">Top 5 Damaged Segments</h3> | |
| <div class="space-y-3"> | |
| <div class="flex items-center justify-between p-2 bg-red-50 rounded"> | |
| <div class="flex items-center space-x-2"> | |
| <div class="distress-marker bg-red-500"></div> | |
| <span class="text-sm font-medium">NH-48 KM 132.4-132.8</span> | |
| </div> | |
| <span class="text-sm font-medium text-red-600">Severe Cracking</span> | |
| </div> | |
| <div class="flex items-center justify-between p-2 bg-yellow-50 rounded"> | |
| <div class="flex items-center space-x-2"> | |
| <div class="distress-marker bg-yellow-500"></div> | |
| <span class="text-sm font-medium">NH-48 KM 138.1-138.5</span> | |
| </div> | |
| <span class="text-sm font-medium text-yellow-600">Moderate Rutting</span> | |
| </div> | |
| <div class="flex items-center justify-between p-2 bg-red-50 rounded"> | |
| <div class="flex items-center space-x-2"> | |
| <div class="distress-marker bg-red-500"></div> | |
| <span class="text-sm font-medium">NH-48 KM 127.2-127.6</span> | |
| </div> | |
| <span class="text-sm font-medium text-red-600">Severe Ravelling</span> | |
| </div> | |
| <div class="flex items-center justify-between p-2 bg-yellow-50 rounded"> | |
| <div class="flex items-center space-x-2"> | |
| <div class="distress-marker bg-yellow-500"></div> | |
| <span class="text-sm font-medium">NH-48 KM 142.3-142.7</span> | |
| </div> | |
| <span class="text-sm font-medium text-yellow-600">Moderate Roughness</span> | |
| </div> | |
| <div class="flex items-center justify-between p-2 bg-yellow-50 rounded"> | |
| <div class="flex items-center space-x-2"> | |
| <div class="distress-marker bg-yellow-500"></div> | |
| <span class="text-sm font-medium">NH-48 KM 135.8-136.2</span> | |
| </div> | |
| <span class="text-sm font-medium text-yellow-600">Moderate Cracking</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Column --> | |
| <div class="flex-1 space-y-6"> | |
| <!-- Pavement Health Trend --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <h3 class="text-md font-medium text-gray-800 mb-3">Pavement Health Trend</h3> | |
| <div class="h-64"> | |
| <canvas id="healthTrendChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Inspection Notes --> | |
| <div class="bg-white rounded-lg shadow-md p-4"> | |
| <div class="flex justify-between items-center mb-3"> | |
| <h3 class="text-md font-medium text-gray-800">Inspection Notes</h3> | |
| <button class="text-blue-600 text-sm font-medium">Add Note</button> | |
| </div> | |
| <div class="space-y-3"> | |
| <div class="p-3 bg-gray-50 rounded-md border border-gray-200"> | |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> | |
| <span>KM 132.5</span> | |
| <span>2 hours ago</span> | |
| </div> | |
| <p class="text-sm text-gray-700">Severe alligator cracking observed in right lane. Recommend patching and overlay.</p> | |
| <div class="flex mt-2 space-x-2"> | |
| <span class="px-2 py-1 bg-red-100 text-red-800 rounded-full text-xs">Critical</span> | |
| <span class="px-2 py-1 bg-blue-100 text-blue-800 rounded-full text-xs">Cracking</span> | |
| </div> | |
| </div> | |
| <div class="p-3 bg-gray-50 rounded-md border border-gray-200"> | |
| <div class="flex justify-between text-sm text-gray-500 mb-1"> | |
| <span>KM 138.3</span> | |
| <span>3 hours ago</span> | |
| </div> | |
| <p class="text-sm text-gray-700">Moderate rutting in left lane. Monitor and consider milling and resurfacing in next FY.</p> | |
| <div class="flex mt-2 space-x-2"> | |
| <span class="px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs">Moderate</span> | |
| <span class="px-2 py-1 bg-purple-100 text-purple-800 rounded-full text-xs">Rutting</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| <script> | |
| // Initialize Map | |
| const map = L.map('map').setView([28.6139, 77.2090], 12); | |
| L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | |
| attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' | |
| }).addTo(map); | |
| // Sample distress data (would come from API in real app) | |
| const distressData = [ | |
| { lat: 28.6139, lng: 77.2090, type: 'cracking', severity: 'critical', km: 132.5 }, | |
| { lat: 28.6150, lng: 77.2100, type: 'rutting', severity: 'moderate', km: 138.3 }, | |
| { lat: 28.6145, lng: 77.2085, type: 'ravelling', severity: 'critical', km: 127.4 }, | |
| { lat: 28.6142, lng: 77.2095, type: 'roughness', severity: 'moderate', km: 142.5 }, | |
| { lat: 28.6135, lng: 77.2080, type: 'cracking', severity: 'moderate', km: 136.0 } | |
| ]; | |
| // Add distress markers to map | |
| distressData.forEach(point => { | |
| const color = point.severity === 'critical' ? 'red' : point.severity === 'moderate' ? 'orange' : 'green'; | |
| const marker = L.circleMarker([point.lat, point.lng], { | |
| radius: 8, | |
| fillColor: color, | |
| color: '#fff', | |
| weight: 1, | |
| opacity: 1, | |
| fillOpacity: 0.8 | |
| }).addTo(map); | |
| marker.bindPopup(` | |
| <div class="text-sm"> | |
| <div class="font-medium">${point.type.charAt(0).toUpperCase() + point.type.slice(1)}</div> | |
| <div class="text-${color}-600">${point.severity.charAt(0).toUpperCase() + point.severity.slice(1)}</div> | |
| <div>KM: ${point.km}</div> | |
| </div> | |
| `); | |
| }); | |
| // Add a sample road path | |
| const roadPath = [ | |
| [28.6139, 77.2090], | |
| [28.6150, 77.2100], | |
| [28.6160, 77.2110], | |
| [28.6170, 77.2120], | |
| [28.6180, 77.2130] | |
| ]; | |
| L.polyline(roadPath, { | |
| color: '#3b82f6', | |
| weight: 6, | |
| opacity: 0.8 | |
| }).addTo(map); | |
| // Initialize Charts | |
| // Distress Distribution Chart | |
| const distressCtx = document.getElementById('distressChart').getContext('2d'); | |
| const distressChart = new Chart(distressCtx, { | |
| type: 'doughnut', | |
| data: { | |
| labels: ['Cracking', 'Rutting', 'Roughness', 'Ravelling'], | |
| datasets: [{ | |
| data: [35, 25, 20, 20], | |
| backgroundColor: [ | |
| '#EF4444', | |
| '#F59E0B', | |
| '#10B981', | |
| '#8B5CF6' | |
| ], | |
| borderWidth: 0 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| position: 'right' | |
| } | |
| } | |
| } | |
| }); | |
| // Pavement Health Trend Chart | |
| const healthTrendCtx = document.getElementById('healthTrendChart').getContext('2d'); | |
| const healthTrendChart = new Chart(healthTrendCtx, { | |
| type: 'line', | |
| data: { | |
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'], | |
| datasets: [{ | |
| label: 'Pavement Health Index', | |
| data: [82, 80, 78, 77, 76, 75], | |
| fill: false, | |
| borderColor: '#3B82F6', | |
| tension: 0.4, | |
| pointBackgroundColor: '#3B82F6', | |
| pointRadius: 4 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| y: { | |
| beginAtZero: false, | |
| min: 70, | |
| max: 100 | |
| } | |
| }, | |
| plugins: { | |
| legend: { | |
| display: false | |
| } | |
| } | |
| } | |
| }); | |
| // Video and Map Sync | |
| const video = document.getElementById('inspection-video'); | |
| const progressBar = document.querySelector('.video-progress'); | |
| video.addEventListener('timeupdate', () => { | |
| const percent = (video.currentTime / video.duration) * 100; | |
| progressBar.style.width = percent + '%'; | |
| // In a real app, we'd update the map position based on video time | |
| // This would involve matching timestamps with GPS coordinates | |
| }); | |
| // Simulate clicking on a distress marker to show popup | |
| setTimeout(() => { | |
| map.eachLayer(layer => { | |
| if (layer instanceof L.CircleMarker) { | |
| layer.openPopup(); | |
| return false; // break after first marker | |
| } | |
| }); | |
| }, 1000); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Soiler/nhai" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |