"""Shared helpers for Elemental Imperium 33×33×6 wallet matrix labeling.""" from __future__ import annotations def linear_index(lpbca: int, branch: int, class_: int) -> int: return lpbca * 198 + branch * 6 + class_ def cell_id(lpbca: int, branch: int, class_: int) -> str: return f"EI-L{lpbca:02d}-B{branch:02d}-C{class_}" def build_label(network_code: str, cid: str, asn: int | None) -> str: base = f"{network_code}.{cid}" if asn is not None: return f"{base}.AS{asn}" return base def match_range_rule(wallet: dict, match: dict) -> bool: """Each key in match is [min, max] inclusive for lpbca, branch, class. Empty {} matches all.""" dims = ("lpbca", "branch", "class") for d in dims: if d not in match: continue pair = match[d] if not isinstance(pair, list) or len(pair) != 2: raise ValueError(f"match.{d} must be [min, max]") lo, hi = int(pair[0]), int(pair[1]) v = int(wallet[d]) if not (lo <= v <= hi): return False return True def resolve_network_asn( wallet: dict, cid: str, base_network: str, base_asn: int | None, overlay: dict | None, ) -> tuple[str, int | None]: """Apply rangeRules (first match wins), then cellOverrides.""" net, asn = base_network, base_asn if overlay: for rule in overlay.get("rangeRules", []): if match_range_rule(wallet, rule.get("match") or {}): net = rule["networkCode"] if "asn" in rule: asn = rule["asn"] break ovr = overlay.get("cellOverrides", {}).get(cid) if isinstance(ovr, dict): if "networkCode" in ovr: net = ovr["networkCode"] if "asn" in ovr: asn = ovr["asn"] return net, asn