2026-01-11 17:16:59 -07:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="en">
|
|
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>Pedestrian Simulator</title>
|
|
|
|
|
|
<link rel="stylesheet" href="style.css">
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div id="app">
|
|
|
|
|
|
<!-- Header with stats -->
|
|
|
|
|
|
<div id="header">
|
|
|
|
|
|
<div class="logo-section">
|
2026-01-11 17:56:54 -07:00
|
|
|
|
<h1>Pedestrian Simulator</h1>
|
2026-01-11 17:16:59 -07:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- User Menu -->
|
|
|
|
|
|
<div id="user-menu" class="user-menu" style="display: none;">
|
|
|
|
|
|
<img id="userAvatar" class="user-avatar" src="" alt="User" />
|
|
|
|
|
|
<span id="userName" class="user-name"></span>
|
|
|
|
|
|
<button id="kmlBrowserButton" class="icon-button" title="Browse KML Files">📂</button>
|
|
|
|
|
|
<button id="logoutButton" class="icon-button" title="Logout">🚪</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="stats-bar">
|
|
|
|
|
|
<!-- Unified Status Bar -->
|
|
|
|
|
|
<div class="stat-group clickable" id="routeInfoGroup">
|
|
|
|
|
|
<span class="stat-label">Route</span>
|
|
|
|
|
|
<span class="stat-value route-text" id="routeInfo">Not Started</span>
|
|
|
|
|
|
<span class="edit-icon" title="Reset/Change Route">✎</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="stat-group">
|
|
|
|
|
|
<span class="stat-label">Steps</span>
|
|
|
|
|
|
<span class="stat-value" id="currentSteps">0</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="stat-group">
|
|
|
|
|
|
<span class="stat-label">Distance</span>
|
|
|
|
|
|
<span class="stat-value" id="tripMeter">0.0 km</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="divider"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="stat-group">
|
|
|
|
|
|
<span class="stat-label">Next Sync</span>
|
|
|
|
|
|
<div class="stat-row">
|
|
|
|
|
|
<span class="stat-value" id="nextSync">--:--</span>
|
|
|
|
|
|
<button id="refreshButton" class="icon-button" title="Refresh Now">⟳</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Street View Container -->
|
|
|
|
|
|
<div id="streetview-container">
|
|
|
|
|
|
<div id="panorama"></div>
|
|
|
|
|
|
<div id="main-map" class="hidden-mode"></div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Minimap -->
|
|
|
|
|
|
<div id="minimap-container">
|
|
|
|
|
|
<div id="minimap"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Start Location Setup Overlay -->
|
|
|
|
|
|
<div id="setup-overlay" class="overlay active">
|
|
|
|
|
|
<div class="setup-card">
|
|
|
|
|
|
<h2>🌍 Plan Your Route</h2>
|
|
|
|
|
|
<p>Enter a start and finish location for your walk</p>
|
|
|
|
|
|
<div class="input-group">
|
|
|
|
|
|
<label>Start Location</label>
|
|
|
|
|
|
<input type="text" id="startLocationInput" placeholder="e.g., Central Park, NY" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="input-group">
|
|
|
|
|
|
<label>Destination</label>
|
|
|
|
|
|
<input type="text" id="endLocationInput" placeholder="e.g., Empire State Building, NY" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button id="startButton" class="primary-btn">Start Journey</button>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="separator">
|
|
|
|
|
|
<span>OR</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="custom-route-section">
|
|
|
|
|
|
<h3>📂 Use Saved Route</h3>
|
|
|
|
|
|
<p class="subtext">Browse and select from your uploaded KML files</p>
|
|
|
|
|
|
<button id="browseKmlButton" class="secondary-btn">Browse KML Files</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<p class="api-note">Note: You'll need a Google Maps API key configured</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- API Key Setup Overlay -->
|
|
|
|
|
|
<div id="apikey-overlay" class="overlay active">
|
|
|
|
|
|
<div class="setup-card">
|
|
|
|
|
|
<h2>🔑 Google Maps API Key Required</h2>
|
|
|
|
|
|
<p>Enter your Google Maps API key to use Street View</p>
|
|
|
|
|
|
<input type="text" id="apiKeyInput" placeholder="Your Google Maps API Key" />
|
|
|
|
|
|
<button id="saveApiKeyButton" class="primary-btn">Save & Continue</button>
|
|
|
|
|
|
<p class="help-text">
|
|
|
|
|
|
<a href="https://developers.google.com/maps/documentation/javascript/get-api-key"
|
|
|
|
|
|
target="_blank">
|
|
|
|
|
|
How to get an API key →
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="app-footer">
|
|
|
|
|
|
<a href="privacy.html" target="_blank">Privacy Policy</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Login Overlay -->
|
|
|
|
|
|
<div id="login-overlay" class="overlay">
|
|
|
|
|
|
<div class="setup-card">
|
|
|
|
|
|
<h2>🔐 Login Required</h2>
|
|
|
|
|
|
<p>Please login with your Fitbit account to continue</p>
|
|
|
|
|
|
<button id="fitbitLoginButton" class="primary-btn">Login with Fitbit</button>
|
|
|
|
|
|
<div class="privacy-link-container">
|
|
|
|
|
|
<a href="privacy.html" target="_blank" class="secondary-link">Privacy Policy</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- KML Browser Modal -->
|
|
|
|
|
|
<div id="kml-browser-overlay" class="overlay">
|
|
|
|
|
|
<div class="kml-browser-card">
|
|
|
|
|
|
<div class="kml-browser-header">
|
|
|
|
|
|
<h2>📂 KML File Browser</h2>
|
|
|
|
|
|
<button id="closeKmlBrowser" class="close-btn">×</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="kml-tabs">
|
|
|
|
|
|
<button class="kml-tab active" data-tab="my-files">My Files</button>
|
|
|
|
|
|
<button class="kml-tab" data-tab="public-files">Public Files</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="kml-tab-content">
|
|
|
|
|
|
<!-- My Files Tab -->
|
|
|
|
|
|
<div id="my-files-tab" class="tab-pane active">
|
|
|
|
|
|
<div class="upload-section">
|
|
|
|
|
|
<input type="file" id="kmlUploadInput" accept=".kml,.xml" style="display: none;" />
|
|
|
|
|
|
<button id="uploadKmlButton" class="primary-btn">📤 Upload KML File</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="sort-controls">
|
|
|
|
|
|
<label>Sort by:</label>
|
|
|
|
|
|
<select id="myFilesSortSelect">
|
|
|
|
|
|
<option value="date">Newest First</option>
|
|
|
|
|
|
<option value="distance">Distance</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="myFilesList" class="kml-file-list">
|
|
|
|
|
|
<p class="empty-message">No KML files uploaded yet</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Public Files Tab -->
|
|
|
|
|
|
<div id="public-files-tab" class="tab-pane">
|
|
|
|
|
|
<div class="sort-controls">
|
|
|
|
|
|
<label>Sort by:</label>
|
|
|
|
|
|
<select id="publicFilesSortSelect">
|
|
|
|
|
|
<option value="votes">Highest Votes</option>
|
|
|
|
|
|
<option value="date">Most Recent</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="publicFilesList" class="kml-file-list">
|
|
|
|
|
|
<p class="empty-message">No public KML files available</p>
|
|
|
|
|
|
</div>
|
2026-01-11 20:24:50 -07:00
|
|
|
|
|
|
|
|
|
|
<div class="pagination-controls">
|
|
|
|
|
|
<button id="prevPublicPage" class="action-btn" disabled>Previous</button>
|
|
|
|
|
|
<span id="publicPageNum">Page 1</span>
|
|
|
|
|
|
<button id="nextPublicPage" class="action-btn">Next</button>
|
|
|
|
|
|
</div>
|
2026-01-11 17:16:59 -07:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- General Confirmation Overlay -->
|
|
|
|
|
|
<div id="confirm-overlay" class="overlay">
|
|
|
|
|
|
<div class="setup-card">
|
|
|
|
|
|
<h2 id="confirmTitle">⚠️ Confirm</h2>
|
|
|
|
|
|
<p id="confirmMessage">Are you sure you want to proceed?</p>
|
|
|
|
|
|
<div style="display: flex; gap: 1rem; width: 100%;">
|
|
|
|
|
|
<button id="generalConfirmButton" class="primary-btn" style="flex: 1;">Yes</button>
|
|
|
|
|
|
<button id="generalCancelButton" class="control-btn" style="flex: 1;">Cancel</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script src="app.js"></script>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
|
|
|
|
|
|
</html>
|