Major redesign with breaking changes:
* New mode enum replaces the old loop boolean: loop (default, preserves
prior behaviour), clamp, pingpong, random, shuffle.
* format input + new index_str (STRING) output for emitting padded
filename-prefix-style values such as 0007 ({:04d}). Bad templates
fall back to str(index) instead of raising.
* Per-node state keyed by ComfyUI unique_id: multiple HoldCounter nodes
in one workflow advance independently instead of sharing a
module-global counter.
* Reset is now a momentary JS button. The hidden reset_trigger int
widget pairs with it; the Python side compares to the per-node
last-seen value and rewinds when it changes. The old sticky reset
BOOLEAN is gone.
* Defensive runs_per_index < 1 guard inside the node.
Internals:
* Index math factored into pure _compute_index() + NodeState helper,
both exercised by a 23-case pytest suite (loop / clamp / pingpong /
random / shuffle / range-inversion / zero-guard).
* Legacy reset/loop widget values from saved v1 workflows are silently
absorbed via a **_legacy kwargs sink so old workflows still load.