feat(sdr): local receivers — browser RTL-SDR, Local ADS-B layer and decoder feeds (#732)

Adds a Local ADS-B layer fed by your own receivers: a browser WebUSB
RTL-SDR (with FM listening) and local 1090/978 MHz decoder feeds
(LOCAL_RECEIVER_FEEDS, local and private addresses only). Local aircraft
draw in magenta with class, silhouettes, 3D models, trails and a position
sanity filter; the click card names the band and input that heard them.

Builds on Sameh Khamis's SDR prototype and the initial GEV port by
Mazeyar Moeini Feizabadi (#134); the decoder-feed design follows the
notes on #57. Closes #57.

Co-authored-by: Sameh Khamis <[email protected]>
Co-authored-by: Mazeyar Moeini Feizabadi <[email protected]>
This commit is contained in:
authored and GitHub committed 2026-09-23 16:00:53 -05:00
1 parent 143cffd7ca
commit 1fc795577a
78 files changed
+12267 -108

No files matched your search

+4 -2
View File
@@ -415,8 +415,10 @@ test('a converted contact never consumes a 3D model CAP SLOT', async () => {
assert.match(loop, /keepDistSq/, `${name}: matched the model-eligibility loop`);
assert.match(loop, /if \(isTr3b\(icao\)\) continue;/,
`${name}: converted contacts are dropped BEFORE entering the capped candidate list`);
// ...and the cap really is applied to that list, so a dropped candidate is a freed slot.
assert.match(source, /modelEligible\.size >= cap/,
// ...and the cap really is applied to that list, so a dropped candidate is a
// freed slot. The four-pass selection itself is the shared
// selectModelEligible (behavior-tested in modelEligibility.test.mjs).
assert.match(source, /modelEligible\s*=\s*selectModelEligible\(\s*cand,\s*\{\s*cap,/,
`${name}: the cap bounds the candidate-derived eligible set`);
}
});