@promptctl/rich-js 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/THIRD-PARTY-NOTICES +29 -1
- package/dist/core/anchor.d.ts +5 -0
- package/dist/core/anchor.js +11 -4
- package/dist/core/animation.d.ts +243 -0
- package/dist/core/animation.js +375 -0
- package/dist/core/ansi.js +2 -2
- package/dist/core/box.d.ts +7 -7
- package/dist/core/cell-widths.d.ts +9 -0
- package/dist/core/cell-widths.js +140 -0
- package/dist/core/cells.d.ts +40 -24
- package/dist/core/cells.js +151 -66
- package/dist/core/clock.d.ts +2 -2
- package/dist/core/clock.js +6 -4
- package/dist/core/color.d.ts +27 -10
- package/dist/core/color.js +21 -29
- package/dist/core/console.d.ts +28 -17
- package/dist/core/console.js +48 -43
- package/dist/core/easing.d.ts +140 -10
- package/dist/core/easing.js +328 -50
- package/dist/core/emoji.d.ts +1 -1
- package/dist/core/emoji.js +1 -2
- package/dist/core/export-html.js +2 -1
- package/dist/core/export-lines.js +3 -3
- package/dist/core/highlighter.d.ts +9 -8
- package/dist/core/highlighter.js +3 -2
- package/dist/core/json.js +3 -2
- package/dist/core/markup.js +16 -12
- package/dist/core/measure.js +3 -3
- package/dist/core/memo.d.ts +11 -2
- package/dist/core/memo.js +16 -0
- package/dist/core/oklch.js +17 -6
- package/dist/core/osc8.d.ts +1 -1
- package/dist/core/osc8.js +4 -5
- package/dist/core/paint.d.ts +2 -1
- package/dist/core/paint.js +4 -3
- package/dist/core/pattern.d.ts +21 -0
- package/dist/core/pattern.js +21 -0
- package/dist/core/place.js +2 -1
- package/dist/core/pretty.js +11 -12
- package/dist/core/protocol.d.ts +136 -21
- package/dist/core/protocol.js +203 -16
- package/dist/core/render.d.ts +15 -2
- package/dist/core/render.js +27 -6
- package/dist/core/segment.d.ts +31 -6
- package/dist/core/segment.js +68 -53
- package/dist/core/spinnerData.d.ts +1 -1
- package/dist/core/state.d.ts +53 -0
- package/dist/core/state.js +82 -0
- package/dist/core/strip.d.ts +11 -13
- package/dist/core/strip.js +126 -113
- package/dist/core/style.d.ts +47 -14
- package/dist/core/style.js +74 -34
- package/dist/core/text.d.ts +5 -8
- package/dist/core/text.js +133 -133
- package/dist/core/timeline.d.ts +109 -0
- package/dist/core/timeline.js +180 -0
- package/dist/core/tween.d.ts +49 -0
- package/dist/core/tween.js +71 -0
- package/dist/core/view.d.ts +92 -0
- package/dist/core/view.js +83 -0
- package/dist/host/app.d.ts +49 -21
- package/dist/host/app.js +72 -38
- package/dist/host/input.js +3 -4
- package/dist/index.d.ts +30 -15
- package/dist/index.js +20 -6
- package/dist/node/traceback.js +4 -3
- package/dist/renderables/change.d.ts +42 -0
- package/dist/renderables/change.js +112 -0
- package/dist/renderables/columns.d.ts +1 -1
- package/dist/renderables/columns.js +3 -3
- package/dist/renderables/constrain.js +2 -1
- package/dist/renderables/effect.d.ts +155 -92
- package/dist/renderables/effect.js +203 -136
- package/dist/renderables/effects.d.ts +137 -24
- package/dist/renderables/effects.js +276 -113
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +18 -9
- package/dist/renderables/flexStrip.js +2 -1
- package/dist/renderables/frames.d.ts +45 -43
- package/dist/renderables/frames.js +57 -45
- package/dist/renderables/glyph-effect.d.ts +158 -0
- package/dist/renderables/glyph-effect.js +237 -0
- package/dist/renderables/glyph-effects.d.ts +147 -0
- package/dist/renderables/glyph-effects.js +283 -0
- package/dist/renderables/group.d.ts +1 -1
- package/dist/renderables/group.js +2 -2
- package/dist/renderables/html-entities.d.ts +8 -0
- package/dist/renderables/html-entities.js +386 -0
- package/dist/renderables/layout.d.ts +10 -9
- package/dist/renderables/layout.js +42 -35
- package/dist/renderables/lifecycle.d.ts +77 -0
- package/dist/renderables/lifecycle.js +132 -0
- package/dist/renderables/list-view.d.ts +2 -2
- package/dist/renderables/list-view.js +11 -8
- package/dist/renderables/live.d.ts +36 -21
- package/dist/renderables/live.js +89 -42
- package/dist/renderables/markdown-parse.d.ts +109 -0
- package/dist/renderables/markdown-parse.js +1427 -0
- package/dist/renderables/markdown-url.d.ts +19 -0
- package/dist/renderables/markdown-url.js +314 -0
- package/dist/renderables/markdown.d.ts +5 -7
- package/dist/renderables/markdown.js +356 -683
- package/dist/renderables/padding.d.ts +7 -20
- package/dist/renderables/padding.js +29 -50
- package/dist/renderables/panel.d.ts +30 -32
- package/dist/renderables/panel.js +65 -109
- package/dist/renderables/progress.d.ts +83 -32
- package/dist/renderables/progress.js +186 -90
- package/dist/renderables/progressBar.d.ts +22 -12
- package/dist/renderables/progressBar.js +33 -10
- package/dist/renderables/prompt.js +3 -2
- package/dist/renderables/python-space.d.ts +13 -0
- package/dist/renderables/python-space.js +25 -0
- package/dist/renderables/scroll.d.ts +50 -0
- package/dist/renderables/scroll.js +106 -0
- package/dist/renderables/spinner.d.ts +57 -24
- package/dist/renderables/spinner.js +101 -49
- package/dist/renderables/status.js +1 -1
- package/dist/renderables/syntax.d.ts +10 -9
- package/dist/renderables/syntax.js +5 -3
- package/dist/renderables/table.d.ts +48 -46
- package/dist/renderables/table.js +170 -208
- package/dist/renderables/traceback.d.ts +3 -3
- package/dist/renderables/traceback.js +12 -10
- package/dist/renderables/tree.d.ts +28 -25
- package/dist/renderables/tree.js +108 -58
- package/dist/renderables/viewport.d.ts +77 -38
- package/dist/renderables/viewport.js +156 -72
- package/dist/template-bindings/animation-funcs.d.ts +78 -9
- package/dist/template-bindings/animation-funcs.js +132 -14
- package/dist/template-bindings/index.d.ts +5 -5
- package/dist/template-bindings/index.js +7 -6
- package/dist/themes/ramp.d.ts +62 -4
- package/dist/themes/ramp.js +82 -4
- package/dist/themes/registry.js +5 -7
- package/dist/widgets/button.js +3 -2
- package/dist/widgets/checkbox.js +4 -3
- package/dist/widgets/dropdown.d.ts +3 -1
- package/dist/widgets/dropdown.js +20 -15
- package/dist/widgets/event-router.js +4 -2
- package/dist/widgets/focus-manager.d.ts +23 -14
- package/dist/widgets/focus-manager.js +34 -33
- package/dist/widgets/hit.d.ts +6 -0
- package/dist/widgets/hit.js +8 -1
- package/dist/widgets/index.d.ts +1 -1
- package/dist/widgets/observable.d.ts +23 -0
- package/dist/widgets/observable.js +43 -0
- package/dist/widgets/slider.d.ts +1 -1
- package/dist/widgets/slider.js +12 -3
- package/dist/widgets/static-item.d.ts +1 -1
- package/dist/widgets/static-item.js +6 -7
- package/dist/widgets/text-input.d.ts +53 -47
- package/dist/widgets/text-input.js +456 -399
- package/dist/widgets/themed-widget.js +2 -1
- package/dist/widgets/toggle.js +4 -3
- package/dist/widgets/types.d.ts +10 -4
- package/dist/widgets/types.js +8 -2
- package/dist/widgets/widget-app.d.ts +32 -6
- package/dist/widgets/widget-app.js +74 -27
- package/dist/widgets/widget-base.d.ts +2 -2
- package/dist/widgets/widget-base.js +29 -21
- package/package.json +9 -5
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animation — a value for a time, and when it next changes: the one type
|
|
3
|
+
* anything in rich-js that changes with time is an instance of.
|
|
4
|
+
*
|
|
5
|
+
* `at(t)` is the value at `t` seconds. `nextChange(t)` is the first moment,
|
|
6
|
+
* on `t`'s own timeline, at which the value may stop being `at(t)`: never
|
|
7
|
+
* before `t`. A later time says the value is held until then, `Infinity`
|
|
8
|
+
* that it never changes again, and `t` itself that it is moving at `t` — it
|
|
9
|
+
* changes every frame, however close together they are drawn. An early
|
|
10
|
+
* answer costs a host a frame that draws what the last one did; a late one
|
|
11
|
+
* skips a change. So an animation that cannot say answers `t`, as
|
|
12
|
+
* `continuous` does. A value drawn as cells carries this answer on every
|
|
13
|
+
* cell (`Style.hold`, both ends of the hold below), so a host holding
|
|
14
|
+
* the composed frame reads it there (`Segment.nextChange`); a value that is
|
|
15
|
+
* not drawn — a number, a colour — has `nextChange` as its only way to say
|
|
16
|
+
* when to look again.
|
|
17
|
+
*
|
|
18
|
+
* `lastChange(t)` is the other end of the same hold: the last moment, never
|
|
19
|
+
* after `t`, at which the value may have become `at(t)` — `-Infinity` if it
|
|
20
|
+
* always was, `t` while it moves. Together they bound the hold, `[lastChange(t),
|
|
21
|
+
* nextChange(t))`, and the answer may be narrower than the truth and never
|
|
22
|
+
* wider. It is what a host running the animation backwards reads
|
|
23
|
+
* (`./timeline.ts`): run down the timeline, the value next changes where it
|
|
24
|
+
* began. An animation that cannot say answers `t` here too.
|
|
25
|
+
*
|
|
26
|
+
* `reduced()` is the same animation with its motion taken out: what it shows,
|
|
27
|
+
* and when it starts and stops showing it, kept; every moment between two
|
|
28
|
+
* values skipped. A loop holds its first value, a one-shot cuts to its end
|
|
29
|
+
* when it starts, a transition to its new state, a stagger has everyone arrived, and an element is
|
|
30
|
+
* there from when it entered until it is told to leave. Terminals have no
|
|
31
|
+
* `prefers-reduced-motion`, so a host is told (`reducedMotion`,
|
|
32
|
+
* `./protocol.ts`), and under it draws every animation's reduced form, which
|
|
33
|
+
* wakes it only where content changes. It is the one place the preference is
|
|
34
|
+
* honoured for every kind at once, because every kind is this type, and each
|
|
35
|
+
* combinator says its reduced form so a built animation answers it too.
|
|
36
|
+
* [LAW:types-are-the-program] It is an animation and not a value because
|
|
37
|
+
* which content shows is a fact about time that motion is not: a value with
|
|
38
|
+
* no time could only show a scheduled exit as already gone.
|
|
39
|
+
*
|
|
40
|
+
* The instances already in the tree: a `Beat` is an animation of which hold
|
|
41
|
+
* is in progress (`./easing.ts`), a `FrameSequence` of the frame shown and a
|
|
42
|
+
* `Spinner` of the spinner drawn (`../renderables/`), and an `Effect` is, for
|
|
43
|
+
* what an element draws in a frame, an animation of how its cells' colours
|
|
44
|
+
* move (`../renderables/effect.ts`). Every kind of motion is one more.
|
|
45
|
+
*
|
|
46
|
+
* An animation of renderables is a renderable — its face, `placedRender`:
|
|
47
|
+
* placed as the child of any container — a `Panel`, a `Table` cell, a
|
|
48
|
+
* `Group`, a container a user wrote — it draws at the time of the frame it
|
|
49
|
+
* is drawn in (`RenderOptions.frame`; 0, its own start, when printed) and
|
|
50
|
+
* stamps its cells with its hold there, under whatever its value's cells
|
|
51
|
+
* already say, so a frame's hold is the intersection of its cells' holds.
|
|
52
|
+
* [LAW:composability] No time is threaded through the code that places it,
|
|
53
|
+
* and no container knows animations exist. An animation placed inside
|
|
54
|
+
* another's value draws at the frame's time too: a combinator remaps the
|
|
55
|
+
* time it hands its parts, never a value's contents, so content that should
|
|
56
|
+
* follow a part's clock is composed into the part (`map`, `all`) and the
|
|
57
|
+
* result placed. [LAW:one-source-of-truth]
|
|
58
|
+
*
|
|
59
|
+
* [LAW:no-ambient-temporal-coupling] Pure: `t` is an argument and never a
|
|
60
|
+
* clock read (`./clock.ts`), the same `t` gives the same value, nothing is
|
|
61
|
+
* kept between calls, and a call costs the same at `t = 0` and `t = 10⁶`, so
|
|
62
|
+
* a host sampling once a second and one sampling sixty times see the same
|
|
63
|
+
* value at every `t` they share.
|
|
64
|
+
*
|
|
65
|
+
* [LAW:one-type-per-behavior] The combinators here are the ones every kind
|
|
66
|
+
* of motion is built from — a constant, a value moving every moment, a map
|
|
67
|
+
* over the value, several at once, one animation after another, and one
|
|
68
|
+
* played again every period — and each says how
|
|
69
|
+
* `nextChange` composes, so an animation built from them answers it without
|
|
70
|
+
* its author doing anything.
|
|
71
|
+
*
|
|
72
|
+
* Tier 5 of `src/core/`: `./easing.ts`, `./measure.ts`, `./protocol.ts`,
|
|
73
|
+
* `./segment.ts` and `./style.ts`, nothing else. [LAW:one-way-deps]
|
|
74
|
+
*/
|
|
75
|
+
import { beat, firstReaching, passAt, positiveSeconds } from "./easing.js";
|
|
76
|
+
import { Measurement } from "./measure.js";
|
|
77
|
+
import { isRenderable, render } from "./protocol.js";
|
|
78
|
+
import { Segment } from "./segment.js";
|
|
79
|
+
import { Style } from "./style.js";
|
|
80
|
+
/**
|
|
81
|
+
* What a frame drawn at `t` shows of `animation` under `motion`, and when
|
|
82
|
+
* that changes: the animation's, or under reduced motion its reduced form's
|
|
83
|
+
* (`reduced`). [LAW:single-enforcer] The one place the preference is read:
|
|
84
|
+
* every placed animation (`placedRender`), every effect, a spinner and
|
|
85
|
+
* the template functions choose here, so a host told once
|
|
86
|
+
* reduces every one.
|
|
87
|
+
*/
|
|
88
|
+
export function shownAt(animation, t, motion) {
|
|
89
|
+
const reduced = motion.reducedMotion === true;
|
|
90
|
+
const drawn = reduced ? animation.reduced() : animation;
|
|
91
|
+
return { value: drawn.at(t), nextChange: drawn.nextChange(t), drawn, reduced };
|
|
92
|
+
}
|
|
93
|
+
/** The hold `shown`, drawn at `t`, is in: its animation's two answers there. */
|
|
94
|
+
export function holdOf(shown, t) {
|
|
95
|
+
return { lastChange: shown.drawn.lastChange(t), nextChange: shown.nextChange };
|
|
96
|
+
}
|
|
97
|
+
/** The style saying a cell is in `hold`. */
|
|
98
|
+
export function stamp(hold) {
|
|
99
|
+
return new Style({ hold });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* `segments`, every one carrying `hold` under whatever it already said: the
|
|
103
|
+
* later `lastChange` and the sooner `nextChange` win (`Style.add`), so a
|
|
104
|
+
* frame's hold is the intersection of its cells', narrower than the truth
|
|
105
|
+
* and never wider. [LAW:single-enforcer] The one way a time is put on drawn
|
|
106
|
+
* cells, by whatever draws for a time it knows.
|
|
107
|
+
*/
|
|
108
|
+
export function stampFrame(segments, hold) {
|
|
109
|
+
return Segment.applyStyle(segments, stamp(hold));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The moment a frame drawn under `options` is drawn for: the frame's time,
|
|
113
|
+
* which the host writes once a frame (`RenderOptions.frame`), or with no
|
|
114
|
+
* frame — a `print` — 0, the start of an animation's own clock, the one
|
|
115
|
+
* moment it can name without reading one. [LAW:one-source-of-truth] Nothing
|
|
116
|
+
* else hands a placed animation its time, so an animation inside another's
|
|
117
|
+
* value draws at the frame's time too, never at a time a combinator mapped.
|
|
118
|
+
*/
|
|
119
|
+
export function frameTimeOf(options) {
|
|
120
|
+
return options.frame?.time ?? 0;
|
|
121
|
+
}
|
|
122
|
+
/** `value` as what an animation's face draws. [LAW:no-silent-failure] An animation of numbers made through `Animation.of` has a face at runtime and nothing to draw. */
|
|
123
|
+
function drawable(value) {
|
|
124
|
+
if (!isRenderable(value))
|
|
125
|
+
throw new TypeError("an Animation is drawn only when its values are renderables; place what it maps to (Animation.map)");
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* An animation's face, `render`: drawn at the time of the frame it is drawn
|
|
130
|
+
* in (`frameTimeOf`), the value `shownAt` picks, every segment stamped with
|
|
131
|
+
* its hold there under whatever its own cells say, and the hold told to the
|
|
132
|
+
* frame (`RenderOptions.onHold`), because a frame of no cells — an element
|
|
133
|
+
* not yet entered — may have cells later, and must say when without taking a
|
|
134
|
+
* row to say it in. A container — the library's or a user's — that draws its
|
|
135
|
+
* children through `render` draws an animation among them with no word about
|
|
136
|
+
* time: the hold goes back the way the time came in. [LAW:composability]
|
|
137
|
+
*/
|
|
138
|
+
export function* placedRender(animation, options) {
|
|
139
|
+
const t = frameTimeOf(options);
|
|
140
|
+
const shown = shownAt(animation, t, options);
|
|
141
|
+
const value = drawable(shown.value);
|
|
142
|
+
const hold = holdOf(shown, t);
|
|
143
|
+
options.onHold?.(hold);
|
|
144
|
+
yield* stampFrame(render(value, options), hold);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* An animation's face, `measure`: what it shows at the frame's time, measured,
|
|
148
|
+
* and its hold there told (`RenderOptions.onHold`), because a container lays
|
|
149
|
+
* out from the measurement and must lay out again when it changes.
|
|
150
|
+
*/
|
|
151
|
+
export function placedMeasure(animation, options) {
|
|
152
|
+
const t = frameTimeOf(options);
|
|
153
|
+
const shown = shownAt(animation, t, options);
|
|
154
|
+
options.onHold?.(holdOf(shown, t));
|
|
155
|
+
return Measurement.get(options, drawable(shown.value));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Every member of `source`, its own and its class's, as own properties of a
|
|
159
|
+
* new object: a method bound to `source`, a getter read off it live, a field
|
|
160
|
+
* as it is. So a class instance keeps its methods, and a spread of the copy
|
|
161
|
+
* is whole.
|
|
162
|
+
*/
|
|
163
|
+
function membersOf(source) {
|
|
164
|
+
const copy = {};
|
|
165
|
+
for (let layer = source; layer !== null && layer !== Object.prototype; layer = Object.getPrototypeOf(layer)) {
|
|
166
|
+
for (const key of Reflect.ownKeys(layer)) {
|
|
167
|
+
if (key === "constructor" || Object.hasOwn(copy, key))
|
|
168
|
+
continue;
|
|
169
|
+
const member = Object.getOwnPropertyDescriptor(layer, key);
|
|
170
|
+
Object.defineProperty(copy, key, member.get !== undefined
|
|
171
|
+
? { enumerable: true, configurable: true, get: () => Reflect.get(source, key) }
|
|
172
|
+
: { enumerable: true, configurable: true, writable: true, value: typeof member.value === "function" ? member.value.bind(source) : member.value });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return copy;
|
|
176
|
+
}
|
|
177
|
+
export const Animation = {
|
|
178
|
+
/**
|
|
179
|
+
* `timed` as an animation: every member it carries kept (`membersOf`),
|
|
180
|
+
* with the face its values call for — `render` and `measure`,
|
|
181
|
+
* drawing it at the frame's time. Every animation made from a literal is
|
|
182
|
+
* made here, the library's and a user's alike. [LAW:single-enforcer] The
|
|
183
|
+
* one cast in the type: a literal's `T` is not known at runtime, so every
|
|
184
|
+
* animation made here has the face, and one whose values are not
|
|
185
|
+
* renderables throws when it is drawn.
|
|
186
|
+
*/
|
|
187
|
+
of(timed) {
|
|
188
|
+
const faced = Object.assign(membersOf(timed), {
|
|
189
|
+
render: (options) => placedRender(faced, options),
|
|
190
|
+
measure: (options) => placedMeasure(faced, options),
|
|
191
|
+
});
|
|
192
|
+
return faced;
|
|
193
|
+
},
|
|
194
|
+
/** `value` at every time, never changing. */
|
|
195
|
+
constant(value) {
|
|
196
|
+
const still = Animation.of({ at: () => value, nextChange: () => Number.POSITIVE_INFINITY, lastChange: () => Number.NEGATIVE_INFINITY, reduced: () => still });
|
|
197
|
+
return still;
|
|
198
|
+
},
|
|
199
|
+
/**
|
|
200
|
+
* `before` until 0, then `after`: an instant change at 0 — a cut, what a
|
|
201
|
+
* one-shot is with its motion taken out, its start kept and its end at once.
|
|
202
|
+
*/
|
|
203
|
+
cut(before, after) {
|
|
204
|
+
const cut = Animation.of({
|
|
205
|
+
at: (t) => (t < 0 ? before : after),
|
|
206
|
+
nextChange: (t) => (t < 0 ? 0 : Number.POSITIVE_INFINITY),
|
|
207
|
+
lastChange: (t) => (t < 0 ? Number.NEGATIVE_INFINITY : 0),
|
|
208
|
+
reduced: () => cut,
|
|
209
|
+
});
|
|
210
|
+
return cut;
|
|
211
|
+
},
|
|
212
|
+
/**
|
|
213
|
+
* The value `at` gives, taken to move at every moment: what an animation
|
|
214
|
+
* that cannot say when it holds still is, so a host draws it every frame.
|
|
215
|
+
* Reduced, it holds its first value, as a loop does; a one-shot built on
|
|
216
|
+
* it says its own end (`transition`, `../renderables/effects.ts`).
|
|
217
|
+
*/
|
|
218
|
+
continuous(at) {
|
|
219
|
+
return Animation.of({ at, nextChange: (t) => t, lastChange: (t) => t, reduced: () => Animation.constant(at(0)) });
|
|
220
|
+
},
|
|
221
|
+
/**
|
|
222
|
+
* The time itself, in seconds, moving at every moment: what a clock, a
|
|
223
|
+
* counter or anything else that reports the time is mapped from. It is
|
|
224
|
+
* information and not motion, so reduced it is itself, and a clock shown
|
|
225
|
+
* to a reader who wants no motion still keeps the time; motion computed
|
|
226
|
+
* from the time is `continuous`, which reduced holds still.
|
|
227
|
+
* [LAW:types-are-the-program]
|
|
228
|
+
*/
|
|
229
|
+
time() {
|
|
230
|
+
const time = Animation.of({ at: (t) => t, nextChange: (t) => t, lastChange: (t) => t, reduced: () => time });
|
|
231
|
+
return time;
|
|
232
|
+
},
|
|
233
|
+
/**
|
|
234
|
+
* `animation`'s value through `f`, changing when it does. Two values `f`
|
|
235
|
+
* maps alike make an early answer, which the contract allows.
|
|
236
|
+
*/
|
|
237
|
+
map(animation, f) {
|
|
238
|
+
return Animation.of({
|
|
239
|
+
at: (t) => f(animation.at(t)),
|
|
240
|
+
nextChange: (t) => animation.nextChange(t),
|
|
241
|
+
lastChange: (t) => animation.lastChange(t),
|
|
242
|
+
reduced: () => Animation.map(animation.reduced(), f),
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
/**
|
|
246
|
+
* Every one of `animations` at once, their values in order, changing when
|
|
247
|
+
* the soonest of them does — so a stack of effects drawn together holds
|
|
248
|
+
* still exactly while each of them does, and reduced each reduced — a
|
|
249
|
+
* stagger with every child arrived. None never changes.
|
|
250
|
+
*/
|
|
251
|
+
all(animations) {
|
|
252
|
+
return Animation.of({
|
|
253
|
+
// [LAW:types-are-the-program] Each value at its own place in the tuple,
|
|
254
|
+
// which `map` cannot say of its array.
|
|
255
|
+
at: (t) => animations.map((animation) => animation.at(t)),
|
|
256
|
+
// A fold, not a spread: a stagger over a table's rows is a list as long
|
|
257
|
+
// as the table, past what an engine takes as arguments.
|
|
258
|
+
nextChange: (t) => animations.reduce((soonest, animation) => Math.min(soonest, animation.nextChange(t)), Number.POSITIVE_INFINITY),
|
|
259
|
+
lastChange: (t) => animations.reduce((latest, animation) => Math.max(latest, animation.lastChange(t)), Number.NEGATIVE_INFINITY),
|
|
260
|
+
reduced: () => Animation.all(animations.map((animation) => animation.reduced())),
|
|
261
|
+
});
|
|
262
|
+
},
|
|
263
|
+
/**
|
|
264
|
+
* `animation` sampled once a hold of `beat`: within a hold, its value at
|
|
265
|
+
* the hold's start, and at each hold's start it moves on. It changes at the
|
|
266
|
+
* first hold's start the sampled animation has moved by: the end of this
|
|
267
|
+
* hold for one that moves every moment, the hold its next change falls in
|
|
268
|
+
* for one that holds longer, and never for one that never changes again.
|
|
269
|
+
* The answer is read off what the animation says, never a comparison of
|
|
270
|
+
* values, so one that is back on the same value by the next hold still
|
|
271
|
+
* turns the beat there, an early answer the contract allows.
|
|
272
|
+
* [LAW:one-source-of-truth] The one stepping rule, for an effect's frames
|
|
273
|
+
* and a transition's schedule alike.
|
|
274
|
+
*/
|
|
275
|
+
onBeat(animation, beat) {
|
|
276
|
+
return Animation.of({
|
|
277
|
+
at: (t) => animation.at(beat.lastChange(t)),
|
|
278
|
+
nextChange(t) {
|
|
279
|
+
const moved = animation.nextChange(beat.lastChange(t));
|
|
280
|
+
if (moved === Number.POSITIVE_INFINITY)
|
|
281
|
+
return moved;
|
|
282
|
+
const end = beat.nextChange(t);
|
|
283
|
+
// The hold boundaries after `t` are `end`, then each hold's end in turn;
|
|
284
|
+
// the value turns at the first one the animation has moved by.
|
|
285
|
+
return moved <= end ? end : beat.lastChange(moved) === moved ? moved : beat.nextChange(moved);
|
|
286
|
+
},
|
|
287
|
+
// The value held now began at this hold's start at the latest: an early
|
|
288
|
+
// answer where the animation had not moved by it, which the contract allows.
|
|
289
|
+
lastChange: (t) => beat.lastChange(t),
|
|
290
|
+
// Reduced, nothing moves between beats, so there is nothing to sample on them.
|
|
291
|
+
reduced: () => animation.reduced(),
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
/**
|
|
295
|
+
* `first` until `seconds`, then `then`, handed the time since it began —
|
|
296
|
+
* each part on its own clock from 0, as every effect is. Before the switch
|
|
297
|
+
* the value next changes when `first`'s does or at the switch, whichever is
|
|
298
|
+
* sooner; after it, when `then`'s does, carried back onto this timeline.
|
|
299
|
+
* Reduced, each part is reduced and the switch kept, so what either shows
|
|
300
|
+
* shows on time; a one-shot that is the motion into what follows says its
|
|
301
|
+
* own end (`transition`, `../renderables/effects.ts`).
|
|
302
|
+
*/
|
|
303
|
+
sequence(first, seconds, then) {
|
|
304
|
+
positiveSeconds("Animation.sequence seconds", seconds);
|
|
305
|
+
// `then`'s moment `local`, on its own clock, carried back onto this
|
|
306
|
+
// timeline: the first moment whose time since the switch reaches
|
|
307
|
+
// `local`, which the sum `local + seconds` can round to either side of —
|
|
308
|
+
// under it, where `at` still shows the old value, or over it, a float
|
|
309
|
+
// after the change showed.
|
|
310
|
+
const carried = (local) => (Number.isFinite(local) ? firstReaching(local + seconds, (x) => x - seconds >= local) : local);
|
|
311
|
+
return Animation.of({
|
|
312
|
+
at: (t) => (t - seconds >= 0 ? then.at(t - seconds) : first.at(t)),
|
|
313
|
+
nextChange(t) {
|
|
314
|
+
const into = t - seconds;
|
|
315
|
+
if (into < 0)
|
|
316
|
+
return Math.min(first.nextChange(t), seconds);
|
|
317
|
+
return Math.max(t, carried(then.nextChange(into)));
|
|
318
|
+
},
|
|
319
|
+
// After the switch the value became what it is at the switch or when
|
|
320
|
+
// `then`'s did since, whichever is later; before it, when `first`'s did.
|
|
321
|
+
lastChange(t) {
|
|
322
|
+
const into = t - seconds;
|
|
323
|
+
if (into < 0)
|
|
324
|
+
return first.lastChange(t);
|
|
325
|
+
return Math.min(t, Math.max(seconds, carried(then.lastChange(into))));
|
|
326
|
+
},
|
|
327
|
+
reduced: () => Animation.sequence(first.reduced(), seconds, then.reduced()),
|
|
328
|
+
});
|
|
329
|
+
},
|
|
330
|
+
/**
|
|
331
|
+
* `nth(n)` for every time in the `n`th turn, `[n·period, (n+1)·period)`,
|
|
332
|
+
* handed the time since that turn began — a one-shot played again every
|
|
333
|
+
* `period` seconds, a different one each turn if `nth` says so. `n` is any
|
|
334
|
+
* integer, so a timeline run back past 0 is in turn −1. Within a turn the
|
|
335
|
+
* value next changes when the turn's does or at the next turn, whichever is
|
|
336
|
+
* sooner, and became what it is when the turn's did or at this turn's start,
|
|
337
|
+
* whichever is later: run backwards, a host wakes where the turn began.
|
|
338
|
+
* Reduced, each turn is reduced and the turns kept, so a turn showing
|
|
339
|
+
* something new still shows it on time and a one-shot inside cuts to its
|
|
340
|
+
* end there. Nothing is walked through: a call reads only its turn.
|
|
341
|
+
*/
|
|
342
|
+
repeat(period, nth) {
|
|
343
|
+
positiveSeconds("Animation.repeat period", period);
|
|
344
|
+
// [LAW:single-enforcer] Which turn a time is in, and how far into it, is
|
|
345
|
+
// `passAt`, the wrap a `beat` and `Phase.loop` read time through, so a
|
|
346
|
+
// repeat beside a loop of the same period turns on the same float; where
|
|
347
|
+
// a turn begins and the next begins are a one-hold beat's two ends.
|
|
348
|
+
const turns = beat([period]);
|
|
349
|
+
// The turn's moment `local`, on its own clock, carried onto this one: the
|
|
350
|
+
// first float the wrap places at or past `local` in turn `n`, or in a
|
|
351
|
+
// later turn, found as `sequence` carries its second part's.
|
|
352
|
+
const carried = (n, began, local) => Number.isFinite(local)
|
|
353
|
+
? firstReaching(began + local, (x) => {
|
|
354
|
+
const { pass, into } = passAt("Animation.repeat", x, period);
|
|
355
|
+
return pass > n || (pass === n && into >= local);
|
|
356
|
+
})
|
|
357
|
+
: local;
|
|
358
|
+
return Animation.of({
|
|
359
|
+
at: (t) => {
|
|
360
|
+
const { pass, into } = passAt("Animation.repeat", t, period);
|
|
361
|
+
return nth(pass).at(into);
|
|
362
|
+
},
|
|
363
|
+
nextChange(t) {
|
|
364
|
+
const { pass, into } = passAt("Animation.repeat", t, period);
|
|
365
|
+
return Math.max(t, Math.min(turns.nextChange(t), carried(pass, turns.lastChange(t), nth(pass).nextChange(into))));
|
|
366
|
+
},
|
|
367
|
+
lastChange(t) {
|
|
368
|
+
const { pass, into } = passAt("Animation.repeat", t, period);
|
|
369
|
+
const began = turns.lastChange(t);
|
|
370
|
+
return Math.min(t, Math.max(began, carried(pass, began, nth(pass).lastChange(into))));
|
|
371
|
+
},
|
|
372
|
+
reduced: () => Animation.repeat(period, (n) => nth(n).reduced()),
|
|
373
|
+
});
|
|
374
|
+
},
|
|
375
|
+
};
|
package/dist/core/ansi.js
CHANGED
|
@@ -51,10 +51,10 @@ import { RichText } from "./text.js";
|
|
|
51
51
|
* and one final byte (`\x1b(B`, `\x1b)0`, `\x1b#8`, `\x1bc`). Only the first
|
|
52
52
|
* three become tokens.
|
|
53
53
|
*/
|
|
54
|
-
const
|
|
54
|
+
const escapes = () => /\r|\x1b\[([0-9;:]*)m|\x1b\[([012]?)K|\x1b\[[0-?]*[ -/]*[@-~]|\x1b[\]P_^X][\s\S]*?(?:\x07|\x1b\\|\x9c|$)|\x1b[ -/]*[0-~]/g;
|
|
55
55
|
function* escapeTokens(bytes) {
|
|
56
56
|
let at = 0;
|
|
57
|
-
for (const match of bytes.matchAll(
|
|
57
|
+
for (const match of bytes.matchAll(escapes())) {
|
|
58
58
|
if (match.index > at)
|
|
59
59
|
yield { kind: "text", text: bytes.slice(at, match.index) };
|
|
60
60
|
if (match[0] === "\r")
|
package/dist/core/box.d.ts
CHANGED
|
@@ -28,19 +28,19 @@ import { Segment } from "./segment.js";
|
|
|
28
28
|
import type { Style } from "./style.js";
|
|
29
29
|
/** A rule spanning the table: the top and bottom borders, and every separator. */
|
|
30
30
|
export interface EdgeChars {
|
|
31
|
-
left: string;
|
|
32
|
-
horizontal: string;
|
|
33
|
-
cross: string;
|
|
34
|
-
right: string;
|
|
31
|
+
readonly left: string;
|
|
32
|
+
readonly horizontal: string;
|
|
33
|
+
readonly cross: string;
|
|
34
|
+
readonly right: string;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* The verticals framing a row of cells. A content line of the grid has no
|
|
38
38
|
* horizontal of its own — its fill column is a placeholder the cells occupy.
|
|
39
39
|
*/
|
|
40
40
|
export interface ContentChars {
|
|
41
|
-
left: string;
|
|
42
|
-
vertical: string;
|
|
43
|
-
right: string;
|
|
41
|
+
readonly left: string;
|
|
42
|
+
readonly vertical: string;
|
|
43
|
+
readonly right: string;
|
|
44
44
|
}
|
|
45
45
|
export type RowLevel = "head" | "row" | "foot" | "mid";
|
|
46
46
|
export interface SubstituteOptions {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cells Rich's `cell_len` gives each code point, and the code points VS16
|
|
3
|
+
* widens. Generated by scripts/cell-widths.py from Rich 15.0.0's Unicode 17.0.0
|
|
4
|
+
* table, which Rich builds from wcwidth's data; regenerate rather than edit.
|
|
5
|
+
*/
|
|
6
|
+
/** The cells Rich gives `codePoint` on its own: none for a C0 or C1 control. */
|
|
7
|
+
export declare function codePointWidth(codePoint: number): 0 | 1 | 2;
|
|
8
|
+
/** Whether VS16 after `codePoint` widens it from one cell to two. */
|
|
9
|
+
export declare function widensToEmoji(codePoint: number): boolean;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cells Rich's `cell_len` gives each code point, and the code points VS16
|
|
3
|
+
* widens. Generated by scripts/cell-widths.py from Rich 15.0.0's Unicode 17.0.0
|
|
4
|
+
* table, which Rich builds from wcwidth's data; regenerate rather than edit.
|
|
5
|
+
*/
|
|
6
|
+
// Every range of code points that does not take one cell, as [first, last,
|
|
7
|
+
// cells]: ascending, disjoint, adjacent ranges of one width merged.
|
|
8
|
+
const RANGES = [
|
|
9
|
+
[0x0, 0x0, 0], [0x300, 0x36f, 0], [0x483, 0x489, 0], [0x591, 0x5bd, 0], [0x5bf, 0x5bf, 0], [0x5c1, 0x5c2, 0],
|
|
10
|
+
[0x5c4, 0x5c5, 0], [0x5c7, 0x5c7, 0], [0x610, 0x61a, 0], [0x61c, 0x61c, 0], [0x64b, 0x65f, 0], [0x670, 0x670, 0],
|
|
11
|
+
[0x6d6, 0x6dc, 0], [0x6df, 0x6e4, 0], [0x6e7, 0x6e8, 0], [0x6ea, 0x6ed, 0], [0x711, 0x711, 0], [0x730, 0x74a, 0],
|
|
12
|
+
[0x7a6, 0x7b0, 0], [0x7eb, 0x7f3, 0], [0x7fd, 0x7fd, 0], [0x816, 0x819, 0], [0x81b, 0x823, 0], [0x825, 0x827, 0],
|
|
13
|
+
[0x829, 0x82d, 0], [0x859, 0x85b, 0], [0x897, 0x89f, 0], [0x8ca, 0x8e1, 0], [0x8e3, 0x903, 0], [0x93a, 0x93c, 0],
|
|
14
|
+
[0x93e, 0x94f, 0], [0x951, 0x957, 0], [0x962, 0x963, 0], [0x981, 0x983, 0], [0x9bc, 0x9bc, 0], [0x9be, 0x9c4, 0],
|
|
15
|
+
[0x9c7, 0x9c8, 0], [0x9cb, 0x9cd, 0], [0x9d7, 0x9d7, 0], [0x9e2, 0x9e3, 0], [0x9fe, 0x9fe, 0], [0xa01, 0xa03, 0],
|
|
16
|
+
[0xa3c, 0xa3c, 0], [0xa3e, 0xa42, 0], [0xa47, 0xa48, 0], [0xa4b, 0xa4d, 0], [0xa51, 0xa51, 0], [0xa70, 0xa71, 0],
|
|
17
|
+
[0xa75, 0xa75, 0], [0xa81, 0xa83, 0], [0xabc, 0xabc, 0], [0xabe, 0xac5, 0], [0xac7, 0xac9, 0], [0xacb, 0xacd, 0],
|
|
18
|
+
[0xae2, 0xae3, 0], [0xafa, 0xaff, 0], [0xb01, 0xb03, 0], [0xb3c, 0xb3c, 0], [0xb3e, 0xb44, 0], [0xb47, 0xb48, 0],
|
|
19
|
+
[0xb4b, 0xb4d, 0], [0xb55, 0xb57, 0], [0xb62, 0xb63, 0], [0xb82, 0xb82, 0], [0xbbe, 0xbc2, 0], [0xbc6, 0xbc8, 0],
|
|
20
|
+
[0xbca, 0xbcd, 0], [0xbd7, 0xbd7, 0], [0xc00, 0xc04, 0], [0xc3c, 0xc3c, 0], [0xc3e, 0xc44, 0], [0xc46, 0xc48, 0],
|
|
21
|
+
[0xc4a, 0xc4d, 0], [0xc55, 0xc56, 0], [0xc62, 0xc63, 0], [0xc81, 0xc83, 0], [0xcbc, 0xcbc, 0], [0xcbe, 0xcc4, 0],
|
|
22
|
+
[0xcc6, 0xcc8, 0], [0xcca, 0xccd, 0], [0xcd5, 0xcd6, 0], [0xce2, 0xce3, 0], [0xcf3, 0xcf3, 0], [0xd00, 0xd03, 0],
|
|
23
|
+
[0xd3b, 0xd3c, 0], [0xd3e, 0xd44, 0], [0xd46, 0xd48, 0], [0xd4a, 0xd4d, 0], [0xd57, 0xd57, 0], [0xd62, 0xd63, 0],
|
|
24
|
+
[0xd81, 0xd83, 0], [0xdca, 0xdca, 0], [0xdcf, 0xdd4, 0], [0xdd6, 0xdd6, 0], [0xdd8, 0xddf, 0], [0xdf2, 0xdf3, 0],
|
|
25
|
+
[0xe31, 0xe31, 0], [0xe34, 0xe3a, 0], [0xe47, 0xe4e, 0], [0xeb1, 0xeb1, 0], [0xeb4, 0xebc, 0], [0xec8, 0xece, 0],
|
|
26
|
+
[0xf18, 0xf19, 0], [0xf35, 0xf35, 0], [0xf37, 0xf37, 0], [0xf39, 0xf39, 0], [0xf3e, 0xf3f, 0], [0xf71, 0xf84, 0],
|
|
27
|
+
[0xf86, 0xf87, 0], [0xf8d, 0xf97, 0], [0xf99, 0xfbc, 0], [0xfc6, 0xfc6, 0], [0x102b, 0x103e, 0], [0x1056, 0x1059, 0],
|
|
28
|
+
[0x105e, 0x1060, 0], [0x1062, 0x1064, 0], [0x1067, 0x106d, 0], [0x1071, 0x1074, 0], [0x1082, 0x108d, 0],
|
|
29
|
+
[0x108f, 0x108f, 0], [0x109a, 0x109d, 0], [0x1100, 0x115f, 2], [0x1160, 0x11ff, 0], [0x135d, 0x135f, 0],
|
|
30
|
+
[0x1712, 0x1715, 0], [0x1732, 0x1734, 0], [0x1752, 0x1753, 0], [0x1772, 0x1773, 0], [0x17b4, 0x17d3, 0],
|
|
31
|
+
[0x17dd, 0x17dd, 0], [0x180b, 0x180f, 0], [0x1885, 0x1886, 0], [0x18a9, 0x18a9, 0], [0x1920, 0x192b, 0],
|
|
32
|
+
[0x1930, 0x193b, 0], [0x1a17, 0x1a1b, 0], [0x1a55, 0x1a5e, 0], [0x1a60, 0x1a7c, 0], [0x1a7f, 0x1a7f, 0],
|
|
33
|
+
[0x1ab0, 0x1add, 0], [0x1ae0, 0x1aeb, 0], [0x1b00, 0x1b04, 0], [0x1b34, 0x1b44, 0], [0x1b6b, 0x1b73, 0],
|
|
34
|
+
[0x1b80, 0x1b82, 0], [0x1ba1, 0x1bad, 0], [0x1be6, 0x1bf3, 0], [0x1c24, 0x1c37, 0], [0x1cd0, 0x1cd2, 0],
|
|
35
|
+
[0x1cd4, 0x1ce8, 0], [0x1ced, 0x1ced, 0], [0x1cf4, 0x1cf4, 0], [0x1cf7, 0x1cf9, 0], [0x1dc0, 0x1dff, 0],
|
|
36
|
+
[0x200b, 0x200f, 0], [0x2028, 0x202e, 0], [0x2060, 0x206f, 0], [0x20d0, 0x20f0, 0], [0x231a, 0x231b, 2],
|
|
37
|
+
[0x2329, 0x232a, 2], [0x23e9, 0x23ec, 2], [0x23f0, 0x23f0, 2], [0x23f3, 0x23f3, 2], [0x25fd, 0x25fe, 2],
|
|
38
|
+
[0x2614, 0x2615, 2], [0x2630, 0x2637, 2], [0x2648, 0x2653, 2], [0x267f, 0x267f, 2], [0x268a, 0x268f, 2],
|
|
39
|
+
[0x2693, 0x2693, 2], [0x26a1, 0x26a1, 2], [0x26aa, 0x26ab, 2], [0x26bd, 0x26be, 2], [0x26c4, 0x26c5, 2],
|
|
40
|
+
[0x26ce, 0x26ce, 2], [0x26d4, 0x26d4, 2], [0x26ea, 0x26ea, 2], [0x26f2, 0x26f3, 2], [0x26f5, 0x26f5, 2],
|
|
41
|
+
[0x26fa, 0x26fa, 2], [0x26fd, 0x26fd, 2], [0x2705, 0x2705, 2], [0x270a, 0x270b, 2], [0x2728, 0x2728, 2],
|
|
42
|
+
[0x274c, 0x274c, 2], [0x274e, 0x274e, 2], [0x2753, 0x2755, 2], [0x2757, 0x2757, 2], [0x2795, 0x2797, 2],
|
|
43
|
+
[0x27b0, 0x27b0, 2], [0x27bf, 0x27bf, 2], [0x2b1b, 0x2b1c, 2], [0x2b50, 0x2b50, 2], [0x2b55, 0x2b55, 2],
|
|
44
|
+
[0x2cef, 0x2cf1, 0], [0x2d7f, 0x2d7f, 0], [0x2de0, 0x2dff, 0], [0x2e80, 0x2e99, 2], [0x2e9b, 0x2ef3, 2],
|
|
45
|
+
[0x2f00, 0x2fd5, 2], [0x2ff0, 0x3029, 2], [0x302a, 0x302f, 0], [0x3030, 0x303e, 2], [0x3041, 0x3096, 2],
|
|
46
|
+
[0x3099, 0x309a, 0], [0x309b, 0x30ff, 2], [0x3105, 0x312f, 2], [0x3131, 0x3163, 2], [0x3164, 0x3164, 0],
|
|
47
|
+
[0x3165, 0x318e, 2], [0x3190, 0x31e5, 2], [0x31ef, 0x321e, 2], [0x3220, 0x3247, 2], [0x3250, 0xa48c, 2],
|
|
48
|
+
[0xa490, 0xa4c6, 2], [0xa66f, 0xa672, 0], [0xa674, 0xa67d, 0], [0xa69e, 0xa69f, 0], [0xa6f0, 0xa6f1, 0],
|
|
49
|
+
[0xa802, 0xa802, 0], [0xa806, 0xa806, 0], [0xa80b, 0xa80b, 0], [0xa823, 0xa827, 0], [0xa82c, 0xa82c, 0],
|
|
50
|
+
[0xa880, 0xa881, 0], [0xa8b4, 0xa8c5, 0], [0xa8e0, 0xa8f1, 0], [0xa8ff, 0xa8ff, 0], [0xa926, 0xa92d, 0],
|
|
51
|
+
[0xa947, 0xa953, 0], [0xa960, 0xa97c, 2], [0xa980, 0xa983, 0], [0xa9b3, 0xa9c0, 0], [0xa9e5, 0xa9e5, 0],
|
|
52
|
+
[0xaa29, 0xaa36, 0], [0xaa43, 0xaa43, 0], [0xaa4c, 0xaa4d, 0], [0xaa7b, 0xaa7d, 0], [0xaab0, 0xaab0, 0],
|
|
53
|
+
[0xaab2, 0xaab4, 0], [0xaab7, 0xaab8, 0], [0xaabe, 0xaabf, 0], [0xaac1, 0xaac1, 0], [0xaaeb, 0xaaef, 0],
|
|
54
|
+
[0xaaf5, 0xaaf6, 0], [0xabe3, 0xabea, 0], [0xabec, 0xabed, 0], [0xac00, 0xd7a3, 2], [0xd7b0, 0xd7ff, 0],
|
|
55
|
+
[0xf900, 0xfaff, 2], [0xfb1e, 0xfb1e, 0], [0xfe00, 0xfe0f, 0], [0xfe10, 0xfe19, 2], [0xfe20, 0xfe2f, 0],
|
|
56
|
+
[0xfe30, 0xfe52, 2], [0xfe54, 0xfe66, 2], [0xfe68, 0xfe6b, 2], [0xfeff, 0xfeff, 0], [0xff01, 0xff60, 2],
|
|
57
|
+
[0xffa0, 0xffa0, 0], [0xffe0, 0xffe6, 2], [0xfff0, 0xfffb, 0], [0x101fd, 0x101fd, 0], [0x102e0, 0x102e0, 0],
|
|
58
|
+
[0x10376, 0x1037a, 0], [0x10a01, 0x10a03, 0], [0x10a05, 0x10a06, 0], [0x10a0c, 0x10a0f, 0], [0x10a38, 0x10a3a, 0],
|
|
59
|
+
[0x10a3f, 0x10a3f, 0], [0x10ae5, 0x10ae6, 0], [0x10d24, 0x10d27, 0], [0x10d69, 0x10d6d, 0], [0x10eab, 0x10eac, 0],
|
|
60
|
+
[0x10efa, 0x10eff, 0], [0x10f46, 0x10f50, 0], [0x10f82, 0x10f85, 0], [0x11000, 0x11002, 0], [0x11038, 0x11046, 0],
|
|
61
|
+
[0x11070, 0x11070, 0], [0x11073, 0x11074, 0], [0x1107f, 0x11082, 0], [0x110b0, 0x110ba, 0], [0x110c2, 0x110c2, 0],
|
|
62
|
+
[0x11100, 0x11102, 0], [0x11127, 0x11134, 0], [0x11145, 0x11146, 0], [0x11173, 0x11173, 0], [0x11180, 0x11182, 0],
|
|
63
|
+
[0x111b3, 0x111c0, 0], [0x111c9, 0x111cc, 0], [0x111ce, 0x111cf, 0], [0x1122c, 0x11237, 0], [0x1123e, 0x1123e, 0],
|
|
64
|
+
[0x11241, 0x11241, 0], [0x112df, 0x112ea, 0], [0x11300, 0x11303, 0], [0x1133b, 0x1133c, 0], [0x1133e, 0x11344, 0],
|
|
65
|
+
[0x11347, 0x11348, 0], [0x1134b, 0x1134d, 0], [0x11357, 0x11357, 0], [0x11362, 0x11363, 0], [0x11366, 0x1136c, 0],
|
|
66
|
+
[0x11370, 0x11374, 0], [0x113b8, 0x113c0, 0], [0x113c2, 0x113c2, 0], [0x113c5, 0x113c5, 0], [0x113c7, 0x113ca, 0],
|
|
67
|
+
[0x113cc, 0x113d0, 0], [0x113d2, 0x113d2, 0], [0x113e1, 0x113e2, 0], [0x11435, 0x11446, 0], [0x1145e, 0x1145e, 0],
|
|
68
|
+
[0x114b0, 0x114c3, 0], [0x115af, 0x115b5, 0], [0x115b8, 0x115c0, 0], [0x115dc, 0x115dd, 0], [0x11630, 0x11640, 0],
|
|
69
|
+
[0x116ab, 0x116b7, 0], [0x1171d, 0x1172b, 0], [0x1182c, 0x1183a, 0], [0x11930, 0x11935, 0], [0x11937, 0x11938, 0],
|
|
70
|
+
[0x1193b, 0x1193e, 0], [0x11940, 0x11940, 0], [0x11942, 0x11943, 0], [0x119d1, 0x119d7, 0], [0x119da, 0x119e0, 0],
|
|
71
|
+
[0x119e4, 0x119e4, 0], [0x11a01, 0x11a0a, 0], [0x11a33, 0x11a39, 0], [0x11a3b, 0x11a3e, 0], [0x11a47, 0x11a47, 0],
|
|
72
|
+
[0x11a51, 0x11a5b, 0], [0x11a8a, 0x11a99, 0], [0x11b60, 0x11b67, 0], [0x11c2f, 0x11c36, 0], [0x11c38, 0x11c3f, 0],
|
|
73
|
+
[0x11c92, 0x11ca7, 0], [0x11ca9, 0x11cb6, 0], [0x11d31, 0x11d36, 0], [0x11d3a, 0x11d3a, 0], [0x11d3c, 0x11d3d, 0],
|
|
74
|
+
[0x11d3f, 0x11d45, 0], [0x11d47, 0x11d47, 0], [0x11d8a, 0x11d8e, 0], [0x11d90, 0x11d91, 0], [0x11d93, 0x11d97, 0],
|
|
75
|
+
[0x11ef3, 0x11ef6, 0], [0x11f00, 0x11f01, 0], [0x11f03, 0x11f03, 0], [0x11f34, 0x11f3a, 0], [0x11f3e, 0x11f42, 0],
|
|
76
|
+
[0x11f5a, 0x11f5a, 0], [0x13430, 0x13440, 0], [0x13447, 0x13455, 0], [0x1611e, 0x1612f, 0], [0x16af0, 0x16af4, 0],
|
|
77
|
+
[0x16b30, 0x16b36, 0], [0x16f4f, 0x16f4f, 0], [0x16f51, 0x16f87, 0], [0x16f8f, 0x16f92, 0], [0x16fe0, 0x16fe3, 2],
|
|
78
|
+
[0x16fe4, 0x16fe4, 0], [0x16ff0, 0x16ff1, 0], [0x16ff2, 0x16ff6, 2], [0x17000, 0x18cd5, 2], [0x18cff, 0x18d1e, 2],
|
|
79
|
+
[0x18d80, 0x18df2, 2], [0x1aff0, 0x1aff3, 2], [0x1aff5, 0x1affb, 2], [0x1affd, 0x1affe, 2], [0x1b000, 0x1b122, 2],
|
|
80
|
+
[0x1b132, 0x1b132, 2], [0x1b150, 0x1b152, 2], [0x1b155, 0x1b155, 2], [0x1b164, 0x1b167, 2], [0x1b170, 0x1b2fb, 2],
|
|
81
|
+
[0x1bc9d, 0x1bc9e, 0], [0x1bca0, 0x1bca3, 0], [0x1cf00, 0x1cf2d, 0], [0x1cf30, 0x1cf46, 0], [0x1d165, 0x1d169, 0],
|
|
82
|
+
[0x1d16d, 0x1d182, 0], [0x1d185, 0x1d18b, 0], [0x1d1aa, 0x1d1ad, 0], [0x1d242, 0x1d244, 0], [0x1d300, 0x1d356, 2],
|
|
83
|
+
[0x1d360, 0x1d376, 2], [0x1da00, 0x1da36, 0], [0x1da3b, 0x1da6c, 0], [0x1da75, 0x1da75, 0], [0x1da84, 0x1da84, 0],
|
|
84
|
+
[0x1da9b, 0x1da9f, 0], [0x1daa1, 0x1daaf, 0], [0x1e000, 0x1e006, 0], [0x1e008, 0x1e018, 0], [0x1e01b, 0x1e021, 0],
|
|
85
|
+
[0x1e023, 0x1e024, 0], [0x1e026, 0x1e02a, 0], [0x1e08f, 0x1e08f, 0], [0x1e130, 0x1e136, 0], [0x1e2ae, 0x1e2ae, 0],
|
|
86
|
+
[0x1e2ec, 0x1e2ef, 0], [0x1e4ec, 0x1e4ef, 0], [0x1e5ee, 0x1e5ef, 0], [0x1e6e3, 0x1e6e3, 0], [0x1e6e6, 0x1e6e6, 0],
|
|
87
|
+
[0x1e6ee, 0x1e6ef, 0], [0x1e6f5, 0x1e6f5, 0], [0x1e8d0, 0x1e8d6, 0], [0x1e944, 0x1e94a, 0], [0x1f004, 0x1f004, 2],
|
|
88
|
+
[0x1f0cf, 0x1f0cf, 2], [0x1f18e, 0x1f18e, 2], [0x1f191, 0x1f19a, 2], [0x1f200, 0x1f202, 2], [0x1f210, 0x1f23b, 2],
|
|
89
|
+
[0x1f240, 0x1f248, 2], [0x1f250, 0x1f251, 2], [0x1f260, 0x1f265, 2], [0x1f300, 0x1f320, 2], [0x1f32d, 0x1f335, 2],
|
|
90
|
+
[0x1f337, 0x1f37c, 2], [0x1f37e, 0x1f393, 2], [0x1f3a0, 0x1f3ca, 2], [0x1f3cf, 0x1f3d3, 2], [0x1f3e0, 0x1f3f0, 2],
|
|
91
|
+
[0x1f3f4, 0x1f3f4, 2], [0x1f3f8, 0x1f3fa, 2], [0x1f3fb, 0x1f3ff, 0], [0x1f400, 0x1f43e, 2], [0x1f440, 0x1f440, 2],
|
|
92
|
+
[0x1f442, 0x1f4fc, 2], [0x1f4ff, 0x1f53d, 2], [0x1f54b, 0x1f54e, 2], [0x1f550, 0x1f567, 2], [0x1f57a, 0x1f57a, 2],
|
|
93
|
+
[0x1f595, 0x1f596, 2], [0x1f5a4, 0x1f5a4, 2], [0x1f5fb, 0x1f64f, 2], [0x1f680, 0x1f6c5, 2], [0x1f6cc, 0x1f6cc, 2],
|
|
94
|
+
[0x1f6d0, 0x1f6d2, 2], [0x1f6d5, 0x1f6d8, 2], [0x1f6dc, 0x1f6df, 2], [0x1f6eb, 0x1f6ec, 2], [0x1f6f4, 0x1f6fc, 2],
|
|
95
|
+
[0x1f7e0, 0x1f7eb, 2], [0x1f7f0, 0x1f7f0, 2], [0x1f90c, 0x1f93a, 2], [0x1f93c, 0x1f945, 2], [0x1f947, 0x1f9ff, 2],
|
|
96
|
+
[0x1fa70, 0x1fa7c, 2], [0x1fa80, 0x1fa8a, 2], [0x1fa8e, 0x1fac6, 2], [0x1fac8, 0x1fac8, 2], [0x1facd, 0x1fadc, 2],
|
|
97
|
+
[0x1fadf, 0x1faea, 2], [0x1faef, 0x1faf8, 2], [0x20000, 0x2fffd, 2], [0x30000, 0x3fffd, 2], [0xe0000, 0xe0fff, 0],
|
|
98
|
+
];
|
|
99
|
+
// The code points one cell wide on their own and two when VARIATION SELECTOR-16
|
|
100
|
+
// asks for emoji presentation.
|
|
101
|
+
const NARROW_TO_WIDE = new Set([
|
|
102
|
+
0x23, 0x2a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xa9, 0xae, 0x203c, 0x2049, 0x2122, 0x2139,
|
|
103
|
+
0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21a9, 0x21aa, 0x2328, 0x23cf, 0x23ed, 0x23ee, 0x23ef, 0x23f1,
|
|
104
|
+
0x23f2, 0x23f8, 0x23f9, 0x23fa, 0x24c2, 0x25aa, 0x25ab, 0x25b6, 0x25c0, 0x25fb, 0x25fc, 0x2600, 0x2601, 0x2602,
|
|
105
|
+
0x2603, 0x2604, 0x260e, 0x2611, 0x2618, 0x261d, 0x2620, 0x2622, 0x2623, 0x2626, 0x262a, 0x262e, 0x262f, 0x2638,
|
|
106
|
+
0x2639, 0x263a, 0x2640, 0x2642, 0x265f, 0x2660, 0x2663, 0x2665, 0x2666, 0x2668, 0x267b, 0x267e, 0x2692, 0x2694,
|
|
107
|
+
0x2695, 0x2696, 0x2697, 0x2699, 0x269b, 0x269c, 0x26a0, 0x26a7, 0x26b0, 0x26b1, 0x26c8, 0x26cf, 0x26d1, 0x26d3,
|
|
108
|
+
0x26e9, 0x26f0, 0x26f1, 0x26f4, 0x26f7, 0x26f8, 0x26f9, 0x2702, 0x2708, 0x2709, 0x270c, 0x270d, 0x270f, 0x2712,
|
|
109
|
+
0x2714, 0x2716, 0x271d, 0x2721, 0x2733, 0x2734, 0x2744, 0x2747, 0x2763, 0x2764, 0x27a1, 0x2934, 0x2935, 0x2b05,
|
|
110
|
+
0x2b06, 0x2b07, 0x1f170, 0x1f171, 0x1f17e, 0x1f17f, 0x1f321, 0x1f324, 0x1f325, 0x1f326, 0x1f327, 0x1f328, 0x1f329,
|
|
111
|
+
0x1f32a, 0x1f32b, 0x1f32c, 0x1f336, 0x1f37d, 0x1f396, 0x1f397, 0x1f399, 0x1f39a, 0x1f39b, 0x1f39e, 0x1f39f, 0x1f3cb,
|
|
112
|
+
0x1f3cc, 0x1f3cd, 0x1f3ce, 0x1f3d4, 0x1f3d5, 0x1f3d6, 0x1f3d7, 0x1f3d8, 0x1f3d9, 0x1f3da, 0x1f3db, 0x1f3dc, 0x1f3dd,
|
|
113
|
+
0x1f3de, 0x1f3df, 0x1f3f3, 0x1f3f5, 0x1f3f7, 0x1f43f, 0x1f441, 0x1f4fd, 0x1f549, 0x1f54a, 0x1f56f, 0x1f570, 0x1f573,
|
|
114
|
+
0x1f574, 0x1f575, 0x1f576, 0x1f577, 0x1f578, 0x1f579, 0x1f587, 0x1f58a, 0x1f58b, 0x1f58c, 0x1f58d, 0x1f590, 0x1f5a5,
|
|
115
|
+
0x1f5a8, 0x1f5b1, 0x1f5b2, 0x1f5bc, 0x1f5c2, 0x1f5c3, 0x1f5c4, 0x1f5d1, 0x1f5d2, 0x1f5d3, 0x1f5dc, 0x1f5dd, 0x1f5de,
|
|
116
|
+
0x1f5e1, 0x1f5e3, 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f6cb, 0x1f6cd, 0x1f6ce, 0x1f6cf, 0x1f6e0, 0x1f6e1, 0x1f6e2,
|
|
117
|
+
0x1f6e3, 0x1f6e4, 0x1f6e5, 0x1f6e9, 0x1f6f0, 0x1f6f3,
|
|
118
|
+
]);
|
|
119
|
+
/** The cells Rich gives `codePoint` on its own: none for a C0 or C1 control. */
|
|
120
|
+
export function codePointWidth(codePoint) {
|
|
121
|
+
if (codePoint < 0x20 || (codePoint >= 0x7f && codePoint < 0xa0))
|
|
122
|
+
return 0;
|
|
123
|
+
let low = 0;
|
|
124
|
+
let high = RANGES.length - 1;
|
|
125
|
+
while (low <= high) {
|
|
126
|
+
const mid = (low + high) >> 1;
|
|
127
|
+
const [first, last, cells] = RANGES[mid];
|
|
128
|
+
if (codePoint < first)
|
|
129
|
+
high = mid - 1;
|
|
130
|
+
else if (codePoint > last)
|
|
131
|
+
low = mid + 1;
|
|
132
|
+
else
|
|
133
|
+
return cells;
|
|
134
|
+
}
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
/** Whether VS16 after `codePoint` widens it from one cell to two. */
|
|
138
|
+
export function widensToEmoji(codePoint) {
|
|
139
|
+
return NARROW_TO_WIDE.has(codePoint);
|
|
140
|
+
}
|