The GPS control was serial-only. Adds a source picker (Serial NMEA /
gpsd) to the dashboard header:
- Backend: new gpsd_reader() thread speaks gpsd's line-delimited JSON
protocol directly (no gps client dep). Parses TPV/SKY into the same
gps_data + gps_history structure as the NMEA reader, so temporal
matching, exports, and everything downstream stay source-agnostic.
- /api/gps/connect now dispatches on source=serial|gpsd. Legacy body
{"port": "..."} still works and is treated as serial.
- /api/status reports gps_source and, for gpsd, gpsd_endpoint.
- Reconnect helper remembers which source was live and retries the
same endpoint.
- Frontend: source dropdown toggles between the serial port list and
a gpsd host:port input pair. Settings persist gps_source /
gpsd_host / gpsd_port alongside gps_port.
Useful when a system-wide GPS is already shared via gpsd (laptop puck
with gpsd -N, Android Bluetooth GPS bridged through gpsd, Pi feeding
several tools). Browser Geolocation source is unchanged.