1package ui23import (4 "io"56 tea "charm.land/bubbletea/v2"7 uv "github.com/charmbracelet/ultraviolet"89 "src.rest/cat/012/internal/sheet"10 "src.rest/cat/012/internal/stress"11)1213// The shapes and the fake terminal below are shared by the stress14// benchmarks (stress_test.go) and the speed gate (speed_test.go), so15// both draw the same frames.1617// scaled is dense-8192x26 under a 3-point color scale over all of it,18// every visible cell a shade: what conditional formatting costs a frame.19func scaled() *sheet.Sheet {20 s := stress.Dense(stress.Rows, 26)21 f, err := sheet.ParseCondFormat(`{"ranges":"A1:Z8192","scale":[{"type":"min","color":"red"},{"type":"percentile","value":"50","color":"yellow"},{"type":"max","color":"green"}]}`)22 if err != nil || s.LoadCondFormats([]sheet.CondFormat{f}) > 0 {23 panic(err)24 }25 return s26}2728// fakeTerm stands in for Bubble Tea's renderer: a cell buffer the frame29// is drawn into and a terminal renderer diffing it to io.Discard.30type fakeTerm struct {31 buf uv.ScreenBuffer32 scr *uv.TerminalRenderer33}3435func newFakeTerm(w, h int) *fakeTerm {36 t := &fakeTerm{buf: uv.NewScreenBuffer(w, h), scr: uv.NewTerminalRenderer(io.Discard, nil)}37 t.scr.Resize(w, h)38 return t39}4041func (t *fakeTerm) frame(m *Model) {42 v := m.View()43 t.buf.Clear()44 uv.NewStyledString(v.Content).Draw(t.buf, t.buf.Bounds())45 t.scr.Render(t.buf.RenderBuffer)46 t.scr.Flush()47}4849func sized(s *sheet.Sheet, w, h int) *Model {50 m := New(s, "")51 m.Update(tea.WindowSizeMsg{Width: w, Height: h})52 return m53}