privateuserh's picture
Add 3 files
cf4865e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UAP Pulse - Advanced Atmospheric Tracking</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/qrcode.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Space Grotesk', sans-serif;
background-color: #0f172a;
color: #e2e8f0;
}
.post-card {
background: linear-gradient(145deg, #1e293b, #0f172a);
border-left: 3px solid #3b82f6;
transition: transform 0.2s;
}
.post-card:hover {
transform: translateY(-2px);
}
.nav-item {
position: relative;
}
.nav-item::after {
content: '';
position: absolute;
width: 0;
height: 2px;
bottom: 0;
left: 0;
background-color: #3b82f6;
transition: width 0.3s;
}
.nav-item:hover::after {
width: 100%;
}
.typewriter {
overflow: hidden;
border-right: 2px solid #3b82f6;
white-space: nowrap;
animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
}
@keyframes typing {
from { width: 0 }
to { width: 100% }
}
@keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: #3b82f6 }
}
.glow {
text-shadow: 0 0 10px rgba(59, 130, 246, 0.7);
}
/* UAP Scanner Window */
.scanner-window {
position: relative;
width: 100%;
height: 400px;
background-color: #000;
border: 2px solid #3b82f6;
border-radius: 8px;
overflow: hidden;
margin-bottom: 20px;
}
.scanner-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(transparent 70%, rgba(59, 130, 246, 0.1) 100%);
pointer-events: none;
}
.scanner-grid {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
linear-gradient(rgba(59, 130, 246, 0.3) 1px, transparent 1px),
linear-gradient(90deg, rgba(59, 130, 246, 0.3) 1px, transparent 1px);
background-size: 20px 20px;
opacity: 0.5;
}
.scanner-crosshair {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 30px;
height: 30px;
border: 2px solid rgba(255, 0, 0, 0.7);
border-radius: 50%;
}
.scanner-crosshair::before, .scanner-crosshair::after {
content: '';
position: absolute;
background-color: rgba(255, 0, 0, 0.7);
}
.scanner-crosshair::before {
width: 2px;
height: 10px;
top: -12px;
left: 50%;
transform: translateX(-50%);
}
.scanner-crosshair::after {
width: 10px;
height: 2px;
top: 50%;
left: -12px;
transform: translateY(-50%);
}
.scanner-coordinates {
position: absolute;
bottom: 10px;
left: 10px;
background-color: rgba(0, 0, 0, 0.7);
padding: 5px 10px;
border-radius: 4px;
font-family: monospace;
color: #3b82f6;
}
.scanner-controls {
position: absolute;
bottom: 10px;
right: 10px;
display: flex;
gap: 10px;
}
.scanner-btn {
background-color: rgba(59, 130, 246, 0.7);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s;
}
.scanner-btn:hover {
background-color: rgba(59, 130, 246, 1);
transform: scale(1.1);
}
.scanner-btn.active {
background-color: rgba(239, 68, 68, 0.7);
}
.scanner-btn.active:hover {
background-color: rgba(239, 68, 68, 1);
}
.uap-marker {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 10px red;
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
50% { transform: translate(-50%, -50%) scale(1.5); opacity: 0.7; }
100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
.uap-info {
position: absolute;
background-color: rgba(0, 0, 0, 0.8);
border: 1px solid #3b82f6;
border-radius: 4px;
padding: 5px;
color: white;
font-size: 12px;
pointer-events: none;
transform: translate(15px, -50%);
min-width: 120px;
display: none;
}
.uap-info::before {
content: '';
position: absolute;
left: -10px;
top: 50%;
transform: translateY(-50%);
border-width: 5px;
border-style: solid;
border-color: transparent #3b82f6 transparent transparent;
}
/* 3D Viewer */
.viewer-3d {
width: 100%;
height: 400px;
background-color: #000;
border: 2px solid #3b82f6;
border-radius: 8px;
margin-top: 20px;
position: relative;
}
.viewer-controls {
position: absolute;
bottom: 10px;
left: 10px;
z-index: 100;
display: flex;
gap: 10px;
}
.atmosphere-levels {
position: absolute;
right: 10px;
top: 10px;
background-color: rgba(0, 0, 0, 0.7);
padding: 10px;
border-radius: 4px;
color: white;
font-size: 12px;
z-index: 100;
}
.atmosphere-level {
margin-bottom: 5px;
padding-left: 15px;
position: relative;
}
.atmosphere-level::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 10px;
height: 10px;
border-radius: 50%;
}
.troposphere::before { background-color: #3b82f6; }
.stratosphere::before { background-color: #10b981; }
.mesosphere::before { background-color: #f59e0b; }
.thermosphere::before { background-color: #ef4444; }
.exosphere::before { background-color: #8b5cf6; }
/* Shape icons */
.shape-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
}
.triangle {
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 35px solid transparent;
position: relative;
}
.triangle::before {
content: '';
position: absolute;
top: 5px;
left: -20px;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 35px solid white;
filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.9));
}
.triangle::after {
content: '';
position: absolute;
top: 6px;
left: -18px;
width: 0;
height: 0;
border-left: 18px solid transparent;
border-right: 18px solid transparent;
border-bottom: 32px solid #1e293b;
}
/* Measurement Band */
.measurement-band {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.measurement-line {
position: absolute;
background-color: rgba(59, 130, 246, 0.5);
width: 2px;
transform-origin: bottom center;
}
.measurement-label {
position: absolute;
color: white;
font-size: 10px;
background-color: rgba(0, 0, 0, 0.7);
padding: 2px 4px;
border-radius: 3px;
white-space: nowrap;
}
/* Advanced Controls Panel */
.controls-panel {
background-color: rgba(15, 23, 42, 0.9);
border: 1px solid #3b82f6;
border-radius: 8px;
padding: 15px;
margin-top: 20px;
}
.controls-title {
font-size: 18px;
font-weight: 600;
color: #3b82f6;
margin-bottom: 15px;
display: flex;
align-items: center;
}
.control-group {
margin-bottom: 15px;
}
.control-label {
display: block;
margin-bottom: 5px;
font-size: 14px;
color: #e2e8f0;
}
.control-input {
width: 100%;
background-color: #1e293b;
border: 1px solid #334155;
border-radius: 4px;
padding: 8px 12px;
color: white;
}
.control-select {
width: 100%;
background-color: #1e293b;
border: 1px solid #334155;
border-radius: 4px;
padding: 8px 12px;
color: white;
}
.control-btn {
background-color: #3b82f6;
color: white;
border: none;
border-radius: 4px;
padding: 8px 15px;
cursor: pointer;
transition: background-color 0.2s;
}
.control-btn:hover {
background-color: #2563eb;
}
.slider-container {
display: flex;
align-items: center;
gap: 10px;
}
.slider-value {
min-width: 40px;
text-align: center;
}
/* Data Visualization */
.data-visualization {
background-color: rgba(15, 23, 42, 0.9);
border: 1px solid #3b82f6;
border-radius: 8px;
padding: 15px;
margin-top: 20px;
}
.data-title {
font-size: 18px;
font-weight: 600;
color: #3b82f6;
margin-bottom: 15px;
display: flex;
align-items: center;
}
.data-value {
font-family: monospace;
color: white;
margin-bottom: 5px;
}
.data-label {
color: #94a3b8;
font-size: 14px;
}
/* Radar Visualization */
.radar-visualization {
width: 100%;
height: 200px;
position: relative;
margin-top: 15px;
}
.radar-circle {
position: absolute;
border: 1px solid rgba(59, 130, 246, 0.3);
border-radius: 50%;
transform: translate(-50%, -50%);
}
.radar-sweep {
position: absolute;
width: 100%;
height: 100%;
clip-path: polygon(50% 50%, 50% 0, 50% 0);
background-color: rgba(59, 130, 246, 0.1);
transform-origin: 50% 50%;
animation: radarSweep 4s linear infinite;
}
@keyframes radarSweep {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.radar-target {
position: absolute;
width: 8px;
height: 8px;
background-color: red;
border-radius: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 5px red;
}
</style>
</head>
<body class="min-h-screen">
<!-- Header -->
<header class="bg-gradient-to-r from-blue-900 to-slate-900 shadow-lg">
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center mb-4 md:mb-0">
<i class="fas fa-ufo text-3xl text-blue-400 mr-3"></i>
<h1 class="text-2xl md:text-3xl font-bold text-white">
<span class="typewriter glow">UAP PULSE</span>
</h1>
</div>
<nav class="flex space-x-6">
<a href="#" class="nav-item text-blue-300 hover:text-white py-2">Latest</a>
<a href="#" class="nav-item text-blue-300 hover:text-white py-2">Reports</a>
<a href="#" class="nav-item text-blue-300 hover:text-white py-2">Analysis</a>
<a href="#" class="nav-item text-blue-300 hover:text-white py-2">Resources</a>
</nav>
</div>
</div>
</header>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
<!-- UAP Scanner Section -->
<section class="mb-12">
<h2 class="text-xl font-semibold text-white mb-4 flex items-center">
<i class="fas fa-satellite-dish text-blue-400 mr-2"></i> Advanced UAP Tracking System
</h2>
<div class="scanner-window" id="scannerWindow">
<div class="scanner-grid"></div>
<div class="scanner-overlay"></div>
<div class="scanner-crosshair"></div>
<div class="measurement-band" id="measurementBand"></div>
<!-- UAP markers will be added here dynamically -->
<div class="scanner-coordinates" id="scannerCoords">
Lat: 34.5362° | Long: -117.2928° | Alt: 831m | Victorville, CA
</div>
<div class="scanner-controls">
<button class="scanner-btn" id="startScanner" title="Start Scanner">
<i class="fas fa-play"></i>
</button>
<button class="scanner-btn" id="stopScanner" title="Stop Scanner">
<i class="fas fa-stop"></i>
</button>
<button class="scanner-btn" id="captureUAP" title="Capture UAP">
<i class="fas fa-camera"></i>
</button>
<button class="scanner-btn" id="toggleMeasurement" title="Toggle Measurement Band">
<i class="fas fa-ruler-combined"></i>
</button>
</div>
<video id="scannerVideo" autoplay muted playsinline style="display: none;"></video>
<canvas id="scannerCanvas" style="display: none;"></canvas>
</div>
<!-- Advanced Controls Panel -->
<div class="controls-panel">
<h3 class="controls-title">
<i class="fas fa-sliders-h mr-2"></i> Tracking Parameters
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="control-group">
<label class="control-label">Reference Satellite</label>
<select class="control-select" id="satelliteSelect">
<option value="ISS">International Space Station (ISS)</option>
<option value="HST">Hubble Space Telescope (HST)</option>
<option value="GPS">GPS Satellite</option>
<option value="STARLINK">Starlink Satellite</option>
</select>
</div>
<div class="control-group">
<label class="control-label">Measurement Technique</label>
<select class="control-select" id="techniqueSelect">
<option value="triangulation">Triangulation</option>
<option value="ranging">LIDAR Ranging</option>
<option value="radar">Radar Tracking</option>
<option value="stereo">Stereoscopic Imaging</option>
</select>
</div>
<div class="control-group">
<label class="control-label">Atmospheric Correction</label>
<select class="control-select" id="atmosphereSelect">
<option value="standard">Standard Atmosphere</option>
<option value="current">Current Conditions</option>
<option value="none">None</option>
</select>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-4">
<div class="control-group">
<label class="control-label">Elevation Angle (°)</label>
<div class="slider-container">
<input type="range" min="0" max="90" value="45" class="w-full" id="elevationSlider">
<span class="slider-value" id="elevationValue">45</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Azimuth Angle (°)</label>
<div class="slider-container">
<input type="range" min="0" max="360" value="180" class="w-full" id="azimuthSlider">
<span class="slider-value" id="azimuthValue">180</span>
</div>
</div>
</div>
<div class="flex justify-end mt-4">
<button class="control-btn" id="calculateBtn">
<i class="fas fa-calculator mr-2"></i> Calculate Position
</button>
</div>
</div>
<!-- Data Visualization Panel -->
<div class="data-visualization">
<h3 class="data-title">
<i class="fas fa-chart-line mr-2"></i> Tracking Data
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<div class="data-label">Object Coordinates</div>
<div class="data-value" id="objCoords">34.5362° N, -117.2928° W</div>
<div class="data-value" id="objAltitude">0.0 km</div>
</div>
<div>
<div class="data-label">Reference Satellite</div>
<div class="data-value" id="satelliteName">ISS</div>
<div class="data-value" id="satelliteDistance">400.0 km</div>
</div>
<div>
<div class="data-label">Measurement Data</div>
<div class="data-value" id="measurementType">Triangulation</div>
<div class="data-value" id="measurementAccuracy">±50 m</div>
</div>
</div>
<!-- Radar Visualization -->
<div class="radar-visualization" id="radarVisualization">
<div class="radar-circle" style="width: 40%; height: 40%; top: 50%; left: 50%;"></div>
<div class="radar-circle" style="width: 70%; height: 70%; top: 50%; left: 50%;"></div>
<div class="radar-circle" style="width: 100%; height: 100%; top: 50%; left: 50%;"></div>
<div class="radar-sweep"></div>
<div class="radar-target" style="top: 30%; left: 40%;"></div>
<div class="radar-target" style="top: 60%; left: 70%;"></div>
</div>
</div>
<!-- 3D Viewer -->
<div class="viewer-3d" id="viewer3d">
<div class="viewer-controls">
<button class="scanner-btn" id="resetView" title="Reset View">
<i class="fas fa-crosshairs"></i>
</button>
<button class="scanner-btn" id="toggleOrbit" title="Toggle Orbit Controls">
<i class="fas fa-globe"></i>
</button>
<button class="scanner-btn" id="toggleAtmosphere" title="Toggle Atmosphere Layers">
<i class="fas fa-layer-group"></i>
</button>
</div>
<div class="atmosphere-levels">
<div class="atmosphere-level troposphere">Troposphere (0-12km)</div>
<div class="atmosphere-level stratosphere">Stratosphere (12-50km)</div>
<div class="atmosphere-level mesosphere">Mesosphere (50-85km)</div>
<div class="atmosphere-level thermosphere">Thermosphere (85-600km)</div>
<div class="atmosphere-level exosphere">Exosphere (600km+)</div>
</div>
</div>
<!-- Detected UAPs List -->
<div class="mt-6 bg-slate-800/50 rounded-lg p-4 border border-slate-700">
<h3 class="font-medium text-white mb-3 flex items-center">
<i class="fas fa-list-ul text-blue-400 mr-2"></i> Tracked Objects
</h3>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-700">
<thead>
<tr>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">ID</th>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">Type</th>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">Coordinates</th>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">Altitude</th>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">Layer</th>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">Velocity</th>
<th class="px-4 py-2 text-left text-xs font-medium text-slate-300 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody id="uapTableBody" class="divide-y divide-slate-700">
<!-- UAP entries will be added here dynamically -->
</tbody>
</table>
</div>
</div>
</section>
<!-- Featured Post -->
<section class="mb-12">
<div class="bg-gradient-to-br from-blue-900/50 to-slate-900/50 rounded-xl p-6 shadow-xl border border-blue-800/30">
<div class="flex items-center mb-4">
<span class="bg-blue-500 text-white text-xs font-semibold px-2.5 py-0.5 rounded">BREAKING</span>
<span class="text-blue-300 text-sm ml-2">June 2024</span>
</div>
<h2 class="text-xl md:text-2xl font-bold text-white mb-3">New Atmospheric Tracking System Deployed in Victorville</h2>
<p class="text-blue-100 mb-4">"The advanced measurement system combines satellite triangulation with ground-based sensors to precisely track unidentified aerial phenomena across all atmospheric layers" - Project Lead Dr. Elena Vasquez.</p>
<div class="flex justify-between items-center">
<span class="text-xs text-blue-300">Source: UAP Research Initiative</span>
<button class="text-blue-400 hover:text-blue-200 text-sm flex items-center" onclick="generateQR('New Atmospheric Tracking System Deployed in Victorville', 'https://uap-pulse.example.com/posts/2024-victorville-tracking')">
<i class="fas fa-qrcode mr-1"></i> QR Code
</button>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="bg-slate-900 mt-16 py-8 border-t border-slate-800">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-4 md:mb-0">
<div class="flex items-center">
<i class="fas fa-ufo text-2xl text-blue-400 mr-2"></i>
<span class="text-xl font-bold text-white">UAP PULSE</span>
</div>
<p class="text-slate-400 text-sm mt-1">Advanced atmospheric tracking and UAP research</p>
</div>
<div class="flex space-x-6">
<a href="#" class="text-slate-400 hover:text-blue-300">
<i class="fab fa-twitter"></i>
</a>
<a href="#" class="text-slate-400 hover:text-blue-300">
<i class="fab fa-facebook"></i>
</a>
<a href="#" class="text-slate-400 hover:text-blue-300">
<i class="fab fa-reddit"></i>
</a>
<a href="#" class="text-slate-400 hover:text-blue-300">
<i class="fas fa-rss"></i>
</a>
</div>
</div>
<div class="border-t border-slate-800 mt-6 pt-6 flex flex-col md:flex-row justify-between items-center">
<p class="text-slate-500 text-sm mb-4 md:mb-0">© 2025 UAP Pulse. All rights reserved. Sponsored by SM+</p>
<div class="flex space-x-4">
<a href="#" class="text-slate-400 hover:text-blue-300 text-sm">Privacy</a>
<a href="#" class="text-slate-400 hover:text-blue-300 text-sm">Terms</a>
<a href="#" class="text-slate-400 hover:text-blue-300 text-sm">Contact</a>
<a href="#" class="text-slate-400 hover:text-blue-300 text-sm">Submit Report</a>
</div>
</div>
</div>
</footer>
<script>
// UAP Scanner and 3D Viewer functionality
document.addEventListener('DOMContentLoaded', function() {
// Scanner variables
const scannerWindow = document.getElementById('scannerWindow');
const scannerVideo = document.getElementById('scannerVideo');
const scannerCanvas = document.getElementById('scannerCanvas');
const scannerCoords = document.getElementById('scannerCoords');
const startScannerBtn = document.getElementById('startScanner');
const stopScannerBtn = document.getElementById('stopScanner');
const captureUAPBtn = document.getElementById('captureUAP');
const toggleMeasurementBtn = document.getElementById('toggleMeasurement');
const uapTableBody = document.getElementById('uapTableBody');
const measurementBand = document.getElementById('measurementBand');
// 3D Viewer variables
const viewer3d = document.getElementById('viewer3d');
const resetViewBtn = document.getElementById('resetView');
const toggleOrbitBtn = document.getElementById('toggleOrbit');
const toggleAtmosphereBtn = document.getElementById('toggleAtmosphere');
// Control panel variables
const satelliteSelect = document.getElementById('satelliteSelect');
const techniqueSelect = document.getElementById('techniqueSelect');
const atmosphereSelect = document.getElementById('atmosphereSelect');
const elevationSlider = document.getElementById('elevationSlider');
const elevationValue = document.getElementById('elevationValue');
const azimuthSlider = document.getElementById('azimuthSlider');
const azimuthValue = document.getElementById('azimuthValue');
const calculateBtn = document.getElementById('calculateBtn');
// Data visualization variables
const objCoords = document.getElementById('objCoords');
const objAltitude = document.getElementById('objAltitude');
const satelliteName = document.getElementById('satelliteName');
const satelliteDistance = document.getElementById('satelliteDistance');
const measurementType = document.getElementById('measurementType');
const measurementAccuracy = document.getElementById('measurementAccuracy');
// Three.js variables
let scene, camera, renderer, controls;
let uapObjects = [];
let orbitEnabled = true;
let atmosphereLayersVisible = true;
// UAP detection variables
let detectedUAPs = [];
let scannerActive = false;
let scanInterval;
let frameCount = 0;
let measurementVisible = false;
// Victorville, CA coordinates (default location)
const viewerLocation = {
lat: 34.5362,
long: -117.2928,
alt: 831 // meters
};
// Satellite data
const satellites = {
ISS: { name: "International Space Station", altitude: 408, color: 0x3b82f6 },
HST: { name: "Hubble Space Telescope", altitude: 540, color: 0x10b981 },
GPS: { name: "GPS Satellite", altitude: 20200, color: 0xf59e0b },
STARLINK: { name: "Starlink Satellite", altitude: 550, color: 0x8b5cf6 }
};
// Measurement techniques
const techniques = {
triangulation: { name: "Triangulation", accuracy: "±50 m" },
ranging: { name: "LIDAR Ranging", accuracy: "±5 m" },
radar: { name: "Radar Tracking", accuracy: "±100 m" },
stereo: { name: "Stereoscopic", accuracy: "±20 m" }
};
// Initialize measurement band
function initMeasurementBand() {
// Clear existing measurement lines
measurementBand.innerHTML = '';
if (!measurementVisible) return;
// Create measurement lines at different angles
const angles = [0, 15, 30, 45, 60, 75, 90];
const distances = [10, 20, 50, 100, 200, 500]; // km
// Create distance circles
distances.forEach(distance => {
const line = document.createElement('div');
line.className = 'measurement-line';
line.style.height = `${distance / 5}%`;
line.style.left = '50%';
line.style.bottom = '50%';
line.style.transform = 'translateX(-50%) rotate(0deg)';
line.style.opacity = '0.3';
measurementBand.appendChild(line);
const label = document.createElement('div');
label.className = 'measurement-label';
label.textContent = `${distance} km`;
label.style.left = '50%';
label.style.bottom = `${50 - distance / 10}%`;
label.style.transform = 'translateX(-50%)';
measurementBand.appendChild(label);
});
// Create angle lines
angles.forEach(angle => {
const line = document.createElement('div');
line.className = 'measurement-line';
line.style.height = '40%';
line.style.left = '50%';
line.style.bottom = '50%';
line.style.transform = `translateX(-50%) rotate(${angle}deg)`;
measurementBand.appendChild(line);
const label = document.createElement('div');
label.className = 'measurement-label';
label.textContent = `${angle}°`;
label.style.left = `${50 + Math.sin(angle * Math.PI / 180) * 20}%`;
label.style.bottom = `${50 - Math.cos(angle * Math.PI / 180) * 20}%`;
measurementBand.appendChild(label);
});
}
// Update measurement visualization
function updateMeasurement() {
const elevation = parseFloat(elevationSlider.value);
const azimuth = parseFloat(azimuthSlider.value);
// Update data display
objAltitude.textContent = `${(elevation * 10).toFixed(1)} km`;
// Calculate "detected" position (simulated)
const lat = viewerLocation.lat + (Math.random() * 0.2 - 0.1);
const long = viewerLocation.long + (Math.random() * 0.2 - 0.1);
objCoords.textContent = `${lat.toFixed(4)}° N, ${long.toFixed(4)}° W`;
// Update satellite info
const selectedSatellite = satelliteSelect.value;
satelliteName.textContent = satellites[selectedSatellite].name;
satelliteDistance.textContent = `${satellites[selectedSatellite].altitude} km`;
// Update technique info
const selectedTechnique = techniqueSelect.value;
measurementType.textContent = techniques[selectedTechnique].name;
measurementAccuracy.textContent = techniques[selectedTechnique].accuracy;
}
// Initialize 3D viewer
function init3DViewer() {
// Create scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
// Create camera
camera = new THREE.PerspectiveCamera(75, viewer3d.clientWidth / viewer3d.clientHeight, 0.1, 10000);
camera.position.z = 50;
// Create renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(viewer3d.clientWidth, viewer3d.clientHeight);
viewer3d.appendChild(renderer.domElement);
// Add controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
// Add ambient light
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
// Add directional light
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
// Add Earth sphere
const geometry = new THREE.SphereGeometry(15, 32, 32);
const material = new THREE.MeshPhongMaterial({
color: 0x3b82f6,
specular: 0x111111,
shininess: 30
});
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);
// Add atmosphere levels as transparent spheres
const addAtmosphereLayer = (radius, color, opacity) => {
const layerGeometry = new THREE.SphereGeometry(radius, 32, 32);
const layerMaterial = new THREE.MeshBasicMaterial({
color: color,
side: THREE.BackSide,
transparent: true,
opacity: opacity
});
const layer = new THREE.Mesh(layerGeometry, layerMaterial);
layer.userData.isAtmosphere = true;
scene.add(layer);
return layer;
};
// Add atmosphere layers (scaled down for visualization)
const troposphere = addAtmosphereLayer(15.5, 0x3b82f6, 0.2); // Troposphere
const stratosphere = addAtmosphereLayer(16, 0x10b981, 0.15); // Stratosphere
const mesosphere = addAtmosphereLayer(16.5, 0xf59e0b, 0.1); // Mesosphere
const thermosphere = addAtmosphereLayer(17.5, 0xef4444, 0.08); // Thermosphere
const exosphere = addAtmosphereLayer(20, 0x8b5cf6, 0.05); // Exosphere
// Add viewer location marker
const viewerMarkerGeometry = new THREE.SphereGeometry(0.3, 16, 16);
const viewerMarkerMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
const viewerMarker = new THREE.Mesh(viewerMarkerGeometry, viewerMarkerMaterial);
// Convert lat/long to 3D position
const phi = (90 - viewerLocation.lat) * (Math.PI / 180);
const theta = (viewerLocation.long + 180) * (Math.PI / 180);
const radius = 15 + viewerLocation.alt / 100000; // Very small offset for surface
viewerMarker.position.set(
radius * Math.sin(phi) * Math.cos(theta),
radius * Math.cos(phi),
radius * Math.sin(phi) * Math.sin(theta)
);
scene.add(viewerMarker);
// Add satellite
function addSatellite(satelliteType) {
// Remove existing satellite
scene.children.forEach(child => {
if (child.userData.isSatellite) {
scene.remove(child);
}
});
const sat = satellites[satelliteType];
const satGeometry = new THREE.BoxGeometry(1, 1, 1);
const satMaterial = new THREE.MeshPhongMaterial({ color: sat.color });
const satellite = new THREE.Mesh(satGeometry, satMaterial);
satellite.userData.isSatellite = true;
// Position satellite in orbit (simplified)
const satRadius = 15 + sat.altitude / 100;
satellite.position.set(satRadius, 0, 0);
satellite.lookAt(0, 0, 0);
scene.add(satellite);
}
// Initial satellite
addSatellite('ISS');
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = viewer3d.clientWidth / viewer3d.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(viewer3d.clientWidth, viewer3d.clientHeight);
});
// Animation loop
function animate() {
requestAnimationFrame(animate);
if (orbitEnabled) {
controls.update();
}
// Rotate satellites
scene.children.forEach(child => {
if (child.userData.isSatellite) {
child.rotation.y += 0.001;
}
});
renderer.render(scene, camera);
}
animate();
// Return functions to control the viewer
return {
addSatellite: addSatellite,
toggleAtmosphere: function(visible) {
scene.children.forEach(child => {
if (child.userData.isAtmosphere) {
child.visible = visible;
}
});
}
};
}
// Initialize scanner
function initScanner() {
// Set up scanner buttons
startScannerBtn.addEventListener('click', startScanner);
stopScannerBtn.addEventListener('click', stopScanner);
captureUAPBtn.addEventListener('click', captureUAP);
toggleMeasurementBtn.addEventListener('click', toggleMeasurement);
// Set up 3D viewer buttons
resetViewBtn.addEventListener('click', resetView);
toggleOrbitBtn.addEventListener('click', toggleOrbitControls);
toggleAtmosphereBtn.addEventListener('click', toggleAtmosphereLayers);
// Set up control panel
elevationSlider.addEventListener('input', function() {
elevationValue.textContent = this.value;
updateMeasurement();
});
azimuthSlider.addEventListener('input', function() {
azimuthValue.textContent = this.value;
updateMeasurement();
});
satelliteSelect.addEventListener('change', function() {
viewer3DControls.addSatellite(this.value);
updateMeasurement();
});
techniqueSelect.addEventListener('change', updateMeasurement);
atmosphereSelect.addEventListener('change', updateMeasurement);
calculateBtn.addEventListener('click', calculatePosition);
// Initialize measurement band
initMeasurementBand();
// Initialize 3D viewer
viewer3DControls = init3DViewer();
// Simulate initial detection
setTimeout(() => {
simulateInitialDetection();
}, 1000);
}
// Toggle measurement band visibility
function toggleMeasurement() {
measurementVisible = !measurementVisible;
toggleMeasurementBtn.classList.toggle('active');
initMeasurementBand();
}
// Toggle atmosphere layers visibility
function toggleAtmosphereLayers() {
atmosphereLayersVisible = !atmosphereLayersVisible;
toggleAtmosphereBtn.classList.toggle('active');
viewer3DControls.toggleAtmosphere(atmosphereLayersVisible);
}
// Calculate position (simulated)
function calculatePosition() {
const elevation = parseFloat(elevationSlider.value);
const azimuth = parseFloat(azimuthSlider.value);
const technique = techniqueSelect.value;
const atmosphere = atmosphereSelect.value;
// Show loading state
calculateBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Calculating...';
calculateBtn.disabled = true;
// Simulate calculation delay
setTimeout(() => {
// Generate random UAP detection
const uapId = 'UAP-' + Date.now().toString().slice(-4);
const shapes = ['triangle', 'circle', 'square', 'cylinder', 'chevron', 'tictac'];
const shape = shapes[Math.floor(Math.random() * shapes.length)];
// Calculate position based on inputs (simplified)
const lat = viewerLocation.lat + (Math.random() * 0.2 - 0.1);
const long = viewerLocation.long + (Math.random() * 0.2 - 0.1);
const altitude = elevation * 10 + (Math.random() * 20 - 10);
// Determine atmosphere layer
let atmosphereLayer, atmosphereColor;
if (altitude < 12) {
atmosphereLayer = 'Troposphere';
atmosphereColor = '#3b82f6';
} else if (altitude < 50) {
atmosphereLayer = 'Stratosphere';
atmosphereColor = '#10b981';
} else if (altitude < 85) {
atmosphereLayer = 'Mesosphere';
atmosphereColor = '#f59e0b';
} else if (altitude < 600) {
atmosphereLayer = 'Thermosphere';
atmosphereColor = '#ef4444';
} else {
atmosphereLayer = 'Exosphere';
atmosphereColor = '#8b5cf6';
}
// Create UAP object
const uap = {
id: uapId,
shape: shape,
lat: lat,
long: long,
altitude: altitude.toFixed(2),
atmosphere: atmosphereLayer,
atmosphereColor: atmosphereColor,
velocity: (Math.random() * 5000 + 500).toFixed(0) + ' km/h',
timestamp: new Date().toLocaleTimeString(),
technique: technique,
satellite: satelliteSelect.value
};
detectedUAPs.push(uap);
addUAPToTable(uap);
addUAPTo3DViewer(uap);
// Reset button
calculateBtn.innerHTML = '<i class="fas fa-calculator mr-2"></i> Calculate Position';
calculateBtn.disabled = false;
// Show success message
alert(`Successfully tracked object ${uapId} at ${altitude.toFixed(2)} km in the ${atmosphereLayer}`);
}, 1500);
}
// Simulate initial detections
function simulateInitialDetection() {
const initialUAPs = [
{
id: 'UAP-1001',
shape: 'triangle',
lat: 34.5362 + 0.05,
long: -117.2928 - 0.03,
altitude: '8.5',
atmosphere: 'Troposphere',
atmosphereColor: '#3b82f6',
velocity: '1200 km/h',
timestamp: new Date().toLocaleTimeString(),
technique: 'radar',
satellite: 'ISS'
},
{
id: 'UAP-1002',
shape: 'tictac',
lat: 34.5362 - 0.12,
long: -117.2928 + 0.08,
altitude: '65.2',
atmosphere: 'Mesosphere',
atmosphereColor: '#f59e0b',
velocity: '3500 km/h',
timestamp: new Date().toLocaleTimeString(),
technique: 'triangulation',
satellite: 'ISS'
},
{
id: 'UAP-1003',
shape: 'circle',
lat: 34.5362 + 0.18,
long: -117.2928 + 0.15,
altitude: '450.0',
atmosphere: 'Thermosphere',
atmosphereColor: '#ef4444',
velocity: '28000 km/h',
timestamp: new Date().toLocaleTimeString(),
technique: 'ranging',
satellite: 'HST'
}
];
initialUAPs.forEach(uap => {
detectedUAPs.push(uap);
addUAPToTable(uap);
addUAPTo3DViewer(uap);
});
}
// Start scanner
function startScanner() {
if (scannerActive) return;
// Request camera access
navigator.mediaDevices.getUserMedia({ video: true })
.then(function(stream) {
scannerVideo.srcObject = stream;
scannerVideo.style.display = 'block';
scannerActive = true;
startScannerBtn.classList.add('active');
// Start detection loop
scanInterval = setInterval(detectUAPs, 100);
})
.catch(function(err) {
console.error("Error accessing camera: ", err);
alert("Could not access camera. Please ensure you've granted camera permissions.");
});
}
// Stop scanner
function stopScanner() {
if (!scannerActive) return;
clearInterval(scanInterval);
const stream = scannerVideo.srcObject;
const tracks = stream.getTracks();
tracks.forEach(function(track) {
track.stop();
});
scannerVideo.srcObject = null;
scannerVideo.style.display = 'none';
scannerActive = false;
startScannerBtn.classList.remove('active');
// Clear any existing UAP markers
clearUAPMarkers();
}
// Detect UAPs in video feed (simulated)
function detectUAPs() {
if (!scannerActive) return;
frameCount++;
// Simulate UAP detection (in a real app, this would use computer vision)
if (frameCount % 30 === 0) {
// Random chance to detect a UAP
if (Math.random() > 0.7) {
const uapId = 'UAP-' + Date.now().toString().slice(-4);
const shapes = ['triangle', 'circle', 'square', 'cylinder', 'chevron', 'tictac'];
const shape = shapes[Math.floor(Math.random() * shapes.length)];
// Random position in scanner window
const x = Math.random() * 80 + 10; // 10-90%
const y = Math.random() * 80 + 10; // 10-90%
// Random altitude (0-1000km)
const altitude = Math.random() * 1000;
// Determine atmosphere layer
let atmosphere, atmosphereColor;
if (altitude < 12) {
atmosphere = 'Troposphere';
atmosphereColor = '#3b82f6';
} else if (altitude < 50) {
atmosphere = 'Stratosphere';
atmosphereColor = '#10b981';
} else if (altitude < 85) {
atmosphere = 'Mesosphere';
atmosphereColor = '#f59e0b';
} else if (altitude < 600) {
atmosphere = 'Thermosphere';
atmosphereColor = '#ef4444';
} else {
atmosphere = 'Exosphere';
atmosphereColor = '#8b5cf6';
}
// Generate random coordinates near user's location (simulated)
const lat = viewerLocation.lat + (Math.random() * 0.2 - 0.1);
const long = viewerLocation.long + (Math.random() * 0.2 - 0.1);
// Create UAP object
const uap = {
id: uapId,
shape: shape,
x: x,
y: y,
lat: lat,
long: long,
altitude: altitude.toFixed(2),
atmosphere: atmosphere,
atmosphereColor: atmosphereColor,
velocity: (Math.random() * 5000 + 500).toFixed(0) + ' km/h',
timestamp: new Date().toLocaleTimeString(),
technique: techniqueSelect.value,
satellite: satelliteSelect.value
};
detectedUAPs.push(uap);
addUAPMarker(uap);
addUAPToTable(uap);
addUAPTo3DViewer(uap);
// Update coordinates display
scannerCoords.textContent = `Lat: ${lat.toFixed(4)}° | Long: ${long.toFixed(4)}° | Alt: ${altitude.toFixed(2)}km | ${atmosphere}`;
}
}
// Simulate movement of existing UAPs
detectedUAPs.forEach(uap => {
// Small random movement
uap.x += (Math.random() - 0.5) * 0.5;
uap.y += (Math.random() - 0.5) * 0.5;
// Update marker position
const marker = document.querySelector(`.uap-marker[data-id="${uap.id}"]`);
if (marker) {
marker.style.left = `${uap.x}%`;
marker.style.top = `${uap.y}%`;
}
// Update 3D position
updateUAPIn3DViewer(uap);
});
}
// Add UAP marker to scanner view
function addUAPMarker(uap) {
const marker = document.createElement('div');
marker.className = 'uap-marker';
marker.dataset.id = uap.id;
marker.style.left = `${uap.x}%`;
marker.style.top = `${uap.y}%`;
marker.style.backgroundColor = uap.atmosphereColor;
marker.style.boxShadow = `0 0 10px ${uap.atmosphereColor}`;
// Add info tooltip
const info = document.createElement('div');
info.className = 'uap-info';
info.innerHTML = `
<strong>${uap.id}</strong><br>
Shape: ${uap.shape}<br>
Alt: ${uap.altitude}km<br>
${uap.atmosphere}
`;
marker.appendChild(info);
// Show info on hover
marker.addEventListener('mouseenter', () => {
info.style.display = 'block';
});
marker.addEventListener('mouseleave', () => {
info.style.display = 'none';
});
scannerWindow.appendChild(marker);
}
// Clear all UAP markers
function clearUAPMarkers() {
document.querySelectorAll('.uap-marker').forEach(marker => {
marker.remove();
});
}
// Add UAP to table
function addUAPToTable(uap) {
const row = document.createElement('tr');
row.className = 'hover:bg-slate-700/50';
row.innerHTML = `
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-white">${uap.id}</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-slate-300">${uap.shape}</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-slate-300">${uap.lat.toFixed(4)}°, ${uap.long.toFixed(4)}°</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-slate-300">${uap.altitude}km</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-slate-300">
<span class="inline-block w-3 h-3 rounded-full mr-1" style="background-color: ${uap.atmosphereColor}"></span>
${uap.atmosphere}
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-slate-300">${uap.velocity}</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-slate-300">
<button class="text-blue-400 hover:text-blue-200 mr-2" onclick="focusUAP('${uap.id}')">
<i class="fas fa-search"></i>
</button>
<button class="text-red-400 hover:text-red-200" onclick="removeUAP('${uap.id}')">
<i class="fas fa-trash"></i>
</button>
</td>
`;
uapTableBody.appendChild(row);
}
// Add UAP to 3D viewer
function addUAPTo3DViewer(uap) {
// Scale down altitude for visualization (Earth radius = 15 units)
const scaledAltitude = parseFloat(uap.altitude) / 1000 * 15 + 15;
// Convert lat/long to 3D position
const phi = (90 - uap.lat) * (Math.PI / 180);
const theta = (uap.long + 180) * (Math.PI / 180);
const x = scaledAltitude * Math.sin(phi) * Math.cos(theta);
const y = scaledAltitude * Math.cos(phi);
const z = scaledAltitude * Math.sin(phi) * Math.sin(theta);
// Create UAP object based on shape
let geometry, material;
switch(uap.shape) {
case 'triangle':
geometry = new THREE.ConeGeometry(0.5, 1, 3);
break;
case 'circle':
geometry = new THREE.SphereGeometry(0.5);
break;
case 'square':
geometry = new THREE.BoxGeometry(0.8, 0.8, 0.8);
break;
case 'cylinder':
geometry = new THREE.CylinderGeometry(0.4, 0.4, 1, 32);
break;
case 'chevron':
// Create a chevron shape using a custom geometry
const chevronShape = new THREE.Shape();
chevronShape.moveTo(-0.5, 0.5);
chevronShape.lineTo(0, -0.5);
chevronShape.lineTo(0.5, 0.5);
geometry = new THREE.ExtrudeGeometry(chevronShape, {
depth: 0.2,
bevelEnabled: false
});
break;
case 'tictac':
geometry = new THREE.CapsuleGeometry(0.3, 1, 4, 8);
break;
default:
geometry = new THREE.SphereGeometry(0.5);
}
material = new THREE.MeshPhongMaterial({
color: new THREE.Color(uap.atmosphereColor),
emissive: new THREE.Color(uap.atmosphereColor),
emissiveIntensity: 0.5,
specular: 0x111111,
shininess: 30
});
const uapObject = new THREE.Mesh(geometry, material);
uapObject.position.set(x, y, z);
uapObject.userData.uapId = uap.id;
// Rotate to face outward from Earth
uapObject.lookAt(0, 0, 0);
// Add to scene
scene.add(uapObject);
// Store reference
uapObjects.push({
id: uap.id,
object: uapObject
});
}
// Update UAP position in 3D viewer
function updateUAPIn3DViewer(uap) {
const uapObj = uapObjects.find(obj => obj.id === uap.id);
if (!uapObj) return;
// Scale down altitude for visualization
const scaledAltitude = parseFloat(uap.altitude) / 1000 * 15 + 15;
// Convert lat/long to 3D position
const phi = (90 - uap.lat) * (Math.PI / 180);
const theta = (uap.long + 180) * (Math.PI / 180);
const x = scaledAltitude * Math.sin(phi) * Math.cos(theta);
const y = scaledAltitude * Math.cos(phi);
const z = scaledAltitude * Math.sin(phi) * Math.sin(theta);
// Update position
uapObj.object.position.set(x, y, z);
// Rotate to face outward from Earth
uapObj.object.lookAt(0, 0, 0);
}
// Capture UAP (take screenshot)
function captureUAP() {
if (!scannerActive || detectedUAPs.length === 0) {
alert("No UAPs detected to capture!");
return;
}
// Get the latest UAP
const uap = detectedUAPs[detectedUAPs.length - 1];
// In a real app, this would capture the actual video frame
// For demo, we'll just show an alert
alert(`Captured UAP ${uap.id}\nShape: ${uap.shape}\nCoordinates: ${uap.lat.toFixed(4)}°, ${uap.long.toFixed(4)}°\nAltitude: ${uap.altitude}km (${uap.atmosphere})`);
// Highlight the UAP in the table
const rows = uapTableBody.querySelectorAll('tr');
rows[rows.length - 1].classList.add('bg-blue-900/30');
setTimeout(() => {
rows[rows.length - 1].classList.remove('bg-blue-900/30');
}, 2000);
}
// Reset 3D view
function resetView() {
camera.position.set(0, 0, 50);
camera.lookAt(0, 0, 0);
controls.target.set(0, 0, 0);
}
// Toggle orbit controls
function toggleOrbitControls() {
orbitEnabled = !orbitEnabled;
controls.enabled = orbitEnabled;
toggleOrbitBtn.classList.toggle('active');
}
// Focus on a specific UAP in 3D view
window.focusUAP = function(uapId) {
const uap = detectedUAPs.find(u => u.id === uapId);
if (!uap) return;
const uapObj = uapObjects.find(obj => obj.id === uapId);
if (!uapObj) return;
// Move camera to view the UAP
const targetPosition = uapObj.object.position.clone();
const cameraPosition = targetPosition.clone().multiplyScalar(1.5);
// Animate camera
gsap.to(camera.position, {
x: cameraPosition.x,
y: cameraPosition.y,
z: cameraPosition.z,
duration: 1,
ease: "power2.inOut"
});
gsap.to(controls.target, {
x: targetPosition.x,
y: targetPosition.y,
z: targetPosition.z,
duration: 1,
ease: "power2.inOut"
});
// Highlight the UAP in the table
const rows = uapTableBody.querySelectorAll('tr');
rows.forEach(row => {
if (row.querySelector('td:first-child').textContent === uapId) {
row.classList.add('bg-blue-900/30');
setTimeout(() => {
row.classList.remove('bg-blue-900/30');
}, 2000);
}
});
};
// Remove a UAP
window.removeUAP = function(uapId) {
// Remove from detected UAPs array
detectedUAPs = detectedUAPs.filter(u => u.id !== uapId);
// Remove from 3D scene
const uapObjIndex = uapObjects.findIndex(obj => obj.id === uapId);
if (uapObjIndex !== -1) {
scene.remove(uapObjects[uapObjIndex].object);
uapObjects.splice(uapObjIndex, 1);
}
// Remove from table
const rows = uapTableBody.querySelectorAll('tr');
rows.forEach(row => {
if (row.querySelector('td:first-child').textContent === uapId) {
row.remove();
}
});
// Remove marker
const marker = document.querySelector(`.uap-marker[data-id="${uapId}"]`);
if (marker) marker.remove();
};
// Generate QR code
function generateQR(title, url) {
const qr = qrcode(0, 'L');
qr.addData(url);
qr.make();
const qrSize = 200;
const qrContainer = document.createElement('div');
qrContainer.style.position = 'fixed';
qrContainer.style.top = '50%';
qrContainer.style.left = '50%';
qrContainer.style.transform = 'translate(-50%, -50%)';
qrContainer.style.backgroundColor = 'white';
qrContainer.style.padding = '20px';
qrContainer.style.borderRadius = '8px';
qrContainer.style.zIndex = '1000';
qrContainer.style.boxShadow = '0 0 20px rgba(0,0,0,0.5)';
const qrTitle = document.createElement('h3');
qrTitle.textContent = title;
qrTitle.style.marginBottom = '10px';
qrTitle.style.textAlign = 'center';
qrContainer.appendChild(qrTitle);
const qrCanvas = qr.createImgTag(4, 0);
qrContainer.innerHTML += qrCanvas;
const closeBtn = document.createElement('button');
closeBtn.textContent = 'Close';
closeBtn.style.display = 'block';
closeBtn.style.margin = '10px auto 0';
closeBtn.style.padding = '5px 15px';
closeBtn.style.backgroundColor = '#3b82f6';
closeBtn.style.color = 'white';
closeBtn.style.border = 'none';
closeBtn.style.borderRadius = '4px';
closeBtn.style.cursor = 'pointer';
closeBtn.addEventListener('click', () => {
document.body.removeChild(qrContainer);
});
qrContainer.appendChild(closeBtn);
document.body.appendChild(qrContainer);
}
// Initialize the scanner
initScanner();
});
</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=privateuserh/privateuserh-uaphe-vbeta1-04" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>