"""The UI gets its gates as a NAMED CONTEXT MAP published by CardsDLL, not by reading
fields. FUN_18006cc60 publishes the IS_* booleans; FUN_18000d550 publishes
TRADE_PILE_SIZE. The Transfer Market screen makes zero requests, so its predicate is
UI-side over that map. Enumerate the WHOLE published map (both publishers) and the
accessor slot behind each name so every term can be read live.
CONTROL: FUN_18006cc60 already decoded correctly with this method (10 names).
Also: polarity of FUN_1801a7260 via its only code caller FUN_1800e2a40, and the
TO_TRADE_PILE literal user FUN_18003e370.
"""
import traceback
try:
    for a, tag in [(0x18000d550, "numeric context publisher (TRADE_PILE_SIZE)"),
                   (0x1800e2a40, "only code caller of TO_TRADE_PILE gate"),
                   (0x18003e370, "TO_TRADE_PILE literal user")]:
        s = dec(a, 300)
        print("\n" + "="*78)
        print("### %#x  %s   len=%d" % (a, tag, len(s)))
        print("="*78)
        print(s)

    print("\n=== model vtable slots used by the publishers ===")
    for slot in (0x270, 0x280, 0x2b0, 0x2b8, 0x2c0, 0x2c8, 0x2d8, 0x2f0,
                 0xa58, 0xa60, 0xa68, 0xa70, 0xa78, 0x818, 0x988, 0x998, 0x9a0, 0x9d0):
        t = qword(0x18021c2a0 + slot)
        f = fm.getFunctionAt(addr(t))
        print("  vt+%#05x -> %#x %s  bytes=%s" % (slot, t, f.getName() if f else "",
                                                  read_bytes(t, 12).hex(" ")))
    print("\n=== IS_STORE_ENABLED accessor (vt+0x280) full ===")
    print(dec(qword(0x18021c2a0 + 0x280)))
except Exception:
    traceback.print_exc()
