Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>{% block title %}MV+{% endblock %}</title> | |
| <link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}"> | |
| <!-- Critical inline CSS to prevent white flash - MUST be first --> | |
| <style> | |
| /* Prevent FOUC (Flash of Unstyled Content) - Maximum aggressive approach */ | |
| html { | |
| background: #0a0a0a ; | |
| background-color: #0a0a0a ; | |
| overflow-x: hidden; | |
| } | |
| html, body { | |
| background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0d1b1b 100%) ; | |
| background-color: #0a0a0a ; | |
| margin: 0 ; | |
| padding: 0 ; | |
| width: 100% ; | |
| height: 100% ; | |
| } | |
| body { | |
| color: #ffffff; | |
| font-family: 'Times New Roman', serif; | |
| min-height: 100vh; | |
| opacity: 1 ; | |
| visibility: visible ; | |
| } | |
| #app { | |
| min-height: 100vh; | |
| background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0d1b1b 100%); | |
| background-color: #0a0a0a; | |
| opacity: 1; | |
| } | |
| /* Ensure navbar has background immediately */ | |
| .navbar { | |
| background: rgba(0, 0, 0, 0.95) ; | |
| background-color: rgba(0, 0, 0, 0.95) ; | |
| } | |
| /* Ensure main content has background */ | |
| .main-content { | |
| background: transparent; | |
| } | |
| </style> | |
| <!-- Preload critical CSS --> | |
| <link rel="preload" href="{{ url_for('static', filename='css/style.css') }}" as="style"> | |
| <!-- External stylesheets --> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet"> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css" rel="stylesheet"> | |
| <!-- Main stylesheet --> | |
| <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> | |
| {% if request.endpoint and 'version_control' in request.endpoint %} | |
| <link rel="stylesheet" href="{{ url_for('static', filename='css/version_control.css') }}"> | |
| {% endif %} | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <nav class="navbar"> | |
| <div class="nav-container"> | |
| <div class="nav-logo"> | |
| <a href="/" class="nav-logo-link"> | |
| <span>MV+</span> | |
| </a> | |
| </div> | |
| <div class="nav-menu"> | |
| <a href="/" class="nav-link {% if request.endpoint == 'home' %}active{% endif %}"> | |
| Home | |
| </a> | |
| <div class="nav-dropdown"> | |
| <span class="nav-link nav-dropdown-trigger {% if request.endpoint and 'demos' in request.endpoint %}active{% endif %}" style="cursor: pointer;"> | |
| Projects | |
| </span> | |
| <div class="nav-dropdown-content"> | |
| <a href="/demos" class="nav-link">Demos</a> | |
| </div> | |
| </div> | |
| <a href="/articles" class="nav-link {% if request.endpoint == 'articles' or request.endpoint == 'article_detail' %}active{% endif %}"> | |
| Articles | |
| </a> | |
| <a href="/about" class="nav-link {% if request.endpoint == 'about' %}active{% endif %}"> | |
| About | |
| </a> | |
| {% if session.user_id %} | |
| <div class="user-menu"> | |
| <span class="user-greeting">Welcome, {{ session.username }}</span> | |
| <a href="/logout" class="nav-link logout-link">Logout</a> | |
| </div> | |
| {% endif %} | |
| </div> | |
| </div> | |
| </nav> | |
| <main class="main-content"> | |
| {% block content %}{% endblock %} | |
| </main> | |
| <footer class="footer"> | |
| <div class="footer-content"> | |
| <div class="visitor-stats"> | |
| <div class="stat-item"> | |
| <span>Total Visitors: {{ stats.total_visitors }}</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span>Unique Visitors: {{ stats.unique_visitors }}</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span>Countries: {{ stats.countries|length }}</span> | |
| </div> | |
| </div> | |
| <div class="footer-text"> | |
| <p>© 2026 MV+</p> | |
| </div> | |
| </div> | |
| </footer> | |
| </div> | |
| <script> | |
| // Suppress SSE-related errors from Hugging Face UI components | |
| (function() { | |
| // Helper function to check if error is SSE-related | |
| function isSSERelatedError(message, filename, stack) { | |
| const fullText = [message, filename, stack].filter(Boolean).join(' ').toLowerCase(); | |
| return fullText.includes('sse') || | |
| fullText.includes('server-sent events') || | |
| fullText.includes('space status') || | |
| fullText.includes('error in input stream') || | |
| fullText.includes('sse stream ended') || | |
| fullText.includes('spaceheader') || | |
| fullText.includes('operation was aborted') || | |
| fullText.includes('domexception') || | |
| fullText.includes('kube-08e8472') || | |
| (filename && (filename.includes('SpaceHeader') || filename.includes('index.js'))); | |
| } | |
| // Override console.error to filter out SSE-related errors | |
| const originalConsoleError = console.error; | |
| console.error = function(...args) { | |
| const errorMessage = args.join(' '); | |
| const stack = new Error().stack || ''; | |
| // Suppress SSE-related errors from Hugging Face UI | |
| if (isSSERelatedError(errorMessage, '', stack)) { | |
| // Silently ignore these errors | |
| return; | |
| } | |
| // Call original console.error for other errors | |
| originalConsoleError.apply(console, args); | |
| }; | |
| // Handle unhandled promise rejections related to SSE | |
| window.addEventListener('unhandledrejection', function(event) { | |
| const reason = event.reason; | |
| const errorMessage = reason?.message || String(reason || ''); | |
| const stack = reason?.stack || ''; | |
| if (isSSERelatedError(errorMessage, '', stack)) { | |
| event.preventDefault(); // Suppress the error | |
| return; | |
| } | |
| }, true); | |
| // Handle general errors related to SSE | |
| window.addEventListener('error', function(event) { | |
| const errorMessage = event.message || String(event.error || ''); | |
| const filename = event.filename || ''; | |
| const stack = event.error?.stack || ''; | |
| if (isSSERelatedError(errorMessage, filename, stack)) { | |
| event.preventDefault(); // Suppress the error | |
| return false; | |
| } | |
| }, true); | |
| // Also suppress console.warn for SSE-related messages | |
| const originalConsoleWarn = console.warn; | |
| console.warn = function(...args) { | |
| const errorMessage = args.join(' '); | |
| if (isSSERelatedError(errorMessage, '', '')) { | |
| return; | |
| } | |
| originalConsoleWarn.apply(console, args); | |
| }; | |
| })(); | |
| // Prevent white flash during page transitions | |
| (function() { | |
| // Set background immediately, even before DOM is ready | |
| if (document.documentElement) { | |
| document.documentElement.style.backgroundColor = '#0a0a0a'; | |
| } | |
| if (document.body) { | |
| document.body.style.backgroundColor = '#0a0a0a'; | |
| } | |
| // Ensure background is maintained during navigation | |
| function setBackground() { | |
| document.documentElement.style.backgroundColor = '#0a0a0a'; | |
| document.body.style.backgroundColor = '#0a0a0a'; | |
| const app = document.getElementById('app'); | |
| if (app) { | |
| app.style.backgroundColor = '#0a0a0a'; | |
| } | |
| } | |
| // Set immediately | |
| setBackground(); | |
| // Set on DOM ready | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', setBackground); | |
| } else { | |
| setBackground(); | |
| } | |
| // Set on page load | |
| window.addEventListener('load', setBackground); | |
| // Set on page show (for back/forward navigation) | |
| window.addEventListener('pageshow', function(event) { | |
| setBackground(); | |
| // Force repaint to prevent flash | |
| if (event.persisted) { | |
| document.body.style.display = 'none'; | |
| document.body.offsetHeight; // Trigger reflow | |
| document.body.style.display = ''; | |
| } | |
| }); | |
| // Set on page visibility change | |
| document.addEventListener('visibilitychange', function() { | |
| if (!document.hidden) { | |
| setBackground(); | |
| } | |
| }); | |
| })(); | |
| </script> | |
| <script src="{{ url_for('static', filename='js/main.js') }}" defer></script> | |
| {% block scripts %}{% endblock %} | |
| </body> | |
| </html> | |