import sys; sys.path.insert(0, "/root/fwa1")
exec(open("/root/fwa1/t4.py").read().split("BK = ")[0])
# coin lifetimes per crew (blocks from b0 to pull; None = not pulled in data)
life = collections.defaultdict(list)
crew_of = {}
for t, cr, b0, pull in ws.execute("select token, crew, b0, pull_b from coin where crew in (?,?) and day>='2026-09-21'", (A, BC)):
    life[cr].append(None if pull is None else (pull - b0) / 10); crew_of[t] = cr
def hazard(cr, a):
    alive = [x for x in life[cr] if x is None or x > a]
    if not alive: return 0
    return sum(1 for x in alive if x is not None and x <= a + 60) / len(alive)
BK = [(0.003, 0.0075, "0.005"), (0.0075, 0.015, "0.01"), (0.015, 0.035, "0.02"), (0.035, 0.075, "0.05"), (0.075, 99, "0.1+")]
def bk(e):
    for lo, hi, n in BK:
        if lo <= e < hi: return n
ev = {}
for day, crew, tok, b, eth, w in rows:
    if tok not in coin: continue
    w = w.lower(); f = ff.get(w)
    if f is None: continue
    fund = (f[0] or "").lower(); via = (f[1] or "").lower()
    if w in crewset or fund in dist or via in dist: cls = "crew"
    elif w in rep or fund in crewset: continue
    else: cls = "outside"
    b0, pull = coin[tok]; age = (b - b0) / 10
    if age < 0: continue
    key = (cls, tok, b // 10) if cls == "outside" else (cls, tok, b, w)   # outside: merge same-second cluster
    e = ev.setdefault(key, [crew, age, 0.0, pull is not None and 0 < pull - b <= 600])
    e[2] += eth
st = collections.defaultdict(lambda: [0, 0, 0.0])
for (cls, *_), (crew, age, eth, pulled) in ev.items():
    k = bk(eth)
    if not k: continue
    for agek in ("all", "0-60s" if age < 60 else "60s+"):
        s = st[(cls, k, agek)]; s[0] += 1; s[1] += pulled; s[2] += hazard(crew, age)
print("class size age | events | pulled<=60s | expected from age alone | lift")
for k in sorted(st):
    n, p, e = st[k]
    print(k, n, "%d (%.0f%%)" % (p, 100 * p / n), "%.1f (%.0f%%)" % (e, 100 * e / n), "%.1fx" % (p / e if e else 0))
