xp12camera
Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/xp12camera.git
add mission generator
Commit 7d86c2791125bfb0f5109a960fcc91e7d56a68fb by SM <seb.michalk@gmail.com> on 2025-06-26 11:09:17 +0200
diff --git a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl
index d1bd2b2..a9f3566 100755
Binary files a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl and b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl differ
diff --git a/mission-generator/css/style.css b/mission-generator/css/style.css
new file mode 100644
index 0000000..07c2910
--- /dev/null
+++ b/mission-generator/css/style.css
@@ -0,0 +1,366 @@
+/* Military Dark Theme */
+:root {
+ --primary-bg: #0d1117;
+ --secondary-bg: #161b22;
+ --tertiary-bg: #21262d;
+ --accent-green: #00ff41;
+ --military-blue: #1e3a5f;
+ --warning-amber: #ffb000;
+ --danger-red: #ff4444;
+ --text-primary: #f0f6fc;
+ --text-secondary: #8b949e;
+ --border-color: #30363d;
+ --hover-bg: #292e36;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ background: var(--primary-bg);
+ color: var(--text-primary);
+ font-family: 'Courier New', 'Monaco', monospace;
+ font-size: 14px;
+ line-height: 1.5;
+ overflow: hidden;
+}
+
+.mission-interface {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+/* Header */
+.mission-header {
+ background: linear-gradient(135deg, var(--secondary-bg), var(--tertiary-bg));
+ border-bottom: 2px solid var(--accent-green);
+ padding: 15px;
+ text-align: center;
+ position: relative;
+}
+
+.mission-header h1 {
+ color: var(--accent-green);
+ font-size: 24px;
+ letter-spacing: 3px;
+ text-shadow: 0 0 10px rgba(0, 255, 65, 0.5);
+ margin-bottom: 5px;
+}
+
+.classification {
+ color: var(--warning-amber);
+ font-size: 12px;
+ letter-spacing: 2px;
+ font-weight: bold;
+}
+
+/* Main Container */
+.main-container {
+ display: flex;
+ flex: 1;
+ height: calc(100vh - 80px);
+}
+
+/* Left Panel - Configuration */
+.config-panel {
+ width: 300px;
+ background: var(--secondary-bg);
+ border-right: 1px solid var(--border-color);
+ padding: 20px;
+ overflow-y: auto;
+}
+
+.panel-section {
+ margin-bottom: 25px;
+}
+
+.panel-section h3 {
+ color: var(--accent-green);
+ font-size: 12px;
+ letter-spacing: 1px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid var(--border-color);
+ padding-bottom: 5px;
+}
+
+.military-select {
+ width: 100%;
+ background: var(--tertiary-bg);
+ border: 1px solid var(--border-color);
+ color: var(--text-primary);
+ padding: 10px;
+ font-family: inherit;
+ font-size: 12px;
+ border-radius: 3px;
+ transition: all 0.3s ease;
+}
+
+.military-select:focus {
+ outline: none;
+ border-color: var(--accent-green);
+ box-shadow: 0 0 5px rgba(0, 255, 65, 0.3);
+}
+
+.military-select option {
+ background: var(--tertiary-bg);
+ color: var(--text-primary);
+}
+
+.airbase-info {
+ margin-top: 10px;
+ padding: 10px;
+ background: var(--tertiary-bg);
+ border-radius: 3px;
+ font-size: 11px;
+ line-height: 1.4;
+ display: none;
+}
+
+.airbase-info.show {
+ display: block;
+}
+
+.airbase-info .info-item {
+ margin-bottom: 5px;
+}
+
+.airbase-info .info-label {
+ color: var(--text-secondary);
+ display: inline-block;
+ width: 80px;
+}
+
+.generate-btn, .export-btn {
+ width: 100%;
+ background: linear-gradient(135deg, var(--military-blue), var(--accent-green));
+ border: none;
+ color: var(--text-primary);
+ padding: 15px;
+ font-family: inherit;
+ font-size: 12px;
+ font-weight: bold;
+ letter-spacing: 1px;
+ border-radius: 3px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ text-transform: uppercase;
+}
+
+.generate-btn:hover, .export-btn:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 5px 15px rgba(0, 255, 65, 0.3);
+}
+
+/* Center Panel - Map */
+.map-panel {
+ flex: 1;
+ position: relative;
+ background: var(--tertiary-bg);
+}
+
+.world-map {
+ width: 100%;
+ height: 100%;
+}
+
+.map-legend {
+ position: absolute;
+ bottom: 20px;
+ left: 20px;
+ background: rgba(33, 38, 45, 0.9);
+ border: 1px solid var(--border-color);
+ border-radius: 3px;
+ padding: 15px;
+ backdrop-filter: blur(5px);
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+ margin-bottom: 8px;
+ font-size: 11px;
+}
+
+.legend-color {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ margin-right: 8px;
+}
+
+.legend-color.airbase {
+ background: var(--accent-green);
+ box-shadow: 0 0 5px rgba(0, 255, 65, 0.5);
+}
+
+.legend-color.patrol-zone {
+ background: var(--military-blue);
+ box-shadow: 0 0 5px rgba(30, 58, 95, 0.5);
+}
+
+/* Right Panel - Briefing */
+.briefing-panel {
+ width: 400px;
+ background: var(--secondary-bg);
+ border-left: 1px solid var(--border-color);
+ display: flex;
+ flex-direction: column;
+}
+
+.briefing-display {
+ flex: 1;
+ padding: 20px;
+ overflow-y: auto;
+ font-size: 11px;
+ line-height: 1.6;
+}
+
+.briefing-placeholder h3 {
+ color: var(--accent-green);
+ margin-bottom: 15px;
+ text-align: center;
+ letter-spacing: 1px;
+}
+
+.briefing-placeholder p {
+ color: var(--text-secondary);
+ margin-bottom: 20px;
+ text-align: center;
+}
+
+.flir-info {
+ background: var(--tertiary-bg);
+ border: 1px solid var(--border-color);
+ border-radius: 3px;
+ padding: 15px;
+ margin-top: 20px;
+}
+
+.flir-info h4 {
+ color: var(--warning-amber);
+ margin-bottom: 10px;
+ font-size: 10px;
+ letter-spacing: 1px;
+}
+
+.flir-info ul {
+ list-style: none;
+ padding-left: 0;
+}
+
+.flir-info li {
+ margin-bottom: 5px;
+ color: var(--text-secondary);
+}
+
+.flir-info li::before {
+ content: "▶ ";
+ color: var(--accent-green);
+ margin-right: 5px;
+}
+
+.export-btn {
+ margin: 20px;
+ margin-top: 0;
+}
+
+/* Mission Briefing Styles */
+.mission-briefing {
+ font-family: 'Courier New', monospace;
+ white-space: pre-line;
+ color: var(--text-primary);
+}
+
+.mission-briefing .briefing-header {
+ color: var(--accent-green);
+ text-align: center;
+ margin-bottom: 20px;
+ font-weight: bold;
+ text-shadow: 0 0 5px rgba(0, 255, 65, 0.3);
+}
+
+.mission-briefing .section-header {
+ color: var(--warning-amber);
+ font-weight: bold;
+ margin: 15px 0 5px 0;
+}
+
+.mission-briefing .objective-item {
+ color: var(--text-secondary);
+ margin-left: 15px;
+}
+
+.mission-briefing .objective-item::before {
+ content: "▶ ";
+ color: var(--accent-green);
+}
+
+.mission-briefing .coordinates {
+ color: var(--military-blue);
+ background: var(--tertiary-bg);
+ padding: 2px 6px;
+ border-radius: 2px;
+ font-weight: bold;
+}
+
+.mission-briefing .frequency {
+ color: var(--accent-green);
+ font-weight: bold;
+}
+
+.mission-briefing .auth-code {
+ color: var(--danger-red);
+ font-weight: bold;
+ background: var(--tertiary-bg);
+ padding: 2px 6px;
+ border-radius: 2px;
+}
+
+/* Responsive Design */
+@media (max-width: 1200px) {
+ .config-panel {
+ width: 250px;
+ }
+
+ .briefing-panel {
+ width: 350px;
+ }
+}
+
+@media (max-width: 900px) {
+ .main-container {
+ flex-direction: column;
+ }
+
+ .config-panel,
+ .briefing-panel {
+ width: 100%;
+ height: 200px;
+ }
+
+ .map-panel {
+ height: calc(100vh - 480px);
+ }
+}
+
+/* Scrollbar Styling */
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: var(--primary-bg);
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--border-color);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--accent-green);
+}
\ No newline at end of file
diff --git a/mission-generator/index.html b/mission-generator/index.html
new file mode 100644
index 0000000..8fd0c28
--- /dev/null
+++ b/mission-generator/index.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Maritime Patrol Mission Generator</title>
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
+ <link rel="stylesheet" href="css/style.css">
+</head>
+<body>
+ <div class="mission-interface">
+ <header class="mission-header">
+ <h1>MARITIME PATROL MISSION GENERATOR</h1>
+ <div class="classification">NATO RESTRICTED</div>
+ </header>
+
+ <div class="main-container">
+ <!-- Left Panel: Mission Configuration -->
+ <div class="config-panel">
+ <div class="panel-section">
+ <h3>DEPARTURE AIRBASE</h3>
+ <select id="airbaseSelect" class="military-select">
+ <option value="">Select Airbase...</option>
+ </select>
+ <div id="airbaseInfo" class="airbase-info"></div>
+ </div>
+
+ <div class="panel-section">
+ <h3>MISSION TYPE</h3>
+ <select id="missionType" class="military-select">
+ <option value="MARITIME_PATROL">Maritime Patrol</option>
+ <option value="SAR">Search and Rescue</option>
+ <option value="RECON">Reconnaissance</option>
+ <option value="ASW">Anti-Submarine Warfare</option>
+ <option value="FISHERY_PATROL">Fishery Protection</option>
+ </select>
+ </div>
+
+ <div class="panel-section">
+ <h3>PATROL AREA</h3>
+ <select id="patrolArea" class="military-select">
+ <option value="">Auto-select based on airbase</option>
+ </select>
+ </div>
+
+ <div class="panel-section">
+ <h3>AIRCRAFT TYPE</h3>
+ <select id="aircraftType" class="military-select">
+ <option value="">Auto-select based on airbase</option>
+ </select>
+ </div>
+
+ <button id="generateMission" class="generate-btn">GENERATE MISSION</button>
+ </div>
+
+ <!-- Center: World Map -->
+ <div class="map-panel">
+ <div id="worldMap" class="world-map"></div>
+ <div class="map-legend">
+ <div class="legend-item">
+ <span class="legend-color airbase"></span>
+ <span>Military Airbases</span>
+ </div>
+ <div class="legend-item">
+ <span class="legend-color patrol-zone"></span>
+ <span>Patrol Areas</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- Right Panel: Mission Briefing -->
+ <div class="briefing-panel">
+ <div id="missionBriefing" class="briefing-display">
+ <div class="briefing-placeholder">
+ <h3>MISSION BRIEFING</h3>
+ <p>Select an airbase and generate a mission to view the operational briefing.</p>
+ <div class="flir-info">
+ <h4>FLIR CAMERA INTEGRATION</h4>
+ <ul>
+ <li>F9: Activate Camera</li>
+ <li>Mouse: Pan/Tilt</li>
+ <li>+/-: Zoom</li>
+ <li>T: Visual Modes</li>
+ <li>SPACE: Target Lock</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <button id="exportBriefing" class="export-btn" style="display: none;">EXPORT BRIEFING</button>
+ </div>
+ </div>
+ </div>
+
+ <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
+ <script src="js/airbase-database.js"></script>
+ <script src="js/patrol-areas.js"></script>
+ <script src="js/mission-generator.js"></script>
+ <script src="js/map-controller.js"></script>
+ <script src="js/app.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/mission-generator/js/airbase-database.js b/mission-generator/js/airbase-database.js
new file mode 100644
index 0000000..7c1b1b2
--- /dev/null
+++ b/mission-generator/js/airbase-database.js
@@ -0,0 +1,1022 @@
+// Comprehensive Military Airbase Database
+const MILITARY_AIRBASES = {
+ // === UNITED STATES ===
+ // Atlantic Coast
+ 'KNHK': {
+ name: 'NAS Patuxent River',
+ country: 'USA',
+ region: 'Atlantic',
+ aircraft: ['P-8A Poseidon', 'P-3C Orion'],
+ coords: [38.286, -76.412],
+ description: 'Naval Air Systems Command test center'
+ },
+ 'KNIP': {
+ name: 'NAS Jacksonville',
+ country: 'USA',
+ region: 'Atlantic',
+ aircraft: ['P-8A Poseidon', 'EP-3E Aries'],
+ coords: [30.236, -81.876],
+ description: 'Primary East Coast maritime patrol base'
+ },
+ 'KNSE': {
+ name: 'NAS Oceana',
+ country: 'USA',
+ region: 'Atlantic',
+ aircraft: ['F/A-18E/F Super Hornet'],
+ coords: [36.821, -76.033],
+ description: 'Master Jet Base for East Coast'
+ },
+ 'KNGP': {
+ name: 'NAS Pensacola',
+ country: 'USA',
+ region: 'Gulf_of_Mexico',
+ aircraft: ['T-6A Texan II', 'T-45 Goshawk'],
+ coords: [30.352, -87.320],
+ description: 'Cradle of Naval Aviation'
+ },
+
+ // Pacific Coast
+ 'PHIK': {
+ name: 'NAS Kaneohe Bay',
+ country: 'USA',
+ region: 'Pacific',
+ aircraft: ['P-8A Poseidon', 'MV-22 Osprey'],
+ coords: [21.450, -157.768],
+ description: 'Pacific maritime patrol operations'
+ },
+ 'PHNL': {
+ name: 'Hickam AFB',
+ country: 'USA',
+ region: 'Pacific',
+ aircraft: ['C-17A Globemaster', 'KC-135 Stratotanker'],
+ coords: [21.319, -157.922],
+ description: 'Pacific Air Forces headquarters'
+ },
+ 'KNKX': {
+ name: 'NAS Miramar',
+ country: 'USA',
+ region: 'Pacific',
+ aircraft: ['F/A-18C/D Hornet', 'F-35C Lightning II'],
+ coords: [32.868, -117.142],
+ description: 'Marine Corps Air Station'
+ },
+ 'KNUW': {
+ name: 'NAS Whidbey Island',
+ country: 'USA',
+ region: 'Pacific',
+ aircraft: ['P-8A Poseidon', 'EA-18G Growler'],
+ coords: [48.351, -122.656],
+ description: 'Electronic attack and maritime patrol hub'
+ },
+
+ // === UNITED KINGDOM ===
+ 'EGPK': {
+ name: 'RAF Kinloss',
+ country: 'UK',
+ region: 'North_Sea',
+ aircraft: ['P-8A Poseidon'],
+ coords: [57.649, -3.560],
+ description: 'Maritime patrol aircraft base'
+ },
+ 'EGQL': {
+ name: 'RAF Lossiemouth',
+ country: 'UK',
+ region: 'North_Sea',
+ aircraft: ['Typhoon FGR4', 'P-8A Poseidon'],
+ coords: [57.705, -3.323],
+ description: 'Quick reaction alert and maritime patrol'
+ },
+ 'EGVA': {
+ name: 'RAF Fairford',
+ country: 'UK',
+ region: 'English_Channel',
+ aircraft: ['B-52H Stratofortress', 'KC-135 Stratotanker'],
+ coords: [51.682, -1.790],
+ description: 'US strategic bomber forward operating base'
+ },
+ 'EGUL': {
+ name: 'RAF Lakenheath',
+ country: 'UK',
+ region: 'North_Sea',
+ aircraft: ['F-15E Strike Eagle', 'F-35A Lightning II'],
+ coords: [52.409, 0.561],
+ description: 'USAFE fighter operations'
+ },
+ 'EGYM': {
+ name: 'RAF Marham',
+ country: 'UK',
+ region: 'North_Sea',
+ aircraft: ['F-35B Lightning II'],
+ coords: [52.648, 0.550],
+ description: 'Lightning Force headquarters'
+ },
+ 'EGXC': {
+ name: 'RAF Coningsby',
+ country: 'UK',
+ region: 'North_Sea',
+ aircraft: ['Typhoon FGR4'],
+ coords: [53.093, -0.166],
+ description: 'Typhoon operations and training'
+ },
+
+ // === FRANCE ===
+ 'LFRB': {
+ name: 'BAN Brest-Lanvéoc',
+ country: 'France',
+ region: 'Atlantic',
+ aircraft: ['Atlantique 2', 'Dauphin'],
+ coords: [48.281, -4.456],
+ description: 'French Navy maritime patrol base'
+ },
+ 'LFTH': {
+ name: 'BAN Hyères',
+ country: 'France',
+ region: 'Mediterranean',
+ aircraft: ['Atlantique 2', 'Falcon 50M'],
+ coords: [43.097, 6.146],
+ description: 'Mediterranean maritime surveillance'
+ },
+ 'LFSI': {
+ name: 'BA 113 Saint-Dizier',
+ country: 'France',
+ region: 'English_Channel',
+ aircraft: ['Rafale B/C'],
+ coords: [48.636, 4.899],
+ description: 'Rafale fighter base'
+ },
+ 'LFSO': {
+ name: 'BA 118 Mont-de-Marsan',
+ country: 'France',
+ region: 'Atlantic',
+ aircraft: ['Rafale B/C', 'Mirage 2000D'],
+ coords: [43.909, -0.507],
+ description: 'Fighter and attack aircraft base'
+ },
+ 'LFOA': {
+ name: 'BA 705 Tours',
+ country: 'France',
+ region: 'English_Channel',
+ aircraft: ['C-135FR', 'C-160 Transall'],
+ coords: [47.432, 0.728],
+ description: 'Air transport and refueling'
+ },
+
+ // === GERMANY ===
+ 'EDXF': {
+ name: 'Nordholz Naval Airbase',
+ country: 'Germany',
+ region: 'North_Sea',
+ aircraft: ['P-3C Orion', 'Sea King'],
+ coords: [53.768, 8.658],
+ description: 'German Navy maritime patrol'
+ },
+ 'ETNW': {
+ name: 'Wittmund AB',
+ country: 'Germany',
+ region: 'North_Sea',
+ aircraft: ['Typhoon'],
+ coords: [53.548, 7.667],
+ description: 'Air defense and QRA'
+ },
+ 'ETNG': {
+ name: 'Geilenkirchen AB',
+ country: 'Germany',
+ region: 'North_Sea',
+ aircraft: ['E-3A Sentry'],
+ coords: [50.961, 6.042],
+ description: 'NATO AWACS base'
+ },
+ 'ETAR': {
+ name: 'Ramstein AB',
+ country: 'Germany',
+ region: 'English_Channel',
+ aircraft: ['C-130J Super Hercules', 'C-17A Globemaster'],
+ coords: [49.437, 7.600],
+ description: 'USAFE headquarters and airlift hub'
+ },
+ 'ETAD': {
+ name: 'Spangdahlem AB',
+ country: 'Germany',
+ region: 'English_Channel',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [49.973, 6.692],
+ description: 'USAFE fighter operations'
+ },
+
+ // === NETHERLANDS ===
+ 'EHVK': {
+ name: 'Volkel AB',
+ country: 'Netherlands',
+ region: 'North_Sea',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [51.656, 5.709],
+ description: 'Primary fighter base'
+ },
+ 'EHLW': {
+ name: 'Leeuwarden AB',
+ country: 'Netherlands',
+ region: 'North_Sea',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [53.229, 5.761],
+ description: 'Fighter operations and training'
+ },
+ 'EHGR': {
+ name: 'Gilze-Rijen AB',
+ country: 'Netherlands',
+ region: 'North_Sea',
+ aircraft: ['C-130H Hercules', 'CH-47D Chinook'],
+ coords: [51.567, 4.932],
+ description: 'Transport and helicopter operations'
+ },
+
+ // === ITALY ===
+ 'LICA': {
+ name: 'NAS Catania-Fontanarossa',
+ country: 'Italy',
+ region: 'Mediterranean',
+ aircraft: ['ATR 72MP', 'AV-8B+ Harrier II'],
+ coords: [37.467, 15.066],
+ description: 'Italian Navy air station'
+ },
+ 'LIPR': {
+ name: 'NAS Pratica di Mare',
+ country: 'Italy',
+ region: 'Mediterranean',
+ aircraft: ['ATR 72MP', 'C-27J Spartan'],
+ coords: [41.652, 12.444],
+ description: 'Italian Air Force coastal command'
+ },
+ 'LIRN': {
+ name: 'NAS Naples (Capodichino)',
+ country: 'Italy',
+ region: 'Mediterranean',
+ aircraft: ['P-8A Poseidon', 'C-40A Clipper'],
+ coords: [40.886, 14.291],
+ description: 'US Navy support facility'
+ },
+ 'LIRS': {
+ name: 'NAS Sigonella',
+ country: 'Italy',
+ region: 'Mediterranean',
+ aircraft: ['P-8A Poseidon', 'MQ-4C Triton'],
+ coords: [37.402, 14.922],
+ description: 'Strategic maritime patrol hub'
+ },
+
+ // === SPAIN ===
+ 'LERT': {
+ name: 'Rota Naval Station',
+ country: 'Spain',
+ region: 'Atlantic',
+ aircraft: ['P-8A Poseidon', 'KC-130J Super Hercules'],
+ coords: [36.645, -6.349],
+ description: 'US/Spanish maritime operations'
+ },
+ 'LEZL': {
+ name: 'Zaragoza AB',
+ country: 'Spain',
+ region: 'Mediterranean',
+ aircraft: ['C-130H Hercules', 'KC-130H'],
+ coords: [41.666, -1.042],
+ description: 'Air transport and refueling'
+ },
+
+ // === NORWAY ===
+ 'ENAT': {
+ name: 'Andøya Air Station',
+ country: 'Norway',
+ region: 'Arctic',
+ aircraft: ['P-3C Orion', 'P-8A Poseidon'],
+ coords: [69.293, 16.144],
+ description: 'Arctic maritime patrol operations'
+ },
+ 'ENBR': {
+ name: 'Bergen Airport Flesland',
+ country: 'Norway',
+ region: 'North_Sea',
+ aircraft: ['Sea King', 'NH90'],
+ coords: [60.294, 5.218],
+ description: 'Search and rescue operations'
+ },
+ 'ENTC': {
+ name: 'Tromsø Airport',
+ country: 'Norway',
+ region: 'Arctic',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [69.683, 18.919],
+ description: 'Arctic air operations'
+ },
+
+ // === PORTUGAL ===
+ 'LPMT': {
+ name: 'Montijo Air Base',
+ country: 'Portugal',
+ region: 'Atlantic',
+ aircraft: ['P-3C Orion', 'C-295M'],
+ coords: [38.703, -8.973],
+ description: 'Maritime patrol and transport'
+ },
+ 'LPLA': {
+ name: 'Lajes Field',
+ country: 'Portugal',
+ region: 'Atlantic',
+ aircraft: ['KC-10A Extender', 'C-130J Super Hercules'],
+ coords: [38.762, -27.091],
+ description: 'Atlantic refueling and transport hub'
+ },
+
+ // === CANADA ===
+ 'CYAW': {
+ name: '14 Wing Greenwood',
+ country: 'Canada',
+ region: 'Atlantic',
+ aircraft: ['CP-140 Aurora'],
+ coords: [44.984, -64.917],
+ description: 'Atlantic maritime patrol operations'
+ },
+ 'CYCO': {
+ name: '19 Wing Comox',
+ country: 'Canada',
+ region: 'Pacific',
+ aircraft: ['CP-140 Aurora'],
+ coords: [49.711, -124.887],
+ description: 'Pacific maritime patrol operations'
+ },
+ 'CYBG': {
+ name: 'CFB Bagotville',
+ country: 'Canada',
+ region: 'Atlantic',
+ aircraft: ['CF-188 Hornet'],
+ coords: [48.331, -70.996],
+ description: 'NORAD air defense'
+ },
+
+ // === AUSTRALIA ===
+ 'YPED': {
+ name: 'RAAF Base Edinburgh',
+ country: 'Australia',
+ region: 'Pacific',
+ aircraft: ['P-8A Poseidon', 'KC-30A MRTT'],
+ coords: [-34.702, 138.621],
+ description: 'Maritime patrol and air-to-air refueling'
+ },
+ 'YWLM': {
+ name: 'RAAF Base Williamtown',
+ country: 'Australia',
+ region: 'Pacific',
+ aircraft: ['F/A-18F Super Hornet', 'E-7A Wedgetail'],
+ coords: [-32.792, 151.841],
+ description: 'Fighter operations and AEW&C'
+ },
+
+ // === JAPAN ===
+ 'RJOI': {
+ name: 'Iwakuni AB',
+ country: 'Japan',
+ region: 'Pacific',
+ aircraft: ['F/A-18C/D Hornet', 'F-35B Lightning II'],
+ coords: [34.144, 132.236],
+ description: 'US Marine Corps air station'
+ },
+ 'RJTY': {
+ name: 'Yokota AB',
+ country: 'Japan',
+ region: 'Pacific',
+ aircraft: ['C-130J Super Hercules', 'UH-1N Huey'],
+ coords: [35.748, 139.348],
+ description: 'PACAF headquarters and airlift'
+ },
+
+ // === SOUTH KOREA ===
+ 'RKSO': {
+ name: 'Osan AB',
+ country: 'South Korea',
+ region: 'Pacific',
+ aircraft: ['F-16C/D Fighting Falcon', 'A-10C Thunderbolt II'],
+ coords: [37.090, 127.030],
+ description: '7th Air Force operations'
+ },
+ 'RKJK': {
+ name: 'Kunsan AB',
+ country: 'South Korea',
+ region: 'Pacific',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [35.904, 126.616],
+ description: 'Wolf Pack fighter operations'
+ },
+
+ // === ICELAND ===
+ 'BIKF': {
+ name: 'Keflavik Air Base',
+ country: 'Iceland',
+ region: 'Arctic',
+ aircraft: ['P-8A Poseidon', 'KC-135 Stratotanker'],
+ coords: [63.985, -22.605],
+ description: 'NATO maritime patrol operations'
+ },
+
+ // === TURKEY ===
+ 'LTAG': {
+ name: 'Incirlik AB',
+ country: 'Turkey',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon', 'KC-135 Stratotanker'],
+ coords: [37.002, 35.426],
+ description: 'NATO southern flank operations'
+ },
+ 'LTBM': {
+ name: 'Merzifon AB',
+ country: 'Turkey',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [40.828, 35.522],
+ description: 'Central Anatolia air defense'
+ },
+
+ // === GREECE ===
+ 'LGSO': {
+ name: 'Souda Bay',
+ country: 'Greece',
+ region: 'Mediterranean',
+ aircraft: ['P-8A Poseidon', 'C-130H Hercules'],
+ coords: [35.546, 24.127],
+ description: 'Eastern Mediterranean operations'
+ },
+ 'LGTT': {
+ name: 'Tanagra AB',
+ country: 'Greece',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon', 'Mirage 2000'],
+ coords: [38.344, 23.565],
+ description: 'Hellenic Air Force fighter operations'
+ },
+ 'LGSM': {
+ name: 'Kastelli AB',
+ country: 'Greece',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [35.421, 25.327],
+ description: 'Aegean Sea air patrol'
+ },
+
+ // === SWEDEN ===
+ 'ESGG': {
+ name: 'Säve Air Base',
+ country: 'Sweden',
+ region: 'North_Sea',
+ aircraft: ['JAS 39 Gripen', 'C-130H Hercules'],
+ coords: [57.774, 11.870],
+ description: 'West coast air defense'
+ },
+ 'ESPA': {
+ name: 'Luleå Air Base',
+ country: 'Sweden',
+ region: 'Arctic',
+ aircraft: ['JAS 39 Gripen'],
+ coords: [65.548, 22.122],
+ description: 'Arctic air surveillance'
+ },
+ 'ESSA': {
+ name: 'Stockholm Arlanda',
+ country: 'Sweden',
+ region: 'North_Sea',
+ aircraft: ['JAS 39 Gripen', 'S 102B Korpen'],
+ coords: [59.651, 17.918],
+ description: 'Capital region air defense'
+ },
+
+ // === FINLAND ===
+ 'EFTU': {
+ name: 'Turku Air Base',
+ country: 'Finland',
+ region: 'Arctic',
+ aircraft: ['F/A-18C/D Hornet'],
+ coords: [60.514, 22.262],
+ description: 'Southwestern Finland air defense'
+ },
+ 'EFRV': {
+ name: 'Rovaniemi Air Base',
+ country: 'Finland',
+ region: 'Arctic',
+ aircraft: ['F/A-18C/D Hornet'],
+ coords: [66.564, 25.830],
+ description: 'Arctic Circle air operations'
+ },
+ 'EFTP': {
+ name: 'Tampere-Pirkkala',
+ country: 'Finland',
+ region: 'Arctic',
+ aircraft: ['F/A-18C/D Hornet', 'C-295M'],
+ coords: [61.414, 23.604],
+ description: 'Central Finland air base'
+ },
+
+ // === DENMARK ===
+ 'EKKA': {
+ name: 'Karup Air Base',
+ country: 'Denmark',
+ region: 'North_Sea',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [56.297, 9.124],
+ description: 'Primary Danish fighter base'
+ },
+ 'EKAH': {
+ name: 'Aalborg Air Base',
+ country: 'Denmark',
+ region: 'North_Sea',
+ aircraft: ['F-35A Lightning II'],
+ coords: [57.092, 9.849],
+ description: 'Northern Jutland air operations'
+ },
+
+ // === POLAND ===
+ 'EPKS': {
+ name: 'Krzesiny Air Base',
+ country: 'Poland',
+ region: 'North_Sea',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [52.331, 16.833],
+ description: 'Western Poland air defense'
+ },
+ 'EPML': {
+ name: 'Malbork Air Base',
+ country: 'Poland',
+ region: 'North_Sea',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [54.026, 19.134],
+ description: 'Baltic coast air operations'
+ },
+ 'EPDE': {
+ name: 'Deblin Air Base',
+ country: 'Poland',
+ region: 'North_Sea',
+ aircraft: ['TS-11 Iskra', 'PZL-130 Orlik'],
+ coords: [51.552, 21.893],
+ description: 'Polish Air Force Academy'
+ },
+
+ // === CZECH REPUBLIC ===
+ 'LKCV': {
+ name: 'Čáslav Air Base',
+ country: 'Czech Republic',
+ region: 'English_Channel',
+ aircraft: ['JAS 39 Gripen'],
+ coords: [49.937, 15.381],
+ description: 'Central Europe air defense'
+ },
+ 'LKNA': {
+ name: 'Náměšť Air Base',
+ country: 'Czech Republic',
+ region: 'English_Channel',
+ aircraft: ['JAS 39 Gripen'],
+ coords: [49.094, 16.125],
+ description: 'Southern Czech air operations'
+ },
+
+ // === HUNGARY ===
+ 'LHKE': {
+ name: 'Kecskemét Air Base',
+ country: 'Hungary',
+ region: 'English_Channel',
+ aircraft: ['JAS 39 Gripen'],
+ coords: [46.917, 19.749],
+ description: 'Hungarian air defense hub'
+ },
+ 'LHPA': {
+ name: 'Pápa Air Base',
+ country: 'Hungary',
+ region: 'English_Channel',
+ aircraft: ['C-17A Globemaster III'],
+ coords: [47.364, 17.500],
+ description: 'NATO strategic airlift'
+ },
+
+ // === ROMANIA ===
+ 'LRCV': {
+ name: 'Câmpia Turzii',
+ country: 'Romania',
+ region: 'Mediterranean',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [46.504, 23.885],
+ description: 'Transylvanian air defense'
+ },
+ 'LRBC': {
+ name: 'Bacău Air Base',
+ country: 'Romania',
+ region: 'Mediterranean',
+ aircraft: ['MiG-21 LanceR'],
+ coords: [46.521, 26.910],
+ description: 'Eastern Romania air operations'
+ },
+
+ // === BULGARIA ===
+ 'LBPG': {
+ name: 'Graf Ignatievo Air Base',
+ country: 'Bulgaria',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [42.288, 25.653],
+ description: 'Central Bulgaria air defense'
+ },
+
+ // === CROATIA ===
+ 'LDPL': {
+ name: 'Pleso Air Base',
+ country: 'Croatia',
+ region: 'Mediterranean',
+ aircraft: ['PC-9M', 'Mi-8/17'],
+ coords: [45.742, 16.068],
+ description: 'Croatian Air Force headquarters'
+ },
+
+ // === SLOVENIA ===
+ 'LJCE': {
+ name: 'Cerklje ob Krki',
+ country: 'Slovenia',
+ region: 'Mediterranean',
+ aircraft: ['PC-9M Hudournik'],
+ coords: [45.898, 15.530],
+ description: 'Slovenian air operations'
+ },
+
+ // === BELGIUM ===
+ 'EBFS': {
+ name: 'Florennes Air Base',
+ country: 'Belgium',
+ region: 'English_Channel',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [50.243, 4.646],
+ description: 'Belgian air defense'
+ },
+ 'EBBL': {
+ name: 'Kleine Brogel',
+ country: 'Belgium',
+ region: 'English_Channel',
+ aircraft: ['F-16AM/BM Fighting Falcon'],
+ coords: [51.168, 5.470],
+ description: 'NATO tactical fighter wing'
+ },
+
+ // === LUXEMBOURG ===
+ 'ELLX': {
+ name: 'Luxembourg Airport',
+ country: 'Luxembourg',
+ region: 'English_Channel',
+ aircraft: ['A400M Atlas'],
+ coords: [49.623, 6.204],
+ description: 'NATO airlift coordination'
+ },
+
+ // === SWITZERLAND ===
+ 'LSMP': {
+ name: 'Payerne Air Base',
+ country: 'Switzerland',
+ region: 'English_Channel',
+ aircraft: ['F/A-18C/D Hornet'],
+ coords: [46.843, 6.915],
+ description: 'Swiss air policing'
+ },
+ 'LSMM': {
+ name: 'Meiringen Air Base',
+ country: 'Switzerland',
+ region: 'English_Channel',
+ aircraft: ['F/A-18C/D Hornet'],
+ coords: [46.743, 8.108],
+ description: 'Alpine air operations'
+ },
+
+ // === AUSTRIA ===
+ 'LOWZ': {
+ name: 'Zeltweg Air Base',
+ country: 'Austria',
+ region: 'English_Channel',
+ aircraft: ['Eurofighter Typhoon'],
+ coords: [47.203, 14.744],
+ description: 'Austrian air surveillance'
+ },
+
+ // === ISRAEL ===
+ 'LLBG': {
+ name: 'Nevatim Airbase',
+ country: 'Israel',
+ region: 'Mediterranean',
+ aircraft: ['F-35I Adir', 'F-16I Sufa'],
+ coords: [31.208, 34.926],
+ description: 'Southern command air operations'
+ },
+ 'LLHS': {
+ name: 'Hatzerim Air Base',
+ country: 'Israel',
+ region: 'Mediterranean',
+ aircraft: ['F-16I Sufa', 'AH-64 Apache'],
+ coords: [31.234, 34.665],
+ description: 'Desert air combat training'
+ },
+ 'LLET': {
+ name: 'Tel Nof Airbase',
+ country: 'Israel',
+ region: 'Mediterranean',
+ aircraft: ['F-15I Ra\'am', 'C-130J Samson'],
+ coords: [31.838, 34.821],
+ description: 'Central command operations'
+ },
+
+ // === INDIA ===
+ 'VOBL': {
+ name: 'INS Hansa Goa',
+ country: 'India',
+ region: 'Indian_Ocean',
+ aircraft: ['P-8I Neptune', 'MiG-29K'],
+ coords: [15.381, 73.831],
+ description: 'Indian Navy western fleet'
+ },
+ 'VOCP': {
+ name: 'Port Blair',
+ country: 'India',
+ region: 'Indian_Ocean',
+ aircraft: ['Dornier 228', 'Mi-8'],
+ coords: [11.641, 92.730],
+ description: 'Andaman & Nicobar operations'
+ },
+ 'VOKX': {
+ name: 'Kochi Naval Base',
+ country: 'India',
+ region: 'Indian_Ocean',
+ aircraft: ['P-8I Neptune', 'Sea King'],
+ coords: [9.942, 76.267],
+ description: 'Southern naval aviation'
+ },
+
+ // === SINGAPORE ===
+ 'WSAP': {
+ name: 'Paya Lebar Air Base',
+ country: 'Singapore',
+ region: 'Pacific',
+ aircraft: ['F-15SG Strike Eagle', 'F-16C/D Fighting Falcon'],
+ coords: [1.360, 103.909],
+ description: 'Republic of Singapore Air Force'
+ },
+ 'WSSL': {
+ name: 'Sembawang Air Base',
+ country: 'Singapore',
+ region: 'Pacific',
+ aircraft: ['C-130H Hercules', 'AS332 Super Puma'],
+ coords: [1.425, 103.813],
+ description: 'Transport and SAR operations'
+ },
+
+ // === MALAYSIA ===
+ 'WMKD': {
+ name: 'Kuantan Air Base',
+ country: 'Malaysia',
+ region: 'Pacific',
+ aircraft: ['F/A-18D Hornet', 'Hawk 208'],
+ coords: [3.775, 103.209],
+ description: 'East coast air defense'
+ },
+ 'WMKB': {
+ name: 'Butterworth Air Base',
+ country: 'Malaysia',
+ region: 'Pacific',
+ aircraft: ['F/A-18D Hornet'],
+ coords: [5.465, 100.390],
+ description: 'FPDA air operations'
+ },
+
+ // === THAILAND ===
+ 'VTBD': {
+ name: 'Don Muang Air Base',
+ country: 'Thailand',
+ region: 'Pacific',
+ aircraft: ['F-16A/B Fighting Falcon', 'JAS 39 Gripen'],
+ coords: [13.912, 100.607],
+ description: 'Royal Thai Air Force headquarters'
+ },
+ 'VTBU': {
+ name: 'U-Tapao Air Base',
+ country: 'Thailand',
+ region: 'Pacific',
+ aircraft: ['C-130H Hercules', 'Saab 340 AEW'],
+ coords: [12.680, 101.005],
+ description: 'Maritime patrol and transport'
+ },
+
+ // === PHILIPPINES ===
+ 'RPLC': {
+ name: 'Clark Air Base',
+ country: 'Philippines',
+ region: 'Pacific',
+ aircraft: ['FA-50 Fighting Eagle'],
+ coords: [15.186, 120.560],
+ description: 'Philippine Air Force operations'
+ },
+ 'RPLL': {
+ name: 'Villamor Air Base',
+ country: 'Philippines',
+ region: 'Pacific',
+ aircraft: ['C-130T Hercules', 'UH-1H Huey'],
+ coords: [14.509, 121.020],
+ description: 'Capital air defense'
+ },
+
+ // === INDONESIA ===
+ 'WIHH': {
+ name: 'Halim Perdanakusuma',
+ country: 'Indonesia',
+ region: 'Pacific',
+ aircraft: ['F-16A/B Fighting Falcon', 'Su-27/30'],
+ coords: [-6.266, 106.891],
+ description: 'Jakarta air defense'
+ },
+ 'WIDD': {
+ name: 'Ngurah Rai Air Base',
+ country: 'Indonesia',
+ region: 'Pacific',
+ aircraft: ['F-16A/B Fighting Falcon'],
+ coords: [-8.748, 115.167],
+ description: 'Bali air operations'
+ },
+
+ // === NEW ZEALAND ===
+ 'NZOH': {
+ name: 'RNZAF Base Ohakea',
+ country: 'New Zealand',
+ region: 'Pacific',
+ aircraft: ['C-130H Hercules', 'P-3K2 Orion'],
+ coords: [-40.206, 175.388],
+ description: 'Transport and maritime patrol'
+ },
+ 'NZWN': {
+ name: 'RNZAF Base Woodbourne',
+ country: 'New Zealand',
+ region: 'Pacific',
+ aircraft: ['King Air 350', 'NH90'],
+ coords: [-41.518, 173.870],
+ description: 'South Island operations'
+ },
+
+ // === SOUTH AFRICA ===
+ 'FAOY': {
+ name: 'Ysterplaat AFB',
+ country: 'South Africa',
+ region: 'Atlantic',
+ aircraft: ['C-130BZ Hercules', 'Casa 212'],
+ coords: [-33.900, 18.498],
+ description: 'Cape Town maritime patrol'
+ },
+ 'FAOR': {
+ name: 'OR Tambo International',
+ country: 'South Africa',
+ region: 'Indian_Ocean',
+ aircraft: ['A400M Atlas', 'C-47TP Turbo Dakota'],
+ coords: [-26.139, 28.246],
+ description: 'Central command operations'
+ },
+ 'FADN': {
+ name: 'Durban Air Station',
+ country: 'South Africa',
+ region: 'Indian_Ocean',
+ aircraft: ['Lynx Mk7', 'Casa 212'],
+ coords: [-29.970, 30.951],
+ description: 'East coast maritime operations'
+ },
+
+ // === CHILE ===
+ 'SCEL': {
+ name: 'Los Cerrillos Air Base',
+ country: 'Chile',
+ region: 'Pacific',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [-33.490, -70.704],
+ description: 'Santiago air defense'
+ },
+ 'SCIP': {
+ name: 'Iquique Air Base',
+ country: 'Chile',
+ region: 'Pacific',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [-20.565, -70.181],
+ description: 'Northern Chile operations'
+ },
+ 'SCTE': {
+ name: 'Teniente Julio Gallardo',
+ country: 'Chile',
+ region: 'Pacific',
+ aircraft: ['C-130H Hercules'],
+ coords: [-53.779, -70.856],
+ description: 'Patagonian operations'
+ },
+
+ // === BRAZIL ===
+ 'SBNT': {
+ name: 'Natal Air Base',
+ country: 'Brazil',
+ region: 'Atlantic',
+ aircraft: ['P-3AM Orion', 'EMB-111'],
+ coords: [-5.911, -35.247],
+ description: 'Atlantic maritime patrol'
+ },
+ 'SBAN': {
+ name: 'Anápolis Air Base',
+ country: 'Brazil',
+ region: 'Atlantic',
+ aircraft: ['F-5EM Tiger II', 'A-29 Super Tucano'],
+ coords: [-16.223, -48.996],
+ description: 'Central Brazil air defense'
+ },
+ 'SBSV': {
+ name: 'Salvador Air Base',
+ country: 'Brazil',
+ region: 'Atlantic',
+ aircraft: ['A-29 Super Tucano'],
+ coords: [-12.911, -38.322],
+ description: 'Northeast coast operations'
+ },
+
+ // === ARGENTINA ===
+ 'SAEZ': {
+ name: 'Ezeiza Air Base',
+ country: 'Argentina',
+ region: 'Atlantic',
+ aircraft: ['A-4AR Fightinghawk'],
+ coords: [-34.822, -58.536],
+ description: 'Buenos Aires air operations'
+ },
+ 'SAWC': {
+ name: 'Comodoro Rivadavia',
+ country: 'Argentina',
+ region: 'Atlantic',
+ aircraft: ['IA-58 Pucará'],
+ coords: [-45.785, -67.465],
+ description: 'Patagonian coastal patrol'
+ },
+
+ // === MOROCCO ===
+ 'GMMN': {
+ name: 'Sale Air Base',
+ country: 'Morocco',
+ region: 'Atlantic',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [34.051, -6.751],
+ description: 'Royal Moroccan Air Force'
+ },
+
+ // === EGYPT ===
+ 'HEAX': {
+ name: 'Alexandria Air Base',
+ country: 'Egypt',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon'],
+ coords: [31.184, 29.949],
+ description: 'Mediterranean coast operations'
+ },
+ 'HECA': {
+ name: 'Cairo West Air Base',
+ country: 'Egypt',
+ region: 'Mediterranean',
+ aircraft: ['F-16C/D Fighting Falcon', 'Rafale'],
+ coords: [30.115, 30.916],
+ description: 'Capital air defense'
+ },
+
+ // === UAE ===
+ 'OMAM': {
+ name: 'Al Minhad Air Base',
+ country: 'UAE',
+ region: 'Indian_Ocean',
+ aircraft: ['F-16E/F Desert Falcon'],
+ coords: [25.027, 55.366],
+ description: 'Coalition air operations'
+ },
+ 'OMAA': {
+ name: 'Al Dhafra Air Base',
+ country: 'UAE',
+ region: 'Indian_Ocean',
+ aircraft: ['F-35A Lightning II', 'Rafale'],
+ coords: [24.248, 54.547],
+ description: 'Western region air defense'
+ },
+
+ // === SAUDI ARABIA ===
+ 'OEPR': {
+ name: 'Prince Sultan Air Base',
+ country: 'Saudi Arabia',
+ region: 'Indian_Ocean',
+ aircraft: ['F-15SA Eagle', 'Typhoon'],
+ coords: [24.069, 47.680],
+ description: 'Central command operations'
+ },
+ 'OERY': {
+ name: 'King Faisal Air Base',
+ country: 'Saudi Arabia',
+ region: 'Indian_Ocean',
+ aircraft: ['F-15SA Eagle'],
+ coords: [27.900, 45.528],
+ description: 'Northern border operations'
+ }
+};
+
+// Export for use in other modules
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = { MILITARY_AIRBASES };
+}
\ No newline at end of file
diff --git a/mission-generator/js/app.js b/mission-generator/js/app.js
new file mode 100644
index 0000000..9a3d417
--- /dev/null
+++ b/mission-generator/js/app.js
@@ -0,0 +1,353 @@
+// Main Application Controller
+class MissionPlannerApp {
+ constructor() {
+ this.missionGenerator = new MissionGenerator();
+ this.mapController = null;
+ this.currentMission = null;
+
+ this.initializeApp();
+ }
+
+ initializeApp() {
+ // Wait for DOM to be ready
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', () => this.setup());
+ } else {
+ this.setup();
+ }
+ }
+
+ setup() {
+ // Initialize map controller
+ this.mapController = new MapController('worldMap');
+
+ // Make map controller globally accessible for popup callbacks
+ window.mapController = this.mapController;
+
+ // Populate airbase dropdown
+ this.populateAirbaseDropdown();
+
+ // Setup event listeners
+ this.setupEventListeners();
+
+ // Initialize UI state
+ this.updatePatrolAreaOptions();
+ this.updateAircraftOptions();
+
+ console.log('Maritime Patrol Mission Generator initialized');
+ }
+
+ populateAirbaseDropdown() {
+ const select = document.getElementById('airbaseSelect');
+ if (!select) return;
+
+ // Clear existing options except the first one
+ select.innerHTML = '<option value="">Select Airbase...</option>';
+
+ // Group airbases by country
+ const groupedAirbases = {};
+ Object.entries(MILITARY_AIRBASES).forEach(([icao, airbase]) => {
+ if (!groupedAirbases[airbase.country]) {
+ groupedAirbases[airbase.country] = [];
+ }
+ groupedAirbases[airbase.country].push({ icao, ...airbase });
+ });
+
+ // Sort countries and add options
+ Object.keys(groupedAirbases).sort().forEach(country => {
+ const optgroup = document.createElement('optgroup');
+ optgroup.label = country;
+
+ groupedAirbases[country]
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .forEach(airbase => {
+ const option = document.createElement('option');
+ option.value = airbase.icao;
+ option.textContent = `${airbase.icao} - ${airbase.name}`;
+ optgroup.appendChild(option);
+ });
+
+ select.appendChild(optgroup);
+ });
+ }
+
+ setupEventListeners() {
+ // Airbase selection
+ const airbaseSelect = document.getElementById('airbaseSelect');
+ if (airbaseSelect) {
+ airbaseSelect.addEventListener('change', (e) => {
+ this.onAirbaseSelected(e.target.value);
+ });
+ }
+
+ // Mission type selection
+ const missionTypeSelect = document.getElementById('missionType');
+ if (missionTypeSelect) {
+ missionTypeSelect.addEventListener('change', () => {
+ this.updateAircraftOptions();
+ });
+ }
+
+ // Patrol area selection
+ const patrolAreaSelect = document.getElementById('patrolArea');
+ if (patrolAreaSelect) {
+ patrolAreaSelect.addEventListener('change', (e) => {
+ this.onPatrolAreaSelected(e.target.value);
+ });
+ }
+
+ // Generate mission button
+ const generateBtn = document.getElementById('generateMission');
+ if (generateBtn) {
+ generateBtn.addEventListener('click', () => {
+ this.generateMission();
+ });
+ }
+
+ // Export briefing button
+ const exportBtn = document.getElementById('exportBriefing');
+ if (exportBtn) {
+ exportBtn.addEventListener('click', () => {
+ this.exportBriefing();
+ });
+ }
+ }
+
+ onAirbaseSelected(icao) {
+ if (!icao) {
+ this.clearAirbaseInfo();
+ this.updatePatrolAreaOptions();
+ this.updateAircraftOptions();
+ return;
+ }
+
+ const airbase = MILITARY_AIRBASES[icao];
+ if (!airbase) return;
+
+ // Update airbase info display
+ this.displayAirbaseInfo(icao, airbase);
+
+ // Update patrol area options based on airbase
+ this.updatePatrolAreaOptions(icao);
+
+ // Update aircraft options based on airbase
+ this.updateAircraftOptions();
+
+ // Highlight on map
+ this.mapController.highlightSelectedAirbase(icao);
+ this.mapController.fitToAirbase(icao);
+ }
+
+ displayAirbaseInfo(icao, airbase) {
+ const infoDiv = document.getElementById('airbaseInfo');
+ if (!infoDiv) return;
+
+ infoDiv.innerHTML = `
+ <div class="info-item">
+ <span class="info-label">Country:</span> ${airbase.country}
+ </div>
+ <div class="info-item">
+ <span class="info-label">Region:</span> ${airbase.region.replace('_', ' ')}
+ </div>
+ <div class="info-item">
+ <span class="info-label">Coordinates:</span> ${airbase.coords[0].toFixed(3)}°N, ${Math.abs(airbase.coords[1]).toFixed(3)}°${airbase.coords[1] < 0 ? 'W' : 'E'}
+ </div>
+ <div class="info-item">
+ <span class="info-label">Aircraft:</span> ${airbase.aircraft.slice(0, 2).join(', ')}${airbase.aircraft.length > 2 ? '...' : ''}
+ </div>
+ <div class="info-item" style="margin-top: 8px; font-size: 10px; color: var(--text-secondary);">
+ ${airbase.description}
+ </div>
+ `;
+
+ infoDiv.classList.add('show');
+ }
+
+ clearAirbaseInfo() {
+ const infoDiv = document.getElementById('airbaseInfo');
+ if (infoDiv) {
+ infoDiv.classList.remove('show');
+ }
+ }
+
+ updatePatrolAreaOptions(selectedAirbaseIcao = null) {
+ const select = document.getElementById('patrolArea');
+ if (!select) return;
+
+ // Clear existing options
+ select.innerHTML = '<option value="">Auto-select based on airbase</option>';
+
+ if (!selectedAirbaseIcao) return;
+
+ const airbase = MILITARY_AIRBASES[selectedAirbaseIcao];
+ if (!airbase) return;
+
+ // Get appropriate patrol areas
+ const { primary, secondary } = getPatrolAreasForAirbase(airbase);
+
+ // Add primary areas
+ if (primary.length > 0) {
+ const primaryGroup = document.createElement('optgroup');
+ primaryGroup.label = 'Primary Areas';
+
+ primary.forEach(areaKey => {
+ const area = PATROL_AREAS[areaKey];
+ if (area) {
+ const option = document.createElement('option');
+ option.value = areaKey;
+ option.textContent = area.name;
+ primaryGroup.appendChild(option);
+ }
+ });
+
+ select.appendChild(primaryGroup);
+ }
+
+ // Add secondary areas
+ if (secondary.length > 0) {
+ const secondaryGroup = document.createElement('optgroup');
+ secondaryGroup.label = 'Secondary Areas';
+
+ secondary.forEach(areaKey => {
+ const area = PATROL_AREAS[areaKey];
+ if (area) {
+ const option = document.createElement('option');
+ option.value = areaKey;
+ option.textContent = area.name;
+ secondaryGroup.appendChild(option);
+ }
+ });
+
+ select.appendChild(secondaryGroup);
+ }
+
+ // Auto-select the first primary area
+ if (primary.length > 0) {
+ select.value = primary[0];
+ this.onPatrolAreaSelected(primary[0]);
+ }
+ }
+
+ updateAircraftOptions() {
+ const airbaseSelect = document.getElementById('airbaseSelect');
+ const aircraftSelect = document.getElementById('aircraftType');
+ const missionTypeSelect = document.getElementById('missionType');
+
+ if (!aircraftSelect || !airbaseSelect) return;
+
+ aircraftSelect.innerHTML = '<option value="">Auto-select based on airbase</option>';
+
+ const selectedAirbase = airbaseSelect.value;
+ if (!selectedAirbase) return;
+
+ const airbase = MILITARY_AIRBASES[selectedAirbase];
+ if (!airbase || !airbase.aircraft) return;
+
+ // Add aircraft options
+ airbase.aircraft.forEach(aircraft => {
+ const option = document.createElement('option');
+ option.value = aircraft;
+ option.textContent = aircraft;
+ aircraftSelect.appendChild(option);
+ });
+
+ // Auto-select best aircraft for mission type
+ const missionType = missionTypeSelect.value;
+ if (missionType) {
+ const bestAircraft = this.missionGenerator.selectAircraft(airbase.aircraft, missionType);
+ aircraftSelect.value = bestAircraft;
+ }
+ }
+
+ onPatrolAreaSelected(areaKey) {
+ if (areaKey) {
+ this.mapController.showPatrolArea(areaKey);
+ } else {
+ this.mapController.clearPatrolAreas();
+ }
+ }
+
+ generateMission() {
+ const airbaseIcao = document.getElementById('airbaseSelect').value;
+ const missionType = document.getElementById('missionType').value;
+ const patrolArea = document.getElementById('patrolArea').value;
+
+ if (!airbaseIcao) {
+ alert('Please select an airbase first.');
+ return;
+ }
+
+ // Auto-select patrol area if not specified
+ let selectedPatrolArea = patrolArea;
+ if (!selectedPatrolArea) {
+ const airbase = MILITARY_AIRBASES[airbaseIcao];
+ const areas = getPatrolAreasForAirbase(airbase);
+ selectedPatrolArea = areas.primary[0];
+
+ // Update UI
+ document.getElementById('patrolArea').value = selectedPatrolArea;
+ this.onPatrolAreaSelected(selectedPatrolArea);
+ }
+
+ try {
+ // Generate the mission
+ this.currentMission = this.missionGenerator.generateMission(
+ airbaseIcao,
+ missionType,
+ selectedPatrolArea
+ );
+
+ // Display the briefing
+ this.displayBriefing(this.currentMission);
+
+ // Show export button
+ document.getElementById('exportBriefing').style.display = 'block';
+
+ } catch (error) {
+ console.error('Mission generation failed:', error);
+ alert('Failed to generate mission. Please check your selections.');
+ }
+ }
+
+ displayBriefing(mission) {
+ const briefingDiv = document.getElementById('missionBriefing');
+ if (!briefingDiv) return;
+
+ const briefingText = this.missionGenerator.generateBriefing(mission);
+
+ briefingDiv.innerHTML = `
+ <div class="mission-briefing">
+ <pre>${briefingText}</pre>
+ </div>
+ `;
+ }
+
+ exportBriefing() {
+ if (!this.currentMission) {
+ alert('No mission generated to export.');
+ return;
+ }
+
+ const briefingText = this.missionGenerator.generateBriefing(this.currentMission);
+ const filename = `Mission_${this.currentMission.id}_${this.currentMission.codename.replace(' ', '_')}.txt`;
+
+ // Create download link
+ const blob = new Blob([briefingText], { type: 'text/plain' });
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = filename;
+
+ // Trigger download
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ }
+}
+
+// Initialize application when page loads
+let app;
+document.addEventListener('DOMContentLoaded', () => {
+ app = new MissionPlannerApp();
+});
\ No newline at end of file
diff --git a/mission-generator/js/map-controller.js b/mission-generator/js/map-controller.js
new file mode 100644
index 0000000..7ec8163
--- /dev/null
+++ b/mission-generator/js/map-controller.js
@@ -0,0 +1,318 @@
+// Map Controller for Leaflet Integration
+class MapController {
+ constructor(mapElementId) {
+ this.mapElementId = mapElementId;
+ this.map = null;
+ this.airbaseMarkers = [];
+ this.patrolAreaLayers = [];
+ this.selectedAirbase = null;
+ this.selectedPatrolArea = null;
+
+ this.initializeMap();
+ this.loadAirbases();
+ }
+
+ initializeMap() {
+ // Initialize map centered on Europe/North Atlantic
+ this.map = L.map(this.mapElementId, {
+ center: [55.0, -5.0],
+ zoom: 4,
+ minZoom: 2,
+ maxZoom: 10,
+ worldCopyJump: true
+ });
+
+ // Dark theme tile layer
+ L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
+ attribution: '© <a href="https://carto.com/attributions">CARTO</a>',
+ subdomains: 'abcd',
+ maxZoom: 19
+ }).addTo(this.map);
+
+ // Add custom CSS for dark theme
+ this.addMapStyles();
+ }
+
+ addMapStyles() {
+ const style = document.createElement('style');
+ style.textContent = `
+ .leaflet-popup-content-wrapper {
+ background: var(--secondary-bg);
+ color: var(--text-primary);
+ border: 1px solid var(--accent-green);
+ border-radius: 3px;
+ }
+
+ .leaflet-popup-tip {
+ background: var(--secondary-bg);
+ border: 1px solid var(--accent-green);
+ }
+
+ .airbase-popup {
+ font-family: 'Courier New', monospace;
+ font-size: 11px;
+ line-height: 1.4;
+ min-width: 200px;
+ }
+
+ .airbase-popup .popup-header {
+ color: var(--accent-green);
+ font-weight: bold;
+ margin-bottom: 8px;
+ text-align: center;
+ border-bottom: 1px solid var(--border-color);
+ padding-bottom: 5px;
+ }
+
+ .airbase-popup .popup-info {
+ margin-bottom: 5px;
+ }
+
+ .airbase-popup .popup-label {
+ color: var(--text-secondary);
+ display: inline-block;
+ width: 60px;
+ }
+
+ .airbase-popup .popup-aircraft {
+ color: var(--warning-amber);
+ font-size: 10px;
+ margin-top: 5px;
+ padding: 3px;
+ background: var(--tertiary-bg);
+ border-radius: 2px;
+ }
+
+ .select-airbase-btn {
+ background: var(--military-blue);
+ color: var(--text-primary);
+ border: 1px solid var(--accent-green);
+ padding: 5px 10px;
+ font-family: inherit;
+ font-size: 10px;
+ cursor: pointer;
+ width: 100%;
+ margin-top: 8px;
+ border-radius: 2px;
+ transition: all 0.3s ease;
+ }
+
+ .select-airbase-btn:hover {
+ background: var(--accent-green);
+ color: var(--primary-bg);
+ }
+ `;
+ document.head.appendChild(style);
+ }
+
+ loadAirbases() {
+ // Clear existing markers
+ this.airbaseMarkers.forEach(marker => this.map.removeLayer(marker));
+ this.airbaseMarkers = [];
+
+ // Create markers for each airbase
+ Object.entries(MILITARY_AIRBASES).forEach(([icao, airbase]) => {
+ const marker = this.createAirbaseMarker(icao, airbase);
+ this.airbaseMarkers.push(marker);
+ marker.addTo(this.map);
+ });
+ }
+
+ createAirbaseMarker(icao, airbase) {
+ const [lat, lon] = airbase.coords;
+
+ // Custom airbase icon
+ const airbaseIcon = L.divIcon({
+ className: 'airbase-marker',
+ html: `<div style="
+ width: 8px;
+ height: 8px;
+ background: var(--accent-green);
+ border: 2px solid var(--primary-bg);
+ border-radius: 50%;
+ box-shadow: 0 0 8px rgba(0, 255, 65, 0.6);
+ "></div>`,
+ iconSize: [12, 12],
+ iconAnchor: [6, 6]
+ });
+
+ const marker = L.marker([lat, lon], { icon: airbaseIcon });
+
+ // Create popup content
+ const popupContent = this.createAirbasePopup(icao, airbase);
+ marker.bindPopup(popupContent, {
+ maxWidth: 250,
+ className: 'airbase-popup-container'
+ });
+
+ // Add click handler
+ marker.on('click', () => {
+ this.selectAirbase(icao);
+ });
+
+ return marker;
+ }
+
+ createAirbasePopup(icao, airbase) {
+ const aircraftList = Array.isArray(airbase.aircraft) ?
+ airbase.aircraft.slice(0, 3).join(', ') +
+ (airbase.aircraft.length > 3 ? '...' : '') :
+ 'Various aircraft';
+
+ return `
+ <div class="airbase-popup">
+ <div class="popup-header">${airbase.name}</div>
+ <div class="popup-info">
+ <span class="popup-label">ICAO:</span> ${icao}
+ </div>
+ <div class="popup-info">
+ <span class="popup-label">Country:</span> ${airbase.country}
+ </div>
+ <div class="popup-info">
+ <span class="popup-label">Region:</span> ${airbase.region.replace('_', ' ')}
+ </div>
+ <div class="popup-info">
+ <span class="popup-label">Coords:</span> ${airbase.coords[0].toFixed(3)}°, ${airbase.coords[1].toFixed(3)}°
+ </div>
+ <div class="popup-aircraft">
+ Aircraft: ${aircraftList}
+ </div>
+ <button class="select-airbase-btn" onclick="window.mapController.selectAirbase('${icao}')">
+ SELECT AIRBASE
+ </button>
+ </div>
+ `;
+ }
+
+ selectAirbase(icao) {
+ this.selectedAirbase = icao;
+ const airbase = MILITARY_AIRBASES[icao];
+
+ // Update airbase selection in UI
+ const airbaseSelect = document.getElementById('airbaseSelect');
+ if (airbaseSelect) {
+ airbaseSelect.value = icao;
+ airbaseSelect.dispatchEvent(new Event('change'));
+ }
+
+ // Highlight selected airbase
+ this.highlightSelectedAirbase(icao);
+
+ // Pan to airbase
+ const [lat, lon] = airbase.coords;
+ this.map.setView([lat, lon], 6);
+
+ // Close popup
+ this.map.closePopup();
+ }
+
+ highlightSelectedAirbase(icao) {
+ // Reset all markers to normal
+ this.airbaseMarkers.forEach(marker => {
+ const element = marker.getElement();
+ if (element) {
+ const icon = element.querySelector('div');
+ if (icon) {
+ icon.style.background = 'var(--accent-green)';
+ icon.style.boxShadow = '0 0 8px rgba(0, 255, 65, 0.6)';
+ }
+ }
+ });
+
+ // Highlight selected marker
+ const selectedMarker = this.airbaseMarkers.find(marker => {
+ const airbase = Object.entries(MILITARY_AIRBASES).find(([code, data]) =>
+ data.coords[0] === marker.getLatLng().lat &&
+ data.coords[1] === marker.getLatLng().lng
+ );
+ return airbase && airbase[0] === icao;
+ });
+
+ if (selectedMarker) {
+ const element = selectedMarker.getElement();
+ if (element) {
+ const icon = element.querySelector('div');
+ if (icon) {
+ icon.style.background = 'var(--warning-amber)';
+ icon.style.boxShadow = '0 0 12px rgba(255, 176, 0, 0.8)';
+ }
+ }
+ }
+ }
+
+ showPatrolArea(patrolAreaKey) {
+ // Clear existing patrol area layers
+ this.clearPatrolAreas();
+
+ const area = PATROL_AREAS[patrolAreaKey];
+ if (!area) return;
+
+ const { bounds } = area;
+
+ // Create rectangle for patrol area
+ const rectangle = L.rectangle([
+ [bounds.south, bounds.west],
+ [bounds.north, bounds.east]
+ ], {
+ color: '#1e3a5f',
+ fillColor: '#1e3a5f',
+ fillOpacity: 0.1,
+ weight: 2,
+ opacity: 0.6,
+ dashArray: '5, 5'
+ });
+
+ rectangle.addTo(this.map);
+ this.patrolAreaLayers.push(rectangle);
+
+ // Add label
+ const center = area.center;
+ const label = L.marker(center, {
+ icon: L.divIcon({
+ className: 'patrol-area-label',
+ html: `<div style="
+ color: var(--military-blue);
+ font-family: 'Courier New', monospace;
+ font-size: 11px;
+ font-weight: bold;
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
+ white-space: nowrap;
+ ">${area.name}</div>`,
+ iconSize: [120, 20],
+ iconAnchor: [60, 10]
+ })
+ });
+
+ label.addTo(this.map);
+ this.patrolAreaLayers.push(label);
+
+ // Fit bounds to show both airbase and patrol area
+ if (this.selectedAirbase) {
+ const airbase = MILITARY_AIRBASES[this.selectedAirbase];
+ const group = new L.featureGroup([rectangle, L.marker(airbase.coords)]);
+ this.map.fitBounds(group.getBounds(), { padding: [20, 20] });
+ }
+ }
+
+ clearPatrolAreas() {
+ this.patrolAreaLayers.forEach(layer => this.map.removeLayer(layer));
+ this.patrolAreaLayers = [];
+ }
+
+ fitToAirbase(icao) {
+ const airbase = MILITARY_AIRBASES[icao];
+ if (airbase) {
+ const [lat, lon] = airbase.coords;
+ this.map.setView([lat, lon], 6);
+ }
+ }
+
+ getMap() {
+ return this.map;
+ }
+}
+
+// Export for use in other modules
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = { MapController };
+}
\ No newline at end of file
diff --git a/mission-generator/js/mission-generator.js b/mission-generator/js/mission-generator.js
new file mode 100644
index 0000000..eb08ba6
--- /dev/null
+++ b/mission-generator/js/mission-generator.js
@@ -0,0 +1,350 @@
+// Mission Generation Logic
+class MissionGenerator {
+ constructor() {
+ this.missionTypes = {
+ 'MARITIME_PATROL': {
+ name: 'Maritime Patrol',
+ description: 'Search and surveillance of designated maritime areas',
+ objectives: [
+ 'Conduct surface surveillance of assigned patrol area',
+ 'Report any suspicious vessel activity to Maritime Operations Center',
+ 'Use FLIR camera system for vessel identification and classification',
+ 'Maintain communication with home base every 30 minutes',
+ 'Document all surface contacts with position and bearing'
+ ],
+ duration: '4-8 hours',
+ minAltitude: 1000,
+ maxAltitude: 25000,
+ equipment: ['FLIR-25HD Camera', 'Maritime Radar', 'ESM Suite', 'SATCOM']
+ },
+ 'SAR': {
+ name: 'Search and Rescue',
+ description: 'Locate and assist vessels or aircraft in distress',
+ objectives: [
+ 'Search designated area using FLIR and visual systems',
+ 'Identify and classify any surface contacts or debris',
+ 'Coordinate with rescue vessels and helicopters if targets located',
+ 'Provide accurate position updates to SAR coordination center',
+ 'Maintain search pattern integrity throughout operation'
+ ],
+ duration: '6-10 hours',
+ minAltitude: 500,
+ maxAltitude: 15000,
+ equipment: ['FLIR-25HD Camera', 'SAR Radar', 'Emergency Beacons', 'Life Rafts']
+ },
+ 'RECON': {
+ name: 'Reconnaissance',
+ description: 'Intelligence gathering over specified maritime areas',
+ objectives: [
+ 'Conduct covert surveillance of designated target area',
+ 'Use FLIR camera system for detailed observation and recording',
+ 'Document vessel movements, types, and activities',
+ 'Maintain operational security throughout mission',
+ 'Collect electronic intelligence where possible'
+ ],
+ duration: '3-6 hours',
+ minAltitude: 2000,
+ maxAltitude: 30000,
+ equipment: ['FLIR-25HD Camera', 'Electronic Intelligence Suite', 'Secure Communications']
+ },
+ 'ASW': {
+ name: 'Anti-Submarine Warfare',
+ description: 'Submarine detection and tracking operations',
+ objectives: [
+ 'Deploy sonobuoys in designated search pattern',
+ 'Monitor passive and active sonar contacts',
+ 'Use FLIR to identify surface vessels and periscopes',
+ 'Coordinate with naval vessels for prosecution',
+ 'Maintain acoustic tracking of subsurface contacts'
+ ],
+ duration: '6-12 hours',
+ minAltitude: 200,
+ maxAltitude: 10000,
+ equipment: ['FLIR-25HD Camera', 'Sonobuoy Dispenser', 'MAD Boom', 'Torpedoes']
+ },
+ 'FISHERY_PATROL': {
+ name: 'Fishery Protection',
+ description: 'Monitor fishing activities and enforce maritime regulations',
+ objectives: [
+ 'Patrol designated fishing zones and protected areas',
+ 'Identify and inspect fishing vessels using FLIR camera',
+ 'Report illegal fishing activities to coast guard',
+ 'Document vessel positions and fishing equipment',
+ 'Coordinate with patrol vessels for enforcement action'
+ ],
+ duration: '4-8 hours',
+ minAltitude: 1000,
+ maxAltitude: 15000,
+ equipment: ['FLIR-25HD Camera', 'Maritime Radar', 'Camera Systems', 'GPS Tracker']
+ }
+ };
+ }
+
+ generateMission(airbaseIcao, missionType, patrolArea) {
+ const airbase = MILITARY_AIRBASES[airbaseIcao];
+ const mission = this.missionTypes[missionType];
+ const area = PATROL_AREAS[patrolArea];
+
+ if (!airbase || !mission || !area) {
+ throw new Error('Invalid mission parameters');
+ }
+
+ const missionData = {
+ id: this.generateMissionId(),
+ codename: this.generateCodename(),
+ type: mission,
+ airbase: airbase,
+ airbaseIcao: airbaseIcao,
+ patrolArea: area,
+ patrolAreaKey: patrolArea,
+ callsign: this.generateCallsign(airbase.country),
+ aircraft: this.selectAircraft(airbase.aircraft, missionType),
+
+ // Timing
+ startTime: this.generateMissionTime(),
+ duration: mission.duration,
+
+ // Navigation
+ waypoints: generatePatrolWaypoints(patrolArea, 4),
+ distance: calculateDistanceToPatrolArea(airbase.coords, patrolArea),
+
+ // Communications
+ frequencies: this.generateFrequencies(),
+
+ // Security
+ authCode: this.generateAuthCode(),
+ classification: 'NATO RESTRICTED',
+
+ // Environmental
+ threatLevel: this.generateThreatLevel(),
+
+ // Generated timestamp
+ generatedAt: new Date().toISOString()
+ };
+
+ return missionData;
+ }
+
+ generateMissionId() {
+ const prefix = 'MP'; // Maritime Patrol
+ const date = new Date().toISOString().slice(2, 10).replace(/-/g, '');
+ const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
+ return `${prefix}${date}${random}`;
+ }
+
+ generateCodename() {
+ const adjectives = [
+ 'NORTHERN', 'SOUTHERN', 'EASTERN', 'WESTERN', 'CENTRAL',
+ 'BLUE', 'GREEN', 'RED', 'GOLD', 'SILVER',
+ 'SWIFT', 'SILENT', 'DEEP', 'HIGH', 'LONG',
+ 'SHARP', 'BRIGHT', 'DARK', 'CLEAR', 'STORM'
+ ];
+
+ const nouns = [
+ 'SENTINEL', 'GUARDIAN', 'WATCHER', 'HUNTER', 'SEEKER',
+ 'FALCON', 'EAGLE', 'HAWK', 'RAVEN', 'ALBATROSS',
+ 'TRIDENT', 'ANCHOR', 'COMPASS', 'BEACON', 'LIGHTHOUSE',
+ 'WAVE', 'TIDE', 'CURRENT', 'REEF', 'DEPTH'
+ ];
+
+ const adj = adjectives[Math.floor(Math.random() * adjectives.length)];
+ const noun = nouns[Math.floor(Math.random() * nouns.length)];
+
+ return `${adj} ${noun}`;
+ }
+
+ generateCallsign(country) {
+ const callsigns = {
+ 'USA': ['POSEIDON', 'CLIPPER', 'SEAHAWK', 'NEPTUNE', 'MARINER'],
+ 'UK': ['KINGFISHER', 'NIMROD', 'GUARDIAN', 'SENTINEL', 'PHOENIX'],
+ 'France': ['ATLANTIQUE', 'FALCON', 'DAUPHIN', 'MISTRAL', 'NAVAL'],
+ 'Germany': ['ORION', 'SEAKING', 'HURRICANE', 'VIKING', 'MARITIME'],
+ 'Italy': ['ATLANTICO', 'SPARTAN', 'HARRIER', 'VESUVIO', 'MARE'],
+ 'Canada': ['AURORA', 'MAPLE', 'ARCTIC', 'PACIFIC', 'ATLANTIC'],
+ 'Australia': ['WEDGETAIL', 'SOUTHERN', 'PACIFIC', 'ANZAC', 'CORAL'],
+ 'Netherlands': ['ORANGE', 'FALCON', 'SEAHORSE', 'NORDKAPP', 'ZUIDERZEE'],
+ 'Norway': ['POLAR', 'VIKING', 'ARCTIC', 'FJORD', 'MIDNIGHT'],
+ 'Spain': ['EAGLE', 'IBERIAN', 'ATLANTIC', 'PELICAN', 'GIBRALTAR'],
+ 'Portugal': ['NAVIGATOR', 'ATLANTIC', 'AZORES', 'CORMORANT', 'MAGELLAN']
+ };
+
+ const countryCallsigns = callsigns[country] || callsigns['USA'];
+ const base = countryCallsigns[Math.floor(Math.random() * countryCallsigns.length)];
+ const number = Math.floor(Math.random() * 99) + 1;
+
+ return `${base} ${number.toString().padStart(2, '0')}`;
+ }
+
+ selectAircraft(availableAircraft, missionType) {
+ // Mission-specific aircraft preferences
+ const preferences = {
+ 'MARITIME_PATROL': ['P-8A Poseidon', 'P-3C Orion', 'Atlantique 2', 'CP-140 Aurora'],
+ 'SAR': ['P-8A Poseidon', 'P-3C Orion', 'C-130J Super Hercules', 'ATR 72MP'],
+ 'RECON': ['P-8A Poseidon', 'EP-3E Aries', 'Atlantique 2', 'ATR 72MP'],
+ 'ASW': ['P-8A Poseidon', 'P-3C Orion', 'Atlantique 2', 'CP-140 Aurora'],
+ 'FISHERY_PATROL': ['P-3C Orion', 'ATR 72MP', 'C-295M', 'Falcon 50M']
+ };
+
+ const preferred = preferences[missionType] || availableAircraft;
+
+ // Find best match
+ for (const aircraft of preferred) {
+ if (availableAircraft.includes(aircraft)) {
+ return aircraft;
+ }
+ }
+
+ // Fallback to first available
+ return availableAircraft[0] || 'P-8A Poseidon';
+ }
+
+ generateMissionTime() {
+ const now = new Date();
+ // Generate mission start time 1-4 hours from now
+ const hoursFromNow = Math.floor(Math.random() * 3) + 1;
+ const startTime = new Date(now.getTime() + hoursFromNow * 60 * 60 * 1000);
+
+ // Round to nearest 15 minutes
+ const minutes = Math.round(startTime.getMinutes() / 15) * 15;
+ startTime.setMinutes(minutes, 0, 0);
+
+ return startTime.toISOString().slice(11, 16) + ' ZULU';
+ }
+
+ generateFrequencies() {
+ return {
+ base: `${(250 + Math.random() * 150).toFixed(3)}`,
+ maritime: `${(250 + Math.random() * 150).toFixed(3)}`,
+ guard: '121.500',
+ emergency: '243.000',
+ sar: `${(250 + Math.random() * 150).toFixed(3)}`
+ };
+ }
+
+ generateAuthCode() {
+ const words = [
+ 'ALPHA', 'BRAVO', 'CHARLIE', 'DELTA', 'ECHO', 'FOXTROT',
+ 'GOLF', 'HOTEL', 'INDIA', 'JULIET', 'KILO', 'LIMA',
+ 'MIKE', 'NOVEMBER', 'OSCAR', 'PAPA', 'QUEBEC', 'ROMEO',
+ 'SIERRA', 'TANGO', 'UNIFORM', 'VICTOR', 'WHISKEY', 'XRAY',
+ 'YANKEE', 'ZULU'
+ ];
+
+ const word1 = words[Math.floor(Math.random() * words.length)];
+ const word2 = words[Math.floor(Math.random() * words.length)];
+ const number = Math.floor(Math.random() * 100).toString().padStart(2, '0');
+
+ return `${word1}-${word2}-${number}`;
+ }
+
+ generateThreatLevel() {
+ const levels = ['LOW', 'MODERATE', 'ELEVATED', 'HIGH'];
+ const weights = [0.4, 0.35, 0.2, 0.05]; // Probability weights
+
+ const random = Math.random();
+ let cumulative = 0;
+
+ for (let i = 0; i < levels.length; i++) {
+ cumulative += weights[i];
+ if (random <= cumulative) {
+ return levels[i];
+ }
+ }
+
+ return 'LOW';
+ }
+
+ generateBriefing(missionData) {
+ const {
+ codename, type, callsign, aircraft, airbase, airbaseIcao,
+ patrolArea, startTime, duration, waypoints, distance,
+ frequencies, authCode, classification, threatLevel
+ } = missionData;
+
+ return `═══════════════════════════════════════
+ MARITIME PATROL MISSION
+ OPERATION ${codename}
+═══════════════════════════════════════
+
+CLASSIFICATION: ${classification}
+
+MISSION TYPE: ${type.name}
+CALLSIGN: ${callsign}
+AIRCRAFT: ${aircraft}
+
+DEPARTURE: ${airbase.name} (${airbaseIcao})
+PATROL AREA: ${patrolArea.name}
+MISSION START: ${startTime}
+ESTIMATED DURATION: ${duration}
+DISTANCE TO AREA: ${distance} nm
+
+PRIMARY OBJECTIVES:
+${type.objectives.map(obj => `▶ ${obj}`).join('\n')}
+
+AREA OF OPERATIONS:
+${patrolArea.description}
+
+KEY PATROL AREAS:
+${patrolArea.keyAreas ? patrolArea.keyAreas.map(area => `• ${area}`).join('\n') : 'Standard patrol pattern'}
+
+PATROL WAYPOINTS:
+${waypoints.map((wp, i) => `${i + 1}. ${wp.name}: ${wp.coords[0].toFixed(3)}°N ${Math.abs(wp.coords[1]).toFixed(3)}°${wp.coords[1] < 0 ? 'W' : 'E'}`).join('\n')}
+
+EQUIPMENT LOADOUT:
+${type.equipment.map(eq => `▶ ${eq}`).join('\n')}
+
+FLIR CAMERA OPERATION:
+▶ F9: Activate/Deactivate Camera
+▶ Mouse: Pan/Tilt Control
+▶ +/-: Zoom In/Out
+▶ Arrow Keys: Fine Adjustment
+▶ T: Cycle Visual Modes (Standard/Mono/Thermal)
+▶ SPACE: Target Lock (Red=Locked, Green=Scanning)
+
+COMMUNICATION FREQUENCIES:
+Home Base: ${frequencies.base}
+Maritime Ops: ${frequencies.maritime}
+SAR Coordination: ${frequencies.sar}
+Guard: ${frequencies.guard}
+Emergency: ${frequencies.emergency}
+
+THREAT ASSESSMENT: ${threatLevel}
+${this.getThreatDescription(threatLevel)}
+
+POTENTIAL HAZARDS:
+${patrolArea.threats ? patrolArea.threats.map(threat => `⚠ ${threat}`).join('\n') : '⚠ Standard maritime hazards'}
+
+SPECIAL INSTRUCTIONS:
+▶ Report all surface contacts immediately
+▶ Maintain minimum altitude ${type.minAltitude}ft AGL
+▶ Weather updates every 30 minutes
+▶ Emergency procedures per SOP-MAR-001
+
+AUTHENTICATION CODE: ${authCode}
+
+MISSION COMMANDER: Duty Operations Officer
+WEATHER BRIEFING: Available via SimBrief/PFPX
+NOTAMS: Check current NOTAMs for patrol area
+
+═══════════════════════════════════════
+ GOOD HUNTING - STAY VIGILANT
+═══════════════════════════════════════
+
+Generated: ${new Date().toUTCString()}`;
+ }
+
+ getThreatDescription(level) {
+ const descriptions = {
+ 'LOW': 'Routine patrol environment. Standard precautions apply.',
+ 'MODERATE': 'Heightened awareness required. Additional reporting protocols in effect.',
+ 'ELEVATED': 'Increased security measures. Avoid unnecessary risks.',
+ 'HIGH': 'Significant threat indicators. Mission-critical security protocols active.'
+ };
+ return descriptions[level] || descriptions['LOW'];
+ }
+}
+
+// Export for use in other modules
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = { MissionGenerator };
+}
\ No newline at end of file
diff --git a/mission-generator/js/patrol-areas.js b/mission-generator/js/patrol-areas.js
new file mode 100644
index 0000000..e779d86
--- /dev/null
+++ b/mission-generator/js/patrol-areas.js
@@ -0,0 +1,297 @@
+// Patrol Areas Database with intelligent region matching
+const PATROL_AREAS = {
+ 'North_Sea': {
+ name: 'North Sea Patrol Zone',
+ bounds: {
+ north: 62.0,
+ south: 51.0,
+ east: 8.0,
+ west: -4.0
+ },
+ center: [56.5, 2.0],
+ description: 'High-traffic shipping lane surveillance and fishery protection',
+ threats: ['Heavy commercial traffic', 'Weather deterioration', 'Fishing vessel interference'],
+ keyAreas: [
+ 'Dogger Bank fishing grounds',
+ 'Norwegian shipping lanes',
+ 'UK-Netherlands ferry routes',
+ 'Oil platform approaches'
+ ]
+ },
+
+ 'English_Channel': {
+ name: 'English Channel Transit Zone',
+ bounds: {
+ north: 51.5,
+ south: 49.0,
+ east: 2.5,
+ west: -5.0
+ },
+ center: [50.25, -1.25],
+ description: 'Critical maritime chokepoint monitoring and cross-channel surveillance',
+ threats: ['Dense commercial traffic', 'Multiple national jurisdictions', 'Restricted military areas'],
+ keyAreas: [
+ 'Dover Strait separation scheme',
+ 'Portsmouth-Le Havre ferry routes',
+ 'Channel Islands approaches',
+ 'Cherbourg naval approaches'
+ ]
+ },
+
+ 'Atlantic': {
+ name: 'North Atlantic Patrol Area',
+ bounds: {
+ north: 65.0,
+ south: 35.0,
+ east: -5.0,
+ west: -70.0
+ },
+ center: [50.0, -37.5],
+ description: 'Long-range maritime patrol and search and rescue operations',
+ threats: ['Extreme weather conditions', 'Long transit times', 'Limited diversion airfields'],
+ keyAreas: [
+ 'GIUK Gap surveillance',
+ 'Trans-Atlantic shipping lanes',
+ 'Grand Banks fishing areas',
+ 'Mid-Atlantic Ridge approaches'
+ ]
+ },
+
+ 'Mediterranean': {
+ name: 'Mediterranean Security Zone',
+ bounds: {
+ north: 45.0,
+ south: 30.0,
+ east: 36.0,
+ west: -6.0
+ },
+ center: [37.5, 15.0],
+ description: 'Central and Eastern Mediterranean patrol operations',
+ threats: ['International tensions', 'Migration routes', 'Multiple sovereign waters'],
+ keyAreas: [
+ 'Strait of Gibraltar approaches',
+ 'Central Mediterranean corridor',
+ 'Aegean Sea patrol zones',
+ 'Libyan coast surveillance'
+ ]
+ },
+
+ 'Gulf_of_Mexico': {
+ name: 'Gulf of Mexico Operations Area',
+ bounds: {
+ north: 31.0,
+ south: 18.0,
+ east: -80.0,
+ west: -98.0
+ },
+ center: [24.5, -89.0],
+ description: 'Gulf coast security and hurricane response operations',
+ threats: ['Hurricane season', 'Oil platform density', 'Drug interdiction operations'],
+ keyAreas: [
+ 'Mississippi Delta approaches',
+ 'Texas offshore platforms',
+ 'Florida Keys corridor',
+ 'Yucatan Channel surveillance'
+ ]
+ },
+
+ 'Pacific': {
+ name: 'Pacific Operations Area',
+ bounds: {
+ north: 50.0,
+ south: 20.0,
+ east: -120.0,
+ west: 120.0
+ },
+ center: [35.0, -180.0],
+ description: 'Wide-area Pacific maritime surveillance and patrol',
+ threats: ['Vast distances', 'Weather systems', 'International waters complexity'],
+ keyAreas: [
+ 'Hawaiian approaches',
+ 'Alaska fishing grounds',
+ 'West Coast shipping lanes',
+ 'Trans-Pacific routes'
+ ]
+ },
+
+ 'Arctic': {
+ name: 'Arctic Maritime Zone',
+ bounds: {
+ north: 85.0,
+ south: 66.5,
+ east: 180.0,
+ west: -180.0
+ },
+ center: [75.0, 0.0],
+ description: 'Arctic Ocean surveillance and search and rescue',
+ threats: ['Extreme cold conditions', 'Limited infrastructure', 'Ice navigation hazards'],
+ keyAreas: [
+ 'Northwest Passage routes',
+ 'Barents Sea approaches',
+ 'Greenland Sea patrol zones',
+ 'Svalbard approaches'
+ ]
+ },
+
+ 'Indian_Ocean': {
+ name: 'Indian Ocean Operations Area',
+ bounds: {
+ north: 30.0,
+ south: -50.0,
+ east: 120.0,
+ west: 30.0
+ },
+ center: [-10.0, 75.0],
+ description: 'Indian Ocean maritime security and anti-piracy operations',
+ threats: ['Piracy activity', 'Monsoon weather patterns', 'Long transit distances'],
+ keyAreas: [
+ 'Arabian Sea patrol zones',
+ 'Bay of Bengal surveillance',
+ 'Strait of Hormuz approaches',
+ 'Mozambique Channel security',
+ 'Malacca Strait monitoring',
+ 'Somali Basin anti-piracy'
+ ]
+ }
+};
+
+// Function to determine appropriate patrol areas based on airbase location
+function getPatrolAreasForAirbase(airbaseData) {
+ const { region, coords } = airbaseData;
+ const [lat, lon] = coords;
+
+ // Primary region assignment
+ const primaryAreas = [region];
+
+ // Add secondary areas based on geographic proximity
+ const secondaryAreas = [];
+
+ // Logic for secondary area assignment
+ switch (region) {
+ case 'North_Sea':
+ if (lat > 55) secondaryAreas.push('Arctic');
+ if (lon < 0) secondaryAreas.push('Atlantic');
+ secondaryAreas.push('English_Channel');
+ break;
+
+ case 'English_Channel':
+ secondaryAreas.push('North_Sea', 'Atlantic');
+ if (lat < 50) secondaryAreas.push('Mediterranean');
+ break;
+
+ case 'Atlantic':
+ if (lat > 55) secondaryAreas.push('Arctic');
+ if (lat < 45) secondaryAreas.push('Mediterranean');
+ if (lon > -20) secondaryAreas.push('North_Sea');
+ if (lon < -60) secondaryAreas.push('Gulf_of_Mexico');
+ break;
+
+ case 'Mediterranean':
+ secondaryAreas.push('Atlantic');
+ if (lat > 42) secondaryAreas.push('English_Channel');
+ break;
+
+ case 'Pacific':
+ if (lat > 45) secondaryAreas.push('Arctic');
+ if (lon > -130 && lat < 35) secondaryAreas.push('Gulf_of_Mexico');
+ break;
+
+ case 'Gulf_of_Mexico':
+ secondaryAreas.push('Atlantic');
+ if (lon < -90) secondaryAreas.push('Pacific');
+ break;
+
+ case 'Arctic':
+ if (lon > -30 && lon < 30) secondaryAreas.push('North_Sea');
+ secondaryAreas.push('Atlantic', 'Pacific');
+ break;
+
+ case 'Indian_Ocean':
+ if (lat > 20) secondaryAreas.push('Mediterranean');
+ if (lon > 100) secondaryAreas.push('Pacific');
+ if (lon < 50) secondaryAreas.push('Atlantic');
+ break;
+ }
+
+ return {
+ primary: primaryAreas,
+ secondary: secondaryAreas.filter(area => !primaryAreas.includes(area))
+ };
+}
+
+// Function to calculate distance between airbase and patrol area center
+function calculateDistanceToPatrolArea(airbaseCoords, patrolAreaKey) {
+ const area = PATROL_AREAS[patrolAreaKey];
+ if (!area) return Infinity;
+
+ const [lat1, lon1] = airbaseCoords;
+ const [lat2, lon2] = area.center;
+
+ // Haversine formula for great circle distance
+ const R = 6371; // Earth's radius in kilometers
+ const dLat = (lat2 - lat1) * Math.PI / 180;
+ const dLon = (lon2 - lon1) * Math.PI / 180;
+
+ const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
+ Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
+ Math.sin(dLon/2) * Math.sin(dLon/2);
+
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+ const distance = R * c;
+
+ return Math.round(distance);
+}
+
+// Function to generate patrol waypoints within an area
+function generatePatrolWaypoints(patrolAreaKey, numWaypoints = 4) {
+ const area = PATROL_AREAS[patrolAreaKey];
+ if (!area) return [];
+
+ const waypoints = [];
+ const { bounds } = area;
+
+ // Generate waypoints in a rough patrol pattern
+ for (let i = 0; i < numWaypoints; i++) {
+ const latRange = bounds.north - bounds.south;
+ const lonRange = bounds.east - bounds.west;
+
+ // Create a roughly rectangular patrol pattern
+ let lat, lon;
+
+ if (i === 0) {
+ // Northwest corner
+ lat = bounds.south + latRange * 0.8;
+ lon = bounds.west + lonRange * 0.2;
+ } else if (i === 1) {
+ // Northeast corner
+ lat = bounds.south + latRange * 0.8;
+ lon = bounds.west + lonRange * 0.8;
+ } else if (i === 2) {
+ // Southeast corner
+ lat = bounds.south + latRange * 0.2;
+ lon = bounds.west + lonRange * 0.8;
+ } else {
+ // Southwest corner
+ lat = bounds.south + latRange * 0.2;
+ lon = bounds.west + lonRange * 0.2;
+ }
+
+ waypoints.push({
+ name: `PATROL_${i + 1}`,
+ coords: [parseFloat(lat.toFixed(3)), parseFloat(lon.toFixed(3))],
+ description: `Patrol waypoint ${i + 1}`
+ });
+ }
+
+ return waypoints;
+}
+
+// Export for use in other modules
+if (typeof module !== 'undefined' && module.exports) {
+ module.exports = {
+ PATROL_AREAS,
+ getPatrolAreasForAirbase,
+ calculateDistanceToPatrolArea,
+ generatePatrolWaypoints
+ };
+}
\ No newline at end of file