# Pilot's Toolkit — Completed Milestones

*Last updated: February 28, 2026*

---

## 🏁 Release Candidate 1 (RC1) — February 28, 2026

Phase I feature set locked. Eight modules, both platforms at parity, all data externalized to versioned JSON (v3 split-file structure with per-aircraft isolation and graceful error handling).

**Modules:** Fuel Order, Pavement Strength, Crosswind, Fuel Buckets, HF Frequencies, Passdown, Flight Level ↔ Meters, Crew Rest
**Platforms:** Web (React/Vite), Android (Kotlin/Jetpack Compose)
**Data:** `reference.json` + `aircraft/{G450,G500,G650,G700}.json`

---

## Aircraft Data Status

| Aircraft | Pavement (ACN/PCN) | Pavement (ACR/PCR) | ESWL | Weight Limits | Fuel Buckets |
|----------|-------------------|-------------------|------|---------------|-------------|
| G450 | ⚠ Updated data pending | ⚠ Updated data pending | ✅ Formula | ✅ 42,000 / 74,600 / 75,000 | ✅ Built-in |
| G500 | ❌ Not started | ❌ Not started | ❌ Not started | ❌ Not started | ❌ Not started |
| G650 | ❌ Not started | ❌ Not started | ✅ Formula | ✅ 52,600 / 99,600 / 100,000 | ❌ Not started |
| G700 | ✅ Complete (±2%) | ✅ Complete (±2%) | ✅ Thresholds (S-85 / D-108) | ✅ 56,000 / 107,600 / 108,000 | ❌ Not started |

*Weight limits shown as: BEW / MTOW / Max Ramp*

---

## Phase I — Web & Android Apps

### Web (React/Vite)

- **Fuel Order Calculator** — ASTM D1250 Table 6B density correction replaces previous linear interpolation. Fuel density input at 15°C reference temperature with three-way unit toggle: specific gravity (SG), kg/L, or lb/US gallon (default) — values auto-convert when switching units. Default 0.810 SG / 6.76 lb/gal (typical Jet-A) so calculator works without a ticket in hand. Ambient temperature corrects the reference density using the ASTM thermal expansion coefficient and volume correction factor (K₀=346.4228, K₁=0.4388 for refined products). Results show both reference density (15°C) and corrected density at ambient temp in lb/gal. Jet-A spec range validation (0.775–0.840 SG). Outputs in US gallons, imperial gallons, and liters, all rounded up to nearest 10. Primary volume unit configurable in hamburger menu with locale-based auto-detection (US → US gal, UK/Caribbean Commonwealth → imp gal, everyone else → liters). °C/°F toggle with live value conversion on switch (integer rounding). Temperature defaults to °C (aviation standard). Auto-calc from Total Required minus On Board. Density display. Temperature warnings adjusted: danger below −40°C (freeze point), warning above +55°C. Fully supersedes the original `fuelorder.cpp` standalone calculator (retired).
- **Pavement Strength Module** — Full PCN/PCR system selector (PCR default) with ACN/ACR output, rigid and flexible pavement types, four subgrade categories (A–D). Dynamic "Airport PCN/PCR" label. Airport comparison banner (green pass / red exceed with percentage). When exceeded, reverse-solves the formula to display maximum allowable weight (rounded down to nearest 500 lbs), or indicates pavement cannot support the aircraft if the result is below basic empty weight. Partial availability support for aircraft with ESWL-only or threshold-only data.
- **Crosswind Calculator** — Combined wind direction/speed input (xxxxx format, auto-slash on blur), separate optional gust field, runway input accepting both runway number (01–36) and heading (010–360). Headwind/tailwind and crosswind components for sustained and gust winds. Tailwind values in red.
- **Fuel Buckets** — Slider-based stage length lookup with interpolated fuel burn. CSV import for operator-specific data via hamburger menu. Per-aircraft localStorage persistence. Named fuel profiles (see below).
- **Named Fuel Profiles** — Fuel bucket schedules are now named per operator/aircraft (e.g., "FLEXJET G450"). Both web and Android. CSV import prompts for a profile name (web: browser prompt, Android: defaults to filename). Profiles exportable as JSON files (`FUEL_PROFILE_name_aircraft.json`) with format identifier, aircraft ID, name, and bucket data — designed for sharing between crew members and devices. JSON import reads the embedded aircraft ID and name, targeting the correct aircraft automatically. Hamburger menu shows loaded profiles with name, aircraft, entry count, export/share button, and clear button. The FuelBucketsModule displays the active profile name. Backward-compatible: old anonymous bucket arrays auto-migrate to `{ name: "Custom", buckets: [...] }` on load. Android uses SharedPreferences storage (fuel_profiles), web uses localStorage.
- **HF Frequencies** — ARINC Atlantic/Pacific page age check via "Valid from" HTML parsing with fallback URL chain (tries each URL in order, stops at first valid response). Atlantic uses end-of-window time for staleness ("Frequencies Valid Until"). Pacific uses start time ("Frequencies Valid From"). 4-hour staleness warning. Date mismatch detection (accepts today/yesterday UTC to handle timezone boundary). Direct link to open ARINC page in browser (points to whichever URL succeeded).
- **Flight Level ↔ Meters** — Two sub-modes: Meters ↔ Feet lookup (OEM Table 15, 107 entries from 300 m / 1,000 ft through 15,100 m / 49,500 ft) with type-ahead search in either direction and exact match highlighting; and China RVSM FLAS (Figure 5, 50 entries) with dual eastbound/westbound toggle filter (both on = all levels, one off = filtered), RVSM level color coding (blue = eastbound 0°–179°, amber = westbound 186°–359°), and operational notes. Both platforms. Source: GVIII-G700 Operating Manual 06-10-00, 2024-03-29.
- **JSON Data Extraction** — All data externalized from inline code into JSON files shared across platforms. Version 3 split-file structure: `reference.json` (airframe-agnostic: meters-to-feet table, China FLAS table, pavement subgrade labels) and per-aircraft files (`aircraft/G450.json`, `G500.json`, `G650.json`, `G700.json`) each containing weight limits, ESWL config, PCN/PCR coefficients, fuel buckets, and wind limitations placeholder. Graceful error handling: each aircraft file loads independently — a malformed file is skipped with a log warning rather than crashing the app. Android uses `DataLoader.init(context)` parsing from `assets/`; web uses Vite static JSON imports with per-aircraft `loadAircraft()` wrapper. ESWL uses `type` discriminator (`formula` vs `thresholds`). Both platforms refactored and build-tested.
- **Crew Rest Calculator (Basic)** — Augmented operations rest period calculator for 3–4 pilots. Inputs: departure time (Zulu), ETE (accepts HH:MM, HHMM, or total minutes), and crew member IDs. Calculates sequential equal-division rest rotation after 30-minute all-hands blocks at departure and arrival. Output: flight summary with total rest window (including total minutes) and per-crew rest schedule with Zulu times. Lock toggle prevents accidental edits while referencing mid-flight; Android state persists across tab switches via `rememberSaveable`. Both platforms. This is a basic implementation — a more sophisticated version incorporating Part 117 compliance is under consideration but may not be attainable.
- **Passdown Module (Round 1)** — Crew passdown form: crew emails (PIC, SIC, Lead CA) at top, registration, date, airport (ICAO, auto-uppercase), FBO, FBO phone (auto-format 10-digit US on blur, clickable tel: link in detail view), maintenance status, narrative, oncoming crew emails (PIC, SIC) at bottom. IndexedDB storage with autocomplete dropdowns (sorted alphabetically) that learn from entries. History view with detail/edit/delete (two-tap confirm). Plain text export (copy to clipboard + email with all crew addresses auto-populated in TO field). Passdown tab in first position, Fuel tab retains default focus. Content card widens for Passdown.
- **Passdown Round 2** — .ptz export/import: gzipped JSON array format (batch-capable by design, single-file workflow for now). Email attachment options: plain text body only, .ptz attachment only, or both. Import: decompress → parse → deduplicate by ID → merge into local DB. Android file association for .ptz. Stale date prompt: if passdown date ≠ today when sending, user chooses "Send Anyway", "Update to Today & Send", or "Cancel". Send tracking: `lastSentAt` timestamp stamped on each send, shown in detail view and as ✉ indicator in history list (not delivery confirmation — tracks intent only). History age styling: today's passdowns get full accent color + left border, yesterday's are muted, older entries are dimmed at 60% opacity — instant visual triage. History search/filter: filter bar at top of history view with registration autocomplete dropdown and From/To date range fields; result count shown when filters active; "Clear" resets all filters. Batch export: "Export (N)" button appears when filters are active with results — exports all matching passdowns as a single .ptz file, sorted by date. Filename convention: `PASSDOWN_BATCH_REG_DATEFROM_DATETO.ptz` (single tail) or `PASSDOWN_BATCH_Nrecords_DATEFROM_DATETO.ptz` (mixed). Maintenance log view eliminated — registration + date range filtering covers the real use case. Narrative search deferred to TBD.
- **Passdown Batch Import Preview** — Import flow now shows a preview screen before committing. Each passdown in the .ptz file is listed with registration, date, location, and PIC. Duplicates (matching ID already in local DB) flagged with "DUPLICATE" badge and unchecked by default. User can select/deselect individual entries, select all, or select none. "Import (N)" commits only checked entries and learns lookups from imported data. Works for both file picker imports and Android file association (tapping .ptz in file manager). Replaces the previous all-or-nothing auto-import flow.
- **Global Aircraft Selector** — Compact chip in top bar, color-coded (teal bold for default, amber semibold for non-default). Full selector in hamburger menu with "Set Default" feature. Persistent via localStorage.
- **Dark Mode** — Toggle in hamburger menu, persisted in localStorage.
- **Hamburger Menu** — Aircraft selector, dark mode toggle, CSV import per aircraft, passdown retention settings (3/6/12/24/36 months or never, auto-purge on app open), About section.
- **UI Polish** — Leading zero stripping on heading inputs, side-by-side wind/gust fields, "Flight Time" label on buckets results, temperature field proportions (2/5 input, 3/5 toggle), disclaimer footer on all modules.
- **User Documentation** — `DOCUMENTATION.md` covering all eight modules (including Crew Rest), data file structure for editors (reference.json and per-aircraft JSON schema with field-level documentation), adding new airframes, .ptz file format (field table, filename conventions, manual inspection command), fuel profile JSON format, fuel bucket CSV format, and app settings.

---

### Android (Kotlin / Jetpack Compose)

- **Status:** Feature parity with web. All eight modules implemented including Crew Rest with lock toggle and rememberSaveable state persistence. Passdown with SharedPreferences/JSON storage, autocomplete, history, detail view with tappable phone (ACTION_DIAL), copy to clipboard, email intent with crew addresses, two-tap delete confirmation. Passdown retention settings in hamburger menu. Fuel profiles: CSV import, JSON import/export, profile management in hamburger menu. Flight Level ↔ Meters with lookup and China FLAS. Scrollable menu. Crosswind input uses focus-loss formatting (no cursor jumping). Data loaded from `assets/` JSON files via `DataLoader.init(context)` with per-aircraft error isolation.
- **Package:** `com.harshmallow.pilottoolkit`

---

## Architecture Notes

- **Web stack:** Single-file React component (toolkit.jsx, ~3400 lines), Vite dev server, no backend, no accounts.
- **Data files:** Split-file JSON structure (v3): `reference.json` (flight levels, subgrade labels) + per-aircraft files in `aircraft/` directory. Web imports via Vite; Android reads from `assets/` via `DataLoader`. Each aircraft file loads independently with graceful error handling.
- **Data storage (web):** localStorage for preferences, dark mode, fuel buckets CSV, retention settings. IndexedDB for passdown records and autocomplete lookups.
- **Data storage (Android):** SharedPreferences for all settings, aircraft defaults, passdown data (JSON serialization), and fuel profiles. Room/SQLite migration planned.
- **Data portability:** CSV import/export for fuel bucket data. Plain text / email export for passdowns. .ptz (gzipped JSON array) for structured import/export, batch-capable.
- **Formulas:** Linear regression fits derived from official aircraft manual charts. R² > 0.99 on all curves. Error estimates noted per aircraft.
- **Disclaimer:** "Not for operational use · Verify all calculations independently" on every module.
