@weasel-js/text 1.11.0 → 1.11.1

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.
@@ -708,19 +708,8 @@ function measureRuns(runs, tabSize) {
708
708
  kerningBefore: 0,
709
709
  drawsInk: false
710
710
  };
711
- const inked = (hit, kerning) => ({
712
- ...blank,
713
- resolved: hit.resolved,
714
- metrics: hit.metrics,
715
- font: hit.font,
716
- glyph: hit.glyph,
717
- advance: hit.advance * (fontSize / hit.metrics.size),
718
- tracking,
719
- kerningBefore: kerning,
720
- drawsInk: true
721
- });
722
711
  if (color) {
723
- entries.push(clusterEnd ? inked(color, 0) : blank);
712
+ entries.push(clusterEnd ? ink(blank, color, 0, tracking) : blank);
724
713
  prev = void 0;
725
714
  } else if (isHardLineBreak(cp)) {
726
715
  entries.push(blank);
@@ -733,19 +722,17 @@ function measureRuns(runs, tabSize) {
733
722
  prev = void 0;
734
723
  } else {
735
724
  const own = glyphIn(resolved, 32);
736
- prev = {
737
- ...blank,
738
- font: own?.font ?? null,
739
- glyph: own?.glyph ?? null,
740
- advance,
741
- tracking,
742
- kerningBefore
743
- };
725
+ blank.font = own?.font ?? null;
726
+ blank.glyph = own?.glyph ?? null;
727
+ blank.advance = advance;
728
+ blank.tracking = tracking;
729
+ blank.kerningBefore = kerningBefore;
730
+ prev = blank;
744
731
  entries.push(prev);
745
732
  }
746
733
  } else {
747
734
  const hit = resolveGlyph(resolved, run.fontFamily, run.fontWeight, run.fontStyle, cp);
748
- const entry = hit ? inked(hit, kerningBefore) : blank;
735
+ const entry = hit ? ink(blank, hit, kerningBefore, tracking) : blank;
749
736
  entries.push(entry);
750
737
  if (!mark) prev = entry;
751
738
  }
@@ -753,6 +740,17 @@ function measureRuns(runs, tabSize) {
753
740
  });
754
741
  return entries;
755
742
  }
743
+ function ink(e, hit, kerning, tracking) {
744
+ e.resolved = hit.resolved;
745
+ e.metrics = hit.metrics;
746
+ e.font = hit.font;
747
+ e.glyph = hit.glyph;
748
+ e.advance = hit.advance * (e.fontSize / hit.metrics.size);
749
+ e.tracking = tracking;
750
+ e.kerningBefore = kerning;
751
+ e.drawsInk = true;
752
+ return e;
753
+ }
756
754
  function mirrorEntries(entries, levels, mirror, runs) {
757
755
  return entries.map((entry, pos) => {
758
756
  if (levels[pos] % 2 === 0) return entry;
@@ -787,12 +785,12 @@ function wrapLines(cps, maxWidth, widthOf) {
787
785
  continue;
788
786
  }
789
787
  let j = i + 1;
790
- let ink = i + 1;
788
+ let ink2 = i + 1;
791
789
  while (j < n && !isHardLineBreak(cps[j]) && (!breaks || breaks[j] === NO_BREAK)) {
792
- if (!hangs(cps[j])) ink = j + 1;
790
+ if (!hangs(cps[j])) ink2 = j + 1;
793
791
  j++;
794
792
  }
795
- if (breaks && i > start && widthOf(start, ink) > maxWidth) {
793
+ if (breaks && i > start && widthOf(start, ink2) > maxWidth) {
796
794
  lines.push({ start, end: i, wrapped: true });
797
795
  start = i;
798
796
  }
@@ -1039,5 +1037,5 @@ function _resetLayoutCacheForTests() {
1039
1037
  }
1040
1038
 
1041
1039
  export { BREAK_ALLOWED, BREAK_MANDATORY, DEFAULT_TAB_SIZE, DEFAULT_TEXT_STYLE, LAYOUT_CACHE_STRUCTURAL_LIMIT, LAYOUT_CACHE_VARIANT_LIMIT, NO_BREAK, _resetBidiWarningForTests, _resetLayoutCacheForTests, cachedLayoutRuns, fontString, graphemeCount, hangs, isHardLineBreak, layoutRuns, lineBreakOpportunities, paragraphDirection, registerBidi, resolveAlign, resolveTextStyle, tabAdvance, widthWithTabs, wrapLines };
1042
- //# sourceMappingURL=chunk-HI4VEOYP.js.map
1043
- //# sourceMappingURL=chunk-HI4VEOYP.js.map
1040
+ //# sourceMappingURL=chunk-JOVZEHBJ.js.map
1041
+ //# sourceMappingURL=chunk-JOVZEHBJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/layout/tabStops.ts","../src/textStyle.ts","../src/layout/lineBreak/lineBreakTable.ts","../src/layout/lineBreak/lineBreaks.ts","../src/layout/bidiRegistry.ts","../src/layout/bidiLines.ts","../src/measure/graphemes.ts","../src/layout/layoutEntries.ts","../src/layout/lineBreak/wrapLines.ts","../src/layout/layoutLines.ts","../src/layout/layoutOpts.ts","../src/layout/layoutRuns.ts","../src/layout/refId.ts","../src/layout/layoutCache.ts"],"names":["lineBreakPropsOf","CLASS_MASK","EAST_ASIAN","PICTOGRAPHIC_CN","BK","CR","LF","NL","SP","ZW","ZWJ","CM","WJ","GL","BA","BB","B2","HY","CB","CL","CP","EX","IN","NS","OP","QU","IS","NU","PO","PR","SY","AL","HL","ID","EB","EM","H2","H3","JL","JV","JT","RI","AK","AP","AS","VF","VI","QU_PI","QU_PF","ink"],"mappings":";;;;;;;;;;AAOO,IAAM,gBAAA,GAAmB;AAUzB,SAAS,UAAA,CAAW,CAAA,EAAW,IAAA,EAAc,GAAA,EAAqB;AACvE,EAAA,IAAI,EAAE,IAAA,GAAO,CAAA,CAAA,EAAI,OAAO,CAAA;AACxB,EAAA,MAAM,UAAU,IAAA,CAAK,KAAA,CAAM,IAAI,IAAI,CAAA,GAAI,KAAK,IAAA,GAAO,CAAA;AACnD,EAAA,OAAO,MAAA,GAAS,GAAA,GAAM,MAAA,GAAS,IAAA,GAAO,MAAA;AACxC;AAQO,SAAS,cACd,KAAA,EACA,GAAA,EACA,IAAA,EACA,MAAA,EACA,WACA,KAAA,EACQ;AACR,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,IAAI,IAAA,GAAO,KAAA;AACX,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,KAAqB;AAChC,IAAA,IAAI,MAAM,IAAA,EAAM;AAChB,IAAA,KAAA,GAAQ,IAAA,EAAM,IAAI,CAAC,CAAA;AACnB,IAAA,CAAA,IAAK,SAAA,CAAU,MAAM,EAAE,CAAA;AAAA,EACzB,CAAA;AACA,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,IAAI,IAAI,KAAA,EAAO;AACf,IAAA,IAAI,KAAK,GAAA,EAAK;AACd,IAAA,GAAA,CAAI,CAAC,CAAA;AACL,IAAA,MAAM,EAAE,IAAA,EAAM,GAAA,EAAI,GAAI,OAAO,CAAC,CAAA;AAC9B,IAAA,CAAA,IAAK,UAAA,CAAW,CAAA,EAAG,IAAA,EAAM,GAAG,CAAA;AAC5B,IAAA,IAAA,GAAO,CAAA,GAAI,CAAA;AAAA,EACb;AACA,EAAA,GAAA,CAAI,GAAG,CAAA;AACP,EAAA,OAAO,CAAA;AACT;;;ACrBO,SAAS,YAAA,CACd,OACA,SAAA,EAC6B;AAC7B,EAAA,IAAI,UAAU,OAAA,IAAW,KAAA,KAAU,WAAW,OAAO,SAAA,KAAc,QAAQ,OAAA,GAAU,MAAA;AACrF,EAAA,IAAI,KAAA,KAAU,KAAA,EAAO,OAAO,SAAA,KAAc,QAAQ,MAAA,GAAS,OAAA;AAC3D,EAAA,OAAO,KAAA;AACT;AAuGA,IAAM,YAAA,GAAsB,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,MAAA,EAAO;AAE3D,SAAS,WAAW,CAAA,EAAyB;AAC3C,EAAA,OAAO,YAAA,CAAa,CAAC,CAAA,GAAI,CAAA,CAAE,KAAA,GAAQ,MAAA;AACrC;AAEA,SAAS,2BAA2B,SAAA,EAA2B;AAC7D,EAAA,OAAO,sBAAsB,SAAS,CAAA,kBAAA,CAAA;AACxC;AAGO,IAAM,kBAAA,GAAwC;AAAA,EACnD,QAAA,EAAU,EAAA;AAAA,EACV,UAAA,EAAY,YAAA;AAAA,EACZ,UAAA,EAAY,GAAA;AAAA,EACZ,SAAA,EAAW,QAAA;AAAA,EACX,KAAA,EAAO,MAAA;AAAA,EACP,SAAA,EAAW,MAAA;AAAA,EACX,UAAA,EAAY,GAAA;AAAA,EACZ,OAAA,EAAS,gBAAA;AAAA,EACT,IAAA,EAAM,KAAA;AAAA,EACN,IAAA,EAAM,EAAE,KAAA,EAAO,YAAA,EAAa;AAAA,EAC5B,UAAA,EAAY,WAAW,YAAY,CAAA;AAAA,EACnC,mBAAA,EAAqB,0BAAA,CAA2B,UAAA,CAAW,YAAY,CAAC,CAAA;AAAA,EACxE,cAAA,EAAgB,IAAA;AAAA,EAChB,aAAA,EAAe,CAAA;AAAA,EACf,SAAA,EAAW,KAAA;AAAA,EACX,aAAA,EAAe,KAAA;AAAA,EACf,QAAA,EAAU,KAAA;AAAA,EACV,aAAA,EAAe,MAAA;AAAA,EACf,eAAA,EAAiB;AACnB;AA0BO,SAAS,gBAAA,CACd,KAAA,EACA,KAAA,EACA,KAAA,GAAQ,CAAA,EACW;AACnB,EAAA,MAAM,OAAO,KAAA,EAAO,IAAA,KAAS,MAAA,GAAY,kBAAA,CAAmB,OAAO,KAAA,CAAM,IAAA;AACzE,EAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,MAAA;AAChC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,IAAA,KAAS,kBAAA,CAAmB,IAAA,IAAQ,MAAA,KAAW,SAClD,kBAAA,GACA;AAAA,MACA,GAAG,kBAAA;AAAA,MACH,IAAA;AAAA,MACA,UAAA,EAAY,UAAA,CAAY,IAAA,EAAM,KAAA,IAAS,IAAK,CAAA;AAAA,MAC5C,qBAAqB,0BAAA,CAA2B,UAAA,CAAY,IAAA,EAAM,KAAA,IAAS,IAAK,CAAC,CAAA;AAAA,MACjF,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW;AAAC,KAC3C;AAAA,EACJ;AACA,EAAA,MAAM,aAAa,KAAA,CAAM,UAAA,IAAc,UAAA,CAAY,IAAA,EAAM,SAAS,IAAK,CAAA;AACvE,EAAA,IAAI,mBAAA;AACJ,EAAA,IAAI,KAAA,CAAM,wBAAwB,MAAA,EAAQ;AACxC,IAAA,mBAAA,GAAsB,IAAA;AAAA,EACxB,CAAA,MAAA,IAAW,KAAA,CAAM,mBAAA,IAAuB,IAAA,EAAM;AAC5C,IAAA,mBAAA,GAAsB,KAAA,CAAM,mBAAA;AAAA,EAC9B,CAAA,MAAO;AACL,IAAA,mBAAA,GAAsB,2BAA2B,UAAU,CAAA;AAAA,EAC7D;AACA,EAAA,OAAO;AAAA,IACL,UAAU,mBAAA,CAAoB,KAAA,CAAM,QAAA,IAAY,kBAAA,CAAmB,UAAU,KAAK,CAAA;AAAA,IAClF,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,kBAAA,CAAmB,UAAA;AAAA,IACnD,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,kBAAA,CAAmB,UAAA;AAAA,IACnD,SAAA,EAAW,KAAA,CAAM,SAAA,IAAa,kBAAA,CAAmB,SAAA;AAAA,IACjD,KAAA,EAAO,KAAA,CAAM,KAAA,IAAS,kBAAA,CAAmB,KAAA;AAAA,IACzC,SAAA,EAAW,KAAA,CAAM,SAAA,IAAa,kBAAA,CAAmB,SAAA;AAAA,IACjD,UAAA,EAAY,KAAA,CAAM,UAAA,IAAc,kBAAA,CAAmB,UAAA;AAAA,IACnD,OAAA,EAAS,KAAA,CAAM,OAAA,IAAW,kBAAA,CAAmB,OAAA;AAAA,IAC7C,IAAA,EAAM,KAAA,CAAM,IAAA,IAAQ,kBAAA,CAAmB,IAAA;AAAA,IACvC,IAAA;AAAA,IACA,UAAA;AAAA,IACA,mBAAA;AAAA,IACA,cAAA,EAAgB,MAAM,cAAA,IAAkB,IAAA;AAAA,IACxC,eAAe,mBAAA,CAAoB,KAAA,CAAM,aAAA,IAAiB,kBAAA,CAAmB,eAAe,KAAK,CAAA;AAAA,IACjG,SAAA,EAAW,KAAA,CAAM,SAAA,IAAa,kBAAA,CAAmB,SAAA;AAAA,IACjD,aAAA,EAAe,KAAA,CAAM,aAAA,IAAiB,kBAAA,CAAmB,aAAA;AAAA,IACzD,QAAA,EAAU,KAAA,CAAM,QAAA,IAAY,kBAAA,CAAmB,QAAA;AAAA,IAC/C,aAAA,EAAe,KAAA,CAAM,aAAA,IAAiB,kBAAA,CAAmB,aAAA;AAAA,IACzD,eAAA,EAAiB,KAAA,CAAM,eAAA,IAAmB,kBAAA,CAAmB,eAAA;AAAA,IAC7D,GAAI,MAAM,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,CAAM,MAAA,EAAO,GAAI,EAAC;AAAA,IAC7D,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW;AAAC,GAC3C;AACF;AAGO,SAAS,WAAW,CAAA,EAA8B;AACvD,EAAA,OAAO,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,CAAA,EAAI,CAAA,CAAE,UAAU,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAA,GAAA,EAAM,aAAA,CAAc,CAAA,CAAE,UAAU,CAAC,CAAA,CAAA;AACtF;;;AC/PA,IAAA,sBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,sBAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,UAAA,EAAA,MAAA,UAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,UAAA,EAAA,MAAA,UAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,eAAA,EAAA,MAAA,eAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,eAAA,EAAA,MAAA,eAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,EAAA,EAAA,MAAA,EAAA;AAAA,EAAA,GAAA,EAAA,MAAA,GAAA;AAAA,EAAA,gBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAQO,IAAM,eAAA,GAAkB,QAAA;AAIxB,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,GAAA,GAAM,CAAA;AACZ,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,CAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,EAAA,GAAK,EAAA;AACX,IAAM,KAAA,GAAQ,EAAA;AACd,IAAM,KAAA,GAAQ,EAAA;AAGd,IAAM,UAAA,GAAa,EAAA;AAEnB,IAAM,UAAA,GAAa,EAAA;AAEnB,IAAM,eAAA,GAAkB,GAAA;AAE/B,IAAM,QAAA,GAAW,kFAAA;AACjB,IAAM,OAAA,GAAU,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,KAAK,GAAG,CAAA;AAIvP,IAAM,IAAA,GAAO,IAAA;AACb,IAAM,MAAA,GACJ,2+MAAA;AAuEF,IAAI,GAAA,GAAyB,IAAA;AAC7B,IAAI,YAAA,GAAkC,IAAA;AACtC,IAAI,YAAA,GAAkC,IAAA;AAEtC,SAAS,MAAA,GAAe;AACtB,EAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAW,KAAO,CAAA;AACrC,EAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAW,IAAI,CAAA;AAClC,EAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAW,IAAI,CAAA;AAClC,EAAA,MAAM,IAAA,GAAO,IAAI,UAAA,CAAW,GAAG,CAAA;AAC/B,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,MAAA,EAAQ,CAAA,EAAA,EAAK,IAAA,CAAK,QAAA,CAAS,UAAA,CAAW,CAAC,CAAC,CAAA,GAAI,QAAQ,CAAC,CAAA;AAClF,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA;AAChC,IAAA,IAAI,QAAQ,EAAA,IAAM,IAAA,IAAQ,IAAI,GAAA,GAAM,GAAA,GAAM,KAAK,IAAA,GAAO,EAAA;AAAA,SACjD;AACH,MAAA,MAAM,CAAA,GAAI,KAAK,IAAI,CAAA;AACnB,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,EAAA;AACd,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,CAAA;AACd,MAAA,IAAI,EAAA,GAAK,KAAA,EAAS,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,GAAA,EAAK,KAAO,CAAC,CAAA;AAChE,MAAA,GAAA,EAAA;AACA,MAAA,EAAA,IAAM,GAAA;AACN,MAAA,GAAA,GAAM,CAAA;AAAA,IACR;AAAA,EACF;AACA,EAAA,GAAA,GAAM,MAAA;AACN,EAAA,YAAA,GAAe,MAAA;AACf,EAAA,YAAA,GAAe,MAAA;AACjB;AAMO,SAAS,iBAAiB,EAAA,EAAoB;AACnD,EAAA,IAAI,GAAA,KAAQ,MAAM,MAAA,EAAO;AACzB,EAAA,IAAI,EAAA,GAAK,KAAA,EAAS,OAAO,GAAA,CAAK,EAAE,CAAA;AAChC,EAAA,IAAI,EAAA,GAAK,SAAU,OAAO,EAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,YAAA;AACf,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,OAAO,MAAA,GAAS,CAAA;AACzB,EAAA,OAAO,KAAK,EAAA,EAAI;AACd,IAAA,MAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,CAAA,IAAM,CAAA;AAC7B,IAAA,IAAI,MAAA,CAAO,GAAG,CAAA,IAAK,EAAA,EAAI,EAAA,GAAK,GAAA;AAAA,cAClB,GAAA,GAAM,CAAA;AAAA,EAClB;AACA,EAAA,OAAO,aAAc,EAAE,CAAA;AACzB;;;ACjLA,IAAM;AAAA,EACJ,gBAAA,EAAAA,iBAAAA;AAAA,EAAkB,UAAA,EAAAC,WAAAA;AAAA,EAAY,UAAA,EAAAC,WAAAA;AAAA,EAAY,eAAA,EAAAC,gBAAAA;AAAA,EAC1C,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,GAAA,EAAAC,IAAAA;AAAA,EAAK,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAC7E,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EACpE,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,EAAA,EAAAC,GAAAA;AAAA,EAAI,KAAA,EAAAC,MAAAA;AAAA,EAAO,KAAA,EAAAC;AAC7B,CAAA,GAAI,sBAAA;AAGG,IAAM,QAAA,GAAW;AAEjB,IAAM,aAAA,GAAgB;AAEtB,IAAM,eAAA,GAAkB;AAE/B,IAAM,MAAA,GAAS,IAAA;AACf,IAAM,aAAA,GAAgB,IAAA;AAEtB,IAAM,OAAO,CAAC,CAAA,KAAuB,MAAMvB,GAAAA,IAAM,CAAA,KAAMsB,UAAS,CAAA,KAAMC,MAAAA;AACtE,IAAM,MAAA,GAAS,CAAC,CAAA,KAAuB,CAAA,KAAM5C,OAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMC,GAAAA;AAM1E,SAAS,gBAAgB,EAAA,EAAqB;AACnD,EAAA,OAAO,MAAA,CAAOP,iBAAAA,CAAiB,EAAE,CAAA,GAAIC,WAAU,CAAA;AACjD;AACA,IAAM,OAAA,GAAS,CAAC,CAAA,KAAuB,CAAA,KAAM8B,OAAM,CAAA,KAAMC,GAAAA;AACzD,IAAM,QAAA,GAAW,CAAC,CAAA,KAAuB,CAAA,KAAMM,GAAAA,IAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMJ,GAAAA,IAAM,CAAA,KAAMC,GAAAA;AAC/F,IAAM,aAAa,CAAC,CAAA,KAAuB,MAAMJ,GAAAA,IAAM,CAAA,KAAMC,OAAM,CAAA,KAAMC,GAAAA;AASlE,SAAS,uBAAuB,GAAA,EAAoC;AACzE,EAAA,MAAM,IAAI,GAAA,CAAI,MAAA;AACd,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAA;AAChC,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,GAAA;AACpB,EAAA,GAAA,CAAI,CAAC,CAAA,GAAI,eAAA;AAGT,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,CAAC,CAAA;AAC5B,EAAA,MAAM,EAAA,GAAK,IAAI,UAAA,CAAW,CAAC,CAAA;AAC3B,EAAA,MAAM,IAAA,GAAO,IAAI,UAAA,CAAW,CAAC,CAAA;AAC7B,EAAA,MAAM,EAAA,GAAK,IAAI,UAAA,CAAW,CAAC,CAAA;AAE3B,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,CAAC,CAAA;AAC9B,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,KAAA,GAAQnC,iBAAAA,CAAiB,GAAA,CAAI,CAAC,CAAC,CAAA;AACrC,IAAA,MAAM,IAAI,KAAA,GAAQC,WAAAA;AAClB,IAAA,IAAA,CAAK,CAAA,KAAMU,GAAAA,IAAM,CAAA,KAAMD,IAAAA,KAAQ,IAAI,CAAA,EAAG;AACpC,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AACtB,MAAA,IAAI,CAAC,MAAA,CAAO,IAAI,KAAK,IAAA,KAASF,GAAAA,IAAM,SAASC,GAAAA,EAAI;AAAA,IACnD;AACA,IAAA,IAAI,CAAA,KAAME,GAAAA,IAAM,CAAA,KAAMD,IAAAA,EAAK;AACzB,MAAA,GAAA,CAAI,CAAC,CAAA,GAAIqB,GAAAA;AAAI,MAAA,EAAA,CAAG,CAAC,CAAA,GAAI,CAAA;AAAG,MAAA,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAAA,IACpC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAG,MAAA,EAAA,CAAG,CAAC,CAAA,GAAI,KAAA,GAAQ7B,WAAAA,GAAa,CAAA,GAAI,CAAA;AAAG,MAAA,IAAA,CAAK,CAAC,CAAA,GAAI,KAAA,GAAQC,gBAAAA,GAAkB,CAAA,GAAI,CAAA;AAAA,IAC1F;AACA,IAAA,EAAA,CAAG,CAAC,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA;AACb,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,CAAA;AACX,IAAA,CAAA,EAAA;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,CAAA;AAId,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAA,CAAwBH,iBAAAA,CAAiB,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA,GAAI,CAAC,CAAC,CAAA,GAAIC,WAAAA,MAAgBS,IAAAA;AAGjG,EAAA,MAAM,YAAA,GAAe,CAAC,CAAA,KAAsB;AAC1C,IAAA,OAAO,CAAA,IAAK,CAAA,IAAK,GAAA,CAAI,CAAC,MAAMF,GAAAA,EAAI,CAAA,EAAA;AAChC,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAEA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,IAAA,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,OAAO,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,GAAA;AAEP,EAAA,SAAS,OAAO,CAAA,EAAmB;AACjC,IAAA,MAAM,IAAI,CAAA,GAAI,CAAA;AACd,IAAA,MAAM,CAAA,GAAI,IAAI,CAAC,CAAA;AACf,IAAA,MAAM,CAAA,GAAI,IAAI,CAAC,CAAA;AAGf,IAAA,IAAI,CAAA,KAAMH,GAAAA,IAAM,CAAA,KAAMC,GAAAA,EAAI,OAAO,QAAA;AACjC,IAAA,IAAI,MAAA,CAAO,CAAC,CAAA,EAAG,OAAO,eAAA;AAEtB,IAAA,IAAI,OAAO,CAAC,CAAA,IAAK,MAAME,GAAAA,IAAM,CAAA,KAAMC,KAAI,OAAO,QAAA;AAE9C,IAAA,MAAM,CAAA,GAAI,aAAa,CAAC,CAAA;AACxB,IAAA,IAAI,KAAK,CAAA,IAAK,GAAA,CAAI,CAAC,CAAA,KAAMA,KAAI,OAAO,aAAA;AAEpC,IAAA,IAAI,SAAA,CAAU,CAAC,CAAA,EAAG,OAAO,QAAA;AAEzB,IAAA,IAAI,MAAMG,GAAAA,IAAM,CAAA,KAAMA,GAAAA,IAAM,CAAA,KAAMC,KAAI,OAAO,QAAA;AAC7C,IAAA,IAAI,CAAA,KAAMA,OAAM,CAAA,KAAML,GAAAA,IAAM,MAAMM,GAAAA,IAAM,CAAA,KAAMG,KAAI,OAAO,QAAA;AAEzD,IAAA,IAAI,CAAA,KAAME,OAAM,CAAA,KAAMC,GAAAA,IAAM,MAAMC,GAAAA,IAAM,CAAA,KAAMS,KAAI,OAAO,QAAA;AAEzD,IAAA,MAAM,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA,GAAI,EAAA;AAC5B,IAAA,IAAI,CAAA,KAAMN,KAAI,OAAO,QAAA;AAErB,IAAA,IAAI,MAAMuB,MAAAA,EAAO;AACf,MAAA,MAAM,IAAI,CAAA,GAAI,CAAA;AACd,MAAA,IAAI,CAAA,GAAI,GAAG,OAAO,QAAA;AAClB,MAAA,MAAM,CAAA,GAAI,IAAI,CAAC,CAAA;AACf,MAAA,IAAI,MAAA,CAAO,CAAC,CAAA,IAAK,CAAA,KAAMvB,OAAM,IAAA,CAAK,CAAC,CAAA,IAAK,CAAA,KAAMX,GAAAA,IAAM,CAAA,KAAML,GAAAA,IAAM,CAAA,KAAMC,KAAI,OAAO,QAAA;AAAA,IACnF;AAEA,IAAA,IAAI,MAAMuC,MAAAA,EAAO;AACf,MAAA,IAAI,CAAA,GAAI,CAAA,IAAK,KAAA,EAAO,OAAO,QAAA;AAC3B,MAAA,MAAM,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AACnB,MAAA,IAAI,CAAA,KAAMxC,GAAAA,IAAM,CAAA,KAAMK,GAAAA,IAAM,CAAA,KAAMD,OAAM,CAAA,KAAMO,GAAAA,IAAM,IAAA,CAAK,CAAC,CAAA,IAAK,CAAA,KAAMC,OAAM,CAAA,KAAMC,GAAAA,IAC1E,CAAA,KAAMK,GAAAA,IAAM,CAAA,KAAMI,GAAAA,IAAM,OAAO,CAAC,CAAA,IAAK,CAAA,KAAMrB,GAAAA,EAAI,OAAO,QAAA;AAAA,IAC/D;AAEA,IAAA,IAAI,CAAA,KAAMD,GAAAA,IAAM,CAAA,KAAMkB,GAAAA,IAAM,CAAA,GAAI,CAAA,GAAI,KAAA,IAAS,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,KAAMC,GAAAA,EAAI,OAAO,aAAA;AACvE,IAAA,IAAI,CAAA,KAAMD,KAAI,OAAO,QAAA;AAErB,IAAA,IAAA,CAAK,MAAMP,GAAAA,IAAM,CAAA,KAAMC,GAAAA,KAAO,CAAA,KAAMG,KAAI,OAAO,QAAA;AAC/C,IAAA,IAAI,CAAA,KAAMP,GAAAA,IAAM,CAAA,KAAMA,GAAAA,EAAI,OAAO,QAAA;AAEjC,IAAA,IAAI,CAAA,KAAMR,KAAI,OAAO,aAAA;AAErB,IAAA,IAAI,CAAA,KAAMiB,GAAAA,IAAM,CAAA,KAAMuB,MAAAA,EAAO,OAAO,QAAA;AACpC,IAAA,IAAI,CAAA,KAAMvB,GAAAA,IAAM,CAAA,KAAMsB,MAAAA,EAAO,OAAO,QAAA;AAEpC,IAAA,IAAI,IAAA,CAAK,CAAC,CAAA,EAAG;AACX,MAAA,IAAI,CAAC,EAAA,CAAG,CAAC,CAAA,EAAG,OAAO,QAAA;AACnB,MAAA,IAAI,CAAA,GAAI,KAAK,KAAA,IAAS,CAAC,GAAG,CAAA,GAAI,CAAC,GAAG,OAAO,QAAA;AAAA,IAC3C;AACA,IAAA,IAAI,IAAA,CAAK,CAAC,CAAA,EAAG;AACX,MAAA,IAAI,CAAC,EAAA,CAAG,CAAC,CAAA,EAAG,OAAO,QAAA;AACnB,MAAA,IAAI,MAAM,CAAA,IAAK,CAAC,GAAG,CAAA,GAAI,CAAC,GAAG,OAAO,QAAA;AAAA,IACpC;AAEA,IAAA,IAAI,CAAA,KAAM7B,GAAAA,IAAM,CAAA,KAAMA,GAAAA,EAAI,OAAO,aAAA;AAEjC,IAAA,IAAA,CAAK,MAAMD,GAAAA,IAAM,EAAA,CAAG,CAAC,CAAA,KAAM,MAAA,KAAW,MAAMc,GAAAA,EAAI;AAC9C,MAAA,IAAI,CAAA,KAAM,GAAG,OAAO,QAAA;AACpB,MAAA,MAAM,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AACnB,MAAA,IAAI,MAAA,CAAO,CAAC,CAAA,IAAK,CAAA,KAAMvB,GAAAA,IAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMS,GAAAA,IAAM,CAAA,KAAML,GAAAA,EAAI,OAAO,QAAA;AAAA,IACxE;AAEA,IAAA,IAAI,CAAA,KAAMC,OAAM,CAAA,KAAMG,GAAAA,IAAM,MAAMM,GAAAA,IAAM,CAAA,KAAMR,KAAI,OAAO,QAAA;AAEzD,IAAA,IAAI,IAAI,CAAA,IAAK,GAAA,CAAI,CAAA,GAAI,CAAC,MAAMiB,GAAAA,KAAO,CAAA,KAAMf,GAAAA,IAAO,CAAA,KAAMH,OAAM,CAAC,EAAA,CAAG,CAAC,CAAA,CAAA,IAAO,CAAA,KAAMkB,KAAI,OAAO,QAAA;AAEzF,IAAA,IAAI,CAAA,KAAMF,GAAAA,IAAM,CAAA,KAAME,GAAAA,EAAI,OAAO,QAAA;AACjC,IAAA,IAAI,CAAA,KAAMV,KAAI,OAAO,QAAA;AAErB,IAAA,IAAK,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,KAAMK,GAAAA,IAAQ,MAAMA,GAAAA,IAAM,OAAA,CAAQ,CAAC,CAAA,EAAI,OAAO,QAAA;AACjE,IAAA,IAAK,CAAA,KAAME,GAAAA,IAAM,UAAA,CAAW,CAAC,CAAA,IAAO,WAAW,CAAC,CAAA,IAAK,CAAA,KAAMD,GAAAA,EAAK,OAAO,QAAA;AACvE,IAAA,IAAA,CAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMD,GAAAA,KAAO,QAAQ,CAAC,CAAA,IAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMD,MAAM,OAAO,QAAA;AAE7F,IAAA,IAAI,CAAA,KAAMA,GAAAA,IAAM,CAAA,KAAMC,GAAAA,EAAI;AACxB,MAAA,IAAI,IAAI,CAAA,KAAMV,GAAAA,IAAM,CAAA,KAAMC,GAAAA,GAAK,IAAI,CAAA,GAAI,CAAA;AACvC,MAAA,OAAO,CAAA,IAAK,MAAM,GAAA,CAAI,CAAC,MAAMU,GAAAA,IAAM,GAAA,CAAI,CAAC,CAAA,KAAMJ,GAAAA,CAAAA,EAAK,CAAA,EAAA;AACnD,MAAA,IAAI,KAAK,CAAA,IAAK,GAAA,CAAI,CAAC,CAAA,KAAMC,KAAI,OAAO,QAAA;AAAA,IACtC;AACA,IAAA,IAAI,CAAA,KAAMC,GAAAA,IAAM,CAAA,KAAMC,GAAAA,EAAI;AACxB,MAAA,IAAI,CAAA,KAAMF,KAAI,OAAO,QAAA;AACrB,MAAA,IAAI,CAAA,KAAMH,GAAAA,IAAM,CAAA,GAAI,CAAA,GAAI,KAAA,EAAO;AAC7B,QAAA,MAAM,CAAA,GAAI,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AACnB,QAAA,IAAI,CAAA,KAAMG,KAAI,OAAO,QAAA;AACrB,QAAA,IAAI,CAAA,KAAMD,GAAAA,IAAM,CAAA,GAAI,CAAA,GAAI,KAAA,IAAS,IAAI,CAAA,GAAI,CAAC,CAAA,KAAMC,GAAAA,EAAI,OAAO,QAAA;AAAA,MAC7D;AAAA,IACF;AACA,IAAA,IAAA,CAAK,MAAMV,GAAAA,IAAM,CAAA,KAAMS,GAAAA,KAAO,CAAA,KAAMC,KAAI,OAAO,QAAA;AAC/C,IAAA,IAAI,MAAMA,GAAAA,EAAI;AACZ,MAAA,IAAI,CAAA,GAAI,CAAA;AACR,MAAA,OAAO,CAAA,IAAK,MAAM,GAAA,CAAI,CAAC,MAAMG,GAAAA,IAAM,GAAA,CAAI,CAAC,CAAA,KAAMJ,GAAAA,CAAAA,EAAK,CAAA,EAAA;AACnD,MAAA,IAAI,KAAK,CAAA,IAAK,GAAA,CAAI,CAAC,CAAA,KAAMC,KAAI,OAAO,QAAA;AAAA,IACtC;AAEA,IAAA,IAAI,CAAA,KAAMW,GAAAA,KAAO,CAAA,KAAMA,GAAAA,IAAM,CAAA,KAAMC,OAAM,CAAA,KAAMH,GAAAA,IAAM,CAAA,KAAMC,GAAAA,CAAAA,EAAK,OAAO,QAAA;AACvE,IAAA,IAAA,CAAK,CAAA,KAAME,OAAM,CAAA,KAAMH,GAAAA,MAAQ,MAAMG,GAAAA,IAAM,CAAA,KAAMC,MAAK,OAAO,QAAA;AAC7D,IAAA,IAAA,CAAK,MAAMA,GAAAA,IAAM,CAAA,KAAMH,GAAAA,KAAO,CAAA,KAAMG,KAAI,OAAO,QAAA;AAC/C,IAAA,IAAK,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,KAAMZ,GAAAA,IAAQ,MAAMC,GAAAA,IAAM,QAAA,CAAS,CAAC,CAAA,EAAI,OAAO,QAAA;AAEnE,IAAA,IAAI,QAAQ,CAAC,CAAA,IAAK,OAAA,CAAQ,CAAC,GAAG,OAAO,QAAA;AAErC,IAAA,MAAM,UAAU,CAAA,KAAMa,GAAAA,IAAM,MAAME,GAAAA,IAAM,EAAA,CAAG,CAAC,CAAA,KAAM,aAAA;AAClD,IAAA,MAAM,UAAU,CAAA,KAAMF,GAAAA,IAAM,MAAME,GAAAA,IAAM,EAAA,CAAG,CAAC,CAAA,KAAM,aAAA;AAClD,IAAA,IAAI,CAAA,KAAMD,GAAAA,IAAM,OAAA,EAAS,OAAO,QAAA;AAChC,IAAA,IAAI,OAAA,KAAY,CAAA,KAAME,GAAAA,IAAM,CAAA,KAAMC,MAAK,OAAO,QAAA;AAC9C,IAAA,IAAI,CAAA,KAAMA,GAAAA,IAAM,CAAA,GAAI,CAAA,KAAM,GAAA,CAAI,IAAI,CAAC,CAAA,KAAMJ,GAAAA,IAAM,GAAA,CAAI,CAAA,GAAI,CAAC,MAAME,GAAAA,IAAM,EAAA,CAAG,CAAA,GAAI,CAAC,CAAA,KAAM,aAAA,CAAA,KAC1E,CAAA,KAAMF,GAAAA,IAAM,EAAA,CAAG,CAAC,CAAA,KAAM,aAAA,CAAA,EAAgB,OAAO,QAAA;AACrD,IAAA,IAAI,OAAA,IAAW,OAAA,IAAW,CAAA,GAAI,CAAA,GAAI,KAAA,IAAS,IAAI,CAAA,GAAI,CAAC,CAAA,KAAMG,GAAAA,EAAI,OAAO,QAAA;AAErE,IAAA,IAAI,CAAA,KAAMnB,GAAAA,IAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,QAAA;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,KAAMC,GAAAA,KAAO,CAAA,KAAMH,GAAAA,IAAM,CAAC,EAAA,CAAG,CAAC,CAAA,EAAG,OAAO,QAAA;AAC3D,IAAA,IAAI,CAAA,KAAMJ,GAAAA,IAAM,CAAC,EAAA,CAAG,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,KAAMO,GAAAA,CAAAA,EAAK,OAAO,QAAA;AAE3D,IAAA,IAAI,CAAA,KAAMc,GAAAA,IAAM,CAAA,KAAMA,GAAAA,EAAI;AACxB,MAAA,IAAI,CAAA,GAAI,CAAA;AACR,MAAA,OAAO,CAAA,IAAK,CAAA,IAAK,GAAA,CAAI,CAAC,MAAMA,GAAAA,EAAI,CAAA,EAAA;AAChC,MAAA,IAAA,CAAK,CAAA,GAAI,CAAA,IAAK,CAAA,KAAM,CAAA,EAAG,OAAO,QAAA;AAAA,IAChC;AAEA,IAAA,IAAI,MAAMN,GAAAA,KAAO,CAAA,KAAMD,OAAM,IAAA,CAAK,CAAC,IAAI,OAAO,QAAA;AAE9C,IAAA,OAAO,aAAA;AAAA,EACT;AACF;;;ACxNA,IAAI,UAAA,GAAkC,IAAA;AAO/B,SAAS,aAAa,MAAA,EAAyC;AACpE,EAAA,UAAA,GAAa,MAAA;AACb,EAAA,OAAO,MAAM;AAAE,IAAA,IAAI,UAAA,KAAe,QAAQ,UAAA,GAAa,IAAA;AAAA,EAAM,CAAA;AAC/D;AAGO,SAAS,cAAA,GAAsC;AACpD,EAAA,OAAO,UAAA;AACT;AAGO,SAAS,iBAAiB,KAAA,EAA8B;AAC7D,EAAA,OAAO,KAAA,GAAQ,CAAA,KAAM,CAAA,GAAI,KAAA,GAAQ,KAAA;AACnC;AAOO,SAAS,kBAAA,CACd,IAAA,EACA,SAAA,GAAoC,MAAA,EACpC,SAA8B,UAAA,EACf;AACf,EAAA,IAAI,SAAA,KAAc,QAAQ,OAAO,SAAA;AACjC,EAAA,IAAI,MAAA,KAAW,MAAM,OAAO,KAAA;AAC5B,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,KAAA,MAAW,MAAM,IAAA,EAAM;AACrB,IAAA,MAAM,EAAA,GAAK,EAAA,CAAG,WAAA,CAAY,CAAC,CAAA;AAC3B,IAAA,IAAI,eAAA,CAAgB,EAAE,CAAA,EAAG;AACzB,IAAA,GAAA,CAAI,KAAK,EAAE,CAAA;AAAA,EACb;AACA,EAAA,OAAO,gBAAA,CAAiB,OAAO,SAAA,CAAU,MAAA,CAAO,QAAQ,GAAA,EAAK,MAAM,CAAC,CAAC,CAAA;AACvE;AAWA,IAAM,UAAA,GAAuD;AAAA,EAC3D,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,MAAQ,IAAM,CAAA;AAAA,EACnD,CAAC,OAAQ,KAAM,CAAA;AAAA,EAAG,CAAC,OAAQ,KAAM,CAAA;AAAA,EACjC,CAAC,OAAS,KAAO,CAAA;AAAA,EAAG,CAAC,QAAS,MAAO;AACvC,CAAA;AAIA,IAAM,iBAAA,GAA8D;AAAA,EAClE,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,MAAQ,IAAM,CAAA;AAAA,EACrE,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,OAAS,KAAO,CAAA;AAAA,EAAG,CAAC,OAAS,KAAO;AACzD,CAAA;AAIA,IAAM,kBAAA,GAA+D;AAAA,EACnE,CAAC,MAAQ,IAAM,CAAA;AAAA,EAAG,CAAC,OAAQ,KAAM,CAAA;AAAA,EAAG,CAAC,OAAQ,KAAM;AACrD,CAAA;AAEA,IAAM,MAAA,GAAQ,CAAC,MAAA,EAAkD,EAAA,KAC/D,OAAO,IAAA,CAAK,CAAC,CAAC,EAAA,EAAI,EAAE,CAAA,KAAM,EAAA,IAAM,EAAA,IAAM,MAAM,EAAE,CAAA;AAEhD,IAAI,gBAAA,GAAmB,KAAA;AAMhB,SAAS,qBAAqB,UAAA,EAAoC;AACvE,EAAA,IAAI,gBAAA,EAAkB;AACtB,EAAA,KAAA,MAAW,MAAM,UAAA,EAAY;AAC3B,IAAA,IAAI,CAAC,MAAA,CAAO,UAAA,EAAY,EAAE,CAAA,IAAK,MAAA,CAAO,iBAAA,EAAmB,EAAE,CAAA,IAAK,MAAA,CAAO,kBAAA,EAAoB,EAAE,CAAA,EAAG;AAChG,IAAA,gBAAA,GAAmB,IAAA;AACnB,IAAA,OAAA,CAAQ,IAAA;AAAA;AAAA;AAAA,MAGN;AAAA,KAIF;AACA,IAAA;AAAA,EACF;AACF;AAGO,SAAS,yBAAA,GAAkC;AAChD,EAAA,gBAAA,GAAmB,KAAA;AACrB;;;AC7EO,SAAS,iBAAA,CACd,MAAA,EACA,UAAA,EACA,OAAA,EACA,SAAA,EACoB;AACpB,EAAA,MAAM,aAA0B,EAAC;AACjC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC3C,IAAA,IAAI,IAAI,UAAA,CAAW,MAAA,IAAU,CAAC,OAAA,CAAQ,CAAC,CAAA,EAAG;AAC1C,IAAA,IAAI,IAAI,KAAA,EAAO;AACb,MAAA,UAAA,CAAW,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,GAAG,QAAA,EAAU,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,MAAM,KAAA,EAAO,CAAC,CAAA,EAAG,SAAS,GAAG,CAAA;AAAA,IACpG;AACA,IAAA,KAAA,GAAQ,CAAA,GAAI,CAAA;AAAA,EACd;AAEA,EAAA,MAAM,OAAA,GAAU,CAAC,EAAA,KAAsC;AACrD,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,IAAI,EAAA,GAAK,WAAW,MAAA,GAAS,CAAA;AAC7B,IAAA,OAAO,KAAK,EAAA,EAAI;AACd,MAAA,MAAM,GAAA,GAAO,KAAK,EAAA,IAAO,CAAA;AACzB,MAAA,IAAI,WAAW,GAAG,CAAA,CAAE,GAAA,IAAO,EAAA,OAAS,GAAA,GAAM,CAAA;AAAA,WACrC,EAAA,GAAK,GAAA;AAAA,IACZ;AACA,IAAA,MAAM,CAAA,GAAI,WAAW,EAAE,CAAA;AACvB,IAAA,OAAO,CAAA,KAAM,UAAa,EAAA,IAAM,CAAA,CAAE,SAAS,EAAA,GAAK,CAAA,CAAE,MAAM,CAAA,GAAI,MAAA;AAAA,EAC9D,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,CAAQ,MAAM,EAAA,EAAI;AAChB,MAAA,MAAM,CAAA,GAAI,QAAQ,IAAI,CAAA;AACtB,MAAA,IAAI,CAAA,KAAM,MAAA,IAAa,EAAA,GAAK,CAAA,CAAE,GAAA,EAAK,OAAO,EAAE,KAAA,EAAO,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAE;AAClE,MAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,CAAA,CAAE,QAAA,EAAU,OAAO,CAAA,CAAE,KAAA,EAAO,EAAA,GAAK,CAAA,CAAE,KAAK,CAAA;AACjE,MAAA,OAAO,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,KAAK,CAAA,EAAG,MAAA,EAAQ,EAAE,MAAA,EAAO;AAAA,IACpE,CAAA;AAAA,IACA,UAAU,EAAA,EAAI;AACZ,MAAA,MAAM,CAAA,GAAI,QAAQ,EAAE,CAAA;AACpB,MAAA,OAAO,MAAM,MAAA,GAAY,CAAA,GAAI,MAAA,CAAO,SAAA,CAAU,EAAE,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACF;AACF;AAWO,SAAS,cAAA,CACd,KAAA,EACA,KAAA,EACA,GAAA,EACU;AACV,EAAA,IAAI,MAAM,MAAA,KAAW,KAAA,EAAO,OAAO,CAAC,GAAG,KAAK,CAAA;AAC5C,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,KAAK,CAAA;AAC1B,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAsB;AAC5C,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG;AACf,MAAA,MAAA,GAAS,CAAA;AACT,MAAA,IAAI,SAAA,GAAY,GAAG,SAAA,GAAY,CAAA;AAAA,IACjC,CAAA,MAAA,IAAW,SAAS,CAAA,EAAG;AACrB,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB,CAAA,MAAO;AACL,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA;AACjC,MAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAAA,WAChB,SAAA,CAAU,GAAA,CAAI,MAAA,EAAQ,CAAC,CAAC,CAAC,CAAA;AAAA,IAChC;AAAA,EACF;AACA,EAAA,IAAI,SAAA,GAAY,GAAG,OAAO,OAAA;AAC1B,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,CAAC,KAAK,EAAC;AACnC,IAAA,MAAM,MAAA,GAAS,CAAA,KAAM,SAAA,GAAY,OAAA,GAAU,EAAC;AAC5C,IAAA,IAAI,IAAI,CAAC,CAAA,MAAO,IAAA,CAAK,GAAG,CAAC,GAAG,KAAK,EAAE,OAAA,EAAQ,EAAG,GAAG,GAAG,CAAC,GAAG,MAAM,CAAA,CAAE,SAAS,CAAA;AAAA,aAChE,IAAA,CAAK,GAAG,MAAA,EAAQ,CAAA,EAAG,GAAG,KAAK,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,GAAA;AACT;AAgBO,SAAS,SAAA,CACd,UAAA,EACA,KAAA,EACA,KAAA,EACW;AACX,EAAA,MAAM,SAAS,IAAI,KAAA,CAAc,KAAK,CAAA,CAAE,KAAK,CAAC,CAAA;AAC9C,EAAA,IAAI,UAAA,KAAe,IAAA,IAAQ,KAAA,KAAU,CAAA,SAAU,EAAE,MAAA,EAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,GAAA,KAAQ,GAAG,GAAG,MAAA,EAAO;AAC7F,EAAA,MAAM,CAAA,GAAI,UAAA,CAAW,OAAA,CAAQ,KAAA,EAAO,QAAQ,KAAK,CAAA;AACjD,EAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,KAAA,EAAO,GAAA,EAAA,EAAO;AACpC,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,MAAA,CAAO,GAAG,CAAA;AAC1B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,SAAS,CAAA,EAAG,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,EAC7D;AAIA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,EAAA,IAAM,EAAE,KAAA,EAAO;AACxB,IAAA,MAAM,MAAM,EAAA,GAAK,KAAA;AACjB,IAAA,IAAI,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA,IAAK,GAAA,IAAO,KAAK,GAAA,GAAM,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,cAAA,CAAe,CAAC,GAAG,IAAI,CAAA,EAAG,KAAA,EAAO,CAAC,GAAA,KAAQ,OAAO,GAAG,CAAA,GAAI,CAAA,KAAM,CAAC,GAAG,MAAA,EAAO;AAC5F;;;ACjJA,IAAI,SAAA;AAEJ,IAAM,gBAAA,GAAmB,mBAAA;AAEzB,SAAS,iBAAA,GAA2C;AAClD,EAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,IAAA,SAAA,GAAY,OAAO,IAAA,KAAS,WAAA,IAAe,WAAA,IAAe,IAAA,GACtD,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,EAAW,EAAE,WAAA,EAAa,UAAA,EAAY,CAAA,GACzD,IAAA;AAAA,EACN;AACA,EAAA,OAAO,SAAA;AACT;AAOO,SAAS,aAAa,IAAA,EAAwB;AACnD,EAAA,MAAM,MAAgB,EAAC;AAGvB,EAAA,IAAI,CAAC,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA,EAAG;AAChC,IAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,IAAK,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK,GAAA,CAAI,KAAK,CAAC,CAAA;AACjD,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAM,iBAAA,EAAkB;AAC9B,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AACtE,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,KAAA,MAAW,MAAM,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,EAAA,IAAM,GAAG,MAAM,CAAA;AAC/C,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,cAAc,IAAA,EAAsB;AAClD,EAAA,OAAO,YAAA,CAAa,IAAI,CAAA,CAAE,MAAA;AAC5B;;;AC3BA,IAAM,eAAA,GAAkB,mBAAA;AA6CjB,SAAS,WAAA,CAAY,MAA8B,OAAA,EAA0B;AAClF,EAAA,MAAM,UAAmB,EAAC;AAG1B,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,QAAA,GAAW,CAAA;AAEf,EAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,EAAK,QAAA,KAAa;AAC9B,IAAA,MAAM,WAAW,kBAAA,CAAmB,GAAA,CAAI,YAAY,GAAA,CAAI,UAAA,EAAY,IAAI,SAAS,CAAA;AACjF,IAAA,MAAM,OAAA,GAAU,UAAU,QAAQ,CAAA;AAClC,IAAA,IAAI,CAAC,OAAA,EAAS;AAGZ,MAAA,aAAA,CAAc,GAAA,CAAI,UAAA,EAAY,GAAA,CAAI,UAAA,EAAY,IAAI,SAAS,CAAA;AAC3D,MAAA,QAAA,IAAY,GAAA,CAAI,MAAA,EAAQ,MAAA,IAAU,GAAA,CAAI,IAAA,CAAK,MAAA;AAC3C,MAAA,IAAA,GAAO,MAAA;AACP,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,QAAA;AAChB,IAAA,MAAM,MAAM,GAAA,CAAI,MAAA;AAChB,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AACzC,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,IAAA,IAAI,KAAA,GAA8B,IAAA;AAClC,IAAA,IAAI,EAAA,GAAK,CAAA;AAET,IAAA,KAAA,MAAW,EAAA,IAAM,IAAI,IAAA,EAAM;AACzB,MAAA,MAAM,EAAA,GAAK,EAAA,CAAG,WAAA,CAAY,CAAC,CAAA;AAC3B,MAAA,MAAM,WAAW,GAAA,CAAI,OAAA,GAAU,IAAI,OAAA,CAAQ,EAAE,IAAI,GAAA,CAAI,QAAA;AACrD,MAAA,IAAI,OAAO,YAAA,EAAc;AACvB,QAAA,KAAA,GAAQ,mBAAA;AAAA,UACN,QAAA;AAAA,UAAU,GAAA,CAAI,UAAA;AAAA,UAAY,GAAA,CAAI,UAAA;AAAA,UAAY,GAAA,CAAI,SAAA;AAAA,UAAW,IAAI,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,WAAA,CAAY,OAAO,CAAC;AAAA,SAClG;AAAA,MACF;AACA,MAAA,MAAM,UAAA,GAAa,EAAA,GAAK,EAAA,CAAG,MAAA,KAAW,YAAY,OAAO,CAAA;AACzD,MAAA,IAAI,UAAA,EAAY,YAAA,GAAe,WAAA,CAAY,OAAA,EAAS,CAAA;AAGpD,MAAA,MAAM,QAAA,GAAW,UAAA,GAAa,GAAA,CAAI,aAAA,GAAgB,CAAA;AAGlD,MAAA,MAAM,WAAW,GAAA,GAAM,OAAA,GAAU,IAAI,MAAA,CAAO,EAAE,IAAI,OAAA,GAAU,EAAA;AAC5D,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,GAAU,GAAA,CAAI,KAAK,EAAE,CAAA,GAAI,OAAA,GAAU,EAAA,GAAK,EAAA,CAAG,MAAA;AAChE,MAAA,EAAA,IAAM,EAAA,CAAG,MAAA;AACT,MAAA,QAAA,GAAW,GAAA,GAAM,OAAA,GAAU,GAAA,CAAI,MAAA,GAAS,MAAA;AAExC,MAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,IAAA,CAAK,EAAE,CAAA;AACpC,MAAA,MAAM,aAAA,GAAgB,IAAA,IAAQ,CAAC,IAAA,GAC3B,KAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,EAAA,EAAI,EAAE,CAAA,IAAK,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,QAAQ,IAAA,CAAA,GACjE,CAAA;AAGJ,MAAA,MAAM,KAAA,GAAe;AAAA,QACnB,GAAA,EAAK,QAAA;AAAA,QAAU,EAAA;AAAA,QAAI,QAAA;AAAA,QACnB,UAAU,IAAA,CAAK,GAAA,CAAI,IAAI,QAAA,EAAU,GAAA,CAAI,aAAa,CAAC,CAAA;AAAA;AAAA,QAEnD,aAAA,EAAe,IAAI,aAAA,IAAiB,CAAA;AAAA,QACpC,QAAA,EAAU,QAAA;AAAA,QAAU,MAAA;AAAA,QAAQ,UAAA;AAAA,QAC5B,QAAA;AAAA,QAAU,OAAA;AAAA,QAAS,IAAA,EAAM,IAAA;AAAA,QAAM,KAAA,EAAO,IAAA;AAAA,QACtC,OAAA,EAAS,CAAA;AAAA,QAAG,QAAA,EAAU,CAAA;AAAA,QAAG,aAAA,EAAe,CAAA;AAAA,QAAG,QAAA,EAAU;AAAA,OACvD;AAEA,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,OAAA,CAAQ,IAAA,CAAK,aAAa,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA,EAAG,QAAQ,IAAI,KAAK,CAAA;AAChE,QAAA,IAAA,GAAO,MAAA;AAAA,MACT,CAAA,MAAA,IAAW,eAAA,CAAgB,EAAE,CAAA,EAAG;AAC9B,QAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAClB,QAAA,IAAA,GAAO,MAAA;AAAA,MACT,CAAA,MAAA,IAAW,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,EAAA,EAAI;AAEhC,QAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,SAAA,CAAU,EAAE,CAAA;AAClC,QAAA,MAAM,UAAU,KAAA,KAAU,IAAA,GAAO,SAAS,QAAA,GAAW,OAAA,CAAQ,QAAQ,QAAA,GAAW,IAAA;AAChF,QAAA,IAAI,OAAO,CAAA,EAAG;AACZ,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,GAAG,KAAA,EAAO,KAAK,EAAE,IAAA,EAAM,OAAA,IAAW,OAAA,GAAU,IAAI,aAAA,CAAA,EAAgB,GAAA,EAAK,OAAA,GAAU,CAAA,IAAK,CAAA;AACnG,UAAA,IAAA,GAAO,MAAA;AAAA,QACT,CAAA,MAAO;AAGL,UAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA;AAChC,UAAA,KAAA,CAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,IAAA;AAC1B,UAAA,KAAA,CAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,IAAA;AAC5B,UAAA,KAAA,CAAM,OAAA,GAAU,OAAA;AAChB,UAAA,KAAA,CAAM,QAAA,GAAW,QAAA;AACjB,UAAA,KAAA,CAAM,aAAA,GAAgB,aAAA;AACtB,UAAA,IAAA,GAAO,KAAA;AACP,UAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,QACnB;AAAA,MACF,CAAA,MAAO;AACL,QAAA,MAAM,GAAA,GAAM,aAAa,QAAA,EAAU,GAAA,CAAI,YAAY,GAAA,CAAI,UAAA,EAAY,GAAA,CAAI,SAAA,EAAW,EAAE,CAAA;AACpF,QAAA,MAAM,QAAQ,GAAA,GAAM,GAAA,CAAI,OAAO,GAAA,EAAK,aAAA,EAAe,QAAQ,CAAA,GAAI,KAAA;AAC/D,QAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAClB,QAAA,IAAI,CAAC,MAAM,IAAA,GAAO,KAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,OAAA;AACT;AAIA,SAAS,GAAA,CAAI,CAAA,EAAU,GAAA,EAAoB,OAAA,EAAiB,QAAA,EAAyB;AACnF,EAAA,CAAA,CAAE,WAAW,GAAA,CAAI,QAAA;AACjB,EAAA,CAAA,CAAE,UAAU,GAAA,CAAI,OAAA;AAChB,EAAA,CAAA,CAAE,OAAO,GAAA,CAAI,IAAA;AACb,EAAA,CAAA,CAAE,QAAQ,GAAA,CAAI,KAAA;AACd,EAAA,CAAA,CAAE,UAAU,GAAA,CAAI,OAAA,IAAW,CAAA,CAAE,QAAA,GAAW,IAAI,OAAA,CAAQ,IAAA,CAAA;AACpD,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,CAAA,CAAE,aAAA,GAAgB,OAAA;AAClB,EAAA,CAAA,CAAE,QAAA,GAAW,IAAA;AACb,EAAA,OAAO,CAAA;AACT;AAUO,SAAS,aAAA,CACd,OAAA,EACA,MAAA,EACA,MAAA,EACA,IAAA,EACS;AACT,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,EAAO,GAAA,KAAQ;AACjC,IAAA,IAAI,MAAA,CAAO,GAAG,CAAA,GAAI,CAAA,KAAM,GAAG,OAAO,KAAA;AAClC,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,KAAA,CAAM,EAAE,CAAA;AAC1B,IAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,KAAA,CAAM,IAAI,OAAO,KAAA;AAC3C,IAAA,IAAI,MAAM,IAAA,KAAS,IAAA,SAAa,EAAE,GAAG,OAAO,EAAA,EAAG;AAC/C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC1B,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,KAAA,CAAM,QAAA,EAAU,GAAA,CAAI,UAAA,EAAY,GAAA,CAAI,UAAA,EAAY,GAAA,CAAI,SAAA,EAAW,EAAA,EAAI,KAAK,CAAA;AACjG,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AACjB,IAAA,OAAO,EAAE,GAAG,KAAA,EAAO,EAAA,EAAI,UAAU,GAAA,CAAI,QAAA,EAAU,OAAA,EAAS,GAAA,CAAI,SAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,KAAA,EAAO,IAAI,KAAA,EAAM;AAAA,EACxG,CAAC,CAAA;AACH;;;ACrLO,IAAM,KAAA,GAAQ,CAAC,EAAA,KAAwB,EAAA,KAAO,MAAM,EAAA,KAAO;AAc3D,SAAS,SAAA,CACd,GAAA,EACA,QAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,IAAI,GAAA,CAAI,MAAA;AACd,EAAA,MAAM,SAAS,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,GAAI,sBAAA,CAAuB,GAAG,CAAA,GAAI,IAAA;AACzE,EAAA,MAAM,QAAuB,EAAC;AAC9B,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,IAAI,CAAA,EAAG;AACZ,IAAA,MAAM,EAAA,GAAK,IAAI,CAAC,CAAA;AAChB,IAAA,IAAI,eAAA,CAAgB,EAAE,CAAA,EAAG;AACvB,MAAA,KAAA,CAAM,KAAK,EAAE,KAAA,EAAO,KAAK,CAAA,EAAG,OAAA,EAAS,OAAO,CAAA;AAC5C,MAAA,CAAA,IAAK,OAAO,EAAA,IAAM,GAAA,CAAI,IAAI,CAAC,CAAA,KAAM,KAAK,CAAA,GAAI,CAAA;AAC1C,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AAAE,MAAA,CAAA,EAAA;AAAK,MAAA;AAAA,IAAU;AAChC,IAAA,IAAI,IAAI,CAAA,GAAI,CAAA;AACZ,IAAA,IAAIe,OAAM,CAAA,GAAI,CAAA;AACd,IAAA,OAAO,CAAA,GAAI,CAAA,IAAK,CAAC,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAC,CAAA,KAAM,CAAC,MAAA,IAAU,MAAA,CAAO,CAAC,MAAM,QAAA,CAAA,EAAW;AAC/E,MAAA,IAAI,CAAC,MAAM,GAAA,CAAI,CAAC,CAAC,CAAA,EAAGA,OAAM,CAAA,GAAI,CAAA;AAC9B,MAAA,CAAA,EAAA;AAAA,IACF;AACA,IAAA,IAAI,UAAU,CAAA,GAAI,KAAA,IAAS,QAAQ,KAAA,EAAOA,IAAG,IAAI,QAAA,EAAU;AACzD,MAAA,KAAA,CAAM,KAAK,EAAE,KAAA,EAAO,KAAK,CAAA,EAAG,OAAA,EAAS,MAAM,CAAA;AAC3C,MAAA,KAAA,GAAQ,CAAA;AAAA,IACV;AACA,IAAA,CAAA,GAAI,CAAA;AAAA,EACN;AACA,EAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,EAAE,OAAO,GAAA,EAAK,CAAA,EAAG,OAAA,EAAS,KAAA,EAAO,CAAA;AAC3D,EAAA,OAAO,KAAA;AACT;;;ACjCA,SAAS,aAAA,CAAc,GAAU,UAAA,EAA4B;AAC3D,EAAA,MAAM,CAAA,GAAI,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,OAAA,CAAQ,IAAA;AACjC,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,CAAA;AAClC,EAAA,IAAI,CAAA,CAAE,OAAA,CAAQ,OAAA,KAAY,MAAA,EAAW,OAAO,MAAA;AAC5C,EAAA,OAAA,CAAQ,CAAA,CAAE,WAAW,UAAA,GAAa,MAAA,GAAS,EAAE,OAAA,CAAQ,OAAA,GAAU,KAAK,CAAA,GAAI,MAAA;AAC1E;AAUO,SAAS,UAAA,CACd,OAAA,EACA,QAAA,EACA,UAAA,EACQ;AAER,EAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,OAAA,CAAQ,SAAS,CAAC,CAAA;AAC/C,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACxB,IAAA,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,GAAI,GAAA,CAAI,CAAC,IAAI,CAAA,CAAE,aAAA,GAAgB,CAAA,CAAE,OAAA,GAAU,CAAA,CAAE,QAAA;AACtD,IAAA,IAAI,CAAA,CAAE,GAAA,EAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAAA,EACxB,CAAC,CAAA;AAED,EAAA,MAAM,YAAY,CAAC,KAAA,EAAe,GAAA,KAChC,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA,GAAU,OAAA,CAAQ,KAAK,EAAE,QAAA,GAAW,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAC,CAAA;AAC7E,EAAA,MAAM,UAAU,IAAA,CAAK,MAAA,KAAW,IAAI,SAAA,GAAY,CAAC,OAAe,GAAA,KAC9D,aAAA,CAAc,KAAA,EAAO,GAAA,EAAK,MAAM,CAAC,CAAA,KAAM,QAAQ,CAAC,CAAA,CAAE,KAAM,SAAS,CAAA;AAEnE,EAAA,OAAO,SAAA,CAAU,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAA,EAAG,QAAA,EAAU,OAAO,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAe;AAChF,IAAA,MAAM,IAAA,GAAa;AAAA,MACjB,OAAO,IAAA,CAAK,KAAA;AAAA,MAAO,SAAS,EAAC;AAAA,MAAG,KAAA,EAAO,CAAA;AAAA,MAAG,MAAA,EAAQ,CAAA;AAAA,MAAG,MAAA,EAAQ,CAAA;AAAA,MAC7D,SAAS,IAAA,CAAK,OAAA;AAAA,MAAS,MAAA,EAAQ;AAAA,KACjC;AACA,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,IAAA,CAAK,GAAA,EAAK;AAC3B,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA;AAC5B,MAAA,IAAA,CAAK,MAAA,GAAS,IAAI,QAAA,GAAW,UAAA;AAC7B,MAAA,IAAA,CAAK,MAAA,GAAS,aAAA,CAAc,GAAA,EAAK,UAAU,CAAA;AAC3C,MAAA,IAAA,CAAK,SAAS,GAAA,CAAI,QAAA;AAClB,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,KAAA,IAAS,IAAI,IAAA,CAAK,KAAA,EAAO,CAAA,GAAI,IAAA,CAAK,KAAK,CAAA,EAAA,EAAK;AAC1C,MAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,MAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,KAAA,GAAQ,IAAI,EAAE,GAAG,CAAA,EAAG,aAAA,EAAe,CAAA,EAAE;AAC7D,MAAA,MAAM,SAAS,CAAA,CAAE,GAAA,GACb,EAAE,GAAG,QAAQ,OAAA,EAAS,UAAA,CAAW,IAAA,CAAK,KAAA,EAAO,EAAE,GAAA,CAAI,IAAA,EAAM,EAAE,GAAA,CAAI,GAAG,GAAE,GACpE,MAAA;AACJ,MAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,MAAM,CAAA;AACxB,MAAA,IAAA,CAAK,KAAA,IAAS,MAAA,CAAO,aAAA,GAAgB,MAAA,CAAO,UAAU,MAAA,CAAO,QAAA;AAC7D,MAAA,IAAA,CAAK,SAAS,IAAA,CAAK,GAAA,CAAI,KAAK,MAAA,EAAQ,CAAA,CAAE,WAAW,UAAU,CAAA;AAC3D,MAAA,IAAA,CAAK,MAAA,GAAS,KAAK,GAAA,CAAI,IAAA,CAAK,QAAQ,aAAA,CAAc,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,IACvE;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,OAAA,CAAQ,IAAA,CAAK,GAAA,GAAM,CAAC,CAAA,CAAE,MAAA;AACpC,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACH;AAIA,SAAS,UAAU,OAAA,EAAmC;AACpD,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,CAAA,IAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,CAAA,EAAA,EAAK;AACpE,IAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,IAAA,IAAA,IAAQ,CAAA,CAAE,aAAA,GAAgB,CAAA,CAAE,OAAA,GAAU,CAAA,CAAE,QAAA;AAAA,EAC1C;AACA,EAAA,OAAO,IAAA;AACT;AAIA,SAAS,SAAS,OAAA,EAAwC;AACxD,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,OAAO,QAAQ,OAAA,CAAQ,MAAA,IAAU,QAAQ,KAAK,CAAA,CAAE,OAAO,EAAA,EAAI,KAAA,EAAA;AAC3D,EAAA,IAAI,IAAA,GAAO,QAAQ,MAAA,GAAS,CAAA;AAC5B,EAAA,OAAO,OAAO,KAAA,IAAS,OAAA,CAAQ,IAAI,CAAA,CAAE,OAAO,EAAA,EAAI,IAAA,EAAA;AAChD,EAAA,KAAA,IAAS,CAAA,GAAI,KAAA,GAAQ,CAAA,EAAG,CAAA,GAAI,MAAM,CAAA,EAAA,EAAK,IAAI,OAAA,CAAQ,CAAC,CAAA,CAAE,EAAA,KAAO,EAAA,EAAI,IAAA,CAAK,IAAI,CAAC,CAAA;AAC3E,EAAA,OAAO,IAAA;AACT;AAIA,SAAS,WAAA,CAAY,KAAA,EAAoC,UAAA,EAAoB,QAAA,EAA0B;AACrG,EAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,CAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,UAAU,CAAA,EAAG,OAAO,KAAA,KAAU,QAAA,GAAW,CAAC,QAAA,GAAW,CAAA,GAAI,CAAC,QAAA;AAC/E,EAAA,MAAM,QAAQ,UAAA,GAAa,QAAA;AAC3B,EAAA,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,CAAA,GAAI,KAAA;AAC1C;AAeO,SAAS,UACd,IAAA,EACA,CAAA,EACA,KAAA,EACA,KAAA,EACA,YACA,OAAA,EACY;AACZ,EAAA,MAAM,EAAE,SAAQ,GAAI,IAAA;AACpB,EAAA,MAAM,IAAA,GAAO,UAAU,OAAO,CAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,KAAK,KAAA,GAAQ,IAAA;AAC9B,EAAA,MAAM,QAAQ,UAAA,GAAa,QAAA;AAC3B,EAAA,MAAM,IAAA,GAAO,OAAA,IAAW,IAAA,CAAK,OAAA,IAAW,OAAO,QAAA,CAAS,UAAU,CAAA,IAAK,KAAA,GAAQ,CAAA,GAC3E,QAAA,CAAS,OAAO,CAAA,uBACZ,GAAA,EAAY;AACpB,EAAA,MAAM,WAAW,IAAA,CAAK,IAAA,GAAO,CAAA,GAAI,KAAA,GAAQ,KAAK,IAAA,GAAO,CAAA;AACrD,EAAA,MAAM,MAAA,GAAS,WAAW,IAAA,CAAK,IAAA;AAC/B,EAAA,MAAM,UAAU,MAAA,GAAS,CAAA,GAAI,IAAI,WAAA,CAAY,KAAA,EAAO,YAAY,QAAQ,CAAA;AAGxE,EAAA,MAAM,SAAA,GAAY,OAAO,CAAA,IAAK,KAAA,CAAM,OAAO,OAAA,CAAQ,MAAA,GAAS,CAAC,CAAA,GAAI,CAAA,KAAM,CAAA;AACvE,EAAA,MAAM,IAAA,GAAO,SAAA,GAAY,OAAA,GAAU,IAAA,GAAO,OAAA;AAC1C,EAAA,MAAM,aAAA,GAAgB,IAAI,IAAA,CAAK,MAAA;AAE/B,EAAA,MAAM,KAAA,GAAuB,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA;AACrD,EAAA,MAAM,SAAwB,EAAC;AAC/B,EAAA,IAAI,IAAA,GAAO,IAAA;AACX,EAAA,IAAI,OAAA,GAAU,EAAA;AACd,EAAA,KAAA,MAAW,GAAA,IAAO,MAAM,MAAA,EAAQ;AAC9B,IAAA,MAAM,CAAA,GAAI,QAAQ,GAAG,CAAA;AAKrB,IAAA,IAAA,IAAQ,OAAA,GAAU,CAAA,GAAI,CAAA,GAClB,GAAA,KAAQ,UAAU,CAAA,GAAI,CAAA,CAAE,aAAA,GACxB,OAAA,KAAY,GAAA,GAAM,CAAA,GAAI,OAAA,CAAQ,OAAO,EAAE,aAAA,GACvC,CAAA;AACJ,IAAA,OAAA,GAAU,GAAA;AACV,IAAA,MAAM,IAAA,GAAO,EAAE,OAAA,GAAU,CAAA,CAAE,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,QAAA,GAAW,CAAA,CAAA;AAClE,IAAA,KAAA,CAAM,GAAG,CAAA,GAAI;AAAA,MACX,UAAU,CAAA,CAAE,QAAA;AAAA,MAAU,QAAQ,CAAA,CAAE,MAAA;AAAA,MAAQ,IAAI,CAAA,CAAE,EAAA;AAAA,MAAI,CAAA,EAAG,IAAA;AAAA,MACrD,OAAA,EAAS,IAAA;AAAA,MAAM,KAAA,EAAO,KAAA,CAAM,MAAA,CAAO,GAAG,CAAA;AAAA,MACtC,UAAU,CAAA,CAAE,QAAA;AAAA,MAAU,YAAY,CAAA,CAAE;AAAA,KACtC;AACA,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,KAAK,CAAA,CAAE,GAAA;AAAA,MAAK,IAAI,CAAA,CAAE,EAAA;AAAA,MAAI,UAAU,CAAA,CAAE,QAAA;AAAA,MAClC,UAAU,CAAA,CAAE,QAAA;AAAA,MAAU,SAAS,CAAA,CAAE,OAAA;AAAA,MAAS,MAAM,CAAA,CAAE,IAAA;AAAA,MAAM,OAAO,CAAA,CAAE,KAAA;AAAA,MACjE,CAAA,EAAG,IAAA;AAAA;AAAA,MAEH,SAAA,EAAW,gBAAgB,CAAA,CAAE,aAAA;AAAA,MAC7B,SAAS,CAAA,CAAE,OAAA;AAAA,MAAS;AAAA,KACrB,CAAA;AACD,IAAA,IAAA,IAAQ,IAAA;AAAA,EACV;AAEA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK;AAAA,MACH,EAAA,EAAI,IAAA;AAAA,MAAM,EAAA,EAAI,CAAA;AAAA,MAAG,EAAA,EAAI,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,MAAA;AAAA,MAAQ,EAAA,EAAI,IAAI,IAAA,CAAK,MAAA;AAAA,MAC9D,SAAA,EAAW,aAAA;AAAA,MAAe,KAAA;AAAA,MAAO,MAAA;AAAA,MAAQ,QAAQ,IAAA,CAAK,MAAA;AAAA,MAAQ,WAAW,MAAA,GAAS;AAAA,KACpF;AAAA,IACA,UAAU,QAAA,GAAW;AAAA,GACvB;AACF;;;AC1IO,SAAS,kBAAkB,IAAA,EAA0C;AAC1E,EAAA,OAAO;AAAA,IACL,UAAU,IAAA,CAAK,QAAA;AAAA,IACf,UAAA,EAAY,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,QAAA;AAAA,IACpC,YAAY,IAAA,CAAK,UAAA;AAAA,IACjB,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,OAAA,EAAS,IAAA,CAAK,OAAA,KAAY,IAAA,IAAQ,KAAK,KAAA,KAAU,SAAA;AAAA,IACjD,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,cAAA,EAAe;AAAA,IAClC,SAAA,EAAW,KAAK,SAAA,IAAa,MAAA;AAAA,IAC7B,OAAA,EAAS,KAAK,OAAA,IAAW;AAAA,GAC3B;AACF;;;ACoGO,SAAS,UAAA,CACd,MACA,IAAA,EACa;AACb,EAAA,MAAM,CAAA,GAAI,kBAAkB,IAAI,CAAA;AAChC,EAAA,MAAM,OAAA,GAAU,WAAA,CAAY,IAAA,EAAM,CAAA,CAAE,OAAO,CAAA;AAC3C,EAAA,MAAM,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AACnC,EAAA,MAAM,EAAE,MAAK,GAAI,CAAA;AAGjB,EAAA,MAAM,UAAA,GAAa,IAAA,GACf,iBAAA,CAAkB,IAAA,EAAM,KAAK,CAAC,CAAA,KAAM,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,GACxE,IAAA;AACJ,EAAA,IAAI,CAAC,IAAA,EAAM,oBAAA,CAAqB,GAAG,CAAA;AAEnC,EAAA,MAAM,QAA0B,EAAC;AACjC,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,QAAQ,UAAA,CAAW,OAAA,EAAS,EAAE,QAAA,EAAU,CAAA,CAAE,UAAU,CAAA,EAAG;AAChE,IAAA,MAAM,QAAQ,SAAA,CAAU,UAAA,EAAY,KAAK,KAAA,EAAO,IAAA,CAAK,QAAQ,MAAM,CAAA;AAGnE,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,OAAA,GAAU,aAAA,CAAc,KAAK,OAAA,EAAS,KAAA,CAAM,MAAA,EAAQ,CAAC,EAAA,KAAO,IAAA,CAAK,MAAA,CAAO,EAAE,GAAG,IAAI,CAAA;AAChG,IAAA,MAAM,QAAQ,CAAA,CAAE,SAAA,KAAc,MAAA,GAAS,CAAA,CAAE,YACrC,gBAAA,CAAiB,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,IAAI,UAAA,EAAY,SAAA,CAAU,KAAK,KAAK,CAAA,IAAK,IAAI,CAAC,CAAA;AACzF,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,YAAA,CAAa,CAAA,CAAE,KAAA,EAAO,KAAK,CAAA,EAAG,CAAA,CAAE,UAAA,EAAY,EAAE,OAAO,CAAA;AAC9F,IAAA,KAAA,CAAM,IAAA,CAAK,OAAO,GAAG,CAAA;AACrB,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,MAAA,CAAO,QAAQ,CAAA;AACvC,IAAA,CAAA,IAAK,IAAA,CAAK,MAAA;AAAA,EACZ;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,EAAE,KAAA,EAAO,MAAA,EAAQ,GAAE,EAAE;AAC/C;;;AChNA,IAAI,SAAA,GAAY,CAAA;AAChB,IAAM,MAAA,uBAAa,OAAA,EAAwB;AAGpC,SAAS,MAAM,CAAA,EAAmB;AACvC,EAAA,IAAI,EAAA,GAAK,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA;AACrB,EAAA,IAAI,OAAO,MAAA,EAAW;AACpB,IAAA,EAAA,GAAK,SAAA,EAAA;AACL,IAAA,MAAA,CAAO,GAAA,CAAI,GAAG,EAAE,CAAA;AAAA,EAClB;AACA,EAAA,OAAO,EAAA;AACT;;;ACmDO,IAAM,0BAAA,GAA6B;AAInC,IAAM,6BAAA,GAAgC;AAQ7C,IAAI,KAAA,uBAAY,OAAA,EAAuC;AACvD,IAAI,UAAA,uBAAiB,GAAA,EAAyB;AAC9C,IAAI,oBAAA,GAAuB,EAAA;AAE3B,SAAS,WAAW,IAAA,EAA8B;AAChD,EAAA,MAAM,CAAA,GAAI,kBAAkB,IAAI,CAAA;AAChC,EAAA,OAAO,CAAA,EAAG,CAAA,CAAE,QAAQ,CAAA,CAAA,EAAI,CAAA,CAAE,UAAU,CAAA,CAAA,EAAI,CAAA,CAAE,UAAU,CAAA,CAAA,EAAI,CAAA,CAAE,KAAK,IAAI,CAAA,CAAE,OAAA,GAAU,GAAA,GAAM,EAAE,CAAA,CAAA,EAC/E,CAAA,CAAE,SAAS,CAAA,CAAA,EAAI,CAAA,CAAE,IAAA,GAAO,KAAA,CAAM,CAAA,CAAE,IAAI,CAAA,GAAI,EAAE,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AACjE;AAOA,SAAS,QAAQ,IAAA,EAAsC;AACrD,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,GAAA,IAAO,CAAA,EAAG,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,UAAA,CAAW,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,UAAU,CAAA,CAAA,EAChE,CAAA,CAAE,QAAQ,CAAA,CAAA,EAAI,CAAA,CAAE,UAAU,CAAA,CAAA,EAAI,CAAA,CAAE,SAAS,CAAA,CAAA,EAAI,CAAA,CAAE,aAAa,CAAA,CAAA,EAC5D,CAAA,CAAE,aAAa,CAAA,CAAA,EAAI,CAAA,CAAE,SAAA,IAAa,EAAE,CAAA,CAAA,EAEpC,CAAA,CAAE,MAAA,GAAS,CAAA,EAAG,CAAA,CAAE,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,EACjE,CAAA,CAAE,OAAA,GAAU,CAAA,CAAE,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,GAAI,EAAE,CAAA,CAAA,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,GAAA;AACT;AAWO,SAAS,gBAAA,CACd,MACA,IAAA,EACa;AACb,EAAA,MAAM,QAAQ,cAAA,EAAe;AAC7B,EAAA,IAAI,KAAA,GAAQ,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAC1B,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,KAAA,GAAQ,EAAE,UAAA,EAAY,KAAA,EAAO,SAAA,kBAAW,IAAI,KAAI,EAAE;AAClD,IAAA,KAAA,CAAM,GAAA,CAAI,MAAM,KAAK,CAAA;AAAA,EACvB,CAAA,MAAA,IAAW,KAAA,CAAM,UAAA,KAAe,KAAA,EAAO;AACrC,IAAA,KAAA,CAAM,UAAA,GAAa,KAAA;AACnB,IAAA,KAAA,CAAM,UAAU,KAAA,EAAM;AAAA,EACxB;AAEA,EAAA,MAAM,GAAA,GAAM,WAAW,IAAI,CAAA;AAC3B,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,SAAA,CAAU,GAAA,CAAI,GAAG,CAAA;AACnC,EAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,GAAA;AAE9B,EAAA,IAAI,yBAAyB,KAAA,EAAO;AAClC,IAAA,UAAA,CAAW,KAAA,EAAM;AACjB,IAAA,oBAAA,GAAuB,KAAA;AAAA,EACzB;AACA,EAAA,MAAM,cAAc,CAAA,EAAG,OAAA,CAAQ,IAAI,CAAC,KAAK,GAAG,CAAA,CAAA;AAC5C,EAAA,IAAI,IAAA,GAAO,UAAA,CAAW,GAAA,CAAI,WAAW,CAAA;AACrC,EAAA,IAAI,SAAS,MAAA,EAAW;AAGtB,IAAA,UAAA,CAAW,OAAO,WAAW,CAAA;AAAA,EAC/B,CAAA,MAAO;AACL,IAAA,IAAA,GAAO,UAAA,CAAW,MAAM,IAAI,CAAA;AAC5B,IAAA,IAAI,UAAA,CAAW,QAAQ,6BAAA,EAA+B;AACpD,MAAA,UAAA,CAAW,OAAO,UAAA,CAAW,IAAA,EAAK,CAAE,IAAA,GAAO,KAAM,CAAA;AAAA,IACnD;AAAA,EACF;AACA,EAAA,UAAA,CAAW,GAAA,CAAI,aAAa,IAAI,CAAA;AAEhC,EAAA,IAAI,MAAM,SAAA,CAAU,IAAA,IAAQ,0BAAA,EAA4B,KAAA,CAAM,UAAU,KAAA,EAAM;AAC9E,EAAA,KAAA,CAAM,SAAA,CAAU,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAC7B,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,yBAAA,GAAkC;AAChD,EAAA,KAAA,uBAAY,OAAA,EAAQ;AACpB,EAAA,UAAA,uBAAiB,GAAA,EAAI;AACrB,EAAA,oBAAA,GAAuB,EAAA;AACzB","file":"chunk-JOVZEHBJ.js","sourcesContent":["/**\n * Tab stops, CSS `tab-size`'s way: a tab runs from where it starts on its line\n * to the next multiple of the stop interval, so its advance is known only once\n * the line it lands on is.\n */\n\n/** CSS `tab-size`'s initial value, in spaces. */\nexport const DEFAULT_TAB_SIZE = 8;\n\n/** A tab's stop interval and the least it may advance, both in world units. */\nexport interface TabStop {\n stop: number;\n /** Half a space: CSS skips a stop nearer than that to the following one. */\n min: number;\n}\n\n/** How far a tab starting `x` into its line advances. */\nexport function tabAdvance(x: number, stop: number, min: number): number {\n if (!(stop > 0)) return 0;\n const toNext = (Math.floor(x / stop) + 1) * stop - x;\n return toNext < min ? toNext + stop : toNext;\n}\n\n/**\n * Width of entries `[start, end)` set on a line opening at `start`, with each\n * tab among them (`tabs`, ascending entry indices) run out to its stop.\n * `flatWidth` is the same measure with every tab taken as zero-width. `piece`\n * hears each stretch between tabs and the x it starts at.\n */\nexport function widthWithTabs(\n start: number,\n end: number,\n tabs: readonly number[],\n stopOf: (index: number) => TabStop,\n flatWidth: (start: number, end: number) => number,\n piece?: (start: number, end: number, x: number) => void,\n): number {\n let x = 0;\n let from = start;\n const lay = (to: number): void => {\n if (to <= from) return;\n piece?.(from, to, x);\n x += flatWidth(from, to);\n };\n for (const t of tabs) {\n if (t < start) continue;\n if (t >= end) break;\n lay(t);\n const { stop, min } = stopOf(t);\n x += tabAdvance(x, stop, min);\n from = t + 1;\n }\n lay(end);\n return x;\n}\n","/**\n * Typography for `TextPose` and friends. Defaults live in\n * `DEFAULT_TEXT_STYLE` and are applied at render/measure time, never written\n * back to the pose.\n *\n * Paint does not live here. A text node carries its fill and stroke in\n * `data.fill` / `data.stroke`, the slots every other node kind uses.\n */\n\nimport type { Paint, ScreenLength, Stroke, Fill } from '@weasel-js/paint';\nimport { isSolidPaint, resolveScreenLength } from '@weasel-js/paint';\nimport { cssFamilyName } from '@weasel-js/font';\nimport type { TextTransform } from './runs/textTransform';\nimport type { FontVariantCaps } from './runs/smallCaps';\nimport { DEFAULT_TAB_SIZE } from './layout/tabStops';\n\n/**\n * Horizontal alignment. `start` / `end` resolve against the reading direction;\n * `left` / `right` are absolute. `justify` spreads every wrapped line across\n * the box by widening its word gaps, and sets a paragraph's last line at the\n * start edge. The same values as CSS `text-align`, with the same meanings.\n */\nexport type TextAlign = 'left' | 'center' | 'right' | 'start' | 'end' | 'justify';\n\n/** Reading direction, which is what gives `start` / `end` their meaning. */\nexport type TextDirection = 'ltr' | 'rtl';\n\n/**\n * Collapse a possibly reading-order-relative alignment to an absolute edge.\n * `justify` collapses to the start edge, which is where it sets every line it\n * does not spread; whether to spread is carried separately, as\n * `LayoutRunsOpts.justify`.\n */\nexport function resolveAlign(\n align: TextAlign,\n direction: TextDirection,\n): 'left' | 'center' | 'right' {\n if (align === 'start' || align === 'justify') return direction === 'rtl' ? 'right' : 'left';\n if (align === 'end') return direction === 'rtl' ? 'left' : 'right';\n return align;\n}\n\n/** User-facing text style. All fields optional; defaults applied at render time via `resolveTextStyle`. */\nexport interface TextStyle {\n /**\n * World units, or `{ px }` for screen pixels — resolved against the view\n * scale passed to {@link resolveTextStyle}, so a label pinned this way\n * stays the same size on screen as the view zooms. Default 16.\n */\n fontSize?: ScreenLength;\n /** Default `'sans-serif'`. */\n fontFamily?: string;\n /** Default 400. */\n fontWeight?: number | string;\n /** Default `'normal'`. */\n fontStyle?: 'normal' | 'italic';\n /** Default `'left'`. Pass `'start'` to align by reading order instead. */\n align?: TextAlign;\n /**\n * Reading direction: the base direction of bidi reordering, and what\n * `align: 'start' | 'end'` resolve against. Default `'auto'`, each\n * paragraph's own first strong character.\n */\n direction?: TextDirection | 'auto';\n /** Multiplier applied to `fontSize`. Default 1.2. */\n lineHeight?: number;\n /** Distance between tab stops, in spaces, as CSS `tab-size`. Default 8. */\n tabSize?: number;\n /**\n * Break lines where they would pass the box width, at the break\n * opportunities of Unicode's line breaking algorithm (UAX #14) — between\n * words, after a hyphen, between CJK characters. Default\n * `false`: a line runs as long as its text, and the box width only resolves\n * `align`. A word longer than the box is never broken.\n */\n wrap?: boolean;\n /**\n * Caret color used by the edit overlay. Defaults to the node's fill when\n * that fill is solid; falls back to `#000` for non-solid paints.\n */\n caretColor?: string;\n /**\n * Selection background color used by the edit overlay's `::selection`\n * pseudo-element. Defaults to a 25%-opacity tint of `caretColor` via CSS\n * `color-mix`. Pass `'none'` to fall back to the browser-native highlight.\n */\n selectionBackground?: string;\n /** Selection text color paired with `selectionBackground`. Default: inherits text color. */\n selectionColor?: string;\n /** Extra advance added after each glyph. World units, or `{ px }` for\n * screen pixels, like {@link TextStyle.fontSize}. Default 0. */\n letterSpacing?: ScreenLength;\n /** Default `false`. */\n underline?: boolean;\n /** Default `false`. */\n strikethrough?: boolean;\n /** Default `false`. */\n overline?: boolean;\n /** CSS `text-transform` for display; the text itself is not rewritten.\n * Default `'none'`. */\n textTransform?: TextTransform;\n /** `'small-caps'` draws lowercase as smaller capitals; the text itself is\n * not rewritten. Default `'normal'`. */\n fontVariantCaps?: FontVariantCaps;\n /**\n * Set the node's text as a superscript or subscript — the default every run\n * inherits. The lines keep the height and baseline the unscripted text would\n * have had. Absent is ordinary text.\n */\n script?: 'super' | 'sub';\n}\n\n/** `TextStyle` with all fields filled in from defaults — what the renderer actually consumes. */\nexport interface ResolvedTextStyle {\n fontSize: number;\n fontFamily: string;\n fontWeight: number | string;\n fontStyle: 'normal' | 'italic';\n /** Still relative if the author wrote it that way — `direction` resolves it. */\n align: TextAlign;\n direction: TextDirection | 'auto';\n lineHeight: number;\n tabSize: number;\n wrap: boolean;\n /** `null` is an explicit no-fill, the way it is on every other node kind:\n * outline-only text, painted by its stroke alone. */\n fill: Fill | null;\n caretColor: string;\n selectionBackground: string | null;\n selectionColor: string | null;\n letterSpacing: number;\n underline: boolean;\n strikethrough: boolean;\n overline: boolean;\n textTransform: TextTransform;\n fontVariantCaps: FontVariantCaps;\n /** Absent is ordinary text. */\n script?: 'super' | 'sub';\n /** Absent means no outline — unlike the other fields, this one has no\n * default to fall back to. See {@link TextPaint.stroke}. */\n stroke?: Stroke;\n}\n\nconst DEFAULT_FILL: Paint = { kind: 'solid', color: '#000' };\n\nfunction paintColor(p: Paint | null): string {\n return isSolidPaint(p) ? p.color : '#000';\n}\n\nfunction defaultSelectionBackground(textColor: string): string {\n return `color-mix(in srgb, ${textColor} 25%, transparent)`;\n}\n\n/** Default resolved style used when a `TextPose` omits `style`. */\nexport const DEFAULT_TEXT_STYLE: ResolvedTextStyle = {\n fontSize: 16,\n fontFamily: 'sans-serif',\n fontWeight: 400,\n fontStyle: 'normal',\n align: 'left',\n direction: 'auto',\n lineHeight: 1.2,\n tabSize: DEFAULT_TAB_SIZE,\n wrap: false,\n fill: { paint: DEFAULT_FILL },\n caretColor: paintColor(DEFAULT_FILL),\n selectionBackground: defaultSelectionBackground(paintColor(DEFAULT_FILL)),\n selectionColor: null,\n letterSpacing: 0,\n underline: false,\n strikethrough: false,\n overline: false,\n textTransform: 'none',\n fontVariantCaps: 'normal',\n};\n\n/** The paint a text node hands its glyphs — `data.fill` and `data.stroke`. Runs inherit these when they name none of their own. */\nexport interface TextPaint {\n /** `null` is an explicit no-fill and absent takes the default black — the\n * reading every other node kind gives `data.fill`. Unfilled text paints\n * through its stroke and nothing else, so it needs one to be visible. */\n fill?: Fill | null;\n /**\n * Outline painted over the glyph fill. Absent means no outline.\n *\n * Only glyphs on the outline tier are stroked: below\n * `textOutlineMinScreenSize` a glyph is a sampled distance field with no\n * geometry to stroke, and it renders unstroked. `width` is in world units —\n * it does not scale with `fontSize`.\n */\n stroke?: Stroke | null;\n}\n\n/**\n * Fill in a partial `TextStyle` with defaults from `DEFAULT_TEXT_STYLE`,\n * taking the glyph paint from the node rather than from the style.\n *\n * `scale` is the view scale any `{ px }` size resolves against — the same\n * mean-of-the-axes factor `resolveStrokeWidth` takes.\n */\nexport function resolveTextStyle(\n style?: TextStyle,\n paint?: TextPaint,\n scale = 1,\n): ResolvedTextStyle {\n const fill = paint?.fill === undefined ? DEFAULT_TEXT_STYLE.fill : paint.fill;\n const stroke = paint?.stroke ?? undefined;\n if (!style) {\n return fill === DEFAULT_TEXT_STYLE.fill && stroke === undefined\n ? DEFAULT_TEXT_STYLE\n : {\n ...DEFAULT_TEXT_STYLE,\n fill,\n caretColor: paintColor((fill?.paint ?? null)),\n selectionBackground: defaultSelectionBackground(paintColor((fill?.paint ?? null))),\n ...(stroke !== undefined ? { stroke } : {}),\n };\n }\n const caretColor = style.caretColor ?? paintColor((fill?.paint ?? null));\n let selectionBackground: string | null;\n if (style.selectionBackground === 'none') {\n selectionBackground = null;\n } else if (style.selectionBackground != null) {\n selectionBackground = style.selectionBackground;\n } else {\n selectionBackground = defaultSelectionBackground(caretColor);\n }\n return {\n fontSize: resolveScreenLength(style.fontSize ?? DEFAULT_TEXT_STYLE.fontSize, scale),\n fontFamily: style.fontFamily ?? DEFAULT_TEXT_STYLE.fontFamily,\n fontWeight: style.fontWeight ?? DEFAULT_TEXT_STYLE.fontWeight,\n fontStyle: style.fontStyle ?? DEFAULT_TEXT_STYLE.fontStyle,\n align: style.align ?? DEFAULT_TEXT_STYLE.align,\n direction: style.direction ?? DEFAULT_TEXT_STYLE.direction,\n lineHeight: style.lineHeight ?? DEFAULT_TEXT_STYLE.lineHeight,\n tabSize: style.tabSize ?? DEFAULT_TEXT_STYLE.tabSize,\n wrap: style.wrap ?? DEFAULT_TEXT_STYLE.wrap,\n fill,\n caretColor,\n selectionBackground,\n selectionColor: style.selectionColor ?? null,\n letterSpacing: resolveScreenLength(style.letterSpacing ?? DEFAULT_TEXT_STYLE.letterSpacing, scale),\n underline: style.underline ?? DEFAULT_TEXT_STYLE.underline,\n strikethrough: style.strikethrough ?? DEFAULT_TEXT_STYLE.strikethrough,\n overline: style.overline ?? DEFAULT_TEXT_STYLE.overline,\n textTransform: style.textTransform ?? DEFAULT_TEXT_STYLE.textTransform,\n fontVariantCaps: style.fontVariantCaps ?? DEFAULT_TEXT_STYLE.fontVariantCaps,\n ...(style.script !== undefined ? { script: style.script } : {}),\n ...(stroke !== undefined ? { stroke } : {}),\n };\n}\n\n/** Build a CSS `font` shorthand suitable for `ctx.font`. */\nexport function fontString(s: ResolvedTextStyle): string {\n return `${s.fontStyle} ${s.fontWeight} ${s.fontSize}px ${cssFamilyName(s.fontFamily)}`;\n}\n","/**\n * GENERATED FILE -- DO NOT EDIT BY HAND.\n *\n * Emitted by `packages/text/scripts/gen-line-break-table.mjs` from the\n * Unicode Character Database. Regenerate with `npm run gen:line-break-table`.\n */\n\n/** The Unicode release this table was generated from. */\nexport const UNICODE_VERSION = '16.0.0';\n\n// Line-breaking classes after UAX #14's LB1 resolution. QU_PI and QU_PF are\n// QU split by General_Category Pi and Pf.\nexport const BK = 0;\nexport const CR = 1;\nexport const LF = 2;\nexport const NL = 3;\nexport const SP = 4;\nexport const ZW = 5;\nexport const ZWJ = 6;\nexport const CM = 7;\nexport const WJ = 8;\nexport const GL = 9;\nexport const BA = 10;\nexport const BB = 11;\nexport const B2 = 12;\nexport const HY = 13;\nexport const CB = 14;\nexport const CL = 15;\nexport const CP = 16;\nexport const EX = 17;\nexport const IN = 18;\nexport const NS = 19;\nexport const OP = 20;\nexport const QU = 21;\nexport const IS = 22;\nexport const NU = 23;\nexport const PO = 24;\nexport const PR = 25;\nexport const SY = 26;\nexport const AL = 27;\nexport const HL = 28;\nexport const ID = 29;\nexport const EB = 30;\nexport const EM = 31;\nexport const H2 = 32;\nexport const H3 = 33;\nexport const JL = 34;\nexport const JV = 35;\nexport const JT = 36;\nexport const RI = 37;\nexport const AK = 38;\nexport const AP = 39;\nexport const AS = 40;\nexport const VF = 41;\nexport const VI = 42;\nexport const QU_PI = 43;\nexport const QU_PF = 44;\n\n/** Low bits of a {@link lineBreakPropsOf} value: the class. */\nexport const CLASS_MASK = 63;\n/** East_Asian_Width is F, W or H — UAX #14's `$EastAsian`. */\nexport const EAST_ASIAN = 64;\n/** Unassigned and Extended_Pictographic, for rule LB30b. */\nexport const PICTOGRAPHIC_CN = 128;\n\nconst ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+,-./:;<=>?@[]^_{|}~';\nconst PALETTE = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 71, 73, 74, 79, 81, 82, 83, 84, 88, 89, 91, 93, 94, 95, 96, 97, 98, 155, 157];\n\n// Run-length encoding over the whole code space: each record is a decimal run\n// length, then one ALPHABET character indexing PALETTE.\nconst RUNS = 2787;\nconst PACKED =\n '9H1K1C2A1B18H1E1R1V1b1Z1Y1b1V1U1Q1b1Z1W1N1W1a10X2W3b1R27b1U1Z1Q29b1U1K1P1b6H1D26H1J1U1Y3Z5b1n1b1' +\n 'K2b1Y1Z2b1L6b1o3b1U520b1L3b1L18b1L32b79H1J12H7J13H14b1W260b7H255b1W1K4b1Z1b45H1K1H1b2H1b2H1R1H8b' +\n '27c4b4c13b6X3b3Y2W2b11H1R1H3R43b21H10X1Y2X3b1H99b1R1b7H1X1b6H2b2H1b4H2b10X23b1H30b27H91b11H15b10' +\n 'X33b9H4b1W1R3b1H2Z22b4H1b9H1b3H1b5H43b3H52b2X5b9H42b24H1X33H54b3H1b18H1b7H10b2H2K10X17b3H56b1H1b' +\n '7H2b2H2b3H9b1H10b2H2b10X2b2Y5b1Y1b1Z2b1H2b3H56b1H1b5H4b2H2b3H3b1H20b10X2H3b1H11b3H56b1H1b8H1b3H1' +\n 'b3H20b2H2b10X1b1Z8b6H1b3H56b1H1b7H2b2H2b3H7b3H10b2H2b10X18b1H59b5H3b3H1b4H9b1H14b10X9b1Z6b5H55b1' +\n 'H1b7H1b3H1b4H7b2H11b2H2b10X7b1L9b3H1L55b1H1b7H1b3H1b4H7b2H11b2H2b10X3b1H12b4H55b2H1b7H1b3H1b4H9b' +\n '1H10b2H2b10X9b1Y7b3H70b1H4b6H1b1H1b8H6b10X2b2H61b1H2b7H4b1Z7b8H1b10X2K85b1H2b9H11b7H1b10X39b4L1b' +\n '2L1J2L1K1J5R1J1b1R3b2H6b10X10b1K1H1b1H1b1H1U1P1U1P2H49b14H1K5H1K2H5b11H1b36H1b2K6b1H9b2L1K1L5b2J' +\n '80b20H1b10X2K10b4H4b3H1b3H2b7H3b4H13b12H1b1H10X4H98b96(72f88g349b3H1b1K158b1K639b1K26b1U1P78b3K3' +\n '6b4H28b3H2K27b2H30b2H64b32H2K1T1b1K1b1K1Z1b1H2b10X24b2R2K1L1b2R1b3H1J1H10X107b2H34b1H118b12H4b12' +\n 'H8b2R10X128b11X60b5H57b10H1b29H2b1H10X6b10X22b31H49b5H47i16H1m8i1b2K10k2K1d4K10d9H9d3K3H30b13H2b' +\n '10X6b38k12H2l48b20H3b5K10X6b10X36b2K80b3H1b21H4b1H6b1H2b3H198b13H1J46H1J3H509b1L2b7K1J3K1F1H1G2H' +\n '1K1J2K1M3b1n1o1U2n1o1U1n4b3S1K2A5H1J8Y1b1n1o1b2T6b1W1U1P3T12b1K1Y4K1b3K1I5b10H13b1U1P14b1U1P17b7' +\n 'Z1Y1Z1y12Z1Y4Z1Y2Z1Y1Z1Y15Z33H18b1Y5b1Y12b1Z251b2Z219b1S24b1U1P1U1P14b2!13b1w1s190b4z3b1!2d1!521' +\n 'b2z1b4d16b2!2b1d1b3d1e2d16b8z1b3d12b12z20b1d22b1!10b6z3b1z13b1z8b2z17b2!5d2!3d4b1d1z3d1b1d1!3b2d' +\n '2b1d2b3d8b1!6b1d2!1d1!1b2d1e1!2b1!7d1z2b2d2#2e26b1z35b1z1b1z4b3z1b1z3b6V1b2R1d3b1U1P1U1P1U1P1U1P' +\n '1U1P1U1P1U1P31b3z24b1z14b1z5b1U1P31b1U1P1U1P1U1P1U1P1U1P403b1U1P1U1P1U1P1U1P1U1P1U1P1U1P1U1P1U1P' +\n '1U1P1U1P63b1U1P1U1P32b1U1P285b2z51b1z4b1z409b3H7b1R3K1b1R1K112b1K14b1H96b32H2V1n1o1n1o3V1n1o1V1n' +\n '1o8K1b1K1U1K2b1n1o2b1n1o1U1P1U1P1U1P1U1P4K1R1b2K1b2K5b2M3K1b2K1U8K1b1K1b2K3b2R1U1Q1U1Q1U1Q1U1Q1K' +\n '34b26!1b89!12b214!26b16!1r2s2!1v2!1w1s1w1s1w1s1w1s1w1s2!1w1s1w1s1w1s1w1s1v1w2s10!6p5!1p5!2v2!1d1' +\n 'b1v1!1v1!1v1!1v1!1v25!1v31!1v1!1v1!1v6!1v6!2v2b2p4v1!2v1!1v1!1v1!1v1!1v25!1v31!1v1!1v1!1v6!1v6!2' +\n 'v4!4v1!5b43!1b94!1b86!9b1!16v31!1b40!8b7024!64z21013!1v1143!3b55!55b2K269b1K1R1K16b10X69b4H1b10H' +\n '32b2H80b2H1b5K266b1H3b1H4b1H23b5H4b1H11b1Y59b2L2R8b2H50b18H8b2K10X6b18H10b1L2b1H10X28b8H2K23b13H' +\n '12b29(3b4H47i13H1m6d3K4d1b1K10k4b2d5b1H10b10X6b41k14H9b3K1H8K2H2b10k2b1d3K27b3H50b1H1b3H2b2H5b2H' +\n '1b1H41b5H2K3b2H236b8H1K2H2b10X6b1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27' +\n '&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&' +\n '1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1' +\n '%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%' +\n '27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%2' +\n '7&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27' +\n '&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&' +\n '1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1' +\n '%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%' +\n '27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%2' +\n '7&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27' +\n '&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&' +\n '1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1' +\n '%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%' +\n '27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%2' +\n '7&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27' +\n '&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&' +\n '1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1' +\n '%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%' +\n '27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%2' +\n '7&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27&1%27' +\n '&1%27&1%27&12b23f4b49g8452b512!29b1c1H10c1b13c1b5c1b1c1b2c1b2c1b10c494b1P1U188b1Y3b16H3s2v2t1w1s' +\n '1u6b1J1H1J1H1J1H2J1H1J1H1J1H2J1H5!1w1s1w1s1w1s1w1s1w1s1w1s1w1s1w1s2!1w1s7!1s1!1s1b2v2t1!1w1s1w1s' +\n '1w1s8!1b1!1y1x1!147b1I1b1t2!1y1x2!1w1s2!1s1!1s11!2v3!1t27!1w1!1s29!1w1!1s1!1w2s1w2s1v1!10v45!2v3' +\n '1!3b6!2b6!2b6!2b3!3b1x1y3!2y1b7z10b3H1O259b3K250b1H226b1H149b5H36b1K48b1K207b10X941b1K199b1K225b' +\n '3H1b2H5b4H40b3H4b1H16b8K141b2H9b6K1S66b7K484b4H8b10X6b10X31b5H1K316b2H1K78b4H70b11H49b4H122b3H2j' +\n '51i14H1m2K5d4b20d10k1H2i2H1i9b1J3H45b11H2b1X4K1H10b1X34b10X6b3H36b14H1b10X4K1b2H44b1H1b1L10b3H48' +\n 'b14H4b2K1b1K4H1b2H10X1b1L1b3K76b12H2K1b2K1b1H2b1H103b1K53b12H5b10X6b4H1b8i2b2i2b22i1b7i1b2i1b5i1' +\n 'b2H1K7H2b2H2b2H1m2b1k6b1H5b1K2k2i2H2b7H3b5H11b10k1b1k2b1k1b2k36i1b1d9H1b1H2b1H1b4H1b4H1m1j1H3d1b' +\n '2d8b2H82b18H4b4K1b10X2K2b1H81b20H12b10X213b7H2b9H1L2K2R3b15K4b2H82b17H2K13b10X6b13L62b13H8b10X6b' +\n '20X57b15H4b10X2b3K237b15H165b10X22b7i2b1i2b8i1b2i1b24i6H1b2H2b3H1m1j1H1j2H3K9b10k119b7H2b7H1b1L1' +\n 'b1H28b10H40b7H1b4H1L1b4K1L1b1H9b11H46b16H3K1b3L2K93b10L230b10X53b8H1b8H1b5K10b10X22b1L1R32b22H1b' +\n '14H122b6H3b1H1b2H1b7H1b1H8b10X48b5H1b2H1b5H8b10X310b18k1K4H2K7b2H1j1H13i1b34i7H3b4H1m2K11d10k1H1' +\n '30b4Y30b1K1136b5K3555b3U3P36b1P3b1U1P1U1P239b1U2P179b1U7J1U1P3J1U1P1U1P1H6b15H4472b1U1P6960b30k1' +\n '8H10k2342b10X4b2K80b10X38b5H1K58b7H3K10b1K11b10X532b2K10X285b2K182b1H1b55H7b4H77b4v1q11b2p14b613' +\n '6!8b768!470z41b1z9!8935b4z1b7z1b2z1b291!15b1v29b3v2b1v14b4v8b396!2465b2H1K4H4172b10X518b46H2b23H' +\n '542b5H3b22H2b7H30b4H148b3H187b87z9b23z1111b50X512b55H4b50H8b1H14b1H2b4K16b5H1b15H1360b7H1b17H2b7' +\n 'H1b2H1b5H100b1H160b7H9b10X356b1H61b4H10X5b1Z492b4H10X244b2H1b10X725b7H109b7H5b10X4b2U844b1Y3b1Y8' +\n '47b4d1!39d4*100d12*15d2*15d1*14d1!1*37d10*142b1z2b10z19b56*26h3!13*44!4*9!7*2!14*6!154*33!12d9!1' +\n 'd70!1d7!1#14!8d2b2d21!2z5!1z5!3#2!1#2!1#2e2d5!12d17!3d1!3d3!5$63!1d1!1d2#2!11#21!19#3!1#4!3#1!3#' +\n '7!1#1!1#14!1z1!1z1!1z5!1#4!1z1!2z74!2d1!7z16!14z13!12z12b1d4!1d24!12d2e4d1#21d1e4d2#13d1!47d8b24' +\n 'd6b1d74!3#3!5#38b3V3T4b35!1#16!3#9!1#5!6d1#3d3!2d3!4*4!11d2!3*4d9!3*116b3d4*5d85b5d6*12!4*1!15*1' +\n '2b4)56b8)10b6)40b8)30b2)12b4)2b62)12b1#2!1#8!8#6!1#9!10#1!1d3#7!1d48!1#61!2#1!2#1!1#17!3#1!13#34' +\n '!84b12*14d2*13!3*10!5*52!3#1!7*15!2*11!6*9#7*240b10X6b1022*2b65534!2b65534!655363b1H30b96H128b24' +\n '0H196112b';\n\nlet bmp: Uint8Array | null = null;\nlet astralStarts: Int32Array | null = null;\nlet astralValues: Uint8Array | null = null;\n\nfunction decode(): void {\n const direct = new Uint8Array(0x10000);\n const starts = new Int32Array(RUNS);\n const values = new Uint8Array(RUNS);\n const slot = new Uint8Array(128);\n for (let i = 0; i < ALPHABET.length; i++) slot[ALPHABET.charCodeAt(i)] = PALETTE[i];\n let cp = 0;\n let run = 0;\n let len = 0;\n for (let i = 0; i < PACKED.length; i++) {\n const code = PACKED.charCodeAt(i);\n if (code <= 57 && code >= 48) len = len * 10 + code - 48;\n else {\n const v = slot[code];\n starts[run] = cp;\n values[run] = v;\n if (cp < 0x10000) direct.fill(v, cp, Math.min(cp + len, 0x10000));\n run++;\n cp += len;\n len = 0;\n }\n }\n bmp = direct;\n astralStarts = starts;\n astralValues = values;\n}\n\n/**\n * The class of `cp` in the low bits (`& CLASS_MASK`), with the\n * {@link EAST_ASIAN} and {@link PICTOGRAPHIC_CN} flags above them.\n */\nexport function lineBreakPropsOf(cp: number): number {\n if (bmp === null) decode();\n if (cp < 0x10000) return bmp![cp];\n if (cp > 0x10ffff) return AL;\n const starts = astralStarts!;\n let lo = 0;\n let hi = starts.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (starts[mid] <= cp) lo = mid;\n else hi = mid - 1;\n }\n return astralValues![lo];\n}\n","/**\n * Line break opportunities per the Unicode Line Breaking Algorithm\n * (UAX #14), default rules, no tailoring: where a line may end, not where it\n * does. Choosing among the opportunities is the wrap's job.\n *\n * Rules LB2–LB31 are applied in order at every position. LB9 is applied up\n * front: a combining mark or ZWJ that follows a base joins it into one unit\n * carrying the base's class, so every later rule reads units, never marks.\n */\n\nimport * as table from './lineBreakTable';\n\n// Copied into module locals: vitest rewrites every read of an imported\n// binding into a property access, which made this loop 25x slower under test.\nconst {\n lineBreakPropsOf, CLASS_MASK, EAST_ASIAN, PICTOGRAPHIC_CN,\n BK, CR, LF, NL, SP, ZW, ZWJ, CM, WJ, GL, BA, BB, B2, HY, CB, CL, CP, EX, IN, NS,\n OP, QU, IS, NU, PO, PR, SY, AL, HL, ID, EB, EM, H2, H3, JL, JV, JT, RI,\n AK, AP, AS, VF, VI, QU_PI, QU_PF,\n} = table;\n\n/** No opportunity before this position. */\nexport const NO_BREAK = 0;\n/** A line may end before this position. */\nexport const BREAK_ALLOWED = 1;\n/** A line must end before this position: after a hard line break, and at the end of text. */\nexport const BREAK_MANDATORY = 2;\n\nconst HYPHEN = 0x2010;\nconst DOTTED_CIRCLE = 0x25cc;\n\nconst isQU = (c: number): boolean => c === QU || c === QU_PI || c === QU_PF;\nconst isHard = (c: number): boolean => c === BK || c === CR || c === LF || c === NL;\n/**\n * Whether a line must end after `cp`: UAX #14's hard breaks, which are LF,\n * VT, FF, CR, NEL, U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR. A CR\n * directly before an LF makes one break with it, not two.\n */\nexport function isHardLineBreak(cp: number): boolean {\n return isHard(lineBreakPropsOf(cp) & CLASS_MASK);\n}\nconst isAlpha =(c: number): boolean => c === AL || c === HL;\nconst isKorean = (c: number): boolean => c === JL || c === JV || c === JT || c === H2 || c === H3;\nconst isIdeoLike = (c: number): boolean => c === ID || c === EB || c === EM;\n\n/**\n * For each position `0..cps.length`, whether a line may break before it:\n * {@link NO_BREAK}, {@link BREAK_ALLOWED} or {@link BREAK_MANDATORY}. Position\n * 0 never breaks and position `cps.length` always does.\n *\n * `cps` is code points, not UTF-16 units — one entry per scalar value.\n */\nexport function lineBreakOpportunities(cps: ArrayLike<number>): Uint8Array {\n const n = cps.length;\n const out = new Uint8Array(n + 1);\n if (n === 0) return out;\n out[n] = BREAK_MANDATORY;\n\n // LB9/LB10: collapse each base and the marks it carries into one unit.\n const cls = new Uint8Array(n);\n const ea = new Uint8Array(n);\n const pict = new Uint8Array(n);\n const cp = new Int32Array(n);\n /** Original index of each unit's first code point. */\n const start = new Int32Array(n);\n let u = 0;\n for (let i = 0; i < n; i++) {\n const props = lineBreakPropsOf(cps[i]);\n const c = props & CLASS_MASK;\n if ((c === CM || c === ZWJ) && u > 0) {\n const base = cls[u - 1];\n if (!isHard(base) && base !== SP && base !== ZW) continue;\n }\n if (c === CM || c === ZWJ) {\n cls[u] = AL; ea[u] = 0; pict[u] = 0;\n } else {\n cls[u] = c; ea[u] = props & EAST_ASIAN ? 1 : 0; pict[u] = props & PICTOGRAPHIC_CN ? 1 : 0;\n }\n cp[u] = cps[i];\n start[u] = i;\n u++;\n }\n const units = u;\n\n // The original class of the code point just before unit `b`, which is the\n // last mark `b - 1` absorbed when it absorbed any.\n const prevIsZWJ = (b: number): boolean => (lineBreakPropsOf(cps[start[b] - 1]) & CLASS_MASK) === ZWJ;\n\n /** The unit before `k`'s run of spaces — `k` itself when it is not a space. */\n const beforeSpaces = (k: number): number => {\n while (k >= 0 && cls[k] === SP) k--;\n return k;\n };\n\n for (let b = 1; b < units; b++) {\n out[start[b]] = decide(b);\n }\n return out;\n\n function decide(b: number): number {\n const a = b - 1;\n const A = cls[a];\n const B = cls[b];\n\n // LB4, LB5\n if (A === CR && B === LF) return NO_BREAK;\n if (isHard(A)) return BREAK_MANDATORY;\n // LB6, LB7\n if (isHard(B) || B === SP || B === ZW) return NO_BREAK;\n // LB8\n const s = beforeSpaces(a);\n if (s >= 0 && cls[s] === ZW) return BREAK_ALLOWED;\n // LB8a\n if (prevIsZWJ(b)) return NO_BREAK;\n // LB11, LB12, LB12a\n if (A === WJ || B === WJ || A === GL) return NO_BREAK;\n if (B === GL && A !== SP && A !== BA && A !== HY) return NO_BREAK;\n // LB13\n if (B === CL || B === CP || B === EX || B === SY) return NO_BREAK;\n // LB14\n const S = s >= 0 ? cls[s] : -1;\n if (S === OP) return NO_BREAK;\n // LB15a\n if (S === QU_PI) {\n const p = s - 1;\n if (p < 0) return NO_BREAK;\n const P = cls[p];\n if (isHard(P) || P === OP || isQU(P) || P === GL || P === SP || P === ZW) return NO_BREAK;\n }\n // LB15b\n if (B === QU_PF) {\n if (b + 1 >= units) return NO_BREAK;\n const N = cls[b + 1];\n if (N === SP || N === GL || N === WJ || N === CL || isQU(N) || N === CP || N === EX\n || N === IS || N === SY || isHard(N) || N === ZW) return NO_BREAK;\n }\n // LB15c, LB15d\n if (A === SP && B === IS && b + 1 < units && cls[b + 1] === NU) return BREAK_ALLOWED;\n if (B === IS) return NO_BREAK;\n // LB16, LB17\n if ((S === CL || S === CP) && B === NS) return NO_BREAK;\n if (S === B2 && B === B2) return NO_BREAK;\n // LB18\n if (A === SP) return BREAK_ALLOWED;\n // LB19\n if (B === QU || B === QU_PF) return NO_BREAK;\n if (A === QU || A === QU_PI) return NO_BREAK;\n // LB19a\n if (isQU(B)) {\n if (!ea[a]) return NO_BREAK;\n if (b + 1 >= units || !ea[b + 1]) return NO_BREAK;\n }\n if (isQU(A)) {\n if (!ea[b]) return NO_BREAK;\n if (a === 0 || !ea[a - 1]) return NO_BREAK;\n }\n // LB20\n if (A === CB || B === CB) return BREAK_ALLOWED;\n // LB20a\n if ((A === HY || cp[a] === HYPHEN) && B === AL) {\n if (a === 0) return NO_BREAK;\n const P = cls[a - 1];\n if (isHard(P) || P === SP || P === ZW || P === CB || P === GL) return NO_BREAK;\n }\n // LB21\n if (B === BA || B === HY || B === NS || A === BB) return NO_BREAK;\n // LB21a\n if (a > 0 && cls[a - 1] === HL && (A === HY || (A === BA && !ea[a])) && B !== HL) return NO_BREAK;\n // LB21b, LB22\n if (A === SY && B === HL) return NO_BREAK;\n if (B === IN) return NO_BREAK;\n // LB23, LB23a, LB24\n if ((isAlpha(A) && B === NU) || (A === NU && isAlpha(B))) return NO_BREAK;\n if ((A === PR && isIdeoLike(B)) || (isIdeoLike(A) && B === PO)) return NO_BREAK;\n if (((A === PR || A === PO) && isAlpha(B)) || (isAlpha(A) && (B === PR || B === PO))) return NO_BREAK;\n // LB25\n if (B === PO || B === PR) {\n let k = A === CL || A === CP ? a - 1 : a;\n while (k >= 0 && (cls[k] === SY || cls[k] === IS)) k--;\n if (k >= 0 && cls[k] === NU) return NO_BREAK;\n }\n if (A === PO || A === PR) {\n if (B === NU) return NO_BREAK;\n if (B === OP && b + 1 < units) {\n const N = cls[b + 1];\n if (N === NU) return NO_BREAK;\n if (N === IS && b + 2 < units && cls[b + 2] === NU) return NO_BREAK;\n }\n }\n if ((A === HY || A === IS) && B === NU) return NO_BREAK;\n if (B === NU) {\n let k = a;\n while (k >= 0 && (cls[k] === SY || cls[k] === IS)) k--;\n if (k >= 0 && cls[k] === NU) return NO_BREAK;\n }\n // LB26, LB27\n if (A === JL && (B === JL || B === JV || B === H2 || B === H3)) return NO_BREAK;\n if ((A === JV || A === H2) && (B === JV || B === JT)) return NO_BREAK;\n if ((A === JT || A === H3) && B === JT) return NO_BREAK;\n if ((isKorean(A) && B === PO) || (A === PR && isKorean(B))) return NO_BREAK;\n // LB28\n if (isAlpha(A) && isAlpha(B)) return NO_BREAK;\n // LB28a\n const aksaraA = A === AK || A === AS || cp[a] === DOTTED_CIRCLE;\n const aksaraB = B === AK || B === AS || cp[b] === DOTTED_CIRCLE;\n if (A === AP && aksaraB) return NO_BREAK;\n if (aksaraA && (B === VF || B === VI)) return NO_BREAK;\n if (A === VI && a > 0 && (cls[a - 1] === AK || cls[a - 1] === AS || cp[a - 1] === DOTTED_CIRCLE)\n && (B === AK || cp[b] === DOTTED_CIRCLE)) return NO_BREAK;\n if (aksaraA && aksaraB && b + 1 < units && cls[b + 1] === VF) return NO_BREAK;\n // LB29, LB30\n if (A === IS && isAlpha(B)) return NO_BREAK;\n if ((isAlpha(A) || A === NU) && B === OP && !ea[b]) return NO_BREAK;\n if (A === CP && !ea[a] && (isAlpha(B) || B === NU)) return NO_BREAK;\n // LB30a\n if (A === RI && B === RI) {\n let k = a;\n while (k >= 0 && cls[k] === RI) k--;\n if ((a - k) % 2 === 1) return NO_BREAK;\n }\n // LB30b\n if (B === EM && (A === EB || pict[a])) return NO_BREAK;\n // LB31\n return BREAK_ALLOWED;\n }\n}\n","/**\n * Where the bidi engine arrives. This package cannot import one (see\n * `bidiSeam.ts`), and most callers of `layoutRuns` are kit code a consumer\n * never touches, so the consumer registers it once and every layout finds it.\n */\nimport type { BidiResolver } from './bidiSeam';\nimport { isHardLineBreak } from './lineBreak/lineBreaks';\nimport type { TextDirection } from '../textStyle';\n\nlet registered: BidiResolver | null = null;\n\n/**\n * Give every text layout a bidi engine: `registerBidi(bidi)`, with `bidi`\n * from `@weasel-js/bidi`. `layoutRuns` uses it whenever its options carry\n * none. Pass `null`, or call the function returned, to take it out again.\n */\nexport function registerBidi(engine: BidiResolver | null): () => void {\n registered = engine;\n return () => { if (registered === engine) registered = null; };\n}\n\n/** The engine {@link registerBidi} was last given, or null. */\nexport function registeredBidi(): BidiResolver | null {\n return registered;\n}\n\n/** Which way a paragraph reads, from an engine's base level for it. */\nexport function directionOfLevel(level: number): TextDirection {\n return level % 2 === 1 ? 'rtl' : 'ltr';\n}\n\n/**\n * The direction `text`'s first paragraph reads in: `direction` when it states\n * one, otherwise its first strong character's. Finding that takes an engine,\n * so with none registered the answer is `'ltr'`.\n */\nexport function paragraphDirection(\n text: string,\n direction: TextDirection | 'auto' = 'auto',\n engine: BidiResolver | null = registered,\n): TextDirection {\n if (direction !== 'auto') return direction;\n if (engine === null) return 'ltr';\n const cps: number[] = [];\n for (const ch of text) {\n const cp = ch.codePointAt(0)!;\n if (isHardLineBreak(cp)) break;\n cps.push(cp);\n }\n return directionOfLevel(engine.baseLevel(engine.analyze(cps, 'auto')));\n}\n\n/**\n * Code point blocks whose letters read right-to-left.\n *\n * A heuristic on purpose: the real answer is `Bidi_Class`, which lives in\n * `@weasel-js/bidi` and is exactly what the caller has not installed when this\n * matters. It can miss a script, and it still counts a combining mark from\n * these blocks as a letter. What it leaves out is carved out below: code\n * points that sit in these blocks and read the same without an engine.\n */\nconst RTL_BLOCKS: ReadonlyArray<readonly [number, number]> = [\n [0x0590, 0x05ff], [0x0600, 0x07bf], [0x0860, 0x08ff],\n [0xfb1d, 0xfdff], [0xfe70, 0xfeff],\n [0x10800, 0x10fff], [0x1e800, 0x1efff],\n];\n\n/** Digits and number signs inside those blocks. They keep their written order\n * in any paragraph, so a string of them is laid out correctly as it is. */\nconst RTL_BLOCK_NUMBERS: ReadonlyArray<readonly [number, number]> = [\n [0x0600, 0x0605], [0x0660, 0x066c], [0x06dd, 0x06dd], [0x06f0, 0x06f9],\n [0x08e2, 0x08e2], [0x10d30, 0x10d39], [0x10e60, 0x10e7e],\n];\n\n/** The Arabic comma, the ornate parentheses, and the byte order mark: no\n * direction of their own, so they take their neighbors'. */\nconst RTL_BLOCK_NEUTRALS: ReadonlyArray<readonly [number, number]> = [\n [0x060c, 0x060c], [0xfd3e, 0xfd3f], [0xfeff, 0xfeff],\n];\n\nconst within =(ranges: ReadonlyArray<readonly [number, number]>, cp: number): boolean =>\n ranges.some(([lo, hi]) => cp >= lo && cp <= hi);\n\nlet warnedLogicalRtl = false;\n\n/**\n * Warn, once per process, when `codePoints` hold right-to-left letters and\n * there is no engine to reorder them.\n */\nexport function warnRtlWithoutEngine(codePoints: Iterable<number>): void {\n if (warnedLogicalRtl) return;\n for (const cp of codePoints) {\n if (!within(RTL_BLOCKS, cp) || within(RTL_BLOCK_NUMBERS, cp) || within(RTL_BLOCK_NEUTRALS, cp)) continue;\n warnedLogicalRtl = true;\n console.warn(\n // Naming the import in `from \"<pkg>\"` form would trip labkit's\n // consumer smoke test, which greps dist for that exact shape.\n 'weasel layoutRuns: this text contains right-to-left characters but no ' +\n '`bidi` engine is registered, so it is being laid out in logical order — ' +\n 'the glyphs will appear reversed. Import `bidi` out of the ' +\n '`@weasel-js/bidi` package and call `registerBidi(bidi)` once at startup.',\n );\n return;\n }\n}\n\n/** Test helper. Do not call from product code. */\nexport function _resetBidiWarningForTests(): void {\n warnedLogicalRtl = false;\n}\n","/**\n * Bidi analysis for a text with hard line breaks in it.\n *\n * UAX #9 is defined per paragraph, and a hard break ends one: embeddings and\n * overrides close there, and the next paragraph resolves its neutrals — and,\n * under `'auto'`, its direction — from its own characters. The engine's\n * `analyze` takes exactly one paragraph, so this splits the code points at the\n * breaks, analyzes each stretch, and answers a line's reorder against whichever\n * stretch the line sits in.\n */\nimport type { BidiAnalysis, BidiReordering, BidiResolver } from './bidiSeam';\n\ninterface Paragraph {\n start: number;\n end: number;\n analysis: BidiAnalysis;\n}\n\n/** A text's paragraphs, analyzed. */\nexport interface AnalyzedParagraphs {\n /** Visual order for the line `[from, to)`, as positions in the whole text. */\n reorder(from: number, to: number): BidiReordering;\n /** The level the paragraph holding position `at` reads at; 0 for a position\n * in none, which is a hard break or a blank line. */\n baseLevel(at: number): number;\n}\n\n/**\n * Analyze `codePoints` paragraph by paragraph. `isBreak` marks the hard breaks,\n * which belong to no paragraph. `reorder` takes one line, which must lie within\n * a single paragraph — true of any line a wrap produces.\n */\nexport function analyzeParagraphs(\n engine: BidiResolver,\n codePoints: readonly number[],\n isBreak: (index: number) => boolean,\n direction: 'ltr' | 'rtl' | 'auto',\n): AnalyzedParagraphs {\n const paragraphs: Paragraph[] = [];\n let start = 0;\n for (let i = 0; i <= codePoints.length; i++) {\n if (i < codePoints.length && !isBreak(i)) continue;\n if (i > start) {\n paragraphs.push({ start, end: i, analysis: engine.analyze(codePoints.slice(start, i), direction) });\n }\n start = i + 1;\n }\n\n const holding = (at: number): Paragraph | undefined => {\n let lo = 0;\n let hi = paragraphs.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (paragraphs[mid].end <= at) lo = mid + 1;\n else hi = mid;\n }\n const p = paragraphs[lo];\n return p !== undefined && at >= p.start && at < p.end ? p : undefined;\n };\n\n return {\n reorder(from, to) {\n const p = holding(from);\n if (p === undefined || to > p.end) return { order: [], levels: [] };\n const r = engine.reorder(p.analysis, from - p.start, to - p.start);\n return { order: r.order.map((i) => i + p.start), levels: r.levels };\n },\n baseLevel(at) {\n const p = holding(at);\n return p === undefined ? 0 : engine.baseLevel(p.analysis);\n },\n };\n}\n\n/**\n * A line's visual order with the positions the engine removed (X9: bidi\n * controls, joiners, soft hyphens) put back beside the character each one\n * follows in the text, on the side that character's direction reads toward.\n * One opening the line sits before the first character that was kept.\n *\n * `order` holds positions `0..count-1` within the line; `rtl` answers for a\n * kept position.\n */\nexport function restoreRemoved(\n order: readonly number[],\n count: number,\n rtl: (pos: number) => boolean,\n): number[] {\n if (order.length === count) return [...order];\n const kept = new Set(order);\n const leading: number[] = [];\n const following = new Map<number, number[]>();\n let anchor = -1;\n let firstKept = -1;\n for (let k = 0; k < count; k++) {\n if (kept.has(k)) {\n anchor = k;\n if (firstKept < 0) firstKept = k;\n } else if (anchor < 0) {\n leading.push(k);\n } else {\n const list = following.get(anchor);\n if (list) list.push(k);\n else following.set(anchor, [k]);\n }\n }\n if (firstKept < 0) return leading;\n const out: number[] = [];\n for (const p of order) {\n const after = following.get(p) ?? [];\n const before = p === firstKept ? leading : [];\n if (rtl(p)) out.push(...[...after].reverse(), p, ...[...before].reverse());\n else out.push(...before, p, ...after);\n }\n return out;\n}\n\n/** One line's visual order. */\nexport interface LineOrder {\n /** Positions within the line, in visual order, left to right. */\n visual: number[];\n /** Resolved embedding level per position; even reads left to right. */\n levels: number[];\n}\n\n/**\n * The visual order of the line of `count` code points opening at `start` in\n * the text `paragraphs` analyzed. With no analysis that is logical order, all\n * at level 0. A position the engine removed still has a place: see\n * {@link restoreRemoved}.\n */\nexport function orderLine(\n paragraphs: AnalyzedParagraphs | null,\n start: number,\n count: number,\n): LineOrder {\n const levels = new Array<number>(count).fill(0);\n if (paragraphs === null || count === 0) return { visual: levels.map((_, pos) => pos), levels };\n const r = paragraphs.reorder(start, start + count);\n for (let pos = 0; pos < count; pos++) {\n const level = r.levels[pos];\n if (typeof level === 'number' && level >= 0) levels[pos] = level;\n }\n // `opts.bidi` is a consumer's to supply, so its order is not trusted to be a\n // permutation: a repeat keeps its first place, and anything that is not a\n // position on the line is dropped.\n const kept = new Set<number>();\n for (const at of r.order) {\n const pos = at - start;\n if (Number.isInteger(pos) && pos >= 0 && pos < count) kept.add(pos);\n }\n return { visual: restoreRemoved([...kept], count, (pos) => levels[pos] % 2 === 1), levels };\n}\n","/**\n * Grapheme clusters: the unit CSS `letter-spacing` tracks, and therefore the\n * unit every tracked width in this package counts. `measuredWidth` and\n * `layoutRuns` both read clusters from here, so the 2D path, the GL path and\n * a DOM overlay agree on how many gaps a string has.\n */\n\nlet segmenter: Intl.Segmenter | null | undefined;\n\nconst NEEDS_SEGMENTING = /[\\r\\u0300-\\uffff]/;\n\nfunction graphemeSegmenter(): Intl.Segmenter | null {\n if (segmenter === undefined) {\n segmenter = typeof Intl !== 'undefined' && 'Segmenter' in Intl\n ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n : null;\n }\n return segmenter;\n}\n\n/**\n * UTF-16 offsets just past each grapheme cluster of `text`, ascending — the\n * last is `text.length`. Without `Intl.Segmenter` every code point is its own\n * cluster.\n */\nexport function graphemeEnds(text: string): number[] {\n const out: number[] = [];\n // Nothing below U+0300 extends a cluster except the LF of a CRLF, so text\n // made only of those is one cluster per code unit without asking.\n if (!NEEDS_SEGMENTING.test(text)) {\n for (let i = 1; i <= text.length; i++) out.push(i);\n return out;\n }\n const seg = graphemeSegmenter();\n if (seg) {\n for (const s of seg.segment(text)) out.push(s.index + s.segment.length);\n return out;\n }\n let at = 0;\n for (const ch of text) out.push(at += ch.length);\n return out;\n}\n\n/** Number of grapheme clusters in `text`: how many times it is tracked. */\nexport function graphemeCount(text: string): number {\n return graphemeEnds(text).length;\n}\n","/**\n * Runs measured code point by code point: which glyph serves each one, how\n * far it advances, and the kerning before it. Nothing here knows about lines.\n *\n * A grapheme cluster with emoji presentation is the exception to one glyph a\n * code point: where the canvas tier draws a color glyph for it, that glyph\n * sits in the slot of the cluster's closing code point, and the code points\n * before it are slots with nothing in them.\n */\nimport {\n glyphIn, metricsOf, resolveColorCluster, resolveFontVariant, resolveGlyph, warnNoMetrics,\n type BmFont, type BmFontChar, type GlyphMetrics, type ResolvedGlyph, type ResolveResult,\n} from '@weasel-js/font';\nimport { graphemeEnds } from '../measure/graphemes';\nimport type { ResolvedRun } from '../runs/resolveRuns';\nimport { isHardLineBreak } from './lineBreak/lineBreaks';\nimport type { TabStop } from './tabStops';\n\n/** A mark that takes no width of its own, which kerning reads through. */\nconst NONSPACING_MARK = /^[\\p{Mn}\\p{Me}]$/u;\n\n/** One code point of the runs, measured. Widths are world units. */\nexport interface Entry {\n /** Index of its run in the runs measured. */\n run: number;\n cp: number;\n /** The glyph's own size, which small caps sets below its run's. */\n fontSize: number;\n /** The size it holds its line at: its run's, or the larger size a shrunken\n * run inherited. */\n lineSize: number;\n /** How far its run is raised off the line's baseline. */\n baselineShift: number;\n /** UTF-16 span of the source character it was drawn from. */\n srcIndex: number;\n srcEnd: number;\n clusterEnd: boolean;\n /** The tier serving the glyph, which is not its run's when the code point\n * escalated, and that tier's metrics. */\n resolved: ResolveResult;\n metrics: GlyphMetrics;\n /** The atlas to sample and the glyph's record in it; null on the outline\n * tier and for a slot with nothing to draw. */\n font: BmFont | null;\n glyph: BmFontChar | null;\n advance: number;\n /** Its run's `letterSpacing` when it closes a grapheme cluster, else 0. */\n tracking: number;\n /** The kerning gap between the entry before it and this one. A\n * nonspacing mark has none, and the entry after it kerns against the\n * mark's base. */\n kerningBefore: number;\n /** Set on a tab, whose `advance` is known only once its line is. */\n tab?: TabStop;\n /** See `LaidOutCell.drawsInk`. */\n drawsInk: boolean;\n}\n\n/**\n * Measure every code point of `runs`, in order. Kerning pairs across run\n * boundaries, in the left glyph's face and at its size, and through a\n * nonspacing mark. A run whose face has\n * no metrics contributes no entries but still takes up its source offsets.\n */\nexport function measureRuns(runs: readonly ResolvedRun[], tabSize: number): Entry[] {\n const entries: Entry[] = [];\n /** The entry the next one kerns against; none across a break, a tab, or a\n * run with no metrics. */\n let prev: Entry | undefined;\n let srcIndex = 0;\n\n runs.forEach((run, runIndex) => {\n const resolved = resolveFontVariant(run.fontFamily, run.fontWeight, run.fontStyle);\n const metrics = metricsOf(resolved);\n if (!metrics) {\n // Laying out as nothing is indistinguishable from empty text downstream,\n // so this is the only signal a consumer ever gets.\n warnNoMetrics(run.fontFamily, run.fontWeight, run.fontStyle);\n srcIndex += run.srcMap?.length ?? run.text.length;\n prev = undefined;\n return;\n }\n const runBase = srcIndex;\n const map = run.srcMap;\n const clusterEnds = graphemeEnds(run.text);\n let cluster = 0;\n let clusterStart = 0;\n /** The color glyph of the cluster being walked, when it has one. */\n let color: ResolvedGlyph | null = null;\n let at = 0;\n\n for (const ch of run.text) {\n const cp = ch.codePointAt(0)!;\n const fontSize = run.sizeMap ? run.sizeMap[at] : run.fontSize;\n if (at === clusterStart) {\n color = resolveColorCluster(\n resolved, run.fontFamily, run.fontWeight, run.fontStyle, run.text.slice(at, clusterEnds[cluster]),\n );\n }\n const clusterEnd = at + ch.length === clusterEnds[cluster];\n if (clusterEnd) clusterStart = clusterEnds[cluster++];\n // World units, deliberately not scaled by fontSize: the same tracking\n // opens the same gap whatever size the run is set at.\n const tracking = clusterEnd ? run.letterSpacing : 0;\n // A transformed run draws characters its source does not have; each\n // takes the source span of the character it was mapped from.\n const srcStart = map ? runBase + map.starts[at] : runBase + at;\n const srcEnd = map ? runBase + map.ends[at] : runBase + at + ch.length;\n at += ch.length;\n srcIndex = map ? runBase + map.length : srcEnd;\n\n const mark = NONSPACING_MARK.test(ch);\n const kerningBefore = prev && !mark\n ? prev.metrics.kernOf(prev.cp, cp) * (prev.fontSize / prev.metrics.size)\n : 0;\n // A slot with nothing in it: no glyph, no width, and none of the\n // tracking or kerning a width would carry. Filled in place when it inks.\n const blank: Entry = {\n run: runIndex, cp, fontSize,\n lineSize: Math.max(run.fontSize, run.strutSize ?? 0),\n // Optional on the authored run type; absent, every y would go NaN.\n baselineShift: run.baselineShift ?? 0,\n srcIndex: srcStart, srcEnd, clusterEnd,\n resolved, metrics, font: null, glyph: null,\n advance: 0, tracking: 0, kerningBefore: 0, drawsInk: false,\n };\n\n if (color) {\n entries.push(clusterEnd ? ink(blank, color, 0, tracking) : blank);\n prev = undefined;\n } else if (isHardLineBreak(cp)) {\n entries.push(blank);\n prev = undefined;\n } else if (cp === 9 || cp === 32) {\n // A face with no space still gets one wide enough to part words.\n const space = metrics.advanceOf(32);\n const advance = space !== null ? space * (fontSize / metrics.size) : fontSize * 0.25;\n if (cp === 9) {\n entries.push({ ...blank, tab: { stop: tabSize * (advance + run.letterSpacing), min: advance / 2 } });\n prev = undefined;\n } else {\n // Its record in the run's own tier, for an atlas that draws one. It\n // never escalates: a face without a space still parts words.\n const own = glyphIn(resolved, 32);\n blank.font = own?.font ?? null;\n blank.glyph = own?.glyph ?? null;\n blank.advance = advance;\n blank.tracking = tracking;\n blank.kerningBefore = kerningBefore;\n prev = blank;\n entries.push(prev);\n }\n } else {\n const hit = resolveGlyph(resolved, run.fontFamily, run.fontWeight, run.fontStyle, cp);\n const entry = hit ? ink(blank, hit, kerningBefore, tracking) : blank;\n entries.push(entry);\n if (!mark) prev = entry;\n }\n }\n });\n return entries;\n}\n\n/** Fill the empty slot `e` with `hit`, in place: one object a code point. An\n * escalated code point is served in another tier's units, so its scale is its own. */\nfunction ink(e: Entry, hit: ResolvedGlyph, kerning: number, tracking: number): Entry {\n e.resolved = hit.resolved;\n e.metrics = hit.metrics;\n e.font = hit.font;\n e.glyph = hit.glyph;\n e.advance = hit.advance * (e.fontSize / hit.metrics.size);\n e.tracking = tracking;\n e.kerningBefore = kerning;\n e.drawsInk = true;\n return e;\n}\n\n/**\n * One line's entries with each bracket in a right-to-left stretch painting as\n * its mirror (UAX #9 L4). `levels` holds the line's resolved level per entry.\n *\n * The outline tier reads the code point directly; the atlas tiers need the\n * other glyph looked up, which may come from another tier, and a face without\n * it keeps the unmirrored one. The advance stays the one the wrap measured.\n */\nexport function mirrorEntries(\n entries: readonly Entry[],\n levels: readonly number[],\n mirror: (cp: number) => number | null,\n runs: readonly ResolvedRun[],\n): Entry[] {\n return entries.map((entry, pos) => {\n if (levels[pos] % 2 === 0) return entry;\n const cp = mirror(entry.cp);\n if (cp === null || cp === entry.cp) return entry;\n if (entry.font === null) return { ...entry, cp };\n const run = runs[entry.run];\n const hit = resolveGlyph(entry.resolved, run.fontFamily, run.fontWeight, run.fontStyle, cp, false);\n if (!hit) return entry;\n return { ...entry, cp, resolved: hit.resolved, metrics: hit.metrics, font: hit.font, glyph: hit.glyph };\n });\n}\n","/**\n * The greedy wrap every text layout in this package shares: each measures its\n * own way and hands the measuring in here, so where a line ends is decided in\n * one place.\n */\n\nimport { isHardLineBreak, lineBreakOpportunities, NO_BREAK } from './lineBreaks';\n\n/** One line of a wrap, as code point indices into the wrapped sequence. */\nexport interface WrappedLine {\n /** First code point on the line. */\n start: number;\n /** One past the last, excluding the hard break that closed it. Trailing spaces are included. */\n end: number;\n /** Closed by the wrap rather than by a hard break or the end of the text. */\n wrapped: boolean;\n}\n\n/** White space that hangs at a line's end and never opens a wrapped line: a\n * space or a tab. */\nexport const hangs = (cp: number): boolean => cp === 32 || cp === 9;\n\n/**\n * Greedy wrap of `cps` at its UAX #14 break opportunities. A line ends at\n * every hard break (CRLF counts once, and neither code point lands on a\n * line), and before any word — the text up to the next opportunity, spaces\n * after it included — whose ink would take the line past `maxWidth`. Only\n * ink has to fit: trailing spaces and tabs hang. A word wider than the line is never\n * split. `Infinity` breaks at hard breaks alone.\n *\n * `widthOf(start, end)` is the width of code points `[start, end)` set on a\n * line of their own starting at `start`; `end` is always one past a\n * non-space, non-tab.\n */\nexport function wrapLines(\n cps: ArrayLike<number>,\n maxWidth: number,\n widthOf: (start: number, end: number) => number,\n): WrappedLine[] {\n const n = cps.length;\n const breaks = Number.isFinite(maxWidth) ? lineBreakOpportunities(cps) : null;\n const lines: WrappedLine[] = [];\n let start = 0;\n let i = 0;\n while (i < n) {\n const cp = cps[i];\n if (isHardLineBreak(cp)) {\n lines.push({ start, end: i, wrapped: false });\n i += cp === 13 && cps[i + 1] === 10 ? 2 : 1;\n start = i;\n continue;\n }\n // A space here opens the text or follows a hard break: it never wraps.\n if (hangs(cp)) { i++; continue; }\n let j = i + 1;\n let ink = i + 1;\n while (j < n && !isHardLineBreak(cps[j]) && (!breaks || breaks[j] === NO_BREAK)) {\n if (!hangs(cps[j])) ink = j + 1;\n j++;\n }\n if (breaks && i > start && widthOf(start, ink) > maxWidth) {\n lines.push({ start, end: i, wrapped: true });\n start = i;\n }\n i = j;\n }\n if (start < n) lines.push({ start, end: n, wrapped: false });\n return lines;\n}\n","/**\n * Measured entries broken into lines, and one line set on its baseline: where\n * each cell and glyph lands once alignment, justification and visual order\n * have had their say.\n */\nimport type { LineOrder } from './bidiLines';\nimport type { Entry } from './layoutEntries';\nimport type { LaidOutCell, LaidOutLineBox, PlacedGlyph } from './layoutRuns';\nimport { hangs, wrapLines } from './lineBreak/wrapLines';\nimport { tabAdvance, widthWithTabs } from './tabStops';\n\n/** One line's entries, measured and not yet placed. */\nexport interface Line {\n /** Index of its first entry among the entries that were broken. */\n start: number;\n /** In logical order. The first has dropped the kerning before it, and a tab\n * has run out to its stop. */\n entries: Entry[];\n width: number;\n height: number;\n /** Line top to baseline. */\n ascent: number;\n /** Closed by the wrap rather than by a hard break or the end of the text:\n * the lines `justify` spreads. */\n wrapped: boolean;\n /** Source offset just past the line's last character. */\n srcEnd: number;\n}\n\n/**\n * How far above the baseline an entry's inline box reaches, CSS's way: the\n * face's ascent plus half the leading its line height leaves around ascent\n * and descent. A face taller than its line box gets negative leading and\n * overflows the box rather than growing it.\n */\nfunction aboveBaseline(e: Entry, lineHeight: number): number {\n const k = e.lineSize / e.metrics.size;\n const ascent = e.metrics.ascent * k;\n if (e.metrics.descent === undefined) return ascent;\n return (e.lineSize * lineHeight - ascent - e.metrics.descent * k) / 2 + ascent;\n}\n\n/**\n * Break `entries` into lines: at hard breaks, and at UAX #14 opportunities\n * when `maxWidth` is finite. A line is as tall as its tallest entry's line\n * box, with one baseline sunk to clear whichever entry reaches highest above\n * it — from unshifted ascents, so a `baselineShift` cannot drag the rest of\n * the line with it. A blank line takes both from the hard break that closed\n * it, the only carrier of a size it has.\n */\nexport function breakLines(\n entries: readonly Entry[],\n maxWidth: number,\n lineHeight: number,\n): Line[] {\n /** `sum[k]`: width of entries `[0, k)` set end to end. */\n const sum = new Float64Array(entries.length + 1);\n const tabs: number[] = [];\n entries.forEach((e, k) => {\n sum[k + 1] = sum[k] + e.kerningBefore + e.advance + e.tracking;\n if (e.tab) tabs.push(k);\n });\n // An entry opening a line drops the kerning before it.\n const flatWidth = (start: number, end: number): number =>\n entries[start].advance + entries[start].tracking + sum[end] - sum[start + 1];\n const widthOf = tabs.length === 0 ? flatWidth : (start: number, end: number): number =>\n widthWithTabs(start, end, tabs, (k) => entries[k].tab!, flatWidth);\n\n return wrapLines(entries.map((e) => e.cp), maxWidth, widthOf).map((span): Line => {\n const line: Line = {\n start: span.start, entries: [], width: 0, height: 0, ascent: 0,\n wrapped: span.wrapped, srcEnd: 0,\n };\n if (span.start === span.end) {\n const brk = entries[span.end];\n line.height = brk.lineSize * lineHeight;\n line.ascent = aboveBaseline(brk, lineHeight);\n line.srcEnd = brk.srcIndex;\n return line;\n }\n for (let k = span.start; k < span.end; k++) {\n const e = entries[k];\n const opened = k > span.start ? e : { ...e, kerningBefore: 0 };\n const placed = e.tab\n ? { ...opened, advance: tabAdvance(line.width, e.tab.stop, e.tab.min) }\n : opened;\n line.entries.push(placed);\n line.width += placed.kerningBefore + placed.advance + placed.tracking;\n line.height = Math.max(line.height, e.lineSize * lineHeight);\n line.ascent = Math.max(line.ascent, aboveBaseline(placed, lineHeight));\n }\n line.srcEnd = entries[span.end - 1].srcEnd;\n return line;\n });\n}\n\n/** Width of the white space a line ends in. CSS aligns a line on its ink, so\n * this hangs past the aligned edge; each space keeps its cell and advance. */\nfunction hungWidth(entries: readonly Entry[]): number {\n let hung = 0;\n for (let k = entries.length - 1; k >= 0 && hangs(entries[k].cp); k--) {\n const e = entries[k];\n hung += e.kerningBefore + e.advance + e.tracking;\n }\n return hung;\n}\n\n/** Positions of the spaces between a line's words. Leading spaces are\n * zero-width slots and trailing ones hang, so neither is a gap. */\nfunction wordGaps(entries: readonly Entry[]): Set<number> {\n const gaps = new Set<number>();\n let first = 0;\n while (first < entries.length && entries[first].cp === 32) first++;\n let last = entries.length - 1;\n while (last > first && entries[last].cp === 32) last--;\n for (let k = first + 1; k < last; k++) if (entries[k].cp === 32) gaps.add(k);\n return gaps;\n}\n\n/** Where a line's ink starts for `align`. With no box to align in, a line\n * anchors on its own width, as the canvas-2D `renderLabel` does. */\nfunction alignOffset(align: 'left' | 'center' | 'right', alignWidth: number, inkWidth: number): number {\n if (align === 'left') return 0;\n if (!Number.isFinite(alignWidth)) return align === 'center' ? -inkWidth / 2 : -inkWidth;\n const slack = alignWidth - inkWidth;\n return align === 'center' ? slack / 2 : slack;\n}\n\n/** A line set at its place in the text. */\nexport interface PlacedLine {\n box: LaidOutLineBox;\n /** Width of the line's ink, hung white space left out and any justified\n * spread counted. */\n inkWidth: number;\n}\n\n/**\n * Set `line` with its top at `y`: align it in `alignWidth`, spread it when it\n * is `justify`'s to spread, then walk the pen through `order`, giving every\n * entry a cell and a placed glyph.\n */\nexport function placeLine(\n line: Line,\n y: number,\n order: LineOrder,\n align: 'left' | 'center' | 'right',\n alignWidth: number,\n justify: boolean,\n): PlacedLine {\n const { entries } = line;\n const hung = hungWidth(entries);\n const inkWidth = line.width - hung;\n const slack = alignWidth - inkWidth;\n const gaps = justify && line.wrapped && Number.isFinite(alignWidth) && slack > 0\n ? wordGaps(entries)\n : new Set<number>();\n const gapExtra = gaps.size > 0 ? slack / gaps.size : 0;\n const spread = gapExtra * gaps.size;\n const inkLeft = spread > 0 ? 0 : alignOffset(align, alignWidth, inkWidth);\n // L1 gives a line's trailing spaces the paragraph's level, so in a\n // right-to-left paragraph they reorder to the left and hang off that side.\n const hangsLeft = hung > 0 && order.levels[entries.length - 1] % 2 === 1;\n const left = hangsLeft ? inkLeft - hung : inkLeft;\n const lineBaselineY = y + line.ascent;\n\n const cells: LaidOutCell[] = new Array(entries.length);\n const glyphs: PlacedGlyph[] = [];\n let penX = left;\n let prevPos = -1;\n for (const pos of order.visual) {\n const e = entries[pos];\n // Kerning is a gap between two adjacent characters, and the wrap measured\n // it logically. Reordering can put a different pair side by side: take\n // the gap that belongs to whichever of the two is logically second, and\n // none across a direction boundary, where the pair never touched.\n penX += prevPos < 0 ? 0\n : pos === prevPos + 1 ? e.kerningBefore\n : prevPos === pos + 1 ? entries[prevPos].kerningBefore\n : 0;\n prevPos = pos;\n const step = e.advance + e.tracking + (gaps.has(pos) ? gapExtra : 0);\n cells[pos] = {\n srcIndex: e.srcIndex, srcEnd: e.srcEnd, cp: e.cp, x: penX,\n advance: step, level: order.levels[pos],\n drawsInk: e.drawsInk, clusterEnd: e.clusterEnd,\n };\n glyphs.push({\n run: e.run, cp: e.cp, fontSize: e.fontSize,\n resolved: e.resolved, metrics: e.metrics, font: e.font, glyph: e.glyph,\n x: penX,\n // Positive raises, and y grows down, so the shift subtracts.\n baselineY: lineBaselineY - e.baselineShift,\n advance: e.advance, step,\n });\n penX += step;\n }\n\n return {\n box: {\n x0: left, y0: y, x1: left + line.width + spread, y1: y + line.height,\n baselineY: lineBaselineY, cells, glyphs, srcEnd: line.srcEnd, justified: spread > 0,\n },\n inkWidth: inkWidth + spread,\n };\n}\n","import type { TextAlign, TextDirection } from '../textStyle';\nimport type { BidiResolver } from './bidiSeam';\nimport { registeredBidi } from './bidiRegistry';\nimport { DEFAULT_TAB_SIZE } from './tabStops';\n\n/** Options for `layoutRuns`. */\nexport interface LayoutRunsOpts {\n /** Wrap width. `Infinity` never wraps. */\n maxWidth: number;\n /**\n * Width of the box `center` / `right` resolve within, with `x = 0` its left\n * edge. Default `maxWidth`. Separate from it so a box can align text it does\n * not wrap. When both are infinite a line anchors on its own width instead:\n * `x = 0` is its midpoint (`center`) or right edge (`right`).\n */\n alignWidth?: number;\n lineHeight: number;\n /**\n * `start` / `end` resolve against `direction`; `left` / `right` are absolute\n * and ignore it, the way CSS `text-align` treats the same values. `justify`\n * is `justify: true` with the start edge.\n */\n align: TextAlign;\n /**\n * Spread each line that wrapped across `alignWidth`, widening its word gaps\n * (spaces between words; not leading or hanging trailing ones) by equal\n * shares of the slack. A line that closes its paragraph, or has no gap, or\n * no slack, keeps `align` — so `align` is CSS `text-align-last` here.\n * Implied by `align: 'justify'`. Default `false`.\n */\n justify?: boolean;\n /**\n * Bidi engine. Default: the one given to `registerBidi`. With neither, the\n * text lays out in logical order, which is correct for left-to-right text\n * and wrong for right-to-left text — see the warning this emits when it\n * detects the latter without one.\n */\n bidi?: BidiResolver;\n /**\n * Reading direction: the base direction of the bidi analysis, and what\n * `start` / `end` resolve against. Default `'auto'`, each paragraph's own\n * first strong character, which only an engine can find: with none, `'auto'`\n * reads left to right.\n */\n direction?: TextDirection | 'auto';\n /**\n * Distance between tab stops, in spaces of the tab's own run (its advance\n * plus the run's tracking), as CSS `tab-size` counts it. A tab advances to\n * the next stop from the start of its line. Default 8.\n */\n tabSize?: number;\n}\n\n/** {@link LayoutRunsOpts} with every default filled in. */\nexport interface ResolvedLayoutOpts {\n maxWidth: number;\n alignWidth: number;\n lineHeight: number;\n align: TextAlign;\n justify: boolean;\n bidi: BidiResolver | null;\n direction: TextDirection | 'auto';\n tabSize: number;\n}\n\n/** Fill in the defaults `layoutRuns` lays out with. */\nexport function resolveLayoutOpts(opts: LayoutRunsOpts): ResolvedLayoutOpts {\n return {\n maxWidth: opts.maxWidth,\n alignWidth: opts.alignWidth ?? opts.maxWidth,\n lineHeight: opts.lineHeight,\n align: opts.align,\n justify: opts.justify === true || opts.align === 'justify',\n bidi: opts.bidi ?? registeredBidi(),\n direction: opts.direction ?? 'auto',\n tabSize: opts.tabSize ?? DEFAULT_TAB_SIZE,\n };\n}\n","/**\n * Runs-aware text layout: wraps `ResolvedRun[]` into lines and places every\n * glyph on them. What to draw for the result — which glyphs share a draw,\n * which tier paints each, where the decoration rules go — is `paintRuns`'.\n * Nothing here reads a run's paint, so recoloring text never lays it out again.\n *\n * A run's `letterSpacing` (world units, so it does not scale with `fontSize`)\n * is added to the advance *after* every grapheme cluster of that run,\n * including the last one on a line — the CSS `letter-spacing` rule. Trailing\n * tracking therefore widens the measured line width and counts toward\n * wrapping. Spaces are tracked like any other character; a newline is not.\n *\n * Word wrap is applied when `maxWidth` is finite, at UAX #14 break\n * opportunities. Forced line breaks are emitted at UAX #14's hard breaks, none\n * of which lays out a cell. Every run on a line shares one baseline, sunk to\n * clear whichever run reaches highest above it; line height is\n * `max(fontSize * lineHeight)` across the line. A face that states its ascent\n * and descent sits in its line the way CSS sets it — half the leading above the\n * ascent, negative when the face is taller than the line, so its glyphs overflow\n * the box rather than growing it. A run a relative size shrank\n * measures at its `strutSize` for both.\n *\n * `ResolvedRun.baselineShift` displaces a run off that shared baseline. The\n * shift moves the run's glyphs and its own decoration rules together, and does\n * not feed back into the line's baseline or its height.\n *\n * Every coordinate out of here is measured from the text's own top-left: the\n * caller translates. That is what lets a text node be dragged without\n * re-laying out.\n */\n\nimport type { BmFont, BmFontChar, GlyphMetrics, ResolveResult } from '@weasel-js/font';\nimport type { ResolvedRun } from '../runs/resolveRuns';\nimport { resolveAlign } from '../textStyle';\nimport { analyzeParagraphs, orderLine } from './bidiLines';\nimport { directionOfLevel, warnRtlWithoutEngine } from './bidiRegistry';\nimport { measureRuns, mirrorEntries } from './layoutEntries';\nimport { breakLines, placeLine } from './layoutLines';\nimport { resolveLayoutOpts, type LayoutRunsOpts } from './layoutOpts';\nimport { isHardLineBreak } from './lineBreak/lineBreaks';\n\n/**\n * One advance cell: a single code point's slot on a line.\n *\n * A cell spans its code point *plus* the kerning that precedes the next one,\n * so a caret snapped to the midpoint between two `x`s lands where the glyphs\n * were actually painted rather than where an unkerned re-measure would put it.\n */\nexport interface LaidOutCell {\n /** UTF-16 offset of this code point in the runs' concatenated source text.\n * Under a length-changing `textTransform` it is the offset of the source\n * character this one was mapped from, so neighbors can share it — both\n * `S` cells of an uppercased `ß` do. */\n srcIndex: number;\n /** One past that source character — `srcIndex + 2` for an astral one. */\n srcEnd: number;\n cp: number;\n /** Left edge of the cell, post-alignment, origin-relative.\n *\n * **Not monotonic across `cells`** once a bidi engine reorders a line: cells\n * stay in logical order and their x values do not. Sort on `x` for visual\n * order; never assume `cells[i + 1].x` is this cell's right edge. */\n x: number;\n /** Width of the cell: its glyph's advance, plus its run's tracking when it\n * closes a grapheme cluster, plus a justified gap's share of the slack. */\n advance: number;\n /** Resolved bidi embedding level — even reads left-to-right. 0 with no\n * engine, which is the same as saying the text was laid out logically. */\n level: number;\n /**\n * Whether this code point can put ink on the page. False for a space and\n * for a code point no tier could serve — each of which still holds its\n * slot. A zero-advance combining mark is `true`: it inks without advancing.\n * An emoji drawn as one color glyph inks from its cluster's closing code\n * point, which holds the whole advance; the ones before it are `false`.\n *\n * A property of the character and the face, not of this call: it does not\n * change when a dynamic bake lands or the outline threshold is crossed. A\n * blank-but-servable glyph (NBSP in a face that has one) reports `true`;\n * read the quad or outline geometry for exact ink extents.\n */\n drawsInk: boolean;\n /**\n * Whether this code point closes a grapheme cluster. A caret stops only\n * after a cell that does: never between a letter and its combining mark,\n * inside a joined emoji, or before a variation selector.\n */\n clusterEnd: boolean;\n}\n\n/**\n * One code point where the pen put it, with what a painter needs to draw it:\n * the tier that serves it and its record there. Carries no paint.\n */\nexport interface PlacedGlyph {\n /** Index of its run in the runs laid out. */\n run: number;\n cp: number;\n /** The glyph's own size, which small caps sets below its run's. */\n fontSize: number;\n /** The tier serving the glyph, which is not its run's own when the code\n * point escalated to the dynamic tier, and that tier's metrics. */\n resolved: ResolveResult;\n metrics: GlyphMetrics;\n /** The atlas to sample and the glyph's record in it. Both null on the\n * outline tier and for a slot with nothing to draw. A dynamic glyph's\n * record gains its atlas rect in place when its bake lands. */\n font: BmFont | null;\n glyph: BmFontChar | null;\n /** Pen position: the left edge of the glyph's slot. */\n x: number;\n /** Its line's baseline, raised by its run's `baselineShift`. */\n baselineY: number;\n /** The glyph's own advance. */\n advance: number;\n /** How far the pen moved past it: `advance`, its run's tracking, and a\n * justified gap's share of the slack. */\n step: number;\n}\n\n/**\n * One laid-out line's box.\n *\n * `[x0, x1]` is the line's own advance width *after* alignment — not the\n * wrap box — so a short centered line reports the span it actually occupies.\n * `[y0, y1]` is the full line box: `y0` is the pen's line top, and the box is\n * as tall as its tallest run's `lineHeight` times that run's size, or the\n * larger size a shrunken run inherited. Ink can escape it vertically; this is\n * the typographic box, not an ink bounding box.\n *\n * Emitted for every line including empty ones, so indices line up with the\n * wrap. An empty line has `x0 === x1`.\n */\nexport interface LaidOutLineBox {\n x0: number; y0: number; x1: number; y1: number;\n /** The line's baseline, for callers placing carets or rules against it. */\n baselineY: number;\n /**\n * One cell per code point on this line, in logical order. Every code point\n * the line covers has exactly one, drawn or not; only a newline has none,\n * since it separates cells rather than being one. The code points are the\n * drawn ones, after `textTransform`, so an uppercased `ß` has two cells.\n *\n * A caret stop is a cell's `x`, and the stop closing the line is `x1` /\n * `srcEnd` — there is one more stop than cell, except that cells sharing a\n * source span have no stop between them.\n */\n cells: LaidOutCell[];\n /** The same code points as placed glyphs, in visual order, left to right. */\n glyphs: PlacedGlyph[];\n /**\n * Source offset just past this line's last cell — the closing caret stop's\n * index, and the only source offset a blank line carries.\n */\n srcEnd: number;\n /** Whether `justify` spread this line's slack across its word gaps — never\n * for a line closing its paragraph, or one with no gap or no slack. */\n justified: boolean;\n}\n\n/** What {@link layoutRuns} returns. Every coordinate is relative to the text's own top-left. */\nexport interface LaidOutRuns {\n /** Per-line boxes in layout order: where the text actually sits inside its\n * wrap box. */\n lines: LaidOutLineBox[];\n /** The text's box. `width` is the widest line measured to its last\n * non-space cell — a trailing space hangs past the aligned edge, so a\n * block wrapped at `maxWidth` never reports wider than it. `height` is the\n * line boxes stacked. Not an ink box: a decoration rule, or a run shifted\n * off the baseline, can fall outside it. */\n bounds: { width: number; height: number };\n}\n\n/**\n * Lay out `runs` into lines of placed glyphs. Wrapping, baselines and tracking\n * follow the rules in this file's module doc.\n */\nexport function layoutRuns(\n runs: readonly ResolvedRun[],\n opts: LayoutRunsOpts,\n): LaidOutRuns {\n const o = resolveLayoutOpts(opts);\n const entries = measureRuns(runs, o.tabSize);\n const cps = entries.map((e) => e.cp);\n const { bidi } = o;\n // Each paragraph is analyzed once; each line then asks for its own range,\n // because L1 resets trailing whitespace against a line's end.\n const paragraphs = bidi\n ? analyzeParagraphs(bidi, cps, (i) => isHardLineBreak(cps[i]), o.direction)\n : null;\n if (!bidi) warnRtlWithoutEngine(cps);\n\n const lines: LaidOutLineBox[] = [];\n let y = 0;\n let width = 0;\n for (const line of breakLines(entries, o.maxWidth, o.lineHeight)) {\n const order = orderLine(paragraphs, line.start, line.entries.length);\n // L4, done per line rather than during analysis: the same code point\n // mirrors in one run and not in another, and the level is known only now.\n if (bidi) line.entries = mirrorEntries(line.entries, order.levels, (cp) => bidi.mirror(cp), runs);\n const reads = o.direction !== 'auto' ? o.direction\n : directionOfLevel(line.entries.length > 0 ? paragraphs?.baseLevel(line.start) ?? 0 : 0);\n const placed = placeLine(line, y, order, resolveAlign(o.align, reads), o.alignWidth, o.justify);\n lines.push(placed.box);\n width = Math.max(width, placed.inkWidth);\n y += line.height;\n }\n return { lines, bounds: { width, height: y } };\n}\n","let nextRefId = 1;\nconst refIds = new WeakMap<object, number>();\n\n/** A stable id for an object a string key cannot serialize. */\nexport function refId(o: object): number {\n let id = refIds.get(o);\n if (id === undefined) {\n id = nextRefId++;\n refIds.set(o, id);\n }\n return id;\n}\n","/**\n * Laid-out text, memoized. The one entry point every caller of `layoutRuns`\n * should reach for — the renderer's paint path, the silhouette measurement\n * behind picking, and caret hit-testing all answer from this.\n *\n * `layoutRuns` is the most expensive derivation in the kit — it walks every\n * codepoint, resolves a face per run, measures, wraps, aligns, and places\n * every glyph — and `drawText` ran it per text command per frame. Measured,\n * when it also built the draw groups: 2.0 ms/frame for 200 short labels, 9.3\n * for 1000, and 25.9 for 200 wrapped paragraphs.\n *\n * ### Two keys, tried in order\n *\n * **Array identity**, in a `WeakMap`, the same contract as the renderer's\n * `WeakMap<Path, Mesh>` — and for the same reason: it makes the entry\n * collectable with whatever owns the runs, and the lookup is a pointer\n * compare. `kit:text`'s memoized `paint` hands back a stable array per node,\n * so the renderer stays on this path.\n *\n * **Structure**, in a bounded `Map`, for every caller that cannot. Measuring\n * a pose resolves its style and allocates a fresh `ResolvedRun[]` each call,\n * so an identity-keyed cache could never hold anything for it — and those\n * callers run on the drag path, once per pose change. Serializing the runs is\n * real work, unlike the pointer compare above, which is exactly why it is\n * second: an identity hit never pays for it.\n *\n * Under either, one entry per distinct `(maxWidth, alignWidth, lineHeight,\n * align, direction, bidi engine, tab size)`. Position is deliberately absent:\n * `layoutRuns` emits origin-relative geometry and `drawText` translates at\n * upload, so a text node dragged across the page keeps hitting the same entry.\n * So is everything that only changes what is drawn — a run's fill, stroke and\n * decorations, the outline threshold — which `cachedPaintRuns` keys on\n * instead. Two runs arrays that differ only there share one layout.\n *\n * ### What the keys cannot see\n *\n * The font set. A face landing changes metrics with no change to the runs, so\n * every lookup compares `faceGeneration()` — advanced by a registration, a\n * load, a fallback policy, and the dynamic atlas measuring a face again or\n * emptying its pages — and drops everything when it moves. A deferred bake\n * landing does not advance it: that fills in a glyph record the layout\n * already holds, and moves no pen. Polled rather than subscribed: a\n * module-load subscription is a cross-package side effect that makes importing\n * this package require the font package's whole surface.\n *\n * ### Bounds\n *\n * Variants per runs array are capped and evicted wholesale, matching\n * `outlineMeshCache`: the refill cost is one layout, and the bookkeeping would\n * cost more than the misses it avoids. The structural map cannot ride an\n * array's lifetime the way the `WeakMap` does — nothing collects its keys —\n * so it is a real LRU with a hard entry count.\n */\n\nimport { faceGeneration } from '@weasel-js/font';\nimport type { ResolvedRun } from '../runs/resolveRuns';\nimport { resolveLayoutOpts, type LayoutRunsOpts } from './layoutOpts';\nimport { layoutRuns, type LaidOutRuns } from './layoutRuns';\nimport { refId } from './refId';\n\n/** Distinct option combinations held for one runs array before the whole set\n * is dropped. Sized for \"a few views onto the same text\". */\nexport const LAYOUT_CACHE_VARIANT_LIMIT = 8;\n\n/** Layouts held against the structural key before the least recently used one\n * is dropped. Sized for \"every text node visible on a page, plus slack\". */\nexport const LAYOUT_CACHE_STRUCTURAL_LIMIT = 64;\n\ninterface Entry {\n /** `generation` when this entry was filled. */\n generation: number;\n byVariant: Map<string, LaidOutRuns>;\n}\n\nlet cache = new WeakMap<readonly ResolvedRun[], Entry>();\nlet structural = new Map<string, LaidOutRuns>();\nlet structuralGeneration = -1;\n\nfunction variantKey(opts: LayoutRunsOpts): string {\n const o = resolveLayoutOpts(opts);\n return `${o.maxWidth}|${o.alignWidth}|${o.lineHeight}|${o.align}|${o.justify ? 'j' : ''}`\n + `|${o.direction}|${o.bidi ? refId(o.bidi) : ''}|${o.tabSize}`;\n}\n\n/**\n * Everything about `runs` that changes the layout. The two author-supplied\n * strings are length-prefixed so neither can forge a neighbouring field by\n * containing a separator; every other term is a number or an enum.\n */\nfunction runsKey(runs: readonly ResolvedRun[]): string {\n let out = '';\n for (const r of runs) {\n out += `${r.text.length}:${r.text}|${r.fontFamily.length}:${r.fontFamily}`\n + `|${r.fontSize}|${r.fontWeight}|${r.fontStyle}|${r.letterSpacing}`\n + `|${r.baselineShift}|${r.strutSize ?? ''}`\n // Ends follow from starts and the length, so the two pin the cells.\n + `|${r.srcMap ? `${r.srcMap.length}:${r.srcMap.starts.join(',')}` : ''}`\n + `|${r.sizeMap ? r.sizeMap.join(',') : ''}|`;\n }\n return out;\n}\n\n/**\n * Lay `runs` out, reusing the previous result when nothing it depends on has\n * changed. Drop-in for `layoutRuns` — same arguments, same return value.\n *\n * **The result is shared and must be treated as immutable.** `drawText`\n * applies position and `verticalAlign` while packing vertices rather than by\n * shifting the layout, precisely so it can be handed the same object every\n * frame.\n */\nexport function cachedLayoutRuns(\n runs: readonly ResolvedRun[],\n opts: LayoutRunsOpts,\n): LaidOutRuns {\n const fonts = faceGeneration();\n let entry = cache.get(runs);\n if (entry === undefined) {\n entry = { generation: fonts, byVariant: new Map() };\n cache.set(runs, entry);\n } else if (entry.generation !== fonts) {\n entry.generation = fonts;\n entry.byVariant.clear();\n }\n\n const key = variantKey(opts);\n const hit = entry.byVariant.get(key);\n if (hit !== undefined) return hit;\n\n if (structuralGeneration !== fonts) {\n structural.clear();\n structuralGeneration = fonts;\n }\n const structuralK = `${runsKey(runs)}\\0${key}`;\n let laid = structural.get(structuralK);\n if (laid !== undefined) {\n // Re-insert to move it to the young end; `Map` iterates in insertion order,\n // which is what makes `keys().next()` the least recently used.\n structural.delete(structuralK);\n } else {\n laid = layoutRuns(runs, opts);\n if (structural.size >= LAYOUT_CACHE_STRUCTURAL_LIMIT) {\n structural.delete(structural.keys().next().value!);\n }\n }\n structural.set(structuralK, laid);\n\n if (entry.byVariant.size >= LAYOUT_CACHE_VARIANT_LIMIT) entry.byVariant.clear();\n entry.byVariant.set(key, laid);\n return laid;\n}\n\n/** Test helper. Do not call from product code. */\nexport function _resetLayoutCacheForTests(): void {\n cache = new WeakMap();\n structural = new Map();\n structuralGeneration = -1;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { S as StyledRun, T as TextStyle, L as LaidOutRuns, R as ResolvedTextStyle, a as ResolvedRun, b as LayoutRunsOpts, c as TextPaint } from './test-seams-BypGSlZj.js';
2
2
  export { B as BidiAnalysis, d as BidiReordering, e as BidiResolver, D as DEFAULT_TEXT_STYLE, F as FontVariantCaps, f as LAYOUT_CACHE_STRUCTURAL_LIMIT, g as LAYOUT_CACHE_VARIANT_LIMIT, h as LaidOutCell, i as LaidOutLineBox, M as MARKDOWN_RUN_GRAMMAR, P as PlacedGlyph, j as RunFlag, k as RunGrammar, l as RunMarker, m as RunSourceMap, n as SCRIPT_METRICS, o as SMALL_CAPS_SCALE, p as ScriptPreset, q as SmallCapsText, r as TextAlign, s as TextDirection, t as TextTransform, u as TransformedRunText, v as cachedLayoutRuns, w as fontString, x as isBoldWeight, y as isSmallCapsLetter, z as layoutRuns, A as markdownToRuns, C as numericWeight, E as paragraphDirection, G as registerBidi, H as resolveAlign, I as resolveRunFace, J as resolveRuns, K as resolveTextStyle, N as runsToMarkdown, O as runsToPlainText, Q as scriptMetrics, U as scriptMetricsFor, V as smallCapsScale, W as smallCapsScaleFor, X as smallCapsText, Y as toRuns, Z as transformRunTexts } from './test-seams-BypGSlZj.js';
3
- import { FaceRuleMetrics, FaceMetrics, FontStyle, BmFontChar } from '@weasel-js/font';
3
+ import { FaceRuleMetrics, FaceMetrics, FontStyle, BmFontChar, ResolveResult } from '@weasel-js/font';
4
4
  import { Fill, Stroke } from '@weasel-js/paint';
5
5
  import { Rect, PathInWorldPose, PolygonPath } from '@weasel-js/geom';
6
6
  import { Mixed } from '@weasel-js/registry';
@@ -162,9 +162,10 @@ interface LaidOutQuad {
162
162
  * One glyph the renderer should tessellate rather than sample.
163
163
  *
164
164
  * `d` is em-space SVG path data — 1 unit is 1 em, y grows down, origin on the
165
- * baseline at the pen. Placing it is therefore a uniform scale by `scale`
165
+ * baseline at the pen — with any synthetic bold already grown into it. Placing it is therefore a uniform scale by `scale`
166
166
  * followed by a translate to `(x, baselineY)`. `key` identifies the cached
167
- * tessellation — face identity plus codepoint.
167
+ * tessellation — face identity plus codepoint, plus the growth of a synthetic
168
+ * bold.
168
169
  */
169
170
  interface LaidOutOutlineGlyph {
170
171
  d: string;
@@ -189,7 +190,8 @@ interface LaidOutGroup {
189
190
  /** Resolved variant — matches the registered atlas and the texture-cache key. */
190
191
  weight: number;
191
192
  style: FontStyle;
192
- /** Gap between the request and the resolved match, for the renderer to fake. */
193
+ /** Gap between the request and the resolved match, for the renderer to fake.
194
+ * An `'outline'` group's bold is already grown into its glyphs. */
193
195
  synthetic: {
194
196
  bold: boolean;
195
197
  italic: boolean;
@@ -209,7 +211,7 @@ interface LaidOutGroup {
209
211
  /** Outline painted over the glyphs. Only ever set on an `'outline'` group —
210
212
  * the SDF tiers have no geometry to stroke, which is why a stroke pulls its
211
213
  * run onto the outline tier at any size. A run the tier cannot serve at all
212
- * (no registered outlines, synthetic bold) stays on the atlas, unstroked. */
214
+ * (no registered outlines) stays on the atlas, unstroked. */
213
215
  stroke?: Stroke;
214
216
  /** Textured glyph quads. Always empty for an `'outline'` group. */
215
217
  quads: LaidOutQuad[];
@@ -659,6 +661,33 @@ declare function setFlagOverRange(runs: readonly StyledRun[], style: TextStyle,
659
661
  */
660
662
  declare const SYNTHETIC_ITALIC_RADIANS = 0.2094;
661
663
 
664
+ /**
665
+ * Synthetic bold as geometry. The renderer fakes a missing bold face by
666
+ * dropping the distance-field threshold, which moves every edge of the glyph
667
+ * outward by `syntheticBoldGrowth`; outlining it is the glyph's own outline
668
+ * grown by that distance.
669
+ */
670
+
671
+ /**
672
+ * How far synthetic bold grows a glyph served as `resolved`, in em per side,
673
+ * and how its corners turn; `null` when the renderer draws it unshifted.
674
+ * An MSDF atlas keeps sharp corners, so its shifted edge meets in a miter; a
675
+ * canvas bake is a true distance field, whose shifted edge rounds them.
676
+ */
677
+ declare function syntheticBoldOffset(resolved: ResolveResult): {
678
+ growth: number;
679
+ join: 'miter' | 'round';
680
+ } | null;
681
+ /**
682
+ * {@link emboldenGlyph} for the renderer's outline tier, which takes outline
683
+ * data: `d` grown as the field draws it, and a tag naming the growth for the
684
+ * glyph's tessellation key. `null` when the renderer draws `resolved` unshifted.
685
+ */
686
+ declare function emboldenGlyphD(d: string, resolved: ResolveResult): {
687
+ d: string;
688
+ tag: string;
689
+ } | null;
690
+
662
691
  /**
663
692
  * Text as path geometry: the glyph outlines a text node draws, placed in
664
693
  * world space and composed into one `Path`. The glyphs are the ones
@@ -752,4 +781,4 @@ declare function textToPathsByPaint(data: TextOutlineSource, pose: PathInWorldPo
752
781
  */
753
782
  declare function loadTextOutlines(data: TextOutlineSource, opts?: TextToPathOptions): Promise<void>;
754
783
 
755
- export { BREAK_ALLOWED, BREAK_MANDATORY, DEFAULT_DECORATION_METRICS, type DecorationKind, type FaceMetricsFn, type FitTextPoseOptions, type FlagKey, type LabelOptions, type LaidOutDecoration, type LaidOutGroup, type LaidOutOutlineGlyph, type LaidOutQuad, LaidOutRuns, type LayoutLine, type LayoutResult, LayoutRunsOpts, type MarkdownFontOptions, type MeasureFn, type MeasureTextBoundsOpts, type MeasuredSpan, type MeasuredText, NO_BREAK, type PaintRunsOpts, type PaintedRuns, type PointInTextPoseOpts, type PositionedRun, type RangeStyle, ResolvedRun, ResolvedTextStyle, type RunStylePatch, SYNTHETIC_ITALIC_RADIANS, type SetFlagResult, type StyleKey, StyledRun, type TextLineBoxesOpts, type TextNodeSource, type TextOutlineSource, TextOutlinesError, type TextOutlinesFailure, TextPaint, type TextPaintPath, type TextPose, type TextPoseLayout, type TextPoseLayoutInput, type TextRenderer, TextStyle, type TextToPathOptions, type TextVerticalAlign, applyStyleToRange, cachedPaintRuns, caretIndexAt, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, fitTextPose, isHardLineBreak, isTextData, layoutMarkdown, layoutTextPose, lineBreakOpportunities, loadTextOutlines, measureText, measureTextBounds, measuredWidth, nodeHasFlag, paintRuns, patchRangeStyle, pointInTextPose, rangeWeight, renderLabel, runsCarryStyling, setFlagOverRange, styleAtRange, supersededKey, textLineBoxes, textPoseLayoutInput, textToPath, textToPathsByPaint, unboldPatch, verticalAlignOffset };
784
+ export { BREAK_ALLOWED, BREAK_MANDATORY, DEFAULT_DECORATION_METRICS, type DecorationKind, type FaceMetricsFn, type FitTextPoseOptions, type FlagKey, type LabelOptions, type LaidOutDecoration, type LaidOutGroup, type LaidOutOutlineGlyph, type LaidOutQuad, LaidOutRuns, type LayoutLine, type LayoutResult, LayoutRunsOpts, type MarkdownFontOptions, type MeasureFn, type MeasureTextBoundsOpts, type MeasuredSpan, type MeasuredText, NO_BREAK, type PaintRunsOpts, type PaintedRuns, type PointInTextPoseOpts, type PositionedRun, type RangeStyle, ResolvedRun, ResolvedTextStyle, type RunStylePatch, SYNTHETIC_ITALIC_RADIANS, type SetFlagResult, type StyleKey, StyledRun, type TextLineBoxesOpts, type TextNodeSource, type TextOutlineSource, TextOutlinesError, type TextOutlinesFailure, TextPaint, type TextPaintPath, type TextPose, type TextPoseLayout, type TextPoseLayoutInput, type TextRenderer, TextStyle, type TextToPathOptions, type TextVerticalAlign, applyStyleToRange, cachedPaintRuns, caretIndexAt, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, emboldenGlyphD, fitTextPose, isHardLineBreak, isTextData, layoutMarkdown, layoutTextPose, lineBreakOpportunities, loadTextOutlines, measureText, measureTextBounds, measuredWidth, nodeHasFlag, paintRuns, patchRangeStyle, pointInTextPose, rangeWeight, renderLabel, runsCarryStyling, setFlagOverRange, styleAtRange, supersededKey, syntheticBoldOffset, textLineBoxes, textPoseLayoutInput, textToPath, textToPathsByPaint, unboldPatch, verticalAlignOffset };