feat: add California SB 34 PRA plate audit generator, pre-trip commute route scanner, background audio driving guard, corridor density heatmap, and open data export (v26)

This commit is contained in:
2026-09-12 18:25:36 -07:00
parent 6783a0b3ba
commit 671c908c46
4 changed files with 1130 additions and 20 deletions
+140 -6
View File
@@ -54,7 +54,7 @@
<meta name="apple-mobile-web-app-title" content="FlockRadar">
<!-- Main Stylesheet -->
<link rel="stylesheet" href="css/styles.css?v=25">
<link rel="stylesheet" href="css/styles.css?v=26">
</head>
<body>
@@ -327,6 +327,11 @@
<span>Satellite / Dark</span>
</button>
<button id="btn-corridor-heatmap" class="btn-hud-action" title="Toggle Surveillance Density Corridor Heatmap">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M2 12h20M4.93 4.93l14.14 14.14M4.93 19.07l14.14-14.14"/></svg>
<span>Heatmap</span>
</button>
<button id="btn-fullscreen-mount" class="btn-hud-action" title="Toggle Fullscreen Dashboard Mount Mode">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>
<span>Fullscreen</span>
@@ -401,6 +406,61 @@
</button>
</div>
<!-- Pre-Trip Surveillance Commute Scanner -->
<div class="tools-group">
<div class="tools-group-label">PRE-TRIP ROUTE SCANNER</div>
<div class="route-scanner-container">
<select id="route-corridor-select" class="route-corridor-select" title="Select corridor to scan camera exposure">
<option value="">Choose Corridor to Scan...</option>
<option value="palmdale-blvd">Palmdale Blvd (SR-14 to 50th E) • 10 Cams</option>
<option value="10th-st-west">10th St West (Ave S to Ave L) • 8 Cams</option>
<option value="sierra-hwy">Sierra Hwy (Palmdale to Lancaster) • 5 Cams</option>
<option value="avenue-s">Avenue S (Cross-Town Corridor) • 4 Cams</option>
<option value="avenue-r-clean">Avenue R (Surveillance-Free Bypass) • 0 Cams</option>
</select>
<div id="route-scan-result" class="route-scan-result hidden">
<div class="scan-score-header">
<span class="scan-score-badge" id="scan-score-badge">EXPOSURE: HIGH</span>
<span class="scan-camera-count" id="scan-camera-count">10 Cameras</span>
</div>
<p class="scan-summary-text" id="scan-summary-text"></p>
<div class="scan-detour-box" id="scan-detour-box">
<strong class="detour-title">🟢 RECOMMENDED BYPASS:</strong>
<p id="scan-detour-text" class="detour-desc"></p>
<button type="button" id="btn-apply-route-bypass" class="btn-detour-apply">Show Clean Detour on Map</button>
</div>
</div>
</div>
</div>
<!-- Civic Privacy & SB 34 Plate Audit -->
<div class="tools-group">
<div class="tools-group-label">CIVIC PRIVACY & LEGAL AUDIT</div>
<button type="button" id="btn-open-pra-generator" class="btn-hud-action btn-tool-item btn-pra-accent" title="Generate formal California Public Records Act demand for license plate read logs">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
<span>Audit My Plate (CA SB 34 Request)</span>
</button>
<button type="button" id="btn-toggle-bg-audio" class="btn-hud-action btn-tool-item" title="Keep radar audio active when using Apple Maps or with locked screen">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 18v-6a9 9 0 0 1 18 0v6"/><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"/></svg>
<span id="bg-audio-label">Background Audio Guard: OFF</span>
</button>
</div>
<!-- Open Data Export -->
<div class="tools-group">
<div class="tools-group-label">OPEN CIVIC DATA EXPORT</div>
<div class="export-btn-grid">
<button type="button" id="btn-export-geojson" class="btn-hud-action btn-tool-item" title="Download camera nodes as GeoJSON for Google Earth / QGIS">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
<span>Export GeoJSON</span>
</button>
<button type="button" id="btn-export-csv" class="btn-hud-action btn-tool-item" title="Download camera nodes as CSV spreadsheet">
<svg class="flock-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
<span>Export CSV</span>
</button>
</div>
</div>
<div class="tools-group">
<div class="tools-group-label">DIAGNOSTICS & SYSTEM</div>
<button id="btn-test-alert" class="btn-hud-action btn-tool-item" title="Immediately test voice alert and radar siren">
@@ -1332,6 +1392,7 @@
<span>Choose Amount</span>
<svg class="flock-svg flock-svg-xs" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
</div>
</a>
</div>
<!-- Viral Share Alternative -->
@@ -1365,6 +1426,79 @@
</div>
</dialog>
<!-- ========================================================================
MODAL 5: CALIFORNIA SB 34 PUBLIC RECORDS ACT (CPRA) REQUEST GENERATOR
======================================================================== -->
<dialog id="pra-modal" class="agency-dialog pra-dialog" aria-labelledby="pra-modal-title">
<div class="modal-header pra-modal-header">
<div class="modal-header-left">
<span class="modal-badge badge-pra">CALIFORNIA SB 34 COMPLIANCE</span>
<h2 id="pra-modal-title" class="modal-agency-name">License Plate Audit Request Generator</h2>
<p class="modal-location-text">Exercise your legal right under Cal. Civil Code § 1798.90.5 & Gov. Code § 7920 to discover all police searches of your vehicle.</p>
</div>
<button class="modal-close-btn" id="pra-modal-close-btn" aria-label="Close Audit Generator">&times;</button>
</div>
<div class="modal-body pra-modal-body">
<!-- Input Parameters -->
<div class="pra-input-grid">
<div class="form-group">
<label for="pra-plate-input" class="form-label">License Plate #:</label>
<input type="text" id="pra-plate-input" class="form-input" placeholder="e.g. 8ABC123" maxlength="8" style="text-transform: uppercase;">
</div>
<div class="form-group">
<label for="pra-state-input" class="form-label">Registration State:</label>
<input type="text" id="pra-state-input" class="form-input" value="CA" maxlength="2" style="text-transform: uppercase;">
</div>
<div class="form-group">
<label for="pra-agency-select" class="form-label">Target Law Enforcement Agency:</label>
<select id="pra-agency-select" class="form-select">
<option value="palmdale">City of Palmdale / Los Angeles County Sheriff's Dept (LASD)</option>
<option value="lancaster">City of Lancaster / LASD Lancaster Station</option>
<option value="bakersfield">Bakersfield Police Department</option>
<option value="chp">California Highway Patrol (CHP)</option>
<option value="riverside">Riverside County Sheriff / DA</option>
<option value="other">Other California Municipal Agency</option>
</select>
</div>
<div class="form-group">
<label for="pra-requester-name" class="form-label">Your Name / Title:</label>
<input type="text" id="pra-requester-name" class="form-input" placeholder="Registered Vehicle Owner">
</div>
</div>
<div class="pra-actions-bar">
<button type="button" id="btn-generate-pra" class="btn-pra-generate">
<svg class="flock-svg flock-svg-sm" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
<span>Generate Formal CPRA Letter</span>
</button>
</div>
<!-- Generated Letter Preview Area -->
<div class="pra-letter-container" id="pra-letter-container">
<div class="pra-letter-header">
<span class="pra-letter-tag">FORMAL LEGAL NOTICE</span>
<div class="pra-letter-actions">
<button type="button" id="btn-copy-pra-letter" class="btn-letter-action" title="Copy letter to clipboard">
<svg class="flock-svg flock-svg-xs" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
<span>Copy Letter</span>
</button>
<a id="btn-email-pra-letter" href="#" class="btn-letter-action btn-letter-email" title="Open in your default email app">
<svg class="flock-svg flock-svg-xs" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
<span>Email Agency</span>
</a>
</div>
</div>
<textarea id="pra-letter-text" class="pra-letter-textarea" readonly placeholder="Click 'Generate Formal CPRA Letter' above to view your ready-to-send records request letter..."></textarea>
</div>
<!-- Legal Summary Callout -->
<div class="pra-legal-notice">
<strong>LEGAL MANDATE:</strong> Under California Government Code § 7922.535, public agencies must respond within 10 calendar days. Under California SB 34 (Civ. Code § 1798.90.55), agencies are strictly prohibited from selling, sharing, or transferring ALPR surveillance data to out-of-state or federal immigration authorities.
</div>
</div>
</dialog>
<!-- Hidden Native Camera / File Input for Mobile Evidence Snapping -->
<input type="file" id="camera-photo-file-input" accept="image/*" capture="environment" style="display: none;">
@@ -1375,11 +1509,11 @@
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- Data & Application Logic with Cache Busting -->
<script src="data/portals.js?v=25"></script>
<script src="js/icons.js?v=25"></script>
<script src="js/auth.js?v=25"></script>
<script src="js/radar.js?v=25"></script>
<script src="js/app.js?v=25"></script>
<script src="data/portals.js?v=26"></script>
<script src="js/icons.js?v=26"></script>
<script src="js/auth.js?v=26"></script>
<script src="js/radar.js?v=26"></script>
<script src="js/app.js?v=26"></script>
<!-- Service Worker Instant Cache Invalidation -->
<script>