Number of logical indices (distinct time points across all series).
Upsert bars into a series by time (used for history paging / backfill / out-of-order corrections — ARCHITECTURE.md §4.2). Existing times are replaced; new times are inserted; the result stays time-sorted.
Prepending older bars shifts every existing logical index up by the
inserted count — callers preserve the viewport by re-reading baseIndex
(the invariant rightEdge − index is unchanged, so visible bars don't move).
All bars of a series paired with their shared logical index.
Fractional logical index → UTC seconds, interpolating between bars and extrapolating past either edge at the nearest bar spacing.
indexToTime only answers for indices that have a bar. Anything anchored to
an arbitrary x — a drawing endpoint, a cursor readout, a projection to the
right of the last bar — needs a time for positions between bars too, which
the gapless axis (§5.3) makes common: everything a weekend or a session
break collapsed away lands there. Returns NaN when there is no data.
The last bar of a series with its shared logical index, in O(1).
Apply a single live bar (ARCHITECTURE.md §4.2 hot path). Returns the kind of change so the chart auto-scrolls only on a genuine right-edge append:
'append' → newer than the last bar (advances baseIndex)'replace' → same time as the last bar (intra-bar tick) or an existing time'insert' → an older time inserted into history (late / out-of-order)Bars of a series whose logical index lies within [fromIndex, toIndex]. Binary-searches the (time-sorted) series into the visible time window instead of scanning all bars, so a full repaint costs O(log n + visible) per series, not O(total bars) - the hot path called for autoscale and drawing every frame.
Logical index of the latest real bar (length - 1), or -1 if empty.