================================================================================
  JS8Reporter – Program Overview
  Version 1.7.5
  Stephen Clay McGehee, KN4AM
================================================================================


PURPOSE
-------
JS8Reporter is a companion application to JS8Spotter. It reads MCF505 Area
Assessment (F!505) forms, F!104 Situation Report forms, and F!309 Situation
Map Pin forms received over the air via JS8Call / JS8Spotter, and displays
that data visually on an offline map of North America. The goal is to give emergency managers and net control
operators a geographic picture of infrastructure conditions and operational
status across a wide area — without requiring any internet connection at
runtime.

JS8Reporter is designed primarily for the Raspberry Pi 4B running Raspberry
Pi OS, but also runs on Linux (Ubuntu/Debian) and Windows 10/11.


OPERATIONAL CONTEXT
--------------------
JS8Reporter sits at the end of a chain of amateur radio digital communication
tools:

  JS8Call (radio software) → JS8Spotter (message logging) → JS8Reporter (display)

  1. JS8Call is a weak-signal HF digital mode application. Operators transmit
     and receive structured text messages over amateur radio frequencies.

  2. JS8Spotter listens to JS8Call, captures incoming messages, and stores
     them in a SQLite database on the local machine.

  3. JS8Reporter reads that database (or imported files) and displays the
     assessment data on a map with filtering, analysis, and reporting tools.

All three programs run on the same machine. No internet connection is needed
once setup is complete.


FORM TYPES SUPPORTED
---------------------

MCF505 / F!505 – Area Assessment Form
  The MCF505 form (also called F!505 in its over-the-air encoding) is a
  32-field structured assessment of civilian infrastructure conditions. It
  covers eight categories:

    Category           Fields
    ----------------   -------------------------------------------------------
    Water              Water Distribution, Water Quality
    Sewage/Waste       Sewage System, Sewage Exposure, Trash Collection,
                       Trash Disposal
    Power              Power System, Power Distribution, Power Grid
    Communications     Internet, Landline, Cell, Mass Media, Postal System
    Economy            Residential Economy, Employment, Retail Commerce,
                       Means of Exchange, Commercial Infrastructure
    Transportation     Roads, Bridges, Airports
    Health/Safety      Medical Facilities, Medical Supplies, Emergency Services,
                       Police, Fire Department, Crime
    Social/Political   Leadership Attitude, Ethnic/Religious Tension,
                       Civil Disturbance, Controlling Authority

  Score scale for each field:
    @3 = Fully Operational
    @2 = Degraded
    @1 = Severely Impaired
    @0 = Destroyed / Non-functional
    @X = Unknown / N/A (excluded from all averages and calculations)

  The only free-text field is the Maidenhead Grid Square, which identifies
  the geographic location of the reporting station. All other fields are
  numeric scores or @X.

  Form specification published at:  https://sitrepnet.com/mcforms/MCF505.txt

F!104 – Situation Report Form
  The F!104 Situation Report is a simpler, single-status form that conveys
  an operator's overall operational status at their location:

    Status 1 = Normal (all operations normal)
    Status 2 = Degraded (under control, but degraded)
    Status 3 = Significant Problems

  F!104 records are stored in the same JS8Spotter database as F!505 records
  and are loaded automatically alongside them. They are displayed on the map
  as a separate, visually distinct layer.

F!309 – Situation Map Pin Form
  The F!309 Situation Map Pin form places a geographic marker on the map to
  report a specific event or situation. Unlike F!505 (infrastructure scoring)
  and F!104 (station status), F!309 is purely a map pin — it conveys what is
  happening, where, and how serious it is.

  Each F!309 pin encodes six fields:
    Affected Area   – Grid Square / city or county / state / region
    Category        – Event type (e.g., Flood, Fire, Medical, Evacuation…)
    Severity        – Minor through Major/Catastrophic, or Unknown
    Situation Frame – Imminence classification (imminent / on-going / chronic…)
    Current Status  – New / Ongoing Deteriorating / Improving / Resolved
    Expiration      – 24 hours, 48 hours, 3 days, 1 week, or 2 weeks

  F!309 pins expire automatically. Once a pin's expiration time (filing
  timestamp + expiration period) has passed, it is hidden from the map.
  The underlying record is retained but no longer displayed.

  F!309 records are stored in the same JS8Spotter database as F!505 and
  F!104 records and are loaded automatically alongside them.


DATA INPUT SOURCES
-------------------
JS8Reporter accepts data from three sources:

1. JS8Spotter Database  (File > Open Assessments Database…)
   Opens a JS8Spotter SQLite .db file directly. This is the primary method
   for live operations. The database is opened read-only, so it is safe to
   use while JS8Spotter is actively running and writing to the same file.

   F!505, F!104, and F!309 records are all loaded automatically from the
   same file. The database path is remembered; JS8Reporter reloads it
   automatically on every subsequent startup.

   Background polling: While a database is open, JS8Reporter polls it every
   60 seconds and automatically adds any new records that have arrived since
   the last load. No manual refresh is needed during monitoring sessions.

2. File Import  (File > Import F505 File… / File > Import F104 File…)
   Imports records from a single plain-text or JS8Spotter CSV export file.
   Useful for loading records prepared manually, received from another
   operator, or exported by external tools (e.g., 505processor).

   The F!505 import accepts the compact 41-character format (32-character
   score string + grid square without the F!505 marker prefix), which is
   the format used by the Export as F505 function and by 505processor.

3. Folder Import  (File > Import All Files from Folder…)
   Scans a configured folder and imports every .txt and .csv file it finds
   (automatically detecting F!505, F!104, and F!309 records in each), plus
   every .flags.json flag pin file found in the same folder.
   Useful for loading accumulated weekly report files to visualize trends.
   Clears all currently loaded F505/F104/F309 records before importing
   (with confirmation); flag pins are merged, not cleared.


CALL SIGN FILTERING (IGNORE.TXT)
----------------------------------
A plain-text file named IGNORE.TXT in the program folder lists call signs
whose assessments should never be loaded, regardless of source. Lines
beginning with # are comments; entries are not case-sensitive. This filter
applies to database loads, file imports, and folder imports.

On startup, if IGNORE.TXT has any entries, JS8Reporter displays a dialog
listing the ignored call signs as a reminder that the filter is active.


DEDUPLICATION
--------------
JS8Reporter automatically handles duplicate records:

  F!505 – same callsign, same calendar day:
    Only the most recently received submission is kept. Older submissions
    for the same callsign on the same day are discarded.

  F!505 – same Maidenhead grid square:
    Configurable in Settings. Options: use only the most recent assessment
    for that grid square, or average all assessments at that grid square.

  F!104 – same grid square:
    Only the most recently received F!104 record for each grid square is
    displayed.

  F!309 – unique UID (callsign + grid + timestamp):
    Each F!309 record is treated as unique. Multiple F!309 pins can exist
    at the same grid square simultaneously. Expired pins are hidden from
    display but retained in memory.


THE MAP
--------
The map is an offline North America base map rendered from Natural Earth
1:50m shapefiles (land masses, country borders, state/province borders,
lakes). It is completely self-contained — no internet connection, no tile
server, no external services.

Four layers of pins are drawn on top of the base map:

F!505 Area Assessment Pins (▼)
  Each valid F!505 record with a recognized Maidenhead grid square appears
  as an inverted-triangle map pin. The pin tip marks the exact grid square
  location. A solid circle above the triangle forms the "head" of the pin
  and makes it easier to click.

  Pin color represents the assessment score (determined by Pin Color Mode):
    Green  (#28a745)  =  Score @3  –  Fully Operational
    Yellow (#ffc107)  =  Score @2  –  Degraded
    Orange (#fd7e14)  =  Score @1  –  Severely Impaired
    Red    (#dc3545)  =  Score @0  –  Destroyed
    Gray   (#888888)  =  All fields @X  –  No scoreable data

  @X scores are excluded from all calculations. A record where every
  field is @X appears as a gray pin — the operator checked in but
  reported no data. Gray pins carry no callsign label on the map.

  Optional pin labels (Settings > Pin Colors): each scored pin can
  display the operator's callsign and current average beside it.

F!104 Situation Report Pins (◆)
  Each valid F!104 record appears as a solid filled diamond at its grid
  square location, drawn on top of the F!505 pin layer.

  Diamond color represents reported operational status:
    Green  (#28a745)  =  Status 1  –  Normal
    Yellow (#ffc107)  =  Status 2  –  Degraded
    Red    (#dc3545)  =  Status 3  –  Significant Problems

  F!104 pins carry no label. The F!104 layer can be toggled on or off via
  View > Show F!104 Pins.

F!309 Situation Map Pins (▲)
  Each valid, unexpired F!309 record appears as a solid upward triangle at
  its grid square location, drawn above the F!104 layer. The brief
  description field is annotated as a text label beside the pin.

  Triangle color represents Severity:
    Green  (#28a745)  =  Severity 1  –  Minor / Limited Impact
    Yellow (#ffc107)  =  Severity 2  –  Moderate
    Orange (#fd7e14)  =  Severity 3  –  Severe
    Red    (#dc3545)  =  Severity 4  –  Major / Catastrophic
    Gray   (#888888)  =  Severity 5  –  Unknown or N/A

  Pins expire automatically when the filing timestamp plus the encoded
  expiration period has passed. The F!309 layer can be toggled via
  View > Show F!309 Pins.

Flag Pins ⚑ (user-placed SitRep markers):
  Manually-placed teardrop pins in a user-chosen color with a short
  description label. Independent of received F!505/F!104 data. Used to
  annotate the map with situational awareness notes from any source.
  Right-click the map to place; right-click a pin to edit or delete.
  Managed via View > Flag Pins….

New Pin Highlight Ring:
  When "New pin highlight" is set to N hours (Settings > General), a bright
  magenta ring is drawn around every F!505, F!104, and F!309 pin received
  within that window. The ring stands out against the base map and makes
  recently-arrived pins visible at a glance. Set to 0 (default) to disable.

ALERT Badge (!):
  When an F!505 assessment or F!104 record carries an active ALERT:
    - A red circle containing a white "!" appears above the pin or diamond.
    - F!505 alert pins display in a red-orange color instead of their
      normal status color.
    - F!104 alert diamonds keep their status color but gain the "!" badge.

Circle Filter Overlay:
  When the Circle Filter is active, a dashed blue ellipse with a center
  crosshair and diameter label is drawn on the map. Only pins inside the
  circle are shown.

Map Legend (lower-left corner):
  A combined legend shows all map symbols (▼ ◆ ▲ ⚑ ○), the F!505 color
  scale, the F!104 color scale (omitted when F!104 pins are hidden), the
  F!309 severity scale (omitted when F!309 pins are hidden), and a Flag
  Pins entry (shown when at least one flag pin exists).

Map Navigation:
  The matplotlib toolbar below the map provides Home, Back, Forward, Pan,
  and Zoom tools. Zoom/pan state is preserved across map refreshes and
  Time Lapse steps.

Clicking a Pin:
  Clicking any F!505 pin, F!104 diamond, or F!309 triangle opens its
  detail in the panel at the bottom of the window.

Pop-Out Map  (View > Pop Out Map):
  The map can be detached into its own resizable window — useful for
  dual-monitor setups or to keep the map visible while working in the
  main window. The pop-out map updates on the same 60-second polling
  cycle. Closing the pop-out window docks the map back into the main
  window rather than dismissing it.


PIN COLOR MODES
----------------
Four modes control what score determines each F!505 pin's color
(Settings > Pin Colors):

  Lowest score across all fields:
    Pin reflects the single worst-scoring field in the entire assessment.

  Average of all fields (default):
    Pin reflects the overall average of all 32 scored fields (excluding @X).

  Average within selected category:
    Pin reflects the average score for one specific category.

  Lowest score within selected category:
    Pin reflects the worst-scoring field within one specific category.

Rounding (for average modes):
  Averaged scores are converted to whole-number color levels.
  Options: Standard rounding (default), Always round up, Always round down.


FILTERS
--------

Date Filter:
  Three modes (set in Settings > Filters, defaults to Previous 14 Days):

  No Filter:
    All loaded records are shown, regardless of date.

  Previous N Days (rolling):
    Shows only records from the past N days relative to today. The window
    automatically advances day by day so no manual adjustment is needed
    during continuous operation.

  Specified Dates:
    Shows only records between a user-specified From date and To date.

  The Date Filter also applies to Time Lapse mode (see below).

  Date source: the filter can apply to the received timestamp or the
  report prepared timestamp (useful when operators re-send old forms).

Circle Filter  (Circle menu):
  Restricts the map and all reports to records whose grid square falls
  within a specified radius of a center point. The center can be set by
  clicking on the map or by entering coordinates in Settings. Radius is
  in miles. The circle is drawn on the map as a geographic ellipse,
  which correctly represents equal distances in all directions on a
  lat/lon projection.

Category Display Filter  (Settings > Filters):
  Limits the map and reports to selected MCF505 categories only. All
  eight categories are included by default.

Duplicate Grid-Square Handling  (Settings > Filters):
  When multiple F!505 assessments share the same grid square, use only
  the most recent (default) or average the scores.


TIME LAPSE
-----------
Time Lapse steps the map through assessment dates to visualize how
conditions have changed over time (View > Time Lapse).

Navigation is manual: Left arrow steps back one date, Right arrow steps
forward one date. Dates wrap around at both ends.

Three modes (Settings > Filters > Time Lapse Mode):

  Rolling Window (default):
    Shows assessments within a sliding N-day window ending on the current
    playback date. As the date advances, earlier records drop off. This is
    the most useful mode for showing recent conditions.

  Cumulative:
    Shows all assessments up to and including the current playback date.
    The map builds up as time advances. Records from the current playback
    date are highlighted.

  Snapshot:
    Shows only assessments from the exact current playback date.

The date list is built from the merged set of F!505 and F!104 timestamps,
so F!104 records also appear in Time Lapse.


ALERT DETECTION
----------------
JS8Reporter automatically scans records for ALERT conditions:

  F!505 assessments:  the word "ALERT" appears in the message text.
  F!104 records:      the alert flag field in the form is set.

When detected:
  - A bold red notification bar appears at the top of the main window,
    identifying the form type, callsign, and grid square.
  - A "Cancel Alert" button appears next to the notification.
  - The alerting pin or diamond displays a red "!" badge on the map.
  - F!505 alert records are shown in bold red in the assessment list.

Clicking "Cancel Alert" dismisses the notification and clears all active
alert badges for both form types. Records arriving after the cancel will
trigger the notification again.

GPIO Alert Output (Raspberry Pi only):
  An optional feature that drives a physical GPIO pin HIGH while an ALERT
  is active, enabling an external warning light or buzzer. Configured in
  Settings > Filters > GPIO Alert Output. Uses Broadcom (BCM) pin numbering;
  default is BCM 17 (physical pin 11 on the 40-pin header).

Alert age threshold:
  On startup or reload, alerts older than a configurable number of hours
  (default: 24) are suppressed automatically. This prevents stale alerts
  from re-firing every time the program is restarted, while still alerting
  for records that arrived while the program was offline. Set to 0 to alert
  regardless of age. Configurable in Settings > Filters > Alerts.

Alert detection can be disabled entirely in Settings > Filters.


ASSESSMENT LIST AND DETAIL PANEL
----------------------------------
Left Panel – Loaded F505 Assessments:
  Lists all loaded F!505 assessments sorted by received date (most recent
  first). Color coding:
    Normal text   = Valid assessment
    Bold red      = Assessment contains an active ALERT
    Gray/italic   = Assessment marked as invalid (excluded from map/reports)

  Click an entry to select it and view its full detail.
  Press Delete to toggle an assessment's valid/invalid status (with
  confirmation). Invalid assessments are excluded from the map and all
  reports but remain visible in the list for reference. Valid/invalid
  status persists between sessions for database-loaded records.

Detail / Summary Panel (bottom-right):

  Summary Table ("Report Detail" — default view):
    Shows a grid of category averages for all currently visible F!505
    assessments, with Min / Max / Avg columns.

  F!505 Assessment Detail ("Report Detail"):
    Full field-by-field detail for a selected assessment: callsign, grid,
    coordinates, state, city/county, timestamps, source, SNR, frequency,
    overall average, per-category scores with color bars, all 32 field
    scores, and notes.

  F!104 Record Detail ("F!104 Detail"):
    Compact detail for a clicked F!104 diamond: callsign, grid, status
    code and label, filed date/time (UTC), age since filed, and alert
    flag if active.

  F!309 Map Pin Detail ("F!309 Detail"):
    Detail for a clicked F!309 triangle: callsign, grid, coordinates,
    description, category, severity, situation frame, current status,
    expiration period, filing date/time (UTC), expiration date/time,
    and age since filed.


REPORTS (Reports Menu)
------------------------
All reports open in a scrollable viewer with Save to Export Folder and
Save As… buttons. Reports respect the active Date Filter and Circle Filter.

  Area Assessment Summary
    Category averages for each reporting station with Min/Max/Avg columns.
    This is the same table shown in the summary panel.

  Full Detail Report
    Complete field-by-field detail for every visible assessment. Formatted
    for printing or filing.

  Score Rankings
    All stations sorted from worst to best overall average score. Useful
    for quickly identifying the most severely affected areas.

  Category Focus  (submenu – 8 categories)
    Field-level scores for all stations, filtered to one category. Stations
    sorted worst to best for that category.

  Alert Records
    Lists only assessments that contain an ALERT, with full detail for each.

  Geographic Summary
    Assessments grouped and subtotaled by state, sorted alphabetically.
    Useful for briefing by jurisdiction.

  Critical Infrastructure
    Lists every infrastructure field (1–32) scored 0 (Destroyed) or 1
    (Severely Impaired) by any station. Shows which stations reported each
    critical condition.

  Trend Analysis
    Shows stations that submitted assessments on more than one date, with
    scores for each date and a direction arrow (↑ ↓ →) indicating whether
    conditions improved, worsened, or held steady.

  Infrastructure Heat Map
    For each category, shows how many field scores fall at each level
    (0/1/2/3/N/A) with percentages. Quick overview of overall conditions.

  Data Quality / Coverage
    Each station's number of fields reported, completion percentage, and
    assessment age in days. Useful for identifying incomplete or old reports.

  Worst Conditions
    Stations ranked by their single worst category average score (lowest
    first). Highlights where the most severe problems are concentrated.

  Network Coverage
    All reporting grid squares with coordinates and date of most recent
    assessment. Sorted north-to-south, west-to-east. Useful for mapping
    network coverage.

  F!104 Summary
    All currently filtered F!104 records in a compact table: callsign, grid,
    status code and label, filed date. Alert records marked with "!".


FLAG PINS
----------
Flag pins are manually-placed situational awareness markers, independent of
received radio traffic. A net control or SitRep officer can place flag pins to
annotate the map with information gathered from any source (radio reports,
voice nets, written messages), then export the pin set and distribute the file
over the radio net for other operators to import.

Workflow:
  1. Right-click any map location → Add Flag Pin Here…
     Fill in Description, Grid Square, Date/Time, Source, and Color.
  2. View > Flag Pins… opens the management dialog:
       - Add, Edit, Delete, Jump to Map location
       - Export — saves all pins to a .flags.json file (includes operator
         callsign as created_by; set in Settings > General)
       - Import — merges pins from a .flags.json file; incoming pins replace
         existing ones only if the incoming updated_at is newer
     File > Export Flag Pins… exports directly without opening the dialog.
  3. Distribute the .flags.json file to other operators.
     Recipients import it; their existing flags are updated if newer.

File format:  sitrep_flags JSON (.flags.json), fully interoperable with
MHGridMapper. The format carries an updated_at timestamp per pin enabling
correct merge behavior when the file is redistributed after updates.

Station callsign (created_by) is set in Settings > General > Station Callsign.


MHGRIDMAPPER LIVE SYNC
-----------------------
When a JS8Spotter database is open, JS8Reporter automatically exports data
for MHGridMapper after every poll cycle and on startup auto-reload:

  data/exports/mhgridmapper_stations.csv  — F!505 assessments
  data/exports/mhgridmapper_f104.txt      — F!104 situation reports
  data/exports/mhgridmapper_f309.txt      — F!309 map pins

MHGridMapper (a companion mapping tool) watches these files for changes and
updates its own map automatically when both programs are running side by side.

The exports apply JS8Reporter's active date filter, deduplication, and circle
filter so both programs always show the same picture. Time Lapse is
intentionally excluded; MHGridMapper always shows the full filtered date range
rather than a single Time Lapse frame. Filter changes in JS8Reporter propagate
to MHGridMapper immediately rather than waiting for the next poll cycle.

No configuration is required. If MHGridMapper is not installed or not running,
the export files are simply written and ignored.


EXPORTING DATA
---------------
  Save Text Report  (File > Save Text Report…  Ctrl+S)
    Saves the Area Assessment Summary table plus full detail for every
    visible assessment as a single formatted text file.

  Export F505 Data  (File > Export F505 Data (CSV/TSV)…  Ctrl+T)
    Exports all visible F!505 assessments as a CSV or TSV file (one row per
    assessment). Columns include callsign, grid, state, timestamps, all
    category averages, and all 32 individual field scores.

  Export Map Image  (File > Export Map Image…  Ctrl+E)
    Saves the current map view as PNG (default), JPEG, or SVG.

  Export as F505  (File > Export as F505…)
    Saves all visible F!505 assessments to a plain-text file in the compact
    F505 format, suitable for transfer to another operator who can import
    the file into their copy of JS8Reporter.

  Export as F104  (File > Export as F104…)
    Saves all visible F!104 Situation Report records to a plain-text file
    in the over-the-air F!104 format (one record per line).

  Export Flag Pins  (File > Export Flag Pins…)
    Saves all current flag pins to a .flags.json file in the sitrep_flags
    format, interoperable with MHGridMapper. Also available via the Export
    button in the View > Flag Pins… management dialog.

  Export Folder:
    All "Save to Export Folder" operations save automatically to
    data/exports/ (or a custom folder set in Settings > Export).


SETTINGS DIALOG  (Settings > Preferences…)
--------------------------------------------
The Settings dialog has five tabs:

  General
    Station Callsign — used as the created_by field in flag pin exports.

  Pin Colors
    Pin color mode, category (for category-specific modes), rounding
    method for averages, and pin label display toggle.

  Filters
    Duplicate grid-square handling, category display filter, Time Lapse
    mode and rolling window size, alert enabled toggle, alert age threshold
    (suppress alerts older than N hours on startup), GPIO alert output
    (Raspberry Pi only).

  Circle
    Circle center latitude and longitude, and radius in miles.

  Export
    Map image format (PNG/JPEG/SVG), tabular data format (CSV/TSV),
    default export folder, and import records folder.

  Auto-Update
    Enable/disable update check on startup, and the version check URL.

All settings are saved to data/settings.json and restored on next startup.
Window sizes and positions are also saved and restored.


AUTO-UPDATE
------------
On startup, JS8Reporter optionally checks a URL (SitRepNet.com) for a newer
release. The check runs in a background thread with a 4-second timeout and
is silently skipped if the network is unavailable. The user must explicitly
approve any update before it is applied. Offline operation is never affected.
The update check URL is configurable in Settings > Auto-Update. The URL
returns a small JSON file (version.json) with the current version tag.


TECHNICAL ARCHITECTURE
-----------------------
  Language:       Python 3.9+
  GUI framework:  Tkinter (included with Python)
  Map rendering:  matplotlib with pyshp (reads Natural Earth shapefiles)
  Data storage:   SQLite (JS8Spotter database, read-only access)
  Settings:       JSON file (data/settings.json)
  Image export:   Pillow (PNG, JPEG); matplotlib SVG backend

  Single-file application: the entire program is in js8reporter.py.
  No server, no database of its own, no internet required at runtime.

  Map data: four Natural Earth 1:50m shapefiles (land, countries,
  states/provinces, lakes) downloaded once by setup.py from naciscdn.org
  and stored in data/shapefiles/. Approximately 8 MB total.

  JS8Spotter database access: the "forms" table is queried for rows with
  typeid matching F!505, F!104, and F!309 records. The database is opened
  with SQLite's read-only URI mode to ensure safety while JS8Spotter is
  running.


FILE STRUCTURE
---------------
  js8reporter/
  ├── js8reporter.py          Main application (single file)
  ├── setup.py                One-time installation script
  ├── run.sh                  Linux/Raspberry Pi launcher
  ├── run.bat                 Windows launcher
  ├── JS8Reporter.ico         Windows icon
  ├── JS8Reporter.png         Linux icon (generated by setup.py)
  ├── JS8Reporter.svg         Source SVG icon
  ├── js8reporter.desktop     Desktop launcher template (Linux)
  ├── IGNORE.TXT              (optional) Call signs to suppress
  ├── JS8Reporter_User_Manual.txt
  ├── Installation_Guide.txt
  ├── JS8Reporter_Program_Overview.txt  (this file)
  ├── Packaging_Instructions.txt
  ├── PROJECT_NOTES.txt
  ├── CHANGELOG.md
  ├── README.md
  ├── LICENSE
  ├── flag_manager.py         Flag pin persistence and import/export
  ├── flag_dialog.py          Flag pin add/edit and management dialogs
  ├── maidenhead.py           Maidenhead grid utilities
  ├── grid_converter.py       Maidenhead ↔ MGRS/USNG coordinate converter
  └── data/
      ├── settings.json       User preferences (auto-generated)
      ├── flags.flags.json    Flag pin store (auto-generated, sitrep_flags format)
      ├── shapefiles/         Natural Earth map data (downloaded by setup.py)
      ├── exports/            Default location for saved reports and exports
      └── imports/            Default location for folder-import source files


INSTALLATION SUMMARY
---------------------
One-time setup (requires internet):

  Linux / Raspberry Pi:
      cd ~/js8reporter
      python3 setup.py

  Windows:
      cd C:\Users\<username>\js8reporter
      python setup.py

setup.py performs three steps:
  [1/3] Creates a Python virtual environment in venv/ and installs:
        matplotlib, numpy, pyshp, Pillow, mgrs
  [2/3] Downloads Natural Earth shapefiles to data/shapefiles/
  [3/3] Installs the desktop launcher (.desktop file on Linux,
        .lnk shortcut on Windows)

setup.py is idempotent — safe to re-run, skips steps already complete.
It also detects and rebuilds a stale venv when the Python version has
changed (e.g., after an OS upgrade), without re-downloading map data.

After setup, no internet is ever required.


PLATFORMS
----------
  Primary:   Raspberry Pi 4B, Raspberry Pi OS Bullseye or Bookworm
  Also runs: Ubuntu, Debian, and most Linux distributions
             Windows 10 / 11


VERSION HISTORY SUMMARY
------------------------
  v1.1.0  2026-03-11  Initial release
  v1.2.0  2026-03-11  Broader JS8Spotter DB compatibility; DB Diagnostic tool
  v1.3.0  2026-03-13  Date filter, Time Lapse, ALERT detection, score bars
  v1.3.1  2026-03-15  Deduplication fix; off-map grid flagging
  v1.3.2  2026-03-17  Cross-platform setup.py; run.sh / run.bat launchers
  v1.4.0  2026-03-21  N-Day rolling filter, auto-advancing date window,
                       auto-polling of open database, zoom/pan preservation
  v1.4.1  2026-03-24  Date source option, sort by received date, datecode fixes
  v1.4.2  2026-05-03  Export as F505, Import All Files from Folder
  v1.4.3  2026-05-04  GPIO alert output (Raspberry Pi)
  v1.4.5  2026-05-07  IGNORE.TXT; GPIO detection fix; Help > About cleanup
  v1.4.6  2026-05-16  Accept compact 41-character F!505 format in file imports
  v1.4.7  2026-05-17  setup.py / run.sh robustness for Python version changes
  v1.4.8  2026-05-26  ALERT pin badges (red "!" on map)
  v1.4.9  2026-05-29  Time Lapse simplified to manual arrow-key navigation
  v1.5.0  2026-06-02  F!104 Situation Report overlay (diamond pins, detail
                       panel, F!104 Summary report, ALERT detection, Time
                       Lapse integration, Import F!104 File, Map Symbols legend)
  v1.5.1  2026-06-07  Fix: map Home button always returns to full extent
  v1.5.2  2026-06-07  Fix: cache shapefile geometry to eliminate render sluggishness
  v1.5.3  2026-06-07  Speed up map rendering with LineCollection/PolyCollection;
                       animated progress bar during startup and pop-out/dock
  v1.5.4  2026-06-09  Fix: re-received F!505 forms update received_time so
                       "Record Date/Time Stamp" filter reflects latest receipt;
                       File > Export as F!104 menu item
  v1.6.0  2026-06-13  Flag Pins: manually-placed SitRep markers; import/export
                       in sitrep_flags format; interoperable with MHGridMapper;
                       Settings > General tab with Station Callsign field
  v1.7.0  2026-06-13  Tools > Grid Converter (Maidenhead ↔ MGRS/USNG);
                       File > Export Flag Pins…; Import All Files from Folder
                       now includes .flags.json; combined right-click context
                       menu for overlapping pins; zoom auto-exits after use;
                       Escape exits Pan/Zoom mode; menu label clarifications
  v1.7.1  2026-06-15  Grid Converter now accepts decimal Lat, Lon input in
                       addition to Maidenhead and MGRS/USNG
  v1.7.2  2026-06-17  F!309 Situation Map Pin (▲ triangle, severity colors,
                       auto-expiration, DB/file/folder import, detail panel,
                       MHGridMapper sync); ALERT age threshold (suppress
                       alerts older than N hours on startup, default 24h);
                       MHGridMapper live sync exports F!505, F!104, F!309
  v1.7.3  2026-06-17  Fix: F!309 triangle (▲) missing from Map Symbols legend
  v1.7.4  2026-06-19  Fix: all-X F!505 records now show as gray pin instead
                       of being silently dropped; gray pins carry no label;
                       MHGridMapper sync timestamps exported in local time;
                       received_time embedded as datecode for records with no
                       form datecode (prevents "age 0" in MHGridMapper popups)
  v1.7.5  2026-06-20  Age field in F!505, F!104, and F!309 detail panels;
                       F!104 callsign fixes (import and export); panel renamed
                       to "Loaded F505 Assessments"; GPIO layout fix (Pi)


DEVELOPER NOTES
----------------
  Developer:      Stephen Clay McGehee, KN4AM
  Development:    Claude Code AI assisted
  GitHub:         https://github.com/StephenClayMcGehee/JS8Reporter
  More info:      SitRepNet.com
  License:        MIT


================================================================================
  End of JS8Reporter Program Overview
================================================================================
