gesso-core 0.6.22 → 0.6.23

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # gesso-core
2
2
 
3
+ ## 0.6.23
4
+
5
+ ### Patch Changes
6
+
7
+ - ae5a84e: A flex or grid container placed in the box its measurement already used no longer lays its children out a second time: placement takes the lines (or the tracks and placements) that measurement worked out. A full layout pass of five thousand nodes is about 7% faster.
8
+ - 62e3bd4: A lazy list's scroll no longer slows down as more rows are measured. Row offsets are kept in a Fenwick tree, so finding a row and recording a row's height cost the logarithm of the list's length rather than the number of rows measured so far: 2,000 scroll frames over 100,000 measured rows went from 7 seconds to 38 ms.
9
+ - 2aecc54: A modifier writing a property it already holds no longer sorts the property's overrides or allocates, which an animated modifier did on every frame.
10
+ - 72f7b90, 4b92a02: Typing into a long text field no longer pushes every label's laid-out paragraph out of the cache: paragraphs of 16K characters or more are remembered apart, in a small budget of their own (eight paragraphs, half a million characters). The memo of a paragraph's hard lines is bounded by the length of the text it holds (a million characters) as well as by count, so a long line edited many times keeps about ten versions rather than twenty thousand: 300 edits of a 100 KB field keep 15 MB.
11
+
3
12
  ## 0.6.22
4
13
 
5
14
  ### Patch Changes
@@ -710,17 +710,30 @@ function removeDeclaredProperty(graph, node, property, flags) {
710
710
  */
711
711
  function writeOverrideProperty(graph, node, property, override, flags) {
712
712
  const overrides = overridesFor(node, property);
713
- const existing = overrides.entries.find((entry) => entry.source === override.source);
713
+ const entries = overrides.entries;
714
+ const existing = entries.find((entry) => entry.source === override.source);
714
715
  if (existing !== void 0) {
715
716
  existing.value = override.value;
716
- existing.order = override.order;
717
+ if (existing.order !== override.order) {
718
+ existing.order = override.order;
719
+ entries.sort((a, b) => a.order - b.order);
720
+ }
717
721
  } else {
718
- warnOnConflict(node, property, overrides.entries, override);
719
- overrides.entries.push({ ...override });
722
+ warnOnConflict(node, property, entries, override);
723
+ entries.splice(insertionIndex(entries, override.order), 0, { ...override });
720
724
  }
721
- overrides.entries.sort((a, b) => a.order - b.order);
722
725
  return applyEffective(graph, node, property, overrides, flags);
723
726
  }
727
+ /**
728
+ * Where a new entry goes in the sorted list: after every entry whose
729
+ * order is at most its own, which is where a push followed by a stable
730
+ * sort would have put it.
731
+ */
732
+ function insertionIndex(entries, order) {
733
+ let index = entries.length;
734
+ while (index > 0 && entries[index - 1].order > order) index--;
735
+ return index;
736
+ }
724
737
  /** Removes one modifier's write, restoring whatever was under it. */
725
738
  function clearOverrideProperty(graph, node, property, source, flags) {
726
739
  const overrides = node.overrides?.get(property);
@@ -6967,8 +6980,23 @@ function layoutParagraph(request, runs) {
6967
6980
  maxContentWidth
6968
6981
  };
6969
6982
  }
6970
- /** Hard lines remembered per measurer before the least recently used is forgotten. */
6983
+ /**
6984
+ * How much a measurer's hard-line memo holds before the least recently
6985
+ * used line is forgotten: a number of lines, and their text counted in
6986
+ * UTF-16 code units, whichever runs out first; the same two bounds as
6987
+ * the paragraph cache (`PARAGRAPH_CACHE_ENTRIES`), for the same reason.
6988
+ *
6989
+ * A count alone let one long hard line, edited over and over, keep a
6990
+ * copy of every version of itself (twice: in its key and in `ownCopy`)
6991
+ * up to the count, 20,000 copies of a line however long. The text
6992
+ * budget is a million code units, so every line of a document that
6993
+ * long is still here for the next edit to find; a longer one is broken
6994
+ * again whole. A line held costs far more than its text, since its
6995
+ * breaking at each width is kept with it: 300 edits of one 100 KB line
6996
+ * held 32 MB at twice this budget and hold 15 MB at it.
6997
+ */
6971
6998
  const HARD_LINE_ENTRIES = 2e4;
6999
+ const HARD_LINE_TEXT = 1 << 20;
6972
7000
  /** Widths a hard line keeps its breaking for: a resize sweeps through many, an edit asks for one. */
6973
7001
  const WIDTHS_PER_LINE = 4;
6974
7002
  /**
@@ -6977,6 +7005,39 @@ const WIDTHS_PER_LINE = 4;
6977
7005
  * so a measurer that is dropped takes its lines with it.
6978
7006
  */
6979
7007
  const hardLineMemos = /* @__PURE__ */ new WeakMap();
7008
+ /** A least-recently-used map of hard lines, bounded by count and by text; see `HARD_LINE_ENTRIES`. */
7009
+ var HardLineMemo = class {
7010
+ entries = /* @__PURE__ */ new Map();
7011
+ text = 0;
7012
+ get size() {
7013
+ return this.entries.size;
7014
+ }
7015
+ /** The code units of text remembered, for specs. */
7016
+ get textLength() {
7017
+ return this.text;
7018
+ }
7019
+ get(key) {
7020
+ const entry = this.entries.get(key);
7021
+ if (entry === void 0) return;
7022
+ this.entries.delete(key);
7023
+ this.entries.set(key, entry);
7024
+ return entry;
7025
+ }
7026
+ set(key, line) {
7027
+ const previous = this.entries.get(key);
7028
+ if (previous !== void 0) {
7029
+ this.entries.delete(key);
7030
+ this.text -= previous.text.length;
7031
+ }
7032
+ while (this.entries.size > 0 && (this.entries.size >= HARD_LINE_ENTRIES || this.text + line.text.length > HARD_LINE_TEXT)) {
7033
+ const [oldest, entry] = this.entries.entries().next().value;
7034
+ this.entries.delete(oldest);
7035
+ this.text -= entry.text.length;
7036
+ }
7037
+ this.entries.set(key, line);
7038
+ this.text += line.text.length;
7039
+ }
7040
+ };
6980
7041
  /** Forgets a measurer's hard lines: what its widths mean has changed, as when a font face arrives. */
6981
7042
  function forgetHardLines(runs) {
6982
7043
  hardLineMemos.delete(runs);
@@ -6984,7 +7045,7 @@ function forgetHardLines(runs) {
6984
7045
  function hardLinesFor(runs) {
6985
7046
  let memo = hardLineMemos.get(runs);
6986
7047
  if (memo === void 0) {
6987
- memo = /* @__PURE__ */ new Map();
7048
+ memo = new HardLineMemo();
6988
7049
  hardLineMemos.set(runs, memo);
6989
7050
  }
6990
7051
  return memo;
@@ -6996,11 +7057,7 @@ function styleKey(request) {
6996
7057
  function hardLine(memo, style, text, wrap, measure) {
6997
7058
  const key = `${style}\0${wrap}\0${text}`;
6998
7059
  const cached = memo.get(key);
6999
- if (cached !== void 0) {
7000
- memo.delete(key);
7001
- memo.set(key, cached);
7002
- return cached;
7003
- }
7060
+ if (cached !== void 0) return cached;
7004
7061
  const own = ownCopy(text);
7005
7062
  const segments = segmentParagraph(own, wrap);
7006
7063
  let minContentWidth = 0;
@@ -7012,10 +7069,6 @@ function hardLine(memo, style, text, wrap, measure) {
7012
7069
  minContentWidth,
7013
7070
  lines: /* @__PURE__ */ new Map()
7014
7071
  };
7015
- if (memo.size >= HARD_LINE_ENTRIES) {
7016
- const oldest = memo.keys().next().value;
7017
- if (oldest !== void 0) memo.delete(oldest);
7018
- }
7019
7072
  memo.set(key, entry);
7020
7073
  return entry;
7021
7074
  }
@@ -7352,10 +7405,74 @@ function spannedRunsFor(request, runs) {
7352
7405
  */
7353
7406
  const PARAGRAPH_CACHE_ENTRIES = 16384;
7354
7407
  const PARAGRAPH_CACHE_TEXT = 1 << 20;
7355
- /** A least-recently-used map of paragraphs, bounded by count and by text; see `PARAGRAPH_CACHE_ENTRIES`. */
7408
+ /**
7409
+ * The key length, in UTF-16 code units, from which a paragraph is
7410
+ * remembered apart from the rest; see `ParagraphCache`.
7411
+ */
7412
+ const LARGE_PARAGRAPH = 16384;
7413
+ /**
7414
+ * The large map's budget, far below the labels': what it mostly holds
7415
+ * is the versions of a field being edited, and only the newest is asked
7416
+ * for again. A version costs much more than its text, since its lines
7417
+ * are kept with it: 300 edits of a 100 KB field held 33 MB in a map
7418
+ * with the labels' budget. Half a million code units still holds every
7419
+ * request for two documents of 250K drawn side by side, so neither
7420
+ * pushes the other out on each frame.
7421
+ */
7422
+ const LARGE_PARAGRAPH_ENTRIES = 8;
7423
+ const LARGE_PARAGRAPH_TEXT = 1 << 19;
7424
+ /**
7425
+ * The paragraph cache: two least-recently-used maps, one for large
7426
+ * paragraphs (a key of `LARGE_PARAGRAPH` code units or more), with a
7427
+ * budget of its own (`LARGE_PARAGRAPH_ENTRIES`), and one for the rest,
7428
+ * with the whole budget of `PARAGRAPH_CACHE_ENTRIES`.
7429
+ *
7430
+ * A keystroke in a long field is a new request keyed by its whole
7431
+ * text, and both the layout engine and paint ask for it. In one map a
7432
+ * 100 KB field spent the text budget in about ten keystrokes, and
7433
+ * every label on screen was laid out again on the next frame. Apart,
7434
+ * the field's versions only push out each other's and those of other
7435
+ * long texts, which is what they did among themselves before, and the
7436
+ * labels are not touched. A paragraph's map is chosen by its key, so a
7437
+ * request finds it again without being told which it is.
7438
+ *
7439
+ * Editable text is not singled out instead: the layout engine's
7440
+ * request does not say whether it is for an editable, and paint (the
7441
+ * caret, the selection) asks for the field's paragraph again on every
7442
+ * frame it is drawn, so it does need remembering somewhere. A short
7443
+ * field still shares the map with labels, but one keystroke there
7444
+ * costs at most `LARGE_PARAGRAPH` of a million code units.
7445
+ */
7356
7446
  var ParagraphCache = class {
7447
+ small = new ParagraphLru(PARAGRAPH_CACHE_ENTRIES, PARAGRAPH_CACHE_TEXT);
7448
+ large = new ParagraphLru(LARGE_PARAGRAPH_ENTRIES, LARGE_PARAGRAPH_TEXT);
7449
+ get size() {
7450
+ return this.small.size + this.large.size;
7451
+ }
7452
+ get(key) {
7453
+ return this.mapFor(key).get(key);
7454
+ }
7455
+ set(key, paragraph, text) {
7456
+ this.mapFor(key).set(key, paragraph, text);
7457
+ }
7458
+ clear() {
7459
+ this.small.clear();
7460
+ this.large.clear();
7461
+ }
7462
+ mapFor(key) {
7463
+ return key.length >= LARGE_PARAGRAPH ? this.large : this.small;
7464
+ }
7465
+ };
7466
+ /** A least-recently-used map of paragraphs, bounded by count and by text; see `PARAGRAPH_CACHE_ENTRIES`. */
7467
+ var ParagraphLru = class {
7468
+ maxEntries;
7469
+ maxText;
7357
7470
  entries = /* @__PURE__ */ new Map();
7358
7471
  text = 0;
7472
+ constructor(maxEntries, maxText) {
7473
+ this.maxEntries = maxEntries;
7474
+ this.maxText = maxText;
7475
+ }
7359
7476
  get size() {
7360
7477
  return this.entries.size;
7361
7478
  }
@@ -7372,7 +7489,7 @@ var ParagraphCache = class {
7372
7489
  this.entries.delete(key);
7373
7490
  this.text -= previous.text;
7374
7491
  }
7375
- while (this.entries.size > 0 && (this.entries.size >= PARAGRAPH_CACHE_ENTRIES || this.text + text > PARAGRAPH_CACHE_TEXT)) {
7492
+ while (this.entries.size > 0 && (this.entries.size >= this.maxEntries || this.text + text > this.maxText)) {
7376
7493
  const [oldest, entry] = this.entries.entries().next().value;
7377
7494
  this.entries.delete(oldest);
7378
7495
  this.text -= entry.text;
@@ -14330,6 +14447,24 @@ var LayoutRecord = class {
14330
14447
  /** Constraints this record was last measured under. */
14331
14448
  lastConstraints = NEVER_MEASURED;
14332
14449
  /**
14450
+ * What a flex or grid container's last measurement worked out about
14451
+ * its children — the flexed items and their lines, or the sized
14452
+ * tracks — kept for its placement to take over. Placement used to
14453
+ * work it all out again, a FlexItem and a set of constraints per
14454
+ * child, even when the box it was placing in was the very one the
14455
+ * measurement had been given; a container's last measurement is
14456
+ * usually its final one, so that was most of them.
14457
+ *
14458
+ * Only the last measurement that actually ran is kept, because it is
14459
+ * the one its children's records still describe: a measurement
14460
+ * recalled from an alternate leaves the children as the last run
14461
+ * left them. Null when that run's content box was not definite on
14462
+ * both axes, since placement's always is. Placement takes it and
14463
+ * clears it whatever it decides, so nothing uses one twice; see
14464
+ * `LayoutEngine.takeArrangement`.
14465
+ */
14466
+ arrangement = null;
14467
+ /**
14333
14468
  * The paragraphs a text leaf was last measured as, one asked with a
14334
14469
  * width and one without; see `LayoutEngine.measureLeaf`. Flex asks
14335
14470
  * an item both questions every pass (its max-content basis, then its
@@ -14542,6 +14677,7 @@ var LayoutRecord = class {
14542
14677
  this.contentWidth = 0;
14543
14678
  this.contentHeight = 0;
14544
14679
  this.lastConstraints = NEVER_MEASURED;
14680
+ this.arrangement = null;
14545
14681
  this.lastBaseWidth = void 0;
14546
14682
  this.lastBaseHeight = void 0;
14547
14683
  this.alternates = null;
@@ -16400,7 +16536,19 @@ var LayoutEngine = class {
16400
16536
  measureGrid(node, rec, content) {
16401
16537
  const paddingH = rec.paddingLeft + rec.paddingRight;
16402
16538
  const paddingV = rec.paddingTop + rec.paddingBottom;
16403
- const grid = this.layoutGrid(node, content, this.definiteAxis(content, "width"), this.definiteAxis(content, "height"));
16539
+ const availableWidth = this.definiteAxis(content, "width");
16540
+ const availableHeight = this.definiteAxis(content, "height");
16541
+ const grid = this.layoutGrid(node, content, availableWidth, availableHeight);
16542
+ let arrangement = null;
16543
+ if (availableWidth !== void 0 && availableHeight !== void 0) arrangement = {
16544
+ kind: "grid",
16545
+ pass: this.layoutPass,
16546
+ content,
16547
+ contentMatters: rec.contentMatters,
16548
+ subgridColumns: rec.subgridColumns,
16549
+ grid
16550
+ };
16551
+ rec.arrangement = arrangement;
16404
16552
  rec.minContentWidth = paddingH + grid.columns.minTotal;
16405
16553
  const first = grid.placements[0];
16406
16554
  if (first !== void 0) {
@@ -16419,7 +16567,8 @@ var LayoutEngine = class {
16419
16567
  const contentWidth = Math.max(0, rec.width - rec.paddingLeft - rec.paddingRight);
16420
16568
  const contentHeight = Math.max(0, rec.height - rec.paddingTop - rec.paddingBottom);
16421
16569
  const content = new Constraints(contentWidth, contentWidth, contentHeight, contentHeight);
16422
- const grid = this.layoutGrid(node, content, contentWidth, contentHeight);
16570
+ const kept = this.takeArrangement(rec, "grid", content);
16571
+ const grid = kept !== null && kept.subgridColumns === rec.subgridColumns ? kept.grid : this.layoutGrid(node, content, contentWidth, contentHeight);
16423
16572
  const gridX = parseCrossAxisAlignment(node.properties.get("x")) ?? 3;
16424
16573
  const gridY = parseCrossAxisAlignment(node.properties.get("y")) ?? 3;
16425
16574
  const mirrored = this.startEdge(node) === "right";
@@ -16681,6 +16830,34 @@ var LayoutEngine = class {
16681
16830
  const paddingV = rec.paddingTop + rec.paddingBottom;
16682
16831
  return new Constraints(Math.max(0, effective.minWidth - paddingH), Math.max(0, effective.maxWidth - paddingH), Math.max(0, effective.minHeight - paddingV), Math.max(0, effective.maxHeight - paddingV));
16683
16832
  }
16833
+ /**
16834
+ * The arrangement a container's measurement kept, when placing it in
16835
+ * `content` would work out the same one again; null otherwise.
16836
+ * Cleared from the record either way, so it is used at most once:
16837
+ * placement shares auto margins out and stretches items in the lines
16838
+ * it is handed, and a second placement in the same pass (a relayout
16839
+ * root inside one already laid out) must start from fresh ones.
16840
+ *
16841
+ * What it is checked against is everything the work reads that is
16842
+ * not fixed for the length of a pass. The pass number stands for the
16843
+ * tree and every property in it, which a pass never changes, and so
16844
+ * for the children, their order and the container's own settings.
16845
+ * The content box is the constraints the children were measured
16846
+ * under and the base their percentages resolved against. The
16847
+ * container's `contentMatters` decided its items' flags, and a parent
16848
+ * can change it between the two (`clearBoundaries`). The children's
16849
+ * records need no check: only this container measures them, so they
16850
+ * are still as its last run left them, which is the run kept. (A
16851
+ * subgrid's cells are the exception, measured unbounded by the grid
16852
+ * around it as well, but `placeGrid` measures each item again before
16853
+ * it reads anything off its record.)
16854
+ */
16855
+ takeArrangement(rec, kind, content) {
16856
+ const kept = rec.arrangement;
16857
+ if (kept === null) return null;
16858
+ rec.arrangement = null;
16859
+ return kept.kind === kind && kept.pass === this.layoutPass && kept.contentMatters === rec.contentMatters && constraintsEqual(kept.content, content) ? kept : null;
16860
+ }
16684
16861
  measureFlex(node, rec, content, direction) {
16685
16862
  const row = direction === 0;
16686
16863
  const paddingMain = row ? rec.paddingLeft + rec.paddingRight : rec.paddingTop + rec.paddingBottom;
@@ -16691,6 +16868,7 @@ var LayoutEngine = class {
16691
16868
  const mainBounded = isFinite(mainMax);
16692
16869
  const mainDefinite = mainBounded && mainMin === mainMax;
16693
16870
  const crossDefinite = row ? isFinite(content.maxHeight) && content.minHeight === content.maxHeight : isFinite(content.maxWidth) && content.minWidth === content.maxWidth;
16871
+ rec.arrangement = null;
16694
16872
  const items = this.collectFlexItems(node, content, direction, config, crossDefinite && !config.wrap);
16695
16873
  if (items.length === 0) {
16696
16874
  rec.minContentWidth = rec.paddingLeft + rec.paddingRight;
@@ -16706,7 +16884,7 @@ var LayoutEngine = class {
16706
16884
  const lineTotal = this.lineOuterMain(line, config.gapMain, "hypothetical");
16707
16885
  const lineWanted = this.lineMaxContentMain(line, config.gapMain);
16708
16886
  if (mainBounded && (mainDefinite || lineTotal > mainMax || lineWanted > mainMax)) {
16709
- this.resolveLine(line, mainMax - config.gapMain * (line.items.length - 1), config);
16887
+ line.free = this.resolveLine(line, mainMax - config.gapMain * (line.items.length - 1), config);
16710
16888
  this.measureFlexedItems(line.items, content, direction, crossDefinite && !config.wrap ? row ? content.maxHeight : content.maxWidth : void 0);
16711
16889
  contentMain = Math.max(contentMain, this.lineOuterMain(line, config.gapMain, "final"));
16712
16890
  } else {
@@ -16722,6 +16900,13 @@ var LayoutEngine = class {
16722
16900
  contentCross += line.cross;
16723
16901
  }
16724
16902
  contentCross += config.gapLine * (lines.length - 1);
16903
+ if (mainDefinite && crossDefinite) rec.arrangement = {
16904
+ kind: "flex",
16905
+ pass: this.layoutPass,
16906
+ content,
16907
+ contentMatters: rec.contentMatters,
16908
+ lines
16909
+ };
16725
16910
  this.setFlexBaseline(rec, lines[0].items, row);
16726
16911
  rec.minContentWidth = this.flexMinContentWidth(rec, items, row, config);
16727
16912
  rec.minContentHeight = row && config.wrap ? paddingCross + contentCross : this.flexMinContentHeight(rec, items, row, config);
@@ -18029,14 +18214,21 @@ var LayoutEngine = class {
18029
18214
  const contentMain = Math.max(0, (row ? rec.width : rec.height) - (row ? paddingH : paddingV));
18030
18215
  const contentCross = Math.max(0, (row ? rec.height : rec.width) - (row ? paddingV : paddingH));
18031
18216
  const content = row ? new Constraints(contentMain, contentMain, contentCross, contentCross) : new Constraints(contentCross, contentCross, contentMain, contentMain);
18032
- const items = this.collectFlexItems(node, content, direction, config, !config.wrap);
18033
- if (items.length === 0) return;
18034
- const lines = this.breakLines(items, config, contentMain);
18035
- for (const line of lines) {
18036
- line.free = this.resolveLine(line, contentMain - config.gapMain * (line.items.length - 1), config);
18037
- this.distributeAutoMargins(line);
18038
- this.measureFlexedItems(line.items, content, direction, config.wrap ? void 0 : contentCross);
18039
- line.cross = this.flexLineCross(line.items, row);
18217
+ const kept = this.takeArrangement(rec, "flex", content);
18218
+ let lines;
18219
+ if (kept !== null) {
18220
+ lines = kept.lines;
18221
+ for (const line of lines) this.distributeAutoMargins(line);
18222
+ } else {
18223
+ const items = this.collectFlexItems(node, content, direction, config, !config.wrap);
18224
+ if (items.length === 0) return;
18225
+ lines = this.breakLines(items, config, contentMain);
18226
+ for (const line of lines) {
18227
+ line.free = this.resolveLine(line, contentMain - config.gapMain * (line.items.length - 1), config);
18228
+ this.distributeAutoMargins(line);
18229
+ this.measureFlexedItems(line.items, content, direction, config.wrap ? void 0 : contentCross);
18230
+ line.cross = this.flexLineCross(line.items, row);
18231
+ }
18040
18232
  }
18041
18233
  this.markFlexBoundaries(lines);
18042
18234
  if (lines.length === 1 && !config.wrap) lines[0].cross = contentCross;
@@ -22389,4 +22581,4 @@ function createCanvasSurface(host) {
22389
22581
  //#endregion
22390
22582
  export { isImeKey as $, visualStatesEqual as $a, scaleSpacing as $i, spannedRunsFor as $n, transformIsIdentity as $r, registerFontStack as $t, withOverrideSource as A, UiBasicColors as Aa, noInsets as Ai, clearLinkHover as An, inheritedPropertyFlags as Ar, adjacentField as At, FlexDirection as B, findEnvironmentKey as Ba, withDensity as Bi, editorFor as Bn, isUiSemanticState as Br, createCanvasTextStyle as Bt, SCROLLBAR_LINGER_MS as C, spansDifferOnlyInPaint as Ca, normalizeBorderRadius as Ci, isNodeInert as Cn, resolveNumber as Cr, hasDrawnText as Ct, formatExplanation as D, colorsEqualPalette as Da, UiEnvironmentKeys as Di, isSubtreeInert as Dn, closestPropertyName as Dr, selectionRectsIn as Dt, formatConstraints as E, textStylesEqual as Ea, propertyValuesEqual as Ei, isPressable as En, resolveString as Er, paragraphGeometryFrom as Et, clampSize as F, normalizeColor as Fa, unknownContainerSize as Fi, setLinkHover as Fn, propertyValuesEqualByName as Fr, detectEditingPlatform as Ft, CrossAxisAlignment as G, overrideSources as Ga, themeExtensionsEqual as Gi, maskText as Gn, UI_SUBGRID_AXES as Gr, runFontString as Gt, placeGridItems as H, UiNode as Ha, hasThemeExtension as Hi, isEditableNode as Hn, statesEqual as Hr, fillTextRects as Ht, constraintsEqual as I, parseColor as Ia, darkTheme as Ii, CARET_BLINK_MS as In, UiProperties as Ir, isPrintable as It, parseCrossAxisAlignment as J, writeOverrideProperty as Ja, highContrastColors as Ji, resolveColorValue as Jn, paintValuesEqual as Jr, textRunBackgrounds as Jt, MainAxisAlignment as K, resetOverrideWarnings as Ka, withThemeExtension as Ki, nextCaretToggle as Kn, validateSubgrid as Kr, spanOf as Kt, tightenConstraints as L, rgb8 as La, lightTheme as Li, CARET_WIDTH as Ln, UI_ROLES as Lr, EditableLayout as Lt, contentOffset as M, colorToRgba as Ma, UiContainerSizeSource as Mi, linkHoverOf as Mn, propertyEffects as Mr, edgeField as Mt, LayoutRecord as N, colorValuesEqual as Na, bandOf as Ni, linkOf as Nn, propertyIsInherited as Nr, editingGroupOf as Nt, formatNumber as O, darkColors as Oa, UiInsetRegistry as Oi, pointerEventsOf as On, findPropertyDefinition as Or, wordRangeIn as Ot, Constraints as P, colorsEqual as Pa, containerBands as Pi, linkRunAtPointIn as Pn, propertyNarrowers as Pr, commandForKey as Pt, capturePointer as Q, visualState as Qa, defaultSpacing as Qi, ParagraphTextMeasurer as Qn, transform as Qr, fontStackFor as Qt, MAX_MEASURES_PER_CHILD as R, rgba as Ra, themesEqual as Ri, EDITOR_PROP as Rn, UI_SEMANTIC_STATES as Rr, applyCanvasTextStyle as Rt, SCROLLBAR_FADE_MS as S, spannedTextOf as Sa, borderRadiusValuesEqual as Si, isNodeHitTestable as Sn, resolveBoolean as Sr, UiInputDispatcher as St, describeOverrides as T, textSpansEqual as Ta, defineProperty as Ti, isNodeTabStop as Tn, resolvePropertyByName as Tr, paragraphGeometry as Tt, sizeGridTracks as U, DirtyNodeSet as Ua, noThemeExtensions as Ui, isMultiline as Un, validateRole as Ur, layoutTextLines as Ut, parseFlexDirection as V, UiEnvironment as Va, defineThemeExtension as Vi, editorOf as Vn, normalizeStates as Vr, drawText as Vt, AlignContent as W, clearOverrideProperty as Wa, themeExtension as Wi, isReadOnly as Wn, validateStates as Wr, runCanvasStyleInto as Wt, CanvasPlatformSurface as X, defaultVisualState as Xa, relativeLuminance as Xi, videoFrameSize as Xn, UiTransforms as Xr, bumpFontStack as Xt, parseMainAxisAlignment as Y, UiVisualState as Ya, raiseContrast as Yi, isVideoSurface as Yn, pathValuesEqual as Yr, textRunDecorations as Yt, UiPlatformAdapter as Z, hasVisualState as Za, densityFactors as Zi, CharacterCountTextMeasurer as Zn, parseTransform as Zr, clearFontStacks as Zt, LABEL_PADDING_X as _, editableSpansOf as _a, UiBorderRadiuses as _i, selectableTextNodes as _n, UiNodeType as _o, previousGraphemeStart as _r, scrollLeaderOf as _t, PaintPictureCache as a, boxShadow as aa, radialGradient as ai, computeObjectFitRect as an, UiGestureEvent as ao, lineIndexForOffset as ar, UiGestureRecognizer as at, snapScroll as b, resolvedSpansOf as ba, borderRadiusEqual as bi, setSelectionRange as bn, UiGraph as br, scrollbarThumbs as bt, EMPTY_RECORDING as c, boxShadowReach as ca, fr as ci, normalizeTextAlign as cn, UiPasteEvent as co, offsetAtX as cr, isScrollContainer as ct, tracePathData as d, isShapeName as da, isMinMaxTrack as di, TEXT_MATCHES_PROP as dn, UiSelectionChangeEvent as do, EditableTextModel as dr, UiFocusManager as dt, spacingEqual as ea, transformsEqual as ei, DEFAULT_FONT_FAMILY as en, MOUSE_POINTER as eo, ELLIPSIS as er, pointerDeviceOf as et, ScaledImageCache as f, shapesEqual as fa, isPercentLength as fi, clearMatchRanges as fn, UiTextChangeEvent as fo, graphemeBoundaries as fr, UiHitTester as ft, paintsAfterChildren as g, defaultTextStyle as ga, resolveLength as gi, clearSelectionRange as gn, wheelDeltaYOf as go, nextWordEnd as gr, SCROLLBAR_THICKNESS as gt, hasDecorationPhase as h, typographyEqual as ha, repeat as hi, TEXT_SELECTION_PROP as hn, noKeyModifiers as ho, nextGraphemeEnd as hr, SCROLLBAR_MIN_THUMB as ht, traceRoundedRect as i, BOX_SHADOW_BLUR_REACH as ia, linearGradient as ii, colorToCss as in, UiFocusEvent as io, lineIndexAtY as ir, UiTouchScroller as it, accumulatedOffsetTo as j, colorToHex as ja, observeViewportInsets as ji, hasTextLinks as jn, inheritedPropertyNames as jr, comparePositions as jt, labelNode as k, lightColors as ka, insetsEqual as ki, resolveCursor as kn, getPropertyNames as kr, textInputOf as kt, PaintRecorder as l, boxShadowsEqual as la, isAutoLength as li, normalizeVerticalAlign as ln, UiPinchEvent as lo, offsetForVerticalMove as lr, UiKeyboardController as lt, decorationRect as m, isTypographyRole as ma, percent as mi, setMatchRanges as mn, UiWheelEvent as mo, lineStartAt as mr, SCROLLBAR_INSET as mt, createCanvasSurface as n, defaultShadows as na, gradientPaint as ni, DEFAULT_FONT_WEIGHT as nn, UiCompositionEvent as no, proportionalFontMetrics as nr, touchActionFor as nt, paintPictures as o, boxShadowArraysEqual as oa, validateGradient as oi, createPaintState as on, UiInputEvent as oo, lineLimit as or, UiPinchRecognizer as ot, decorationColor as p, defaultTypography as pa, minmax as pi, matchRangesOf as pn, UiWheelDeltaMode as po, lineEndAt as pr, SCROLLBAR_HOVER_ZONE as pt, parseAlignContent as q, writeDeclaredProperty as qa, contrastRatio as qi, syncEditorValue as qn, inputsEqual as qr, textMeasureRequest as qt, Canvas2DRenderer as r, shadowsEqual as ra, gradientsEqual as ri, DEFAULT_TEXT_COLOR as rn, UiEventType as ro, caretRectFor as rr, UiEditingController as rt, PaintTarget as s, boxShadowRadius as sa, auto as si, isPaintVisible as sn, UiKeyboardEvent as so, offsetAtPoint as sr, UiWheelController as st, CanvasSurface as t, spacingSteps as ta, MAX_GRADIENT_STOPS as ti, DEFAULT_FONT_SIZE as tn, UiBeforeInputEvent as to, layoutParagraph as tr, prepareInputSurface as tt, replayPaint as u, defaultShapes as ua, isFrLength as ui, resolvePaintState as un, UiPointerEvent as uo, selectionRects as ur, UiPointerController as ut, drawOverlayShapes as v, flattenTextSpans as va, borderRadius as vi, selectableTextOf as vn, DirtyFlags as vo, previousWordStart as vr, scrollRange as vt, describeLength as w, textContentOf as wa, uniformBorderRadius as wi, isNodeSelectable as wn, resolveProperty as wr, offsetAtPointIn as wt, LayoutEngine as x, spanAtOffset as xa, borderRadiusIsZero as xi, isNodeFocusable as xn, DEFAULT_LINE_HEIGHT_FACTOR as xr, scrollbarZoneAt as xt, labelOrigin as y, hiddenRangesOf as ya, borderRadiusCorners as yi, selectionRangeOf as yn, UiBinding as yo, wordRangeAt as yr, scrollbarThumb as yt, isLayoutProtocol as z, createEnvironmentKey as za, withContrast as zi, caretVisibleAt as zn, isUiRole as zr, buildFontString as zt };
22391
22583
 
22392
- //# sourceMappingURL=CanvasSurface-BxHC-NQ8.js.map
22584
+ //# sourceMappingURL=CanvasSurface-D5QaKaWH.js.map