PlateSolve++

You are given star-tracker detections from 4 frames and a reference star catalog.

Files:
  - frame1.csv ... frame4.csv   (detections)
  - catalog.csv                 (reference catalog)
  - seed.json                   (approx pointing for frame1 only)
  - cipher1.bin..cipher4.bin, nonce1.bin..nonce4.bin  (encrypted flag parts)
  - crypto.txt                  (cipher/key details)

Detections (frame*.csv):
  - x_px, y_px   : centroid pixel coordinates (0..2047)
  - flux         : brightness proxy (higher = brighter)
  - sigma_px     : width/uncertainty proxy (lower = sharper)
  - ts           : timestamp (not required)

Catalog (catalog.csv):
  - star_id      : integer identifier
  - ra_deg       : right ascension (degrees)
  - dec_deg      : declination (degrees)
  - mag          : magnitude (lower = brighter)

Goal:
  Plate-solve each frame, derive that frame’s key, and decrypt its ciphertext.
  Each decryption returns: "PART i/4: ...".
  Combine the 4 parts in order to get the final flag.

Notes:
  - Frames contain junk detections and a few very bright outliers; filtering helps.
  - The camera has radial lens distortion (a model with k1/k2 is sufficient).
