@weasel-js/text 1.13.0-rc.0 → 1.14.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.
@@ -37,12 +37,13 @@ interface TransformedRunText {
37
37
  * `capitalize`'s word starts see across run boundaries — a word split by
38
38
  * styling still gets one capital.
39
39
  *
40
- * Mappings are the locale-independent ones JavaScript's `toUpperCase` /
41
- * `toLowerCase` implement, which include `ß` → `SS` and final sigma.
40
+ * Mappings are JavaScript's `toLocaleUpperCase` / `toLocaleLowerCase` under
41
+ * `langs[i]`, a BCP 47 tag, so `i` uppercases to `İ` under `tr`; absent is
42
+ * the locale-independent mapping. Both include `ß` → `SS` and final sigma.
42
43
  * `capitalize` titlecases the first code point of each word when it has a
43
44
  * case to change, and leaves every other character as it was.
44
45
  */
45
- declare function transformRunTexts(texts: readonly string[], transforms: readonly TextTransform[]): TransformedRunText[];
46
+ declare function transformRunTexts(texts: readonly string[], transforms: readonly TextTransform[], langs?: readonly (string | undefined)[]): TransformedRunText[];
46
47
 
47
48
  /**
48
49
  * Synthetic small caps: lowercase drawn as capitals at a smaller size, the
@@ -71,8 +72,8 @@ declare function smallCapsScale(face?: FaceMetrics): number;
71
72
  * resolved through the font registry exactly as layout resolves the run. */
72
73
  declare function smallCapsScaleFor(family: string, weight: number, style: FontStyle): number;
73
74
  /** Whether small caps draws `ch` as a smaller capital: whether it has a
74
- * capital other than itself. */
75
- declare function isSmallCapsLetter(ch: string): boolean;
75
+ * capital other than itself under `lang`, a BCP 47 tag. */
76
+ declare function isSmallCapsLetter(ch: string, lang?: string): boolean;
76
77
  /** A run's drawn text under small caps. `small[i]` says whether UTF-16 unit
77
78
  * `i` of `text` draws at the small size; absent when none does. */
78
79
  interface SmallCapsText {
@@ -83,9 +84,10 @@ interface SmallCapsText {
83
84
  /**
84
85
  * Apply small caps to a run's drawn text. `srcMap` is the map `textTransform`
85
86
  * already produced for it, if any; the result's map composes the two, so
86
- * each drawn unit still names the source character it came from.
87
+ * each drawn unit still names the source character it came from. Capitals
88
+ * are `lang`'s, so `i` is drawn `İ` under `tr`.
87
89
  */
88
- declare function smallCapsText(text: string, srcMap?: RunSourceMap): SmallCapsText;
90
+ declare function smallCapsText(text: string, srcMap?: RunSourceMap, lang?: string): SmallCapsText;
89
91
 
90
92
  /**
91
93
  * Canonical inline-styling primitive for text nodes. A node's text is
@@ -162,6 +164,19 @@ interface StyledRun {
162
164
  * own; `'normal'` turns an inherited one off.
163
165
  */
164
166
  fontVariantCaps?: FontVariantCaps;
167
+ /**
168
+ * Degrees to turn each of this run's glyphs, clockwise, each about its own
169
+ * pen on the baseline — SVG's `rotate` with one value for the run. The
170
+ * glyphs keep their places along the line; only their angle changes. A
171
+ * different angle per glyph is a run per glyph.
172
+ */
173
+ rotate?: number;
174
+ /**
175
+ * The run's language, as a BCP 47 tag (`'sr'`, `'ur-PK'`): a shaper draws
176
+ * the face's forms for it, such as Serbian Cyrillic italics or Urdu digits.
177
+ * Overrides the node's own; absent inherits it.
178
+ */
179
+ lang?: string;
165
180
  }
166
181
  /** Normalize the two accepted spellings of text content — a plain string or
167
182
  * an array of runs — to runs. Throws on a run with no string `text`. */
@@ -308,6 +323,12 @@ interface TextStyle {
308
323
  * have had. Absent is ordinary text.
309
324
  */
310
325
  script?: 'super' | 'sub';
326
+ /**
327
+ * The text's language, as a BCP 47 tag (`'sr'`, `'ur-PK'`), which every run
328
+ * inherits: a shaper draws the face's forms for it. Absent draws the face's
329
+ * default forms.
330
+ */
331
+ lang?: string;
311
332
  }
312
333
  /** `TextStyle` with all fields filled in from defaults — what the renderer actually consumes. */
313
334
  interface ResolvedTextStyle {
@@ -334,6 +355,8 @@ interface ResolvedTextStyle {
334
355
  fontVariantCaps: FontVariantCaps;
335
356
  /** Absent is ordinary text. */
336
357
  script?: 'super' | 'sub';
358
+ /** Absent is no language: the face's default forms. */
359
+ lang?: string;
337
360
  /** Absent means no outline — unlike the other fields, this one has no
338
361
  * default to fall back to. See {@link TextPaint.stroke}. */
339
362
  stroke?: Stroke;
@@ -431,6 +454,16 @@ interface ResolvedRun {
431
454
  * `fontSize`.
432
455
  */
433
456
  strutSize?: number;
457
+ /** Degrees each glyph turns, clockwise about its pen on the baseline.
458
+ * Absent is upright. */
459
+ rotate?: number;
460
+ /** OpenType features a shaper turns on for this run (`'smcp'` for small
461
+ * caps drawn from the face's own glyphs). Absent is none; a run that is not
462
+ * shaped ignores it. */
463
+ fontFeatures?: readonly string[];
464
+ /** BCP 47 language tag a shaper selects the face's forms by: the run's own,
465
+ * else the node's. Absent is none. */
466
+ lang?: string;
434
467
  }
435
468
  /** What one script preset expands to. */
436
469
  type ScriptPreset = Readonly<{
@@ -454,6 +487,14 @@ declare function scriptMetrics(face?: FaceMetrics): Readonly<Record<'super' | 's
454
487
  * either half per run with `baselineShift` / `fontScale`.
455
488
  */
456
489
  declare function scriptMetricsFor(family: string, weight: number, style: FontStyle): Readonly<Record<'super' | 'sub', ScriptPreset>>;
490
+ /**
491
+ * How far below the top of a line box a face's ascent starts, CSS's way: half
492
+ * the leading a line height of `lineHeight` (a multiple of `fontSize`) leaves
493
+ * around the face's ascent and descent, in the units `fontSize` is in. It is
494
+ * negative for a face taller than its line. `undefined` when no registered
495
+ * face of `(family, weight, style)` states its ascent and descent.
496
+ */
497
+ declare function halfLeadingFor(family: string, weight: number, style: FontStyle, fontSize: number, lineHeight: number): number | undefined;
457
498
  /** A `TextStyle.fontWeight` as a number: the CSS keywords `bold` and
458
499
  * `normal` read as 700 and 400, anything unparseable as 400. */
459
500
  declare function numericWeight(w: number | string): number;
@@ -512,6 +553,74 @@ interface BidiResolver {
512
553
  baseLevel(analysis: BidiAnalysis): number;
513
554
  }
514
555
 
556
+ /**
557
+ * The shaping contract, declared here and implemented elsewhere.
558
+ *
559
+ * This package does not depend on `@weasel-js/text-shaping` and must not, for the
560
+ * reason it does not depend on `@weasel-js/bidi`: a consumer setting only
561
+ * Latin text never downloads HarfBuzz's WebAssembly, and another engine can
562
+ * stand in. `@weasel-js/text-shaping` satisfies these types structurally.
563
+ *
564
+ * Without a shaper, layout finds each code point's glyph on its own and kerns
565
+ * pairs, which is right for Latin, Greek, Cyrillic and CJK and wrong for any
566
+ * script whose letters change shape with their neighbors.
567
+ */
568
+ /** One glyph a shaping produced. Every length is in ems, and y grows down. */
569
+ interface ShapedGlyph {
570
+ /** Glyph index in the face; 0 (`.notdef`) when it has none for the cluster. */
571
+ gid: number;
572
+ /** UTF-16 offset in the shaped text where the glyph's cluster starts. */
573
+ cluster: number;
574
+ advance: number;
575
+ /** Where it is drawn, from the pen. */
576
+ dx: number;
577
+ dy: number;
578
+ /** Whether it was shaped right to left, in which case the shaper already
579
+ * drew a mirrored character as its mirror. */
580
+ rtl: boolean;
581
+ }
582
+ /**
583
+ * A shaping engine: registered with `registerShaper` or passed to
584
+ * `layoutRuns` as `opts.shaper`. `@weasel-js/text-shaping`'s `loadShaper()`
585
+ * resolves with one. `face` is a font file's bytes (an sfnt), the same buffer
586
+ * every call for the same face.
587
+ */
588
+ interface TextShaper {
589
+ /** Glyphs in logical order: clusters by ascending `cluster`, and the glyphs
590
+ * of one cluster in the order they are drawn, left to right. `language` is
591
+ * a BCP 47 tag selecting the face's forms for that language; absent draws
592
+ * its default forms. */
593
+ shape(face: ArrayBuffer, text: string, features?: readonly string[], language?: string): readonly ShapedGlyph[];
594
+ /** Em-space path data for glyph `gid`, moved by `(dx, dy)`; null for one
595
+ * with no contours. */
596
+ glyphD(face: ArrayBuffer, gid: number, dx?: number, dy?: number): string | null;
597
+ /** Whether the face has OpenType feature `tag`. */
598
+ hasFeature(face: ArrayBuffer, tag: string): boolean;
599
+ }
600
+ /**
601
+ * What a shaped code point draws: the glyphs of the cluster it opens, set
602
+ * from its pen. The other code points of a cluster carry one with no glyphs.
603
+ */
604
+ interface ShapedCluster {
605
+ /** Em-space outline of every glyph in the cluster at its place, or null
606
+ * when none has contours. */
607
+ d: string | null;
608
+ /** Names `d` among the glyphs of one face, for caching what is built from it. */
609
+ key: string;
610
+ /** Each glyph and where it is drawn, in ems from the pen, y down. */
611
+ glyphs: readonly {
612
+ gid: number;
613
+ x: number;
614
+ y: number;
615
+ }[];
616
+ /** Whether it was shaped right to left. */
617
+ rtl: boolean;
618
+ /** The text the cluster's glyphs stand for, in logical order: what a reader
619
+ * copies or searches for when it reads them back. Empty on a code point
620
+ * another one draws. */
621
+ text: string;
622
+ }
623
+
515
624
  /** Options for `layoutRuns`. */
516
625
  interface LayoutRunsOpts {
517
626
  /** Wrap width. `Infinity` never wraps. */
@@ -545,6 +654,13 @@ interface LayoutRunsOpts {
545
654
  * detects the latter without one.
546
655
  */
547
656
  bidi?: BidiResolver;
657
+ /**
658
+ * Shaping engine. Default: the one given to `registerShaper`. With neither,
659
+ * each code point is laid out as its own glyph and pairs are kerned, which
660
+ * is wrong for scripts whose letters join or reorder, Arabic and Devanagari
661
+ * among them.
662
+ */
663
+ shaper?: TextShaper;
548
664
  /**
549
665
  * Reading direction: the base direction of the bidi analysis, and what
550
666
  * `start` / `end` resolve against. Default `'auto'`, each paragraph's own
@@ -594,8 +710,8 @@ interface LayoutRunsOpts {
594
710
  /**
595
711
  * One advance cell: a single code point's slot on a line.
596
712
  *
597
- * A cell spans its code point *plus* the kerning that precedes the next one,
598
- * so a caret snapped to the midpoint between two `x`s lands where the glyphs
713
+ * A cell spans its code point *plus* the kerning that precedes the glyph to
714
+ * its right, so a caret snapped to the midpoint between two `x`s lands where the glyphs
599
715
  * were actually painted rather than where an unkerned re-measure would put it.
600
716
  */
601
717
  interface LaidOutCell {
@@ -614,7 +730,10 @@ interface LaidOutCell {
614
730
  * order; never assume `cells[i + 1].x` is this cell's right edge. */
615
731
  x: number;
616
732
  /** Width of the cell: its glyph's advance, plus its run's tracking when it
617
- * closes a grapheme cluster, plus a justified gap's share of the slack. */
733
+ * closes a grapheme cluster, plus a justified gap's share of the slack,
734
+ * plus the kerning before the glyph to its right. A cell ends at its right
735
+ * neighbor's `x`, except across a combining mark that takes no room: the
736
+ * mark keeps 0 and the glyph it sits on takes the kerning. */
618
737
  advance: number;
619
738
  /** Resolved bidi embedding level — even reads left-to-right. 0 with no
620
739
  * engine, which is the same as saying the text was laid out logically. */
@@ -660,15 +779,24 @@ interface PlacedGlyph {
660
779
  * record gains its atlas rect in place when its bake lands. */
661
780
  font: BmFont | null;
662
781
  glyph: BmFontChar | null;
782
+ /** What it draws when a shaper shaped its run: its cluster's glyphs, set
783
+ * from this pen, in place of the glyph its code point maps to. Null or
784
+ * absent when its run was not shaped. */
785
+ shaped?: ShapedCluster | null;
663
786
  /** Pen position: the left edge of the glyph's slot. */
664
787
  x: number;
665
788
  /** Its line's baseline, raised by its run's `baselineShift`. */
666
789
  baselineY: number;
667
790
  /** The glyph's own advance. */
668
791
  advance: number;
669
- /** How far the pen moved past it: `advance`, its run's tracking, and a
670
- * justified gap's share of the slack. */
792
+ /** How far the pen moved past it: `advance`, its run's tracking, a
793
+ * justified gap's share of the slack, and the kerning before the next glyph
794
+ * along the line. */
671
795
  step: number;
796
+ /** Degrees its run turns each glyph, clockwise about `(x, baselineY)`, its
797
+ * pen on the baseline. 0, or absent on a glyph built by hand, is upright.
798
+ * The turn moves no pen: the glyphs after it sit where they would. */
799
+ rotate?: number;
672
800
  }
673
801
  /**
674
802
  * One laid-out line's box.
@@ -752,15 +880,19 @@ declare function layoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts):
752
880
  * compare. `kit:text`'s memoized `paint` hands back a stable array per node,
753
881
  * so the renderer stays on this path.
754
882
  *
755
- * **Structure**, in a bounded `Map`, for every caller that cannot. Measuring
883
+ * **Structure**, in a bounded list, for every caller that cannot. Measuring
756
884
  * a pose resolves its style and allocates a fresh `ResolvedRun[]` each call,
757
885
  * so an identity-keyed cache could never hold anything for it — and those
758
- * callers run on the drag path, once per pose change. Serializing the runs is
759
- * real work, unlike the pointer compare above, which is exactly why it is
760
- * second: an identity hit never pays for it.
886
+ * callers run on the drag path, once per pose change. The runs are hashed,
887
+ * and a matching hash compared field by field with the runs that filled the
888
+ * entry, which it holds. No key is built: a HUD readout whose text changes
889
+ * every frame misses here every frame, and a string key was a string of
890
+ * every label's text a frame for the collector. Those held runs are why a
891
+ * run must not be mutated once laid out, the promise the identity key
892
+ * already asks of its array.
761
893
  *
762
894
  * Under either, one entry per distinct `(maxWidth, alignWidth, lineHeight,
763
- * align, direction, bidi engine, tab size)`. Position is deliberately absent:
895
+ * align, direction, bidi engine, shaper, tab size)`. Position is deliberately absent:
764
896
  * `layoutRuns` emits origin-relative geometry and `drawText` translates at
765
897
  * upload, so a text node dragged across the page keeps hitting the same entry.
766
898
  * So is everything that only changes what is drawn — a run's fill, stroke and
@@ -782,9 +914,18 @@ declare function layoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts):
782
914
  *
783
915
  * Variants per runs array are capped and evicted wholesale, matching
784
916
  * `outlineMeshCache`: the refill cost is one layout, and the bookkeeping would
785
- * cost more than the misses it avoids. The structural map cannot ride an
786
- * array's lifetime the way the `WeakMap` does — nothing collects its keys —
787
- * so it is a real LRU with a hard entry count.
917
+ * cost more than the misses it avoids. The structural list cannot ride an
918
+ * array's lifetime the way the `WeakMap` does, so it is a real LRU with a
919
+ * hard entry count.
920
+ *
921
+ * ### Giving arrays back
922
+ *
923
+ * A layout's columns and its paintings' quads go back to a pool for the next
924
+ * text of the same size once nothing can reach them: `dropRuns` has removed
925
+ * every runs array filing it, the structural list has evicted it, and every
926
+ * call handed it passed `'read'`. One `'keep'` handout pins it for good. That
927
+ * is what lets a readout rewritten every frame, whose widget drops the runs it
928
+ * replaces and whose renderer only reads, lay out into last frame's arrays.
788
929
  */
789
930
 
790
931
  /** Distinct option combinations held for one runs array before the whole set
@@ -793,6 +934,10 @@ declare const LAYOUT_CACHE_VARIANT_LIMIT = 8;
793
934
  /** Layouts held against the structural key before the least recently used one
794
935
  * is dropped. Sized for "every text node visible on a page, plus slack". */
795
936
  declare const LAYOUT_CACHE_STRUCTURAL_LIMIT = 64;
937
+ /** What a call means to do with the layout it is handed: `'keep'` may hold
938
+ * it, or anything in it, for as long as it likes; `'read'` is done with it
939
+ * before its next call into the text caches, and keeps nothing of it. */
940
+ type CacheUse = 'keep' | 'read';
796
941
  /**
797
942
  * Lay `runs` out, reusing the previous result when nothing it depends on has
798
943
  * changed. Drop-in for `layoutRuns` — same arguments, same return value.
@@ -801,8 +946,21 @@ declare const LAYOUT_CACHE_STRUCTURAL_LIMIT = 64;
801
946
  * applies position and `verticalAlign` while packing vertices rather than by
802
947
  * shifting the layout, precisely so it can be handed the same object every
803
948
  * frame.
949
+ *
950
+ * `use` is `'read'` for a caller done with the result before its next call
951
+ * into these caches, keeping nothing of it, which lets the cache recycle the
952
+ * layout's arrays later; see "Giving arrays back".
953
+ */
954
+ declare function cachedLayoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts, use?: CacheUse): LaidOutRuns;
955
+ /**
956
+ * Forget what the caches hold for `runs`, which its caller will not lay out
957
+ * again: a readout replacing its text drops the runs it drew last. A layout no
958
+ * other runs array or caller can reach gives its arrays to the next layout of
959
+ * the same size, so text rewritten every frame stops allocating them.
960
+ *
961
+ * Passing `runs` again afterwards is only a cache miss.
804
962
  */
805
- declare function cachedLayoutRuns(runs: readonly ResolvedRun[], opts: LayoutRunsOpts): LaidOutRuns;
963
+ declare function dropRuns(runs: readonly ResolvedRun[]): void;
806
964
  /** Test helper. Do not call from product code. */
807
965
  declare function _resetLayoutCacheForTests(): void;
808
966
 
@@ -827,4 +985,4 @@ declare function paragraphDirection(text: string, direction?: TextDirection | 'a
827
985
  /** Test helper. Do not call from product code. */
828
986
  declare function _resetBidiWarningForTests(): void;
829
987
 
830
- export { _resetBidiWarningForTests as $, layoutRuns as A, type BidiAnalysis as B, markdownToRuns as C, DEFAULT_TEXT_FILL as D, numericWeight as E, type FontVariantCaps as F, paragraphDirection as G, registerBidi as H, resolveAlign as I, resolveRunFace as J, resolveRuns as K, type LaidOutRuns as L, MARKDOWN_RUN_GRAMMAR as M, resolveTextStyle as N, runsToMarkdown as O, type PlacedGlyph as P, runsToPlainText as Q, type ResolvedTextStyle as R, type StyledRun as S, type TextStyle as T, scriptMetrics as U, scriptMetricsFor as V, smallCapsScale as W, smallCapsScaleFor as X, smallCapsText as Y, toRuns as Z, transformRunTexts as _, type ResolvedRun as a, _resetLayoutCacheForTests as a0, type LayoutRunsOpts as b, type TextPaint as c, type BidiReordering as d, type BidiResolver as e, DEFAULT_TEXT_STYLE as f, LAYOUT_CACHE_STRUCTURAL_LIMIT as g, LAYOUT_CACHE_VARIANT_LIMIT as h, type LaidOutCell as i, type LaidOutLineBox as j, type RunFlag as k, type RunGrammar as l, type RunMarker as m, type RunSourceMap as n, SCRIPT_METRICS as o, SMALL_CAPS_SCALE as p, type ScriptPreset as q, type SmallCapsText as r, type TextAlign as s, type TextDirection as t, type TextTransform as u, type TransformedRunText as v, cachedLayoutRuns as w, fontString as x, isBoldWeight as y, isSmallCapsLetter as z };
988
+ export { scriptMetricsFor as $, dropRuns as A, type BidiAnalysis as B, type CacheUse as C, DEFAULT_TEXT_FILL as D, fontString as E, type FontVariantCaps as F, halfLeadingFor as G, isBoldWeight as H, isSmallCapsLetter as I, layoutRuns as J, markdownToRuns as K, type LaidOutRuns as L, MARKDOWN_RUN_GRAMMAR as M, numericWeight as N, paragraphDirection as O, type PlacedGlyph as P, registerBidi as Q, type ResolvedTextStyle as R, type StyledRun as S, type TextStyle as T, resolveAlign as U, resolveRunFace as V, resolveRuns as W, resolveTextStyle as X, runsToMarkdown as Y, runsToPlainText as Z, scriptMetrics as _, type ResolvedRun as a, smallCapsScale as a0, smallCapsScaleFor as a1, smallCapsText as a2, toRuns as a3, transformRunTexts as a4, _resetBidiWarningForTests as a5, _resetLayoutCacheForTests as a6, type LayoutRunsOpts as b, type TextShaper as c, type TextPaint as d, type BidiReordering as e, type BidiResolver as f, DEFAULT_TEXT_STYLE as g, LAYOUT_CACHE_STRUCTURAL_LIMIT as h, LAYOUT_CACHE_VARIANT_LIMIT as i, type LaidOutCell as j, type LaidOutLineBox as k, type RunFlag as l, type RunGrammar as m, type RunMarker as n, type RunSourceMap as o, SCRIPT_METRICS as p, SMALL_CAPS_SCALE as q, type ScriptPreset as r, type ShapedCluster as s, type ShapedGlyph as t, type SmallCapsText as u, type TextAlign as v, type TextDirection as w, type TextTransform as x, type TransformedRunText as y, cachedLayoutRuns as z };
@@ -1,3 +1,3 @@
1
- export { $ as _resetBidiWarningForTests, a0 as _resetLayoutCacheForTests } from './test-seams-B0BDm36M.js';
1
+ export { a5 as _resetBidiWarningForTests, a6 as _resetLayoutCacheForTests } from './test-seams-DHGfE_6p.js';
2
2
  import '@weasel-js/paint';
3
3
  import '@weasel-js/font';
@@ -1,3 +1,3 @@
1
- export { _resetBidiWarningForTests, _resetLayoutCacheForTests } from './chunk-ADRQIIHS.js';
1
+ export { _resetBidiWarningForTests, _resetLayoutCacheForTests } from './chunk-FODNMBHI.js';
2
2
  //# sourceMappingURL=test-seams.js.map
3
3
  //# sourceMappingURL=test-seams.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/text",
3
- "version": "1.13.0-rc.0",
3
+ "version": "1.14.0",
4
4
  "description": "Typography for weasel: styled runs, style resolution, kerned glyph layout, wrap and measurement. No scene graph, no React.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,9 +20,9 @@
20
20
  "./package.json": "./package.json"
21
21
  },
22
22
  "dependencies": {
23
- "@weasel-js/geom": "1.13.0-rc.0",
24
- "@weasel-js/paint": "1.13.0-rc.0",
25
- "@weasel-js/registry": "1.13.0-rc.0"
23
+ "@weasel-js/geom": "1.14.0",
24
+ "@weasel-js/paint": "1.14.0",
25
+ "@weasel-js/registry": "1.14.0"
26
26
  },
27
27
  "scripts": {
28
28
  "test": "vitest run",
@@ -51,9 +51,9 @@
51
51
  "provenance": true
52
52
  },
53
53
  "devDependencies": {
54
- "@weasel-js/bidi": "1.13.0-rc.0"
54
+ "@weasel-js/bidi": "1.14.0"
55
55
  },
56
56
  "peerDependencies": {
57
- "@weasel-js/font": "1.13.0-rc.0"
57
+ "@weasel-js/font": "1.14.0"
58
58
  }
59
59
  }