import Big from "big.js"; /** * Proportional distribution of one header discount across lines, in exact * integer minor units, by largest remainder. * * This is the allocation docs/planning/discount-authority.md §5.2 step 3 and * §12 decision 5 require: the UI and the API both call it, the server compares * the client's `RecDisc` to its result to the minor unit, and a mismatch is a * `400`. That comparison is only safe because there is exactly one * implementation, so its ordering rules are part of the contract and must not * change silently: * * 1. Each line's exact share is `amount × weight / Σweight`. * 2. Every line receives the floor of its share. * 3. The minor units left over (always fewer than the number of lines with a * fractional share) go one each to the lines with the largest fractional * remainder. * 4. Equal remainders are ordered by `TieBreak` ascending, compared as plain * strings by UTF-16 code unit. Callers build it from the stable line id so * the order does not depend on array position when ids exist. * * Guarantees, for `0 ≤ amount ≤ Σweight`: the shares sum to `amount` exactly, * no share exceeds its line's weight, and a zero-weight line receives nothing. * Outside that range the function refuses rather than producing a best effort. */ export interface AllocationSlot { /** Opaque key the caller uses to find its line in the result. */ readonly Key: string; /** Non-negative integer minor units: the line's remaining capacity. */ readonly Weight: Big; /** Deterministic ordering for equal remainders; see the module comment. */ readonly TieBreak: string; } export type AllocationOutcome = { readonly Ok: true; readonly Shares: ReadonlyMap; } | { readonly Ok: false; readonly Code: "NO_CAPACITY" | "EXCEEDS_CAPACITY" | "INVALID_INPUT"; readonly Detail: string; }; /** * Allocates `amount` (non-negative integer minor units) across `slots`. * Keys must be unique. */ export declare function AllocateLargestRemainder(amount: Big, slots: readonly AllocationSlot[]): AllocationOutcome;