- derive the canonical layer list up front using declared layerCount so there is always a sane top/inner/bottom ordering even when SRJs only mention a subset of layers
- dedupe layer names case-insensitively, clamp any extra innerN references back into the available z indices, and store lowercase lookups so "Top"/"top" share the same z
- during initState re-map every obstacle to valid zLayers, throw only when actual numeric indices fall outside 0..layerCount-1, and persist missing zLayers back onto the SRJ for downstream solvers
- add regression tests covering mixed-case layer names, out-of-range inner layers on low layerCount boards, and the basic zLayer mapping to prevent future regressions