'use client'; import { TERRITORIES } from '@/game/board'; import { Input } from '@/components/ui/input'; export type ShipmentClauseInput = { territory: string; minimum: number }; export function invalidShipmentClause(claim: ShipmentClauseInput) { return !Number.isSafeInteger(claim.minimum) || claim.minimum < 1 || claim.minimum > 20; } /** Destination and physical minimum shared by flat and nested question builders. */ export function ShipmentClauseFields({ id, value, onChange }: { id: string; value: ShipmentClauseInput; onChange: (claim: ShipmentClauseInput) => void; }) { return <> onChange({ ...value, minimum: event.currentTarget.valueAsNumber })} />

A whole minimum of one to twenty physical forces in the same shipment from reserves this turn. Skipping makes this shipment condition false.

; } export function ShipmentClaimFields({ id, clauses, join, onClauses, onJoin }: { id: string; clauses: ShipmentClauseInput[]; join: 'single' | 'and' | 'or'; onClauses: (clauses: ShipmentClauseInput[]) => void; onJoin: (join: 'single' | 'and' | 'or') => void; }) { return <> {clauses.slice(0, join === 'single' ? 1 : 2).map((claim, index) => { const update = (next: ShipmentClauseInput) => onClauses(clauses.map((previous, i) => i === index ? next : previous)); return
Shipment condition {index + 1}
; })}

All conditions describe the same shipment from reserves. AND requires both; OR requires at least one. A No answer requires the whole statement to be false. Skipping shipment makes every shipment condition false.

; }