This is an Ocean Network Express (ONE) booking confirmation (titled 'Booking Receipt Notice', issued by an 'OCEAN NETWORK EXPRESS …' branch/agent on the 'From :' line).

The document is a fixed key/value form. Three vessel slots may appear: 'Pre Carrier', 'Trunk Vessel', and 'Post Carrier' — each with its own 'IMO/Flag/Call Sign' line and 'Latest ETA/ETD' (or 'ETA/ETD') cell. The 'Latest ETA/ETD' value '<ETA>/<ETD>' is the vessel's arrival/departure at the port where that vessel LOADS the cargo (POL for the first vessel, T/S Port for a connecting vessel).

transportLegs rules:
- Ocean only. The cargo path is determined by which carrier slots have a populated 'IMO/Flag/Call Sign' line (IMO present = ocean vessel on this leg):
  - Only Trunk Vessel populated → exactly 1 leg, POL → POD.
  - Pre Carrier + Trunk Vessel populated (Post Carrier empty) → 2 legs. Pre Carrier feeder runs POL → T/S Port, then Trunk runs T/S Port → POD.
  - Trunk Vessel + Post Carrier populated (Pre Carrier empty) → 2 legs. Trunk runs POL → T/S Port, then Post Carrier feeder runs T/S Port → POD.
  - Pre Carrier + Trunk Vessel + Post Carrier ALL populated → 3 legs (rare). The document prints only ONE 'T/S Port' value, but the actual route has TWO transhipments — the second T/S city is NOT printed in the document. Emit: leg 1 Pre Carrier POL → printed T/S Port; leg 2 Trunk Vessel printed T/S Port → null (the unprinted second T/S); leg 3 Post Carrier null → POD. Do NOT invent or infer the second T/S city; leave it null on both leg 2 portOfDischarge and leg 3 portOfLoading. All three vessels MUST be emitted, never collapsed.
- Pre/Post Carrier inland-skip guardrail: emit a Pre/Post Carrier as a leg ONLY when its 'IMO/Flag/Call Sign' line is populated (IMO present = ocean feeder vessel). If a Pre/Post Carrier slot is filled but its 'IMO/Flag/Call Sign' is entirely blank, it represents inland pre/on-carriage (rail/truck/barge) and must NOT be emitted as a transport leg.
- Per-shape mapping:
  - SINGLE LEG (Direct):
    - portOfLoading = 'Port of Loading' city; portOfDischarge = 'Port of Discharging' city.
    - vesselName/voyage/imoNumber from the Trunk Vessel row.
    - etd = the ETD half (2nd value) of the Trunk Vessel's 'Latest ETA/ETD'.
    - eta = the ETA half (1st value) of 'POD / DEL ETA'.
  - TWO LEGS, Pre Carrier feeder (Pre Carrier populated):
    - Leg 1 (POL → T/S):
      - portOfLoading = 'Port of Loading' city; portOfDischarge = 'T/S Port' city.
      - vesselName/voyage/imoNumber from the Pre Carrier row.
      - etd = ETD half of the Pre Carrier's 'Latest ETA/ETD'.
      - eta = ETA half (1st value) of the Trunk Vessel's 'Latest ETA/ETD' (= Trunk's arrival at T/S Port).
    - Leg 2 (T/S → POD):
      - portOfLoading = 'T/S Port' city; portOfDischarge = 'Port of Discharging' city.
      - vesselName/voyage/imoNumber from the Trunk Vessel row.
      - etd = ETD half of the Trunk Vessel's 'Latest ETA/ETD'.
      - eta = ETA half (1st value) of 'POD / DEL ETA'.
  - TWO LEGS, Post Carrier feeder (Post Carrier populated):
    - Leg 1 (POL → T/S):
      - portOfLoading = 'Port of Loading' city; portOfDischarge = 'T/S Port' city.
      - vesselName/voyage/imoNumber from the Trunk Vessel row.
      - etd = ETD half of the Trunk Vessel's 'Latest ETA/ETD'.
      - eta = ETA half (1st value) of the Post Carrier's 'ETA/ETD' (= Post Carrier's arrival at T/S Port).
    - Leg 2 (T/S → POD):
      - portOfLoading = 'T/S Port' city; portOfDischarge = 'Port of Discharging' city.
      - vesselName/voyage/imoNumber from the Post Carrier row.
      - etd = ETD half of the Post Carrier's 'ETA/ETD'.
      - eta = ETA half (1st value) of 'POD / DEL ETA'.
  - THREE LEGS (rare — Pre Carrier + Trunk Vessel + Post Carrier all populated, only one T/S Port printed):
    - Leg 1 (POL → printed T/S Port):
      - portOfLoading = 'Port of Loading' city; portOfDischarge = 'T/S Port' city.
      - vesselName/voyage/imoNumber from the Pre Carrier row.
      - etd = ETD half of the Pre Carrier's 'Latest ETA/ETD'.
      - eta = ETA half (1st value) of the Trunk Vessel's 'Latest ETA/ETD' (= Trunk's arrival at the printed T/S Port).
    - Leg 2 (printed T/S Port → unprinted 2nd T/S):
      - portOfLoading = 'T/S Port' city; portOfDischarge = null (the second transhipment city is NOT printed anywhere in the document — do NOT guess or infer it).
      - vesselName/voyage/imoNumber from the Trunk Vessel row.
      - etd = ETD half of the Trunk Vessel's 'Latest ETA/ETD'.
      - eta = ETA half (1st value) of the Post Carrier's 'ETA/ETD' (= Post Carrier's arrival at the unprinted 2nd T/S).
    - Leg 3 (unprinted 2nd T/S → POD):
      - portOfLoading = null (same unprinted second T/S — leave null, do NOT repeat the printed T/S Port city); portOfDischarge = 'Port of Discharging' city.
      - vesselName/voyage/imoNumber from the Post Carrier row.
      - etd = ETD half of the Post Carrier's 'ETA/ETD'.
      - eta = ETA half (1st value) of 'POD / DEL ETA'.
- Connectivity (after dropping inland rows): leg N's portOfDischarge MUST equal leg N+1's portOfLoading WHEN both are non-null. The final leg's portOfDischarge MUST equal the document's 'Port of Discharging' city — NEVER 'Place of Delivery' (that is post-ocean inland delivery, even when its city matches POD). The only legitimate null intermediate is the 3-leg case above where the second T/S city is not printed in the document.
- Time integrity ('no time travel'): each leg's eta MUST be >= its etd, AND <= the next leg's etd.
- Strip trailing terminal/facility text from port cells. The 'T/S Port' cell often appends the terminal in parens (e.g. 'CAI MEP TCIT (TAN CANG CAIMEP INTL TERMINAL)' → 'CAI MEP'). Keep state/province suffixes that are part of the city (e.g. 'HAMBURG, HH', 'BREMERHAVEN, HB').
- Extract 'Proforma 1st vessel ETD' into the top-level proformaDate field only — it is the originally announced proforma departure of the first vessel and is NOT a leg's etd. NEVER use it as any leg's etd; always use the 'Latest ETA/ETD' values on the carrier rows for leg etd/eta.

containers rules:
- The 'Equipment Type/Q'ty' row encodes '<type>-<qty>' (e.g. "40'DRY HC.-5", "20'DRY ST.-1", "40'DRY HC.-15"). Emit <qty> container entries, all sharing the same 'Empty Pick UP CY' depot (its first line). Preserve the literal type token including the trailing period.
