# Prompt 1 — El motor de cálculo (con sus pruebas)

Pégale esto a tu IA tal cual. El resultado es un archivo de JavaScript puro y
otro de pruebas que corren con Node. No sigas al prompt 2 hasta que las
pruebas pasen.

---

Construye el motor de cálculo de un divisor de gastos de viaje en JavaScript
puro (sin dependencias, sin DOM), en un archivo `motor_gastos.js` que funcione
igual en el navegador (global `MotorGastos`) y en Node (`module.exports`).

El modelo de datos es una BITÁCORA DE EVENTOS que solo crece:

- `{ tipo: 'persona', id, nombre }`
- `{ tipo: 'gasto', id, descripcion, monto, moneda, pago, entre, partes? }`
  donde `monto` está en CENTAVOS ENTEROS, `pago` es el id de quien pagó,
  `entre` los ids que comparten, y `partes` (opcional) pesos por id para
  divisiones desiguales.
- `{ tipo: 'anulacion', gasto: <id del gasto> }`

Reglas estrictas:

1. TODO el dinero en centavos enteros. Una función `aCentavos(texto)` que
   convierte "4,500.50" → 450050, rechaza negativos y no-números devolviendo
   null. Nunca aritmética con flotantes sobre dinero.
2. `repartir(centavos, entre, partes)`: la suma de las partes debe ser
   EXACTAMENTE el monto. Centavos sobrantes: de uno en uno a quienes mayor
   fracción perdieron al truncar; a igual fracción, orden alfabético del id
   (determinista: dos máquinas calculan idéntico). El resultado no debe
   depender del orden del arreglo `entre`.
3. `reducir(eventos)` → estado: personas, gastos vivos (los anulados fuera,
   pero disponibles en `anulados`), tolerante a eventos malformados (los
   ignora, no truena). Un gasto con un id ya visto se cuenta UNA sola vez:
   si la cola offline sube un evento y el teléfono muere antes de vaciarla,
   ese evento llegará dos veces — y el dinero no puede contarse doble.
4. `saldos(estado, monedaBase, tiposCambio)`: positivo = le deben. Un gasto
   cuya moneda no tenga tipo de cambio NO se suma en silencio: se devuelve en
   una lista `sinCambio` para que la interfaz avise.
5. `arreglo(saldos)`: transferencias mínimas con algoritmo voraz (el que más
   debe paga al que más le deben). A lo más n-1 transferencias. Determinista.

Y las pruebas (`pruebas_motor.js`, corren con `node pruebas_motor.js`, salen
con código 1 si algo falla):

- 100 centavos entre 3 suma exacto y difiere a lo más 1 centavo.
- El reparto no depende del orden de entrada.
- Partes ponderadas 2:1.
- 0.1 + 0.2 en centavos sí da 30.
- Moneda sin tipo de cambio: se reporta y no toca saldos.
- Anulación quita el gasto pero queda en historial.
- El mismo gasto (mismo id) dos veces en la bitácora cuenta una sola vez.
- 200 escenarios aleatorios CON SEMILLA FIJA: los saldos siempre suman cero,
  el arreglo paga exactamente el saldo de cada quien, y nunca hay más de n-1
  transferencias.

Muéstrame primero las pruebas, luego el motor, y corre las pruebas.
