Marlin Lee
Refactor: split panels into pure logic + UI layers
fb9c7be
"""
Mutable session state and the dataset registry.
All Bokeh callbacks share state through:
- _S : per-session scalar flags (active dataset index, render token, etc.)
- _all_datasets : list of dataset dicts loaded at startup
- active_ds() : returns the currently selected dataset dict
Panels read dataset data via active_ds()['key'] rather than through
module-level aliases, making data-flow explicit.
"""
from __future__ import annotations
class _S:
"""Mutable scalars shared by all callbacks. No global statements needed."""
active: int = 0 # index into _all_datasets
render_token: int = 0 # bump on each feature selection; stale renders bail out
search_filter = None # None or set of feature indices matching current name search
color_by: str = "Log Frequency"
hf_push = None # active Bokeh timeout handle for debounced HuggingFace push
gallery_page: int = 0 # current page in the MEI thumbnail gallery
_all_datasets: list[dict] = []
def active_ds() -> dict:
"""Return the currently selected dataset dict."""
return _all_datasets[_S.active]
def display_name(feat: int) -> str:
"""Label to show in tables: manual name takes priority over auto-interp."""
ds = active_ds()
manual = ds['feature_names'].get(feat)
if manual:
return manual
auto = ds['auto_interp_names'].get(feat)
return f"[auto] {auto}" if auto else ""