# Slot Factory — Índice de Archivos y Dependencias

Documento complementario a `SLOT_FACTORY_DOCUMENTATION.md`. Describe, archivo por archivo, qué hace cada módulo del repositorio y de qué otros archivos del propio repositorio depende (imports/`require` verificados directamente en el código fuente — no se infieren dependencias transitivas).

Convenciones:
- La columna **Dependencias** lista solo archivos del repositorio, con rutas relativas a la raíz del proyecto. Cuando un archivo no importa nada del repo (solo usa globals como `PIXI`/`window`, o no tiene dependencias) se indica `—`.
- Librerías externas (`xstate`, `i18next`, `express`) y CDNs se mencionan solo entre paréntesis cuando son relevantes; no se listan como "archivos".
- "Sin consumidores detectados" (marcado ⚠️ en la descripción) reproduce los hallazgos de código muerto de la documentación principal — repetido aquí para que quien mire un archivo suelto lo sepa sin tener que abrir el otro documento.

---

## Raíz del repositorio

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `app.js` | Bootstrap del servidor Express: sirve `public/` como estático y monta las rutas de la API bajo `/api`; escucha en el puerto 3000. | `routes.js` |
| `controllers.js` | Lógica de negocio del servidor: `slotConfig()` sirve `{config, manifest}`; `spinButton()` calcula el RNG de paradas de reel, evalúa paylines/wilds/scatters (`pays()`), y resuelve los loops completos de Free Games y Hold & Win. Es la autoridad del resultado del juego. | `server/data/jsons/slotConfig.json` |
| `routes.js` | Define las dos rutas de la API: `GET /api/slotConfig` y `POST /api/spinButton`, delegando a `controllers.js`. | `controllers.js` |
| `package.json` | Manifiesto npm: dependencias runtime (`@pixi/sound`, `express`, `i18next`, `xstate`) y script `assets` (invoca `assetpack`, config no incluida en el repo analizado). | — |
| `package-lock.json` | Lockfile de npm. | — |
| `AGENTS.md` | Protocolo de flujo Git para agentes/colaboradores (ramas, commits, despliegue a `santosdefortuna.bullpower.ar`). No es parte de la arquitectura del juego. | — |
| `.gitignore` | Exclusiones de Git. | — |

---

## `public/` (raíz)

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `index.html` | Punto de entrada HTML. Define un `importmap` (resuelve `xstate`/`i18next` desde CDN), carga PixiJS 8 / pixi-filters / `@pixi/sound` como globals vía `<script>`, y arranca `main.js` como ES module. Muestra un loader HTML/CSS puro antes de que PixiJS inicialice. | `public/main.js` (vía `<script type="module">`) |
| `main.js` | Bootstrap del frontend: `createActor(appMachine).start()`. | `public/machines/appMachine.js`; importa `public/utils/resize.js` pero no lo usa (import muerto) |
| `loaderScreen.js` | Construye la pantalla de carga PixiJS: logo animado trazando el contorno de un SVG (medido con la API DOM de paths) + barra de progreso con glow. Expone `updateLayout()`/`setProgress()`. | — (usa `PIXI`/`fetch`/`DOMParser` globales) |

---

## `public/machines/`

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `appMachine.js` | Máquina raíz de la SPA. Invoca `loadingMachine` (proveyéndole `fetchConfig`/`initPixiLogic`/`loadAssetsLogic`) y luego `gameMachine` (`systemId:'gameActor'`, proveyéndole `winLoopLogic`/`winTierCelebrationActor`/`updateBet`/`syncBetUI`/`initializeGame`/`resetSymbols`). Maneja resize global y arranque de i18next. | `public/machines/loadingMachine.js`, `public/machines/gameMachine.js`, `public/loaderScreen.js`, `public/utils/resize.js` (import muerto, ver arriba), `public/game/winLoopLogic.js`, `public/game/winTierCelebrationActor.js`, `public/game/resetSymbols.js`, `public/game/updateBet.js`, `public/game/syncBetUI.js`, `public/game/initializeGame.js`, `public/utils/viewport.js` |
| `gameMachine.js` | Máquina central del ciclo de vida del juego: `initializing → baseGame ⇄ freeGames/holdAndWin`. Orquesta spin, autoplay, bet, menús, paytable, audio y ambas features. El archivo más grande del proyecto (2454 líneas). | `public/ui/setUIInteraction.js`, `public/game/reelTickerActor.js`, `public/game/resetSymbols.js`, `public/utils/clickCatcher.js`, `public/game/transitionActor.js`, `public/game/applySymbolData.js`, `public/utils/playSound.js`, `public/game/createPayTableView.js`, `public/ui/createSpinCounter.js`, `public/ui/spinCounter.js`, `public/utils/createAutoplayMenu.js`, `public/ui/createAutoplayStatus.js`, `public/game/hwCreateStickyCoin.js`, `public/game/hwCaptureInitialCoins.js`, `public/utils/hwIsCoin.js`, `public/ui/hwAnimateMultipliers.js`, `public/ui/hwAnimateCollectAllPrizes.js`, `public/ui/hwCreateJackpot.js`, `public/game/hwCleanupStickyLayer.js`, `public/game/hwUpdateJackpotInitial.js`, `public/game/hwUpdateJackpot.js`, `public/game/hwCleanUpJackpot.js`, `public/game/animateSymbol.js`, `public/utils/viewport.js`, `public/game/syncBetUI.js`, `public/game/createMenuView.js` (import muerto — nunca invocado), `public/game/createMobileMenu.js`, `public/game/createDesktopMenu.js`, `public/utils/betChangeAction.js`, `public/game/renderPaytableTab.js`, `public/game/renderRulesTab.js`, `public/game/renderConfigTab.js`, `public/utils/formatMoney.js`, `public/game/winTierCelebrationActor.js`, `public/utils/animateRollingWin.js` |
| `loadingMachine.js` | Máquina de carga: `fetchingConfig → initializingPIXI → loadingAssets → ready`. Diseñada para ser genérica: los 3 actores que invoca (`fetchConfig`, `initPixiLogic`, `loadAssetsLogic`) se reciben por `.provide()` del padre, no se importan aquí. | — |

---

## `public/game/`

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `animateSymbol.js` | Actor XState (`fromCallback`) que resalta uno o varios símbolos específicos (usado para la animación de scatter que dispara FG/HW); emite el evento de completado incluso si hay error. | `public/utils/createShineEffect.js` |
| `applySymbolData.js` | Asigna textura/animación/valor de texto a una instancia de símbolo ya creada; oculta el sprite si es `ghost`; guarda metadata de negocio (`hwValue`, `hwType`, `symbolName`) en el container. | `public/utils/formatMoney.js` |
| `createBackground.js` | Crea la capa de fondo (dos sprites con máscara de canal alfa) y partículas de polvo ambientales; expone `updateLayout`. | `public/utils/createDustParticles.js` |
| `createDesktopMenu.js` | Construye el menú de escritorio (paytable/reglas/config) posicionado sobre el área de reels, usando el componente de tabs genérico. | `public/game/createTabsView.js` |
| `createHWGrid.js` | Helper puro: crea una matriz `cols×rows` rellena con un valor inicial. ⚠️ Solo usado desde `hwCaptureInitialCoins.js`; `gameMachine.js` reimplementa la misma lógica inline en su acción `hwCreateGrid` en vez de reutilizarlo. | — |
| `createMenuView.js` | ⚠️ Implementación alternativa y completa de un menú con tabs propias. **Código muerto**: se importa en `gameMachine.js` pero nunca se invoca (siempre se usa `createMobileMenu`/`createDesktopMenu`); además usa `PIXI.BitMapText` (typo) que rompería si se ejecutara. | `public/utils/viewport.js` |
| `createMobileMenu.js` | Construye el menú para dispositivos móviles (ocupa desde debajo del frame hasta el borde de pantalla), usando el mismo componente de tabs genérico que la versión desktop. | `public/game/createTabsView.js` |
| `createPayTableView.js` | Renderiza las páginas de la tabla de pagos leyendo `config.ui[device].payTableLayout` y `config.payTable.symbols`; escala los pagos en vivo según `bet/betMin`. | `public/utils/createDynamicText.js` |
| `createReels.js` | Crea el `displayContainer` (con máscara) y, por cada columna, `rows+1` instancias de símbolo (una fila extra oculta como buffer del giro). Expone `updateLayout` (delega en `applyReelsLayout`). | `public/utils/applyReelsLayout.js`, `public/utils/createSymbolInstance.js` |
| `createTabsView.js` | Componente de tabs genérico y agnóstico de dominio: recibe `tabs`+callback de render, dibuja botones con highlight y delega el contenido. | — |
| `gameRootContainer.js` | `createRoot(pixiApp)`: crea el `PIXI.Container` `'gameRoot'`, calcula el `hitArea` y lo agrega a `app.stage`. Es el container raíz que se propaga como `activeRoot` por el resto del sistema. | `public/utils/viewport.js` |
| `hwCaptureInitialCoins.js` | Al entrar a Hold & Win, recorre el display del spin de disparo y "captura" como monedas sticky iniciales los símbolos que `hwIsCoin` identifica como tipo `holdAndWin`. | `public/game/hwCreateStickyCoin.js`, `public/game/createHWGrid.js`, `public/utils/hwIsCoin.js` |
| `hwCleanUpJackpot.js` | Exporta `hwCleanupJackpot`: destruye el container PixiJS de los jackpots y limpia las referencias de `context.holdAndWin`. | — |
| `hwCleanupStickyLayer.js` | Al salir de Hold & Win, "graba" el estado visual final de las monedas sticky de vuelta en los sprites del reel base (usa la capa visual como fuente de verdad, no `serverData`/`grid`, según su propio comentario), y destruye la capa temporal. | `public/game/applySymbolData.js` |
| `hwCreateStickyCoin.js` | Crea (o reutiliza) la instancia visual de un símbolo "sticky" en la capa de Hold & Win, en la posición `(col,row)`; determina su `hwType` desde la paytable. | `public/utils/createSymbolInstance.js` |
| `hwUpdateGrid.js` | ⚠️ **Código muerto y roto**: no está importado en ningún archivo del repo; si se ejecutara fallaría (llama a `hwCreateStickyCoin` sin importarla, con una firma de argumentos obsoleta respecto a la versión actual). | `public/utils/hwIsCoin.js` (import presente, pero el archivo entero es inalcanzable) |
| `hwUpdateJackpot.js` | Por cada respin evaluado, resetea visualmente los íconos de jackpot y resalta el nivel activo (`activePrize` del servidor). | — |
| `hwUpdateJackpotInitial.js` | Variante de `hwUpdateJackpot.js` ejecutada una sola vez al entrar a Hold & Win, para resaltar el jackpot correspondiente al trigger inicial. ⚠️ Mezcla nombres inconsistentes (`hwScattersCount` tratado como objeto premio). | — |
| `initializeGame.js` | Acción `assign` central de arranque: instala fuentes bitmap, calcula tamaño de pantalla, arma el mapa de texturas de fuente, inicializa volúmenes, parsea símbolos y llama `setupSlot`. Cablea los handlers de UI a eventos de la máquina. | `public/game/parseSymbols.js`, `public/game/setupSlot.js`, `public/utils/denominationUpdate.js`, `public/utils/installBitmapFont.js`, `public/game/initializeSoundVolumes.js`, `public/utils/buildFontTextureMap.js`, `public/utils/viewport.js` |
| `initializeSoundVolumes.js` | Lee `config.game.sounds` (buses `music`/`sounds`) y aplica el volumen a los sonidos `PIXI.sound` (`music`, `spinButtonClick`, `reelSpinning`, `reelStop`). | — |
| `parseSymbols.js` | Construye `symbolsData`: por cada nombre en `config.game.symbolsNames`, ordena los frames del spritesheet cargado y los cruza con `config.payTable.symbols` (`value`, `valueType`, `textStyle`, `isGhost`). | — |
| `playWinPopUp.js` | Anima un popup de texto de ganancia (escala con easing "OutBack") sobre un ticker de PixiJS. ⚠️ Tiene una referencia a variables (`ticker`/`update`) usadas antes de su declaración en una rama de early-return — bug latente no disparado en el uso actual. | — |
| `reelSpin.js` | `updateReelLogic()`: lógica de giro/rebote ejecutada cada frame por `reelTickerActor`. Recicla símbolos, inyecta el resultado real del servidor en los últimos frames, aplica visibilidad de Hold & Win (duplicando la lógica de `syncReelVisibility.js`). | `public/game/applySymbolData.js` |
| `reelTickerActor.js` | Actor XState (`fromCallback`) que anima el giro de todas las columnas vía `pixiApp.ticker`; emite `REEL_IMPACT`/`REEL_STOPPED`/`ALL_REELS_STOPPED`; recibe `FORCE_QUICK_STOP`. | `public/game/reelSpin.js` |
| `renderConfigTab.js` | Contenido de la tab "Config" del menú: sliders de sonido/música y selector de idioma; único punto de la UI de menús que envía eventos directos a la máquina (`SET_SOUND_VOLUME`, `SET_MUSIC_VOLUME`, `CHANGE_LANGUAGE`). | `public/utils/createSliderToggle.js` |
| `renderPaytableTab.js` | Wrapper trivial que reenvía props a `createPayTableView`. | `public/game/createPayTableView.js` |
| `renderRulesTab.js` | Contenido de la tab "Reglas": un único `BitmapText` traducido (`MENU_RULES_P1`), sin paginación. | — |
| `resetSymbols.js` | Restaura `alpha=1`, `scale=1` y frame de animación en todos los símbolos del display — se llama al entrar a cada `spinning`. | — |
| `setupSlot.js` | Orquesta la construcción visual del slot: crea el root, el fondo, la UI y los reels; cablea los botones a eventos de la máquina. | `public/game/gameRootContainer.js`, `public/game/createBackground.js`, `public/ui/createUI.js`, `public/game/createReels.js` |
| `syncBetUI.js` | Sincroniza el texto/estado de los botones de apuesta con `context.bet`/`denominations`/features activas. | `public/utils/denominationUpdate.js` |
| `syncReelVisibility.js` | ⚠️ **Código muerto**: exporta la lógica "genérica" de ocultar símbolos bajo celdas de Hold & Win llenas, pero no se importa en ningún otro archivo — la versión que realmente corre está duplicada inline en `reelSpin.js`. | — |
| `transitionActor.js` | Actor XState (`fromCallback`) para los popups de transición entre modos (`fg_start`/`hw_start`/`end`/`aditionalSpins`/`fgMaxWinReached`), con máquina de fases propia por ticker. | `public/utils/formatMoney.js`, `public/utils/animateRollingWin.js` |
| `updateBet.js` | Acción `assign` que calcula la siguiente denominación válida según la dirección (`+`/`-`) del click. | `public/utils/denominationUpdate.js` |
| `winLoopLogic.js` | Actor XState (`fromCallback`) que anima cada línea ganadora de `context.serverData.pays`: resalta símbolos, popup de texto, partícula recorriendo la línea. En juego base entra en loop infinito (no emite `WIN_LOOP_FINISHED` por sí solo); en features especiales recorre `pays` una vez. | `public/game/resetSymbols.js`, `public/game/playWinPopUp.js`, `public/utils/formatMoney.js`, `public/game/animateSymbol.js`, `public/utils/createShineEffect.js`, `public/utils/animationPaylinePoints.js` |
| `winTierCelebrationActor.js` | Actor XState (`fromPromise`) de celebración de tiers altos (`BIG/SUPER/MEGA/EPIC`): monedas explotando, mesh 3D rotando, shockwave filter. El archivo tiene 1409 líneas; solo las últimas ~440 (desde la línea 966) son código activo, el resto son 3 versiones anteriores comentadas en bloque. | `public/utils/formatMoney.js` |

---

## `public/ui/`

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `UIManager.js` | Clase instanciada (no singleton) que centraliza la creación/registro de displayObjects de UI desde `config.ui[device]`, con fallback a `desktop`; marca automáticamente como botón cualquier elemento cuyo nombre contenga "button". | `public/utils/applyUILayout.js` |
| `createAccumulator.js` | Container simple con un único `BitmapText` (`valueText`); sin métodos de actualización propios. | — |
| `createAutoplayStatus.js` | Widget flotante con botón STOP + contador de spins restantes con animación de pulso. | — |
| `createSpinCounter.js` | Wrapper que instancia `spinCounter`, lo registra en el ticker, y se suscribe (`self.subscribe`) al snapshot del actor XState para auto-actualizarse. | `public/ui/spinCounter.js` |
| `createUI.js` | Orquestador de alto nivel de la UI: instancia `UIManager`, crea una lista hardcodeada de ~17 elementos "esenciales" (tolerando ausencias en config), agrega 3 accumulators, cablea `handlers.onInfo`/`onMenu`. | `public/ui/UIManager.js`, `public/utils/applyUILayout.js`, `public/ui/createAccumulator.js` |
| `getActiveConfig.js` | ⚠️ **Sin consumidores detectados** en todo el repo (solo su propia definición aparece por búsqueda de texto). Mergea `{...desktop, ...mobile}`. | — |
| `hwAnimateCollectAllPrizes.js` | Animación final de recolección de premios de Hold & Win: monedas y jackpot vuelan hacia el acumulador de premio; al terminar envía `COLLECT_FINISHED`. | `public/utils/hwGetPrizeValue.js` (importado pero **no usado**), `public/utils/formatMoney.js`, `public/utils/animateRollingWin.js`, `public/utils/animateParticles.js` |
| `hwAnimateMultipliers.js` | Procesa símbolos "booster" nuevos: anima partículas hacia cada multiplicador activo del tablero y les suma el valor del booster. | `public/utils/viewport.js`, `public/utils/animateParticles.js` |
| `hwCreateJackpot.js` | Crea los sprites de los niveles de jackpot desde `config.features.holdAndWin.jackpotLevels`. | `public/utils/createSymbolInstance.js`, `public/utils/viewport.js`, `public/utils/applyUILayout.js` |
| `setUIInteraction.js` | Togglea `eventMode`/`alpha` de todos los elementos marcados como botón (`el.isButton`) para habilitar/deshabilitar la interacción de UI en bloque. | — |
| `spinCounter.js` | Clase `spinCounter extends PIXI.Container`: counter circular con anillo de progreso (textura con máscara de arco, o `Graphics` si no hay textura). | — |
| `hwAnimate...` (ver arriba) | | |

---

## `public/utils/`

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `animateParticles.js` | Anima una partícula individual de `source` a `target` en trayectoria Bézier cuadrática. | — |
| `animateRollingWin.js` | Anima un contador numérico (`BitmapText`) con easing cúbico; expone `skipRollingWin`. | `public/utils/formatMoney.js` |
| `animationPaylineBorder.js` | Calcula puntos de una línea de pago en modo "contorno perimetral" (el modo usado actualmente por `winLoopLogic`). | — |
| `animationPaylineCenter.js` | Calcula puntos de una línea de pago en modo "centro de cada símbolo" (no usado por `winLoopLogic.js` en la instancia actual). | — |
| `animationPaylinePoints.js` | `getPaylinePoints()`: delega en `animationPaylineBorder`/`animationPaylineCenter` según el modo pedido. | `public/utils/animationPaylineBorder.js`, `public/utils/animationPaylineCenter.js` |
| `applyReelsLayout.js` | Recalcula posición/escala de columnas y símbolos tras un resize. ⚠️ Hardcodea `nativeWidth/Height=256` en paralelo a `createReels.js`, que sí lee `config.display.symbolWidth/Height` — riesgo de desincronización si cambia el config. | — |
| `applyUILayout.js` | Motor de layout: convierte coordenadas normalizadas (`\|x\|≤1`) a píxeles sobre un "lienzo virtual" fijo (1100×720 desktop / 720×1100 mobile — valor duplicado en `viewport.js`). | — |
| `betChangeAction.js` | Devuelve el array de 3 acciones XState encadenadas para un cambio de apuesta (update → reset símbolos → sync UI). | `public/game/resetSymbols.js` |
| `buildFontTextureMap.js` | Genera un diccionario carácter→`Texture` renderizando cada char con `PIXI.Text`. ⚠️ Sin consumidor detectado dentro del alcance grepeado. | — |
| `clickCatcher.js` | Crea una `Graphics` transparente full-size que captura clicks para bloquear input durante animaciones/features. | — |
| `createAutoplayMenu.js` | Panel completo de configuración de autoplay (cantidad de spins, límite de pérdida, toggles). | `public/utils/createAutoplayToggle.js`, `public/utils/createDropdownSelector.js`, `public/utils/applyUILayout.js` |
| `createAutoplayToggle.js` | Toggle visual on/off genérico basado en texturas inyectadas. | — |
| `createDropdownSelector.js` | Dropdown genérico de items `{id,label}` con hover/selección/cierre. | — |
| `createDustParticles.js` | Sistema de partículas de "polvo" flotante, reciclado por límites de contenedor. | — |
| `createDynamicText.js` | Renderiza texto dinámico de paytable: tipo `"static"` (fijo traducido) o `"payout"` (tabla de pagos calculada desde `instancespay`). | `public/utils/formatMoney.js` |
| `createShineEffect.js` | Efecto de "brillo" que atraviesa un sprite (gradiente + máscara). | — |
| `createSliderToggle.js` | Slider arrastrable 0–1 (usado para volumen). | — |
| `createSymbolInstance.js` | Construye la instancia visual base de un símbolo (4 hijos: fondo, animación, marco, texto de valor) y delega el llenado de datos. | `public/game/applySymbolData.js` |
| `denominationUpdate.js` | Lógica pura de navegación de denominaciones (`getNextBet`) y render del bet box (`renderBetUpdate`). | `public/utils/formatMoney.js` |
| `formatMoney.js` | `Intl.NumberFormat('es-AR', ...)`. Locale hardcodeado, no viene de config. | — |
| `hwGetPrizeValue.js` | Dado un `coin`, calcula `symbol.value * bet` desde la paytable. ⚠️ Importado en `hwAnimateCollectAllPrizes.js` pero nunca invocado ahí — huérfano. | `public/utils/formatMoney.js` (import también sin uso dentro de este archivo) |
| `hwIsCoin.js` | Predicado puro: `true` si el símbolo es de tipo `holdAndWin` y no es el `ghost`. | — |
| `installBitmapFont.js` | Instala una `PIXI.BitmapFont` desde un TTF ya cargado, con charset amplio (multi-moneda/acentos). | — |
| `playSound.js` | Reproduce un sonido por `key` desde `context.assets.sounds`. ⚠️ Lee `context.config.config.game.soundsVolumes`, ruta que no existe en el esquema real (`game.sounds` sí existe) — el volumen individual siempre cae al fallback. | — |
| `pulseEffect.js` | Anima un pulso de escala sobre cualquier displayObject, retorna una `Promise`. | — |
| `resize.js` | Ajusta `scale`/`pivot` del root según pantalla real vs. diseño base. ⚠️ Contiene un clamp de escala mínima calculado pero no aplicado, y una expression statement huérfana sin efecto (vestigio de un `console.log` borrado). | — |
| `viewport.js` | `getScreenSize(pixiApp)` y `getUIScaleFactor(pixiApp, device)` (mismo esquema de lienzo virtual 1100×720/720×1100 que `applyUILayout.js`, duplicado). | — |

---

## `server/data/jsons/`

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `slotConfig.json` | Configuración completa de la instancia actual del slot ("Santos de Fortuna"): `reels` (tiras, nunca expuestas al cliente), `config` (display/game/animations/autoplay/features/payTable/denominations/ui/i18n), `manifest` (bundles de assets). Fuente única de verdad de lo que hace a este juego "este" juego. | — (es consumido por `controllers.js` y, parcialmente, por el cliente vía `GET /api/slotConfig`) |

---

## `server/slotConfigEditor/` — herramienta de desarrollo, desconectada del runtime

| ARCHIVO | DESCRIPCIÓN | DEPENDENCIAS (archivos del repo) |
|---|---|---|
| `index.html` | Página standalone del editor visual de `slotConfig.json`. Carga `helpers.js` y `editor.js` como `<script>` clásicos (no ES modules, no `<script type="module">`) — ambos comparten scope global. No referenciada por `app.js`/`routes.js`: no forma parte del servidor Express. | `helpers.js`, `editor.js` (por orden de carga en `<script>`, scope global compartido) |
| `helpers.js` | Define funciones globales de construcción de formulario (`createSection`, `createTab`, `createNumberInput`, `createTextInput`, `createCheckbox`, `createArrayEditor`, `syncArrayLength`) usadas por `editor.js`. | — |
| `editor.js` | Lógica del editor: carga un `slotConfig.json` local vía `<input type="file">`, arma un formulario con 5 secciones (Display, Game, Features parcial, PayTable — `instancespay`/`lines` —, Denominations) usando las funciones de `helpers.js`, y permite descargar el resultado editado. No escribe de vuelta al archivo real del servidor. | `helpers.js` (dependencia de scope global, no `import`) |
| `sections/denominations.js` | ⚠️ **Código muerto**: reimplementa `renderDenominationsSection` con una firma distinta a la de `editor.js`; `index.html` nunca carga este archivo. | — |
| `sections/display.js` | ⚠️ **Código muerto**: ídem, `renderDisplaySection`. | — |
| `sections/features.js` | ⚠️ **Código muerto**: ídem, `renderFeaturesSection`. | — |
| `sections/game.js` | ⚠️ **Código muerto**: ídem, `renderGameSection`. | — |

---

## Notas sobre "dependencias" no capturadas por imports estáticos

Varios archivos se comunican con otros **sin** un `import`/`require` directo, típicamente porque XState v5 resuelve actores/acciones por nombre de string vía `.provide()`, o porque un módulo espera recibir una referencia como parámetro en tiempo de ejecución en vez de importarla. Estos casos ya están señalados en `SLOT_FACTORY_DOCUMENTATION.md` (secciones 5 y 6) y se resumen aquí porque no aparecen en la tabla de imports:

- `gameMachine.js` referencia `'winLoopLogic'` y `'winTierCelebrationActor'` como strings (`src: 'winLoopLogic'`) — la implementación real llega inyectada desde `appMachine.js` vía `.provide()`, no por import directo dentro de `gameMachine.js` (aunque sí importa `winTierCelebrationActor.js` directamente para pasárselo a `.provide()` en su propio código, ver tabla de `appMachine.js`).
- `loadingMachine.js` no importa ningún actor propio: los tres (`fetchConfig`, `initPixiLogic`, `loadAssetsLogic`) llegan por `.provide()` desde `appMachine.js`.
- Los módulos de UI que reciben `pixiApp`, `root`/`activeRoot`, `translator`, `handlers` como parámetros (la mayoría de `public/ui/*.js` y varios de `public/game/*.js`) dependen en tiempo de ejecución de lo que `gameMachine.js`/`appMachine.js`/`initializeGame.js` les inyecte, sin tener un `import` de esos archivos — esa dependencia queda documentada en la columna de "quién invoca" de `SLOT_FACTORY_DOCUMENTATION.md`, no en este índice de imports estáticos.
