Protect & storage lists:
- protect.csv: unlocked garage cars (state != 0, locked == false) worth
locking more copies of. Needed copies = best configs surviving the
RQ-band thresholds (prize cars and RQ >= 80 always count); already
locked copies (copy_count) are subtracted, surplus drops off the list.
- storage.csv: Keep/Trash recommendation for storage cars (state == 0)
using the same copy-count logic; surplus unlocked copies are fusion
material.
- user_data.rs now parses card state (garage vs storage), garage slots
(user.garageSlots/garageSlotsUsed), and unlocked card maps.
Dynamic trash thresholds:
- TrashThresholds derive RQ 20-29/30-39 as half/a quarter of a base
value (--trash-base-count, default 4); RQ 40+ never covered.
- plan_trash_rules escalates the base automatically while projected free
garage slots (capacity - used + unlocked non-best copies + new trash
candidates, copies counted per card) stay below --garage-min-free
(default 20), stopping when no further cars qualify. Effective
thresholds and projection are printed.
- Improve-based low-value cars (best target count at or below the band
threshold) land in trash.csv; collect_improve_entries is shared with
improve.csv and computed once per run.
Same-car tie resolution:
- resolve_tied_configs collapses tie-equivalent configs of the same car
per track (compute_car_counts, write_details_csv), preferring the
player's owned final-build config. Fixes phantom rows like the
Mercedes 280 SL 332 entry tied at 61.31 by its owned 323, inflated
per-config track counts, and pointless second-copy recommendations.
Wishlist:
- Prize cars are excluded from the ideal wishlist and surface in
remove.csv via the ideal-set difference.
CLI: new protect command; --trash-base-count/--garage-min-free on
trash/protect/all; details command reuses counts for tie resolution.
README updated for all new files, flags, and criteria.
- Add improve command to all command tables and usage sections
- Add normalized_config field to BestCarRecord struct documentation
- Update CarCounts.by_rid type from String to (String, String)
- Update CarCounts.guid_to_rid type to HashMap<String, HashSet<(String, String)>>
- Add owned_configs field to MyCarsData and CarCounts docs
- Add normalize_to_final_build() to API docs
- Update CSV format examples to include FinalBuild column
- Update my_cars.json structure with engineMajor/weightMajor/chassisMajor
- Update timing file example with v2c_ version prefix
- Add version prefix stripping to data transformation docs
- Update CHANGELOG.md with Unreleased section
- Fix compare_records description to include normalized config sorting
- Replace stdout output with structured CSV file generation
- Add wishlist, all commands with --min-count and --max-wishlist flags
- Introduce CarCounts struct for shared analysis computation
- Improve error handling: return Result instead of unwrap/panic
- Add prize field to BestCarRecord
- Remove TODO.md
- Extract shared types (Car, BestCarRecord, AnalysisContext) into src/lib.rs
- Replace global static BEST_CARS with injected AnalysisContext for testability
- Add semaphore-bounded concurrency (limit 20) in parse_all_times()
- Replace hardcoded track name match with track_names.json loaded via include_str!
- Replace magic number 115 with const MAX_RQ: u8 = 113
- Improve floating-point tie comparison with TIME_TOLERANCE (5ms) constant
- Remove src/club.rs binary (topdrives.club no longer maintained)
- Remove scraper dependency from Cargo.toml
- Remove tracks.txt (replaced by track_names.json)
- Remove empty/placeholder test bodies
- Improve error handling in get_file() for response body read
- Add load_my_cars_data() combining owned + wishlist extraction in one I/O
- Update CHANGELOG, README, and all docs to reflect changes