three-text 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * three-text v0.4.0
2
+ * three-text v0.4.2
3
3
  * Copyright (C) 2025 Countertype LLC
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
@@ -178,8 +178,8 @@ const DEFAULT_EMERGENCY_STRETCH = 0;
178
178
  const SPACE_STRETCH_RATIO = 0.5; // stretch = 50% of space width (fontdimen 3 / fontdimen 2)
179
179
  const SPACE_SHRINK_RATIO = 1 / 3; // shrink = 33% of space width (fontdimen 4 / fontdimen 2)
180
180
 
181
- // Knuth-Plass line breaking algorithm with Liang hyphenation
182
- // References: tex.web (TeX), linebreak.c (LuaTeX), break.lua (SILE)
181
+ // Knuth-Plass line breaking with Liang hyphenation
182
+ // References: break.lua (SILE), tex.web (TeX), linebreak.c (LuaTeX), pTeX, xeCJK
183
183
  var ItemType;
184
184
  (function (ItemType) {
185
185
  ItemType[ItemType["BOX"] = 0] = "BOX";
@@ -195,7 +195,7 @@ var FitnessClass;
195
195
  FitnessClass[FitnessClass["DECENT"] = 2] = "DECENT";
196
196
  FitnessClass[FitnessClass["TIGHT"] = 3] = "TIGHT"; // lines shrinking 0.5 to 1.0 of their shrinkability
197
197
  })(FitnessClass || (FitnessClass = {}));
198
- // Active node management with Map for O(1) lookup by (position, fitness)
198
+ // Active node management with Map for lookup by (position, fitness)
199
199
  class ActiveNodeList {
200
200
  constructor() {
201
201
  this.nodesByKey = new Map();
@@ -215,6 +215,9 @@ class ActiveNodeList {
215
215
  existing.previous = node.previous;
216
216
  existing.hyphenated = node.hyphenated;
217
217
  existing.line = node.line;
218
+ existing.cumWidth = node.cumWidth;
219
+ existing.cumStretch = node.cumStretch;
220
+ existing.cumShrink = node.cumShrink;
218
221
  return true;
219
222
  }
220
223
  return false;
@@ -264,17 +267,24 @@ const EMERGENCY_STRETCH_INCREMENT = 0.1;
264
267
  class LineBreak {
265
268
  // TeX: badness function (tex.web lines 2337-2348)
266
269
  // Computes badness = 100 * (t/s)³ where t=adjustment, s=stretchability
270
+ // Simplified from TeX's fixed-point integer arithmetic to floating-point
271
+ //
272
+ // Returns INF_BAD+1 for overfull boxes so they're rejected even when
273
+ // threshold=INF_BAD in emergency pass
267
274
  static badness(t, s) {
268
275
  if (t === 0)
269
276
  return 0;
270
277
  if (s <= 0)
271
278
  return INF_BAD + 1;
272
- const r = Math.abs(t) / s;
279
+ const r = Math.abs(t / s);
273
280
  if (r > 10)
274
281
  return INF_BAD + 1;
275
- return Math.min(Math.round(100 * r * r * r), INF_BAD);
282
+ return Math.min(Math.round(100 * r ** 3), INF_BAD);
276
283
  }
277
- // TeX fitness classification (tex.web lines 16796-16812)
284
+ // TeX fitness classification (tex.web lines 16099-16105, 16799-16812)
285
+ // TeX uses badness thresholds 12 and 99, which correspond to ratios ~0.5 and ~1.0
286
+ // We use ratio directly since we compute it anyway. Well, and because SILE does
287
+ // it this way. Thanks Simon :)
278
288
  static fitnessClass(ratio) {
279
289
  if (ratio < -0.5)
280
290
  return FitnessClass.TIGHT; // shrinking significantly
@@ -284,27 +294,6 @@ class LineBreak {
284
294
  return FitnessClass.LOOSE; // stretching 0.5-1.0
285
295
  return FitnessClass.VERY_LOOSE; // stretching > 1.0
286
296
  }
287
- // Build prefix sums so we can quickly compute the width/stretch/shrink
288
- // of any range [a, b] as cumulative[b] - cumulative[a]
289
- static computeCumulativeWidths(items) {
290
- const n = items.length + 1;
291
- const width = new Float64Array(n);
292
- const stretch = new Float64Array(n);
293
- const shrink = new Float64Array(n);
294
- for (let i = 0; i < items.length; i++) {
295
- const item = items[i];
296
- width[i + 1] = width[i] + item.width;
297
- if (item.type === ItemType.GLUE) {
298
- stretch[i + 1] = stretch[i] + item.stretch;
299
- shrink[i + 1] = shrink[i] + item.shrink;
300
- }
301
- else {
302
- stretch[i + 1] = stretch[i];
303
- shrink[i + 1] = shrink[i];
304
- }
305
- }
306
- return { width, stretch, shrink };
307
- }
308
297
  static findHyphenationPoints(word, language = 'en-us', availablePatterns, lefthyphenmin = DEFAULT_LEFT_HYPHEN_MIN, righthyphenmin = DEFAULT_RIGHT_HYPHEN_MIN) {
309
298
  let patternTrie;
310
299
  if (availablePatterns && availablePatterns[language]) {
@@ -430,7 +419,7 @@ class LineBreak {
430
419
  );
431
420
  }
432
421
  static isCJPunctuation(char) {
433
- return this.isCJClosingPunctuation(char) || this.isCJOpeningPunctuation(char);
422
+ return (this.isCJClosingPunctuation(char) || this.isCJOpeningPunctuation(char));
434
423
  }
435
424
  static itemizeCJKText(text, measureText, measureTextWidths, context, startOffset = 0, glueParams) {
436
425
  const items = [];
@@ -453,7 +442,9 @@ class LineBreak {
453
442
  const char = chars[i];
454
443
  const nextChar = i < chars.length - 1 ? chars[i + 1] : null;
455
444
  if (/\s/.test(char)) {
456
- const width = widths ? (widths[i] ?? measureText(char)) : measureText(char);
445
+ const width = widths
446
+ ? (widths[i] ?? measureText(char))
447
+ : measureText(char);
457
448
  items.push({
458
449
  type: ItemType.GLUE,
459
450
  width,
@@ -496,11 +487,17 @@ class LineBreak {
496
487
  static itemizeParagraph(text, measureText, measureTextWidths, hyphenate, language, availablePatterns, lefthyphenmin, righthyphenmin, context, lineWidth) {
497
488
  const items = [];
498
489
  const chars = Array.from(text);
490
+ // Inter-character glue for CJK justification
491
+ // Matches pTeX's default \kanjiskip behavior
499
492
  let cjkGlueParams;
500
493
  const getCjkGlueParams = () => {
501
494
  if (!cjkGlueParams) {
502
495
  const baseCharWidth = measureText('字');
503
- cjkGlueParams = { width: 0, stretch: baseCharWidth * 0.04, shrink: baseCharWidth * 0.04 };
496
+ cjkGlueParams = {
497
+ width: 0,
498
+ stretch: baseCharWidth * 0.04,
499
+ shrink: baseCharWidth * 0.04
500
+ };
504
501
  }
505
502
  return cjkGlueParams;
506
503
  };
@@ -608,7 +605,9 @@ class LineBreak {
608
605
  }
609
606
  }
610
607
  }
611
- else if (hyphenate && segment.length >= lefthyphenmin + righthyphenmin && /^\p{L}+$/u.test(segment)) {
608
+ else if (hyphenate &&
609
+ segment.length >= lefthyphenmin + righthyphenmin &&
610
+ /^\p{L}+$/u.test(segment)) {
612
611
  const hyphenPoints = this.findHyphenationPoints(segment, language, availablePatterns, lefthyphenmin, righthyphenmin);
613
612
  if (hyphenPoints.length > 0) {
614
613
  let lastPoint = 0;
@@ -714,9 +713,8 @@ class LineBreak {
714
713
  // TeX: line_break inner loop (tex.web lines 16169-17256)
715
714
  // Finds optimal breakpoints using Knuth-Plass algorithm
716
715
  static lineBreak(items, lineWidth, threshold, emergencyStretch, context) {
717
- const cumulative = this.computeCumulativeWidths(items);
718
716
  const activeNodes = new ActiveNodeList();
719
- // Start node
717
+ // Start node with zero cumulative width
720
718
  activeNodes.insert({
721
719
  position: 0,
722
720
  line: 0,
@@ -725,17 +723,41 @@ class LineBreak {
725
723
  previous: null,
726
724
  hyphenated: false,
727
725
  active: true,
728
- activeIndex: 0
726
+ activeIndex: 0,
727
+ cumWidth: 0,
728
+ cumStretch: 0,
729
+ cumShrink: 0
729
730
  });
731
+ // Cumulative width from paragraph start, representing items[0..i-1]
732
+ let cumWidth = 0;
733
+ let cumStretch = 0;
734
+ let cumShrink = 0;
730
735
  // Process each item
731
736
  for (let i = 0; i < items.length; i++) {
732
737
  const item = items[i];
733
738
  // Check if this is a legal breakpoint
734
- const isBreakpoint = (item.type === ItemType.PENALTY && item.penalty < INFINITY_PENALTY) ||
735
- (item.type === ItemType.DISCRETIONARY) ||
736
- (item.type === ItemType.GLUE && i > 0 && items[i - 1].type === ItemType.BOX);
737
- if (!isBreakpoint)
739
+ const isBreakpoint = (item.type === ItemType.PENALTY &&
740
+ item.penalty < INFINITY_PENALTY) ||
741
+ item.type === ItemType.DISCRETIONARY ||
742
+ (item.type === ItemType.GLUE &&
743
+ i > 0 &&
744
+ items[i - 1].type === ItemType.BOX);
745
+ if (!isBreakpoint) {
746
+ // Accumulate width for non-breakpoint items
747
+ if (item.type === ItemType.BOX) {
748
+ cumWidth += item.width;
749
+ }
750
+ else if (item.type === ItemType.GLUE) {
751
+ const glue = item;
752
+ cumWidth += glue.width;
753
+ cumStretch += glue.stretch;
754
+ cumShrink += glue.shrink;
755
+ }
756
+ else if (item.type === ItemType.DISCRETIONARY) {
757
+ cumWidth += item.width;
758
+ }
738
759
  continue;
760
+ }
739
761
  // Get penalty and flagged status
740
762
  let pi = 0;
741
763
  let flagged = false;
@@ -757,23 +779,20 @@ class LineBreak {
757
779
  const bestDemerits = [Infinity, Infinity, Infinity, Infinity];
758
780
  // Nodes to deactivate
759
781
  const toDeactivate = [];
760
- // Current cumulative values at position i
761
- const curWidth = cumulative.width[i];
762
- const curStretch = cumulative.stretch[i];
763
- const curShrink = cumulative.shrink[i];
764
782
  // Try each active node as predecessor
765
783
  const active = activeNodes.getActive();
766
784
  for (let j = 0; j < active.length; j++) {
767
785
  const a = active[j];
768
- // Line width from a to i using cumulative arrays
769
- const lineW = curWidth - cumulative.width[a.position] + breakWidth;
770
- const lineStretch = curStretch - cumulative.stretch[a.position];
771
- const lineShrink = curShrink - cumulative.shrink[a.position];
786
+ // Line width from a to i
787
+ const lineW = cumWidth - a.cumWidth + breakWidth;
788
+ const lineStretch = cumStretch - a.cumStretch;
789
+ const lineShrink = cumShrink - a.cumShrink;
772
790
  const shortfall = lineWidth - lineW;
773
791
  let ratio;
774
792
  if (shortfall > 0) {
775
793
  const effectiveStretch = lineStretch + emergencyStretch;
776
- ratio = effectiveStretch > 0 ? shortfall / effectiveStretch : Infinity;
794
+ ratio =
795
+ effectiveStretch > 0 ? shortfall / effectiveStretch : Infinity;
777
796
  }
778
797
  else if (shortfall < 0) {
779
798
  ratio = lineShrink > 0 ? shortfall / lineShrink : -Infinity;
@@ -783,7 +802,7 @@ class LineBreak {
783
802
  }
784
803
  // Calculate badness
785
804
  const bad = this.badness(shortfall, shortfall > 0 ? lineStretch + emergencyStretch : lineShrink);
786
- // Check feasibility - THIS IS THE KEY FIX: compare bad vs threshold, not ratio
805
+ // Check feasibility
787
806
  if (ratio < -1) {
788
807
  toDeactivate.push(a);
789
808
  continue;
@@ -823,7 +842,10 @@ class LineBreak {
823
842
  previous: a,
824
843
  hyphenated: flagged,
825
844
  active: true,
826
- activeIndex: -1
845
+ activeIndex: -1,
846
+ cumWidth: cumWidth,
847
+ cumStretch: cumStretch,
848
+ cumShrink: cumShrink
827
849
  };
828
850
  }
829
851
  }
@@ -840,6 +862,19 @@ class LineBreak {
840
862
  if (activeNodes.size() === 0 && pi !== EJECT_PENALTY) {
841
863
  return null;
842
864
  }
865
+ // Accumulate width after evaluating this breakpoint
866
+ if (item.type === ItemType.BOX) {
867
+ cumWidth += item.width;
868
+ }
869
+ else if (item.type === ItemType.GLUE) {
870
+ const glue = item;
871
+ cumWidth += glue.width;
872
+ cumStretch += glue.stretch;
873
+ cumShrink += glue.shrink;
874
+ }
875
+ else if (item.type === ItemType.DISCRETIONARY) {
876
+ cumWidth += item.width;
877
+ }
843
878
  }
844
879
  // Find best solution
845
880
  let best = null;
@@ -903,7 +938,8 @@ class LineBreak {
903
938
  return allLines;
904
939
  }
905
940
  let useHyphenation = hyphenate;
906
- if (useHyphenation && (!hyphenationPatterns || !hyphenationPatterns[language])) {
941
+ if (useHyphenation &&
942
+ (!hyphenationPatterns || !hyphenationPatterns[language])) {
907
943
  logger.warn(`Hyphenation patterns for ${language} not available`);
908
944
  useHyphenation = false;
909
945
  }
@@ -925,7 +961,8 @@ class LineBreak {
925
961
  if (!width || width === Infinity) {
926
962
  const measuredWidth = measureText(text);
927
963
  perfLogger.end('LineBreak.breakText');
928
- return [{
964
+ return [
965
+ {
929
966
  text,
930
967
  originalStart: 0,
931
968
  originalEnd: text.length - 1,
@@ -933,7 +970,8 @@ class LineBreak {
933
970
  isLastLine: true,
934
971
  naturalWidth: measuredWidth,
935
972
  endedWithHyphen: false
936
- }];
973
+ }
974
+ ];
937
975
  }
938
976
  // First pass: without hyphenation
939
977
  let items = this.itemizeText(text, measureText, measureTextWidths, false, language, hyphenationPatterns, lefthyphenmin, righthyphenmin, context, width);
@@ -966,7 +1004,8 @@ class LineBreak {
966
1004
  return this.postLineBreak(text, items, breakpoints, width, align, direction, context);
967
1005
  }
968
1006
  perfLogger.end('LineBreak.breakText');
969
- return [{
1007
+ return [
1008
+ {
970
1009
  text,
971
1010
  originalStart: 0,
972
1011
  originalEnd: text.length - 1,
@@ -975,25 +1014,30 @@ class LineBreak {
975
1014
  isLastLine: true,
976
1015
  naturalWidth: measureText(text),
977
1016
  endedWithHyphen: false
978
- }];
1017
+ }
1018
+ ];
979
1019
  }
980
1020
  // TeX: post_line_break (tex.web lines 17260-17448)
981
1021
  // Creates the actual lines from the computed breakpoints
982
1022
  static postLineBreak(text, items, breakpoints, lineWidth, align, direction, context) {
983
1023
  if (breakpoints.length === 0) {
984
- return [{
1024
+ return [
1025
+ {
985
1026
  text,
986
1027
  originalStart: 0,
987
1028
  originalEnd: text.length - 1,
988
1029
  xOffset: 0
989
- }];
1030
+ }
1031
+ ];
990
1032
  }
991
1033
  const lines = [];
992
1034
  let lineStart = 0;
993
1035
  for (let i = 0; i < breakpoints.length; i++) {
994
1036
  const breakpoint = breakpoints[i];
995
1037
  const willHaveFinalLine = breakpoints[breakpoints.length - 1] + 1 < items.length - 1;
996
- const isLastLine = willHaveFinalLine ? false : i === breakpoints.length - 1;
1038
+ const isLastLine = willHaveFinalLine
1039
+ ? false
1040
+ : i === breakpoints.length - 1;
997
1041
  const lineTextParts = [];
998
1042
  let originalStart = -1;
999
1043
  let originalEnd = -1;
@@ -1003,7 +1047,8 @@ class LineBreak {
1003
1047
  for (let j = lineStart; j < breakpoint; j++) {
1004
1048
  const item = items[j];
1005
1049
  if ((item.type === ItemType.PENALTY && !item.text) ||
1006
- (item.type === ItemType.DISCRETIONARY && !item.noBreak)) {
1050
+ (item.type === ItemType.DISCRETIONARY &&
1051
+ !item.noBreak)) {
1007
1052
  continue;
1008
1053
  }
1009
1054
  if (item.originIndex !== undefined) {
@@ -1031,7 +1076,8 @@ class LineBreak {
1031
1076
  const breakItem = items[breakpoint];
1032
1077
  let endedWithHyphen = false;
1033
1078
  if (breakpoint < items.length) {
1034
- if (breakItem.type === ItemType.PENALTY && breakItem.flagged) {
1079
+ if (breakItem.type === ItemType.PENALTY &&
1080
+ breakItem.flagged) {
1035
1081
  lineTextParts.push('-');
1036
1082
  naturalWidth += breakItem.width;
1037
1083
  endedWithHyphen = true;
@@ -1097,7 +1143,8 @@ class LineBreak {
1097
1143
  if (item.type === ItemType.PENALTY)
1098
1144
  continue;
1099
1145
  if (item.originIndex !== undefined) {
1100
- if (finalOriginalStart === -1 || item.originIndex < finalOriginalStart) {
1146
+ if (finalOriginalStart === -1 ||
1147
+ item.originIndex < finalOriginalStart) {
1101
1148
  finalOriginalStart = item.originIndex;
1102
1149
  }
1103
1150
  if (item.originIndex > finalOriginalEnd) {
@@ -4509,7 +4556,14 @@ class TextShaper {
4509
4556
 
4510
4557
  var hb = {exports: {}};
4511
4558
 
4512
- var fs = {}; const readFileSync = () => { throw new Error('fs not available in browser'); };
4559
+ var fs = {};
4560
+ const readFileSync = (...args) => {
4561
+ const req = typeof globalThis !== 'undefined' ? globalThis.require : undefined;
4562
+ if (typeof req === 'function') {
4563
+ return req('fs').readFileSync(...args);
4564
+ }
4565
+ throw new Error('fs not available in this environment');
4566
+ };
4513
4567
 
4514
4568
  var fs$1 = /*#__PURE__*/Object.freeze({
4515
4569
  __proto__: null,
@@ -4520,7 +4574,7 @@ var fs$1 = /*#__PURE__*/Object.freeze({
4520
4574
  var require$$0 = /*@__PURE__*/getAugmentedNamespace(fs$1);
4521
4575
 
4522
4576
  (function (module, exports) {
4523
- var createHarfBuzz=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename;}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href;}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require$$0;scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){process.argv[1].replace(/\\/g,"/");}process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href;}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)};}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status);};xhr.onerror=reject;xhr.send(null);})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)};}}else;console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAPU8;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=new Int8Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAP32"]=new Int32Array(b);Module["HEAPU32"]=new Uint32Array(b);Module["HEAPF32"]=new Float32Array(b);new BigInt64Array(b);new BigUint64Array(b);}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift());}}callRuntimeCallbacks(onPreRuns);}function initRuntime(){runtimeInitialized=true;wasmExports["__wasm_call_ctors"]();}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift());}}callRuntimeCallbacks(onPostRuns);}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies);}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback();}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("hb.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw "both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason);}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return {env:wasmImports,wasi_snapshot_preview1:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;Module["wasmExports"]=wasmExports;wasmMemory=wasmExports["memory"];Module["wasmMemory"]=wasmMemory;updateMemoryViews();wasmTable=wasmExports["__indirect_function_table"];assignWasmExports(wasmExports);removeRunDependency();return wasmExports}addRunDependency();function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod));});})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status;}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module);}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var __abort_js=()=>abort("");var runtimeKeepaliveCounter=0;var __emscripten_runtime_keepalive_clear=()=>{noExitRuntime=false;runtimeKeepaliveCounter=0;};var timers={};var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e);};var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true;}quit_(code,new ExitStatus(code));};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status);};var _exit=exitJS;var maybeExit=()=>{if(!keepRuntimeAlive()){try{_exit(EXITSTATUS);}catch(e){handleException(e);}}};var callUserCallback=func=>{if(ABORT){return}try{func();maybeExit();}catch(e){handleException(e);}};var _emscripten_get_now=()=>performance.now();var __setitimer_js=(which,timeout_ms)=>{if(timers[which]){clearTimeout(timers[which].id);delete timers[which];}if(!timeout_ms)return 0;var id=setTimeout(()=>{delete timers[which];callUserCallback(()=>__emscripten_timeout(which,_emscripten_get_now()));},timeout_ms);timers[which]={id,timeout_ms};return 0};var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var uleb128EncodeWithLen=arr=>{const n=arr.length;return [n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(bytes);var instance=new WebAssembly.Instance(module,{e:{f:func}});var wrappedFunc=instance.exports["f"];return wrappedFunc};var wasmTable;var getWasmTableEntry=funcPtr=>wasmTable.get(funcPtr);var updateTableMap=(offset,count)=>{if(functionsInTableMap){for(var i=offset;i<offset+count;i++){var item=getWasmTableEntry(i);if(item){functionsInTableMap.set(item,i);}}}};var functionsInTableMap;var getFunctionAddress=func=>{if(!functionsInTableMap){functionsInTableMap=new WeakMap;updateTableMap(0,wasmTable.length);}return functionsInTableMap.get(func)||0};var freeTableIndexes=[];var getEmptyTableSlot=()=>{if(freeTableIndexes.length){return freeTableIndexes.pop()}return wasmTable["grow"](1)};var setWasmTableEntry=(idx,func)=>wasmTable.set(idx,func);var addFunction=(func,sig)=>{var rtn=getFunctionAddress(func);if(rtn){return rtn}var ret=getEmptyTableSlot();try{setWasmTableEntry(ret,func);}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);setWasmTableEntry(ret,wrapped);}functionsInTableMap.set(func,ret);return ret};var removeFunction=index=>{functionsInTableMap.delete(getWasmTableEntry(index));setWasmTableEntry(index,null);freeTableIndexes.push(index);};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])Module["arguments"];if(Module["thisProgram"])Module["thisProgram"];}Module["wasmMemory"]=wasmMemory;Module["wasmExports"]=wasmExports;Module["addFunction"]=addFunction;Module["removeFunction"]=removeFunction;var __emscripten_timeout;function assignWasmExports(wasmExports){Module["_hb_blob_create"]=wasmExports["hb_blob_create"];Module["_hb_blob_destroy"]=wasmExports["hb_blob_destroy"];Module["_hb_blob_get_length"]=wasmExports["hb_blob_get_length"];Module["_hb_blob_get_data"]=wasmExports["hb_blob_get_data"];Module["_hb_buffer_serialize_glyphs"]=wasmExports["hb_buffer_serialize_glyphs"];Module["_hb_buffer_create"]=wasmExports["hb_buffer_create"];Module["_hb_buffer_destroy"]=wasmExports["hb_buffer_destroy"];Module["_hb_buffer_get_content_type"]=wasmExports["hb_buffer_get_content_type"];Module["_hb_buffer_set_direction"]=wasmExports["hb_buffer_set_direction"];Module["_hb_buffer_set_script"]=wasmExports["hb_buffer_set_script"];Module["_hb_buffer_set_language"]=wasmExports["hb_buffer_set_language"];Module["_hb_buffer_set_flags"]=wasmExports["hb_buffer_set_flags"];Module["_hb_buffer_set_cluster_level"]=wasmExports["hb_buffer_set_cluster_level"];Module["_hb_buffer_get_length"]=wasmExports["hb_buffer_get_length"];Module["_hb_buffer_get_glyph_infos"]=wasmExports["hb_buffer_get_glyph_infos"];Module["_hb_buffer_get_glyph_positions"]=wasmExports["hb_buffer_get_glyph_positions"];Module["_hb_glyph_info_get_glyph_flags"]=wasmExports["hb_glyph_info_get_glyph_flags"];Module["_hb_buffer_guess_segment_properties"]=wasmExports["hb_buffer_guess_segment_properties"];Module["_hb_buffer_add_utf8"]=wasmExports["hb_buffer_add_utf8"];Module["_hb_buffer_add_utf16"]=wasmExports["hb_buffer_add_utf16"];Module["_hb_buffer_set_message_func"]=wasmExports["hb_buffer_set_message_func"];Module["_hb_language_from_string"]=wasmExports["hb_language_from_string"];Module["_hb_script_from_string"]=wasmExports["hb_script_from_string"];Module["_hb_version"]=wasmExports["hb_version"];Module["_hb_version_string"]=wasmExports["hb_version_string"];Module["_hb_feature_from_string"]=wasmExports["hb_feature_from_string"];Module["_malloc"]=wasmExports["malloc"];Module["_free"]=wasmExports["free"];Module["_hb_draw_funcs_set_move_to_func"]=wasmExports["hb_draw_funcs_set_move_to_func"];Module["_hb_draw_funcs_set_line_to_func"]=wasmExports["hb_draw_funcs_set_line_to_func"];Module["_hb_draw_funcs_set_quadratic_to_func"]=wasmExports["hb_draw_funcs_set_quadratic_to_func"];Module["_hb_draw_funcs_set_cubic_to_func"]=wasmExports["hb_draw_funcs_set_cubic_to_func"];Module["_hb_draw_funcs_set_close_path_func"]=wasmExports["hb_draw_funcs_set_close_path_func"];Module["_hb_draw_funcs_create"]=wasmExports["hb_draw_funcs_create"];Module["_hb_draw_funcs_destroy"]=wasmExports["hb_draw_funcs_destroy"];Module["_hb_face_create"]=wasmExports["hb_face_create"];Module["_hb_face_destroy"]=wasmExports["hb_face_destroy"];Module["_hb_face_reference_table"]=wasmExports["hb_face_reference_table"];Module["_hb_face_get_upem"]=wasmExports["hb_face_get_upem"];Module["_hb_face_collect_unicodes"]=wasmExports["hb_face_collect_unicodes"];Module["_hb_font_draw_glyph"]=wasmExports["hb_font_draw_glyph"];Module["_hb_font_glyph_to_string"]=wasmExports["hb_font_glyph_to_string"];Module["_hb_font_create"]=wasmExports["hb_font_create"];Module["_hb_font_set_variations"]=wasmExports["hb_font_set_variations"];Module["_hb_font_destroy"]=wasmExports["hb_font_destroy"];Module["_hb_font_set_scale"]=wasmExports["hb_font_set_scale"];Module["_hb_set_create"]=wasmExports["hb_set_create"];Module["_hb_set_destroy"]=wasmExports["hb_set_destroy"];Module["_hb_ot_var_get_axis_infos"]=wasmExports["hb_ot_var_get_axis_infos"];Module["_hb_set_get_population"]=wasmExports["hb_set_get_population"];Module["_hb_set_next_many"]=wasmExports["hb_set_next_many"];Module["_hb_shape"]=wasmExports["hb_shape"];__emscripten_timeout=wasmExports["_emscripten_timeout"];}var wasmImports={_abort_js:__abort_js,_emscripten_runtime_keepalive_clear:__emscripten_runtime_keepalive_clear,_setitimer_js:__setitimer_js,emscripten_resize_heap:_emscripten_resize_heap,proc_exit:_proc_exit};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun();}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun();},1);}else {doRun();}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()();}}}preInit();run();if(runtimeInitialized){moduleRtn=Module;}else {moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject;});}
4577
+ var createHarfBuzz=(()=>{var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;return async function(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename;}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href;}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require$$0;scriptDirectory=(typeof __dirname!=="undefined"?__dirname+"/":"");readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){process.argv[1].replace(/\\/g,"/");}process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href;}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)};}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status);};xhr.onerror=reject;xhr.send(null);})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)};}}else;console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var EXITSTATUS;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAPU8;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=new Int8Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAP32"]=new Int32Array(b);Module["HEAPU32"]=new Uint32Array(b);Module["HEAPF32"]=new Float32Array(b);new BigInt64Array(b);new BigUint64Array(b);}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift());}}callRuntimeCallbacks(onPreRuns);}function initRuntime(){runtimeInitialized=true;wasmExports["__wasm_call_ctors"]();}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift());}}callRuntimeCallbacks(onPostRuns);}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies);}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback();}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("hb.wasm")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw "both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason);}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return {env:wasmImports,wasi_snapshot_preview1:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;Module["wasmExports"]=wasmExports;wasmMemory=wasmExports["memory"];Module["wasmMemory"]=wasmMemory;updateMemoryViews();wasmTable=wasmExports["__indirect_function_table"];assignWasmExports(wasmExports);removeRunDependency();return wasmExports}addRunDependency();function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod));});})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status;}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module);}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var __abort_js=()=>abort("");var runtimeKeepaliveCounter=0;var __emscripten_runtime_keepalive_clear=()=>{noExitRuntime=false;runtimeKeepaliveCounter=0;};var timers={};var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e);};var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true;}quit_(code,new ExitStatus(code));};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status);};var _exit=exitJS;var maybeExit=()=>{if(!keepRuntimeAlive()){try{_exit(EXITSTATUS);}catch(e){handleException(e);}}};var callUserCallback=func=>{if(ABORT){return}try{func();maybeExit();}catch(e){handleException(e);}};var _emscripten_get_now=()=>performance.now();var __setitimer_js=(which,timeout_ms)=>{if(timers[which]){clearTimeout(timers[which].id);delete timers[which];}if(!timeout_ms)return 0;var id=setTimeout(()=>{delete timers[which];callUserCallback(()=>__emscripten_timeout(which,_emscripten_get_now()));},timeout_ms);timers[which]={id,timeout_ms};return 0};var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var uleb128EncodeWithLen=arr=>{const n=arr.length;return [n%128|128,n>>7,...arr]};var wasmTypeCodes={i:127,p:127,j:126,f:125,d:124,e:111};var generateTypePack=types=>uleb128EncodeWithLen(Array.from(types,type=>{var code=wasmTypeCodes[type];return code}));var convertJsFunctionToWasm=(func,sig)=>{var bytes=Uint8Array.of(0,97,115,109,1,0,0,0,1,...uleb128EncodeWithLen([1,96,...generateTypePack(sig.slice(1)),...generateTypePack(sig[0]==="v"?"":sig[0])]),2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);var module=new WebAssembly.Module(bytes);var instance=new WebAssembly.Instance(module,{e:{f:func}});var wrappedFunc=instance.exports["f"];return wrappedFunc};var wasmTable;var getWasmTableEntry=funcPtr=>wasmTable.get(funcPtr);var updateTableMap=(offset,count)=>{if(functionsInTableMap){for(var i=offset;i<offset+count;i++){var item=getWasmTableEntry(i);if(item){functionsInTableMap.set(item,i);}}}};var functionsInTableMap;var getFunctionAddress=func=>{if(!functionsInTableMap){functionsInTableMap=new WeakMap;updateTableMap(0,wasmTable.length);}return functionsInTableMap.get(func)||0};var freeTableIndexes=[];var getEmptyTableSlot=()=>{if(freeTableIndexes.length){return freeTableIndexes.pop()}return wasmTable["grow"](1)};var setWasmTableEntry=(idx,func)=>wasmTable.set(idx,func);var addFunction=(func,sig)=>{var rtn=getFunctionAddress(func);if(rtn){return rtn}var ret=getEmptyTableSlot();try{setWasmTableEntry(ret,func);}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);setWasmTableEntry(ret,wrapped);}functionsInTableMap.set(func,ret);return ret};var removeFunction=index=>{functionsInTableMap.delete(getWasmTableEntry(index));setWasmTableEntry(index,null);freeTableIndexes.push(index);};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])Module["arguments"];if(Module["thisProgram"])Module["thisProgram"];}Module["wasmMemory"]=wasmMemory;Module["wasmExports"]=wasmExports;Module["addFunction"]=addFunction;Module["removeFunction"]=removeFunction;var __emscripten_timeout;function assignWasmExports(wasmExports){Module["_hb_blob_create"]=wasmExports["hb_blob_create"];Module["_hb_blob_destroy"]=wasmExports["hb_blob_destroy"];Module["_hb_blob_get_length"]=wasmExports["hb_blob_get_length"];Module["_hb_blob_get_data"]=wasmExports["hb_blob_get_data"];Module["_hb_buffer_serialize_glyphs"]=wasmExports["hb_buffer_serialize_glyphs"];Module["_hb_buffer_create"]=wasmExports["hb_buffer_create"];Module["_hb_buffer_destroy"]=wasmExports["hb_buffer_destroy"];Module["_hb_buffer_get_content_type"]=wasmExports["hb_buffer_get_content_type"];Module["_hb_buffer_set_direction"]=wasmExports["hb_buffer_set_direction"];Module["_hb_buffer_set_script"]=wasmExports["hb_buffer_set_script"];Module["_hb_buffer_set_language"]=wasmExports["hb_buffer_set_language"];Module["_hb_buffer_set_flags"]=wasmExports["hb_buffer_set_flags"];Module["_hb_buffer_set_cluster_level"]=wasmExports["hb_buffer_set_cluster_level"];Module["_hb_buffer_get_length"]=wasmExports["hb_buffer_get_length"];Module["_hb_buffer_get_glyph_infos"]=wasmExports["hb_buffer_get_glyph_infos"];Module["_hb_buffer_get_glyph_positions"]=wasmExports["hb_buffer_get_glyph_positions"];Module["_hb_glyph_info_get_glyph_flags"]=wasmExports["hb_glyph_info_get_glyph_flags"];Module["_hb_buffer_guess_segment_properties"]=wasmExports["hb_buffer_guess_segment_properties"];Module["_hb_buffer_add_utf8"]=wasmExports["hb_buffer_add_utf8"];Module["_hb_buffer_add_utf16"]=wasmExports["hb_buffer_add_utf16"];Module["_hb_buffer_set_message_func"]=wasmExports["hb_buffer_set_message_func"];Module["_hb_language_from_string"]=wasmExports["hb_language_from_string"];Module["_hb_script_from_string"]=wasmExports["hb_script_from_string"];Module["_hb_version"]=wasmExports["hb_version"];Module["_hb_version_string"]=wasmExports["hb_version_string"];Module["_hb_feature_from_string"]=wasmExports["hb_feature_from_string"];Module["_malloc"]=wasmExports["malloc"];Module["_free"]=wasmExports["free"];Module["_hb_draw_funcs_set_move_to_func"]=wasmExports["hb_draw_funcs_set_move_to_func"];Module["_hb_draw_funcs_set_line_to_func"]=wasmExports["hb_draw_funcs_set_line_to_func"];Module["_hb_draw_funcs_set_quadratic_to_func"]=wasmExports["hb_draw_funcs_set_quadratic_to_func"];Module["_hb_draw_funcs_set_cubic_to_func"]=wasmExports["hb_draw_funcs_set_cubic_to_func"];Module["_hb_draw_funcs_set_close_path_func"]=wasmExports["hb_draw_funcs_set_close_path_func"];Module["_hb_draw_funcs_create"]=wasmExports["hb_draw_funcs_create"];Module["_hb_draw_funcs_destroy"]=wasmExports["hb_draw_funcs_destroy"];Module["_hb_face_create"]=wasmExports["hb_face_create"];Module["_hb_face_destroy"]=wasmExports["hb_face_destroy"];Module["_hb_face_reference_table"]=wasmExports["hb_face_reference_table"];Module["_hb_face_get_upem"]=wasmExports["hb_face_get_upem"];Module["_hb_face_collect_unicodes"]=wasmExports["hb_face_collect_unicodes"];Module["_hb_font_draw_glyph"]=wasmExports["hb_font_draw_glyph"];Module["_hb_font_glyph_to_string"]=wasmExports["hb_font_glyph_to_string"];Module["_hb_font_create"]=wasmExports["hb_font_create"];Module["_hb_font_set_variations"]=wasmExports["hb_font_set_variations"];Module["_hb_font_destroy"]=wasmExports["hb_font_destroy"];Module["_hb_font_set_scale"]=wasmExports["hb_font_set_scale"];Module["_hb_set_create"]=wasmExports["hb_set_create"];Module["_hb_set_destroy"]=wasmExports["hb_set_destroy"];Module["_hb_ot_var_get_axis_infos"]=wasmExports["hb_ot_var_get_axis_infos"];Module["_hb_set_get_population"]=wasmExports["hb_set_get_population"];Module["_hb_set_next_many"]=wasmExports["hb_set_next_many"];Module["_hb_shape"]=wasmExports["hb_shape"];__emscripten_timeout=wasmExports["_emscripten_timeout"];}var wasmImports={_abort_js:__abort_js,_emscripten_runtime_keepalive_clear:__emscripten_runtime_keepalive_clear,_setitimer_js:__setitimer_js,emscripten_resize_heap:_emscripten_resize_heap,proc_exit:_proc_exit};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun();}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun();},1);}else {doRun();}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()();}}}preInit();run();if(runtimeInitialized){moduleRtn=Module;}else {moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject;});}
4524
4578
  return moduleRtn}})();{module.exports=createHarfBuzz;module.exports.default=createHarfBuzz;}
4525
4579
  } (hb));
4526
4580
 
@@ -5504,7 +5558,11 @@ class Text {
5504
5558
  for (const pattern of Object.keys(options.color.byText)) {
5505
5559
  let index = 0;
5506
5560
  while ((index = options.text.indexOf(pattern, index)) !== -1) {
5507
- byTextMatches.push({ pattern, start: index, end: index + pattern.length });
5561
+ byTextMatches.push({
5562
+ pattern,
5563
+ start: index,
5564
+ end: index + pattern.length
5565
+ });
5508
5566
  for (let i = index; i < index + pattern.length; i++) {
5509
5567
  coloredTextIndices.add(i);
5510
5568
  }