···3131 const range = (from: number, to: number): number[] =>
3232 Array.from({ length: Math.max(to - from + 1, 0) }, (_, i) => from + i);
33333434- // both ends, the current page and its two neighbours, and the two gaps
3534 const SLOTS = 7;
36353737- // the row is always SLOTS long once a gap is needed, so both gaps are permanent
3838- // residents. that is what lets the plate be placed from an index rather than
3939- // measured, and why paging the middle of a long range moves the numbers, not the row
4036 export function paginate(page: number, count: number): PaginationItem[] {
4137 if (count <= SLOTS) return range(1, count);
4242- // near either end a gap would hide fewer pages than the slots it costs, so the
4343- // window opens flush against that end and only the far gap is drawn
4438 if (page < 4) return [...range(1, 5), "gap-end", count];
4539 if (page > count - 3) return [1, "gap-start", ...range(count - 4, count)];
4640 return [1, "gap-start", ...range(page - 1, page + 1), "gap-end", count];