@phin-tech/dottie 0.6.1 → 0.6.3

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.
@@ -1,4 +1,4 @@
1
- /*! dottie.js 0.6.1 | Apache-2.0 | https://github.com/phin-tech/dottie */
1
+ /*! dottie.js 0.6.3 | Apache-2.0 | https://github.com/phin-tech/dottie */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
4
4
  var __export = (target, all) => {
@@ -11,6 +11,7 @@ var __publicField = (obj, key, value2) => __defNormalProp(obj, typeof key !== "s
11
11
  var index_exports = {};
12
12
  __export(index_exports, {
13
13
  BOIL_DRAWINGS: () => BOIL_DRAWINGS,
14
+ BUNDLED_FONTS: () => BUNDLED_FONTS,
14
15
  DottieFormatError: () => DottieFormatError,
15
16
  DottiePlayer: () => DottiePlayer,
16
17
  KINDS: () => KINDS,
@@ -20,6 +21,7 @@ __export(index_exports, {
20
21
  Playback: () => Playback,
21
22
  SUPPORTED_VERSION: () => SUPPORTED_VERSION,
22
23
  VERSION: () => VERSION,
24
+ addFonts: () => addFonts,
23
25
  allowedURL: () => allowedURL,
24
26
  black: () => black,
25
27
  bounds: () => bounds,
@@ -31,6 +33,8 @@ __export(index_exports, {
31
33
  cloneElement: () => cloneElement,
32
34
  definePlayer: () => definePlayer,
33
35
  elementIndex: () => elementIndex,
36
+ fontFaces: () => fontFaces,
37
+ fontFile: () => fontFile,
34
38
  frameTimes: () => frameTimes,
35
39
  inkOnDark: () => inkOnDark,
36
40
  inspect: () => inspect,
@@ -49,6 +53,7 @@ __export(index_exports, {
49
53
  sameColor: () => sameColor,
50
54
  sampleTimes: () => sampleTimes,
51
55
  sceneAt: () => sceneAt,
56
+ setFontBase: () => setFontBase,
52
57
  stableSortBy: () => stableSortBy,
53
58
  still: () => still,
54
59
  svg: () => svg,
@@ -56,6 +61,7 @@ __export(index_exports, {
56
61
  themeNamed: () => themeNamed,
57
62
  themes: () => themes,
58
63
  transientElements: () => transientElements,
64
+ usedFonts: () => usedFonts,
59
65
  webLink: () => webLink,
60
66
  withRoughness: () => withRoughness
61
67
  });
@@ -70,7 +76,7 @@ var KNOWN_FIELDS = {
70
76
  symbol: ["id", "name", "width", "height", "layers", "elements", "timeline", "button", "params"],
71
77
  layer: ["id", "name", "visible", "locked"],
72
78
  rgba: ["r", "g", "b", "a"],
73
- style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "gridSize", "opacity", "dashOffset"],
79
+ style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "font", "gridSize", "opacity", "dashOffset", "textColor"],
74
80
  element: [
75
81
  "id",
76
82
  "kind",
@@ -111,7 +117,8 @@ var KNOWN_FIELDS = {
111
117
  extensionRef: ["id", "shape", "version", "params"],
112
118
  normalizedPoint: ["x", "y"],
113
119
  normalizedRect: ["x", "y", "width", "height"],
114
- connector: ["start", "end", "routing", "startHead", "endHead"],
120
+ connector: ["start", "end", "routing", "startHead", "endHead", "waypoints", "hops"],
121
+ waypoint: ["x", "y"],
115
122
  timeline: ["fps", "duration", "boil", "settle", "poster", "tracks", "camera", "markers"],
116
123
  track: ["element", "keys", "boil", "follow", "repeats", "march"],
117
124
  keyframe: ["t", "x", "y", "width", "height", "rotation", "strokeWidth", "stroke", "fill", "visible", "reveal", "opacity", "ease"],
@@ -190,9 +197,11 @@ var Reader = class {
190
197
  roughness: num(s.roughness) ?? 1,
191
198
  bowing: num(s.bowing) ?? 1,
192
199
  fontSize: num(s.fontSize) ?? 18,
200
+ font: str(s.font) || null,
193
201
  gridSize: num(s.gridSize) ?? null,
194
202
  opacity: num(s.opacity) ?? null,
195
- dashOffset: num(s.dashOffset) ?? null
203
+ dashOffset: num(s.dashOffset) ?? null,
204
+ textColor: rgba(s.textColor) ?? null
196
205
  };
197
206
  }
198
207
  endpoint(v) {
@@ -220,7 +229,12 @@ var Reader = class {
220
229
  end: this.endpoint(v.end),
221
230
  routing: routing && ["straight", "curved", "elbow"].includes(routing) ? routing : "straight",
222
231
  startHead: head(v.startHead, "none"),
223
- endHead: head(v.endHead, "arrow")
232
+ endHead: head(v.endHead, "arrow"),
233
+ waypoints: Array.isArray(v.waypoints) ? v.waypoints.filter(isObj).map((w) => {
234
+ this.fields(w, "waypoint");
235
+ return { x: num(w.x) ?? 0, y: num(w.y) ?? 0 };
236
+ }) : null,
237
+ hops: typeof v.hops === "boolean" ? v.hops : null
224
238
  };
225
239
  }
226
240
  image(v, table) {
@@ -497,8 +511,18 @@ function isAutomaticInk(c) {
497
511
  function cloneElement(e) {
498
512
  return {
499
513
  ...e,
500
- style: { ...e.style, stroke: { ...e.style.stroke }, fill: { ...e.style.fill } },
501
- connector: e.connector ? { ...e.connector, start: { ...e.connector.start }, end: { ...e.connector.end } } : null
514
+ style: {
515
+ ...e.style,
516
+ stroke: { ...e.style.stroke },
517
+ fill: { ...e.style.fill },
518
+ textColor: e.style.textColor ? { ...e.style.textColor } : null
519
+ },
520
+ connector: e.connector ? {
521
+ ...e.connector,
522
+ start: { ...e.connector.start },
523
+ end: { ...e.connector.end },
524
+ waypoints: e.connector.waypoints?.map((w) => ({ ...w })) ?? null
525
+ } : null
502
526
  };
503
527
  }
504
528
  function orderedElements(page) {
@@ -517,6 +541,159 @@ function elementIndex(page) {
517
541
  return m;
518
542
  }
519
543
 
544
+ // src/metrics.ts
545
+ var monoAdvance = 0.60205078125;
546
+ var monoAscent = 0.92822265625;
547
+ var monoDescent = 0.23583984375;
548
+ var families = { "Architects Daughter": { "faces": { "regular": { "ascent": 0.986328125, "descent": 0.4033203125, "k": {}, "leading": 0, "w": { " ": 400.39, "_": 686.52, "-": 310.55, "\u2013": 310.55, "\u2014": 411.13, ",": 177.73, ";": 124.02, ":": 166.99, "!": 134.77, "?": 505.86, ".": 140.63, "\u2026": 422.85, "\xB7": 140.63, "'": 162.11, "\u2018": 162.11, "\u2019": 162.11, '"': 236.33, "\u201C": 236.33, "\u201D": 236.33, "(": 297.85, ")": 351.56, "[": 424.8, "]": 541.02, "{": 352.54, "}": 478.52, "@": 1042.97, "*": 507.81, "/": 455.08, "\\": 501.95, "&": 669.92, "#": 637.7, "%": 518.55, "\u2022": 192.38, "`": 171.88, "^": 306.64, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 524.41, "\xD7": 470.7, "<": 475.59, "=": 492.19, ">": 471.68, "|": 145.51, "~": 444.34, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556.64, "0": 630.86, "1": 127.93, "2": 572.27, "3": 508.79, "4": 680.66, "5": 708.01, "6": 626.95, "7": 615.23, "8": 648.44, "9": 569.34, "a": 508.79, "A": 640.63, "b": 561.52, "B": 710.94, "c": 632.81, "C": 708.01, "d": 512.7, "D": 648.44, "e": 541.02, "E": 591.8, "\xE9": 541.02, "f": 593.75, "F": 692.38, "g": 515.63, "G": 692.38, "h": 495.12, "H": 605.47, "i": 151.37, "I": 151.37, "j": 177.73, "J": 529.3, "k": 614.26, "K": 605.47, "l": 157.23, "L": 692.38, "m": 778.32, "M": 827.15, "n": 500, "N": 626.95, "o": 562.5, "O": 669.92, "p": 556.64, "P": 637.7, "q": 513.67, "Q": 712.89, "r": 551.76, "R": 712.89, "s": 501.95, "S": 642.58, "t": 404.3, "T": 623.05, "u": 507.81, "U": 561.52, "v": 518.55, "V": 626.95, "w": 808.59, "W": 940.43, "x": 470.7, "X": 599.61, "y": 548.83, "Y": 534.18, "z": 495.12, "Z": 784.18 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } }, "Caveat": { "faces": { "bold": { "ascent": 0.9600067138671875, "descent": 0.3000030517578125, "k": { "AC": -20, "AE": -10, "AG": -10, "AH": -10, "AI": 10, "Aj": 10, "AJ": 10, "AL": -10, "AM": 10, "An": -10, "AO": -20, "AP": -10, "Aq": -10, "AQ": -20, "Ar": -10, "As": -10, "AS": -35, "AT": -50, "Au": -10, "AU": -20, "av": -20, "Av": -5, "AV": -40, "aw": -10, "AW": -20, "Ax": 10, "AX": -10, "ay": -20, "Ay": -10, "AY": -65, "Az": 20, "AZ": -10, "ba": -10, "bc": -10, "BC": -20, "bd": -10, "Bf": 10, "BF": -20, "Bg": 10, "bh": -5, "Bi": 10, "BI": -10, "bj": -5, "Bj": 10, "BJ": -10, "Bk": 10, "Bl": 10, "Bm": 10, "BP": -10, "BR": -10, "BS": -20, "BT": -40, "bu": -10, "BU": -20, "BV": -50, "BW": -50, "bx": -10, "Bx": 10, "BX": -40, "by": -10, "BY": -65, "Bz": 40, "BZ": -30, "CA": -20, "Cc": -5, "CC": -10, "Cd": -10, "CE": -10, "CG": -10, "Cj": 10, "CJ": -10, "CK": -10, "cl": 10, "Cl": 5, "Cn": -5, "CO": -10, "CP": -10, "CQ": -20, "Cs": -10, "CS": -10, "Ct": 10, "CT": -20, "Cu": -10, "CU": -10, "Cv": -20, "CV": -20, "cw": -10, "Cw": -10, "CW": -20, "Cx": 20, "CX": -30, "cy": -5, "CY": -35, "Cz": 20, "CZ": -40, "DA": -10, "Db": 10, "Dc": 10, "De": 10, "Df": 20, "DF": -10, "Dg": 10, "Dh": 10, "Di": 15, "DI": -10, "Dj": 5, "DJ": -10, "Dk": 10, "Dl": 10, "Dm": 20, "DM": -5, "dn": -10, "Do": 10, "Dp": 10, "Dq": 10, "Dr": 10, "Ds": 10, "dt": 10, "Dt": 20, "DT": -40, "du": -10, "Dv": 30, "DV": -30, "Dw": 20, "DW": -10, "Dx": 20, "DX": -50, "Dy": 10, "DY": -50, "Dz": 30, "DZ": -30, "EC": -10, "ED": -10, "EG": -10, "EJ": -10, "el": 10, "EO": -10, "EQ": -20, "ES": -40, "ET": -10, "EU": -20, "Ev": -10, "EV": -25, "Ew": -10, "EW": -30, "Ex": 10, "EX": -40, "Ey": -10, "EY": -50, "Ez": 20, "EZ": -20, "fa": -10, "Fa": -30, "FA": -40, "Fc": -20, "FC": -10, "Fd": -20, "FD": 20, "Fe": -15, "ff": 10, "Ff": 10, "FF": 20, "Fg": -10, "fh": 10, "Fh": 20, "fi": 10, "Fi": 10, "FI": 10, "fj": 10, "Fj": 10, "FJ": 20, "Fk": 10, "fl": 20, "Fl": 20, "FL": 10, "fm": 10, "FM": -10, "Fn": -20, "FN": 10, "Fo": -20, "FO": 10, "Fp": -10, "FP": -10, "Fq": -10, "FQ": 10, "Fr": -10, "FS": 10, "ft": 40, "Ft": 10, "FT": -30, "Fu": -10, "fv": 10, "Fv": 10, "FV": 10, "FW": 10, "fy": 10, "FY": 10, "Fz": 10, "FZ": -10, "GA": -10, "Gf": 10, "Gh": 10, "gi": 10, "Gi": 10, "GI": -10, "Gj": 10, "GJ": -10, "Gk": 10, "Gl": 10, "Gm": 10, "GM": -10, "GN": 10, "GP": -20, "GS": -10, "Gt": 10, "GU": -10, "Gv": 10, "GV": -10, "GW": -20, "Gx": 10, "GX": -40, "gy": 10, "GY": -40, "Gz": 10, "GZ": -20, "Hb": 10, "hf": -10, "Hf": 10, "hg": -20, "Hh": 10, "Hi": 10, "Hj": 20, "Hk": 10, "Hl": 10, "Hm": 10, "hq": -10, "hs": -10, "Ht": 20, "hv": -30, "Hv": 10, "hw": -15, "Hx": 20, "hy": -30, "Hy": 10, "Hz": 20, "Ia": -10, "IA": 10, "Ib": 10, "Ic": -10, "Id": -10, "ID": 30, "Ie": -10, "if": 10, "If": 20, "IF": 40, "Ig": -10, "Ih": 30, "Ii": 20, "II": 30, "Ij": 30, "IJ": 40, "Ik": 20, "IK": 10, "Il": 20, "IL": 10, "IM": 30, "In": -10, "IN": 20, "Io": -10, "Ip": 10, "Iq": -20, "Ir": -10, "IR": 10, "Is": -10, "It": 10, "Iu": -10, "IU": 10, "iv": 10, "Iv": -20, "IV": 30, "Iw": -25, "IW": 20, "Ix": 10, "IX": 10, "Iy": -10, "IY": 30, "Iz": 20, "IZ": 20, "Ja": -10, "Jb": 10, "Jc": -10, "Jd": -10, "Je": -10, "Jf": 10, "Jh": 10, "Ji": 10, "JI": -10, "Jj": 20, "JJ": 10, "Jk": 10, "Jl": 20, "Jn": -10, "Jo": -10, "JO": -10, "Jp": 10, "JP": -10, "Jq": -10, "JQ": -10, "JR": -10, "jt": 10, "Jt": 20, "JT": 10, "ju": -10, "Ju": -20, "JU": -10, "jx": 10, "JX": -25, "jy": 10, "JY": -20, "jz": 10, "Jz": 10, "JZ": -20, "Ka": -40, "kc": 20, "Kc": -40, "KC": -10, "Kd": -40, "KD": 10, "ke": 10, "Ke": -40, "kf": 20, "Kf": 10, "KF": 20, "Kg": -40, "KG": -10, "kh": 10, "Kh": 10, "ki": 10, "Ki": 10, "Kj": 40, "KJ": 20, "kk": 20, "Kk": 10, "kl": 20, "Kl": 10, "km": 10, "KM": 20, "Kn": -40, "ko": 10, "Ko": -50, "KO": -10, "Kp": 10, "Kq": -50, "kr": 10, "Ks": -40, "kt": 10, "Kt": 10, "KT": -10, "ku": 10, "Ku": -60, "kv": 10, "Kv": -30, "Kw": -40, "Kx": -10, "KX": -10, "ky": -10, "Ky": -30, "kz": 10, "Lb": -10, "LC": -20, "LE": -20, "Lf": 10, "Lg": -10, "LG": -20, "Lh": -10, "Li": 10, "LI": -40, "Lj": 20, "Lk": 10, "ll": 10, "Ll": 10, "LL": -20, "Ln": -20, "LO": -25, "Lp": 10, "Lq": -40, "LQ": -30, "Ls": -10, "LS": -65, "lt": 10, "Lt": -10, "LT": -70, "Lu": -40, "LU": -45, "Lv": -60, "LV": -70, "Lw": -40, "LW": -40, "Lx": 10, "Ly": -20, "LY": -90, "lz": 20, "Lz": 30, "LZ": -10, "Mb": 10, "md": 10, "Mf": 10, "Mh": 10, "Mi": 10, "MJ": 10, "Mk": 10, "Ml": 10, "mo": 20, "Mp": 10, "MP": -10, "Mq": -10, "MQ": -10, "MS": -20, "Mt": 20, "MT": -30, "Mu": -10, "MU": -20, "mv": -15, "Mv": 10, "MV": -20, "mw": -10, "MW": -30, "Mx": 10, "MX": -10, "my": -10, "My": -10, "MY": -50, "Mz": 10, "MZ": -10, "nb": -15, "Nb": 10, "Ne": 10, "Nf": 10, "Ng": 10, "Nh": 10, "Ni": 20, "Nj": 20, "Nk": 20, "Nl": 20, "Nm": 10, "Nq": 10, "ns": -5, "nt": -10, "Nt": 20, "nu": -10, "nv": -20, "Nv": 30, "nw": -20, "NW": -10, "Nx": 30, "NX": -20, "ny": -20, "Ny": 10, "NY": -20, "Nz": 40, "NZ": -10, "OA": -10, "OD": -10, "Of": 20, "Og": 20, "Oh": 10, "Oi": 20, "OI": -10, "oj": -5, "Oj": 20, "Ok": 10, "Ol": 20, "OL": 10, "Om": 20, "Oo": 10, "Op": 10, "Oq": 10, "OQ": 10, "Os": 10, "Ot": 20, "OT": -10, "ou": -10, "ov": 5, "Ov": 30, "OV": -10, "ow": -10, "Ow": 10, "OW": -10, "Ox": 30, "OX": -40, "oy": -10, "Oy": 20, "OY": -40, "Oz": 30, "OZ": -20, "Pa": -40, "PA": -40, "Pc": -30, "Pd": -40, "PD": -10, "Pe": -20, "Pf": 10, "Pg": -10, "Ph": 10, "Pi": 10, "PI": -10, "Pj": 20, "PJ": -10, "Pk": 10, "Pl": 10, "Pm": 10, "PM": -30, "pn": -10, "Pn": -10, "PN": -10, "Po": -30, "Pq": -30, "Ps": -20, "PS": 10, "Pt": 20, "pu": -10, "Pu": -30, "Pv": 10, "Px": 10, "PX": -35, "py": -10, "PY": -20, "Pz": 10, "PZ": -50, "Qb": 10, "Qf": 20, "Qg": 20, "qh": -10, "Qh": 10, "Qi": 20, "qj": 10, "Qj": 90, "QJ": 80, "Qk": 10, "Ql": 20, "Qm": 20, "qn": -10, "qo": -10, "Qp": 20, "Qt": 30, "QT": -10, "qu": -10, "Qv": 20, "QV": -10, "QW": -10, "Qx": 20, "QX": -20, "Qy": 50, "QY": -30, "Qz": 40, "QZ": -10, "ra": -5, "Ra": -10, "RA": -25, "RB": -10, "Rc": -10, "RC": -20, "Rd": -10, "RD": 10, "Re": -10, "RE": -20, "Rf": 20, "RF": 10, "Rg": -10, "RG": -10, "ri": 5, "RI": -10, "Rj": 30, "RJ": 30, "RL": -10, "RM": -20, "Rn": -10, "RN": 10, "Ro": -10, "RO": -10, "Rp": 20, "Rq": -30, "RQ": -10, "Rr": -10, "Rs": -10, "Rt": 10, "RT": -10, "Ru": -30, "RU": -20, "rv": 20, "RV": -10, "Rw": -10, "RW": -10, "Rx": 10, "RX": -20, "Ry": 10, "RY": -30, "Rz": 20, "RZ": -45, "Sa": -10, "Sb": 10, "Sc": -20, "Sd": -25, "SD": 20, "Se": -20, "SE": -10, "sf": 10, "Sf": 20, "SF": 30, "Sg": -20, "Sh": 20, "Si": 20, "SI": 10, "Sj": 30, "SJ": 30, "Sk": 10, "Sl": 20, "SL": 20, "Sn": -20, "SN": 10, "So": -10, "SO": 10, "Sq": -20, "Sr": -10, "Ss": -10, "st": 10, "St": 20, "Su": -20, "sv": 20, "Sv": -50, "SV": 20, "Sw": -30, "SW": 10, "sx": 15, "Sx": 10, "Sy": -15, "SY": 10, "sz": 20, "Sz": 20, "SZ": -10, "Ta": -90, "TA": -50, "Tc": -80, "TC": -10, "Td": -110, "TD": 10, "Te": -90, "TE": -10, "Tf": 20, "TF": 30, "Tg": -80, "TG": -10, "Th": 20, "ti": 5, "TI": 10, "Tj": 20, "Tk": 10, "Tl": 20, "Tm": -50, "TM": -30, "Tn": -90, "To": -90, "Tp": -80, "Tq": -120, "Tr": -80, "Ts": -80, "Tt": 10, "TT": -30, "Tu": -90, "tv": 10, "Tv": -70, "TV": 10, "Tw": -100, "tx": 20, "Tx": -60, "TX": -10, "Ty": -50, "tz": 30, "Tz": -40, "TZ": -10, "ub": -10, "Ub": 20, "UE": 10, "uf": 10, "Uf": 30, "UF": 10, "Ug": 10, "Uh": 30, "ui": 10, "Ui": 30, "Uj": 40, "uk": 10, "Uk": 20, "ul": 10, "Ul": 30, "Um": 30, "Up": 10, "UQ": 30, "Ur": 10, "UR": 10, "Us": 10, "Ut": 50, "UT": 20, "Uu": 10, "UU": 10, "Uv": 50, "UV": 10, "Uw": 10, "ux": 10, "Ux": 30, "UX": -10, "Uy": 10, "UY": -10, "uz": 30, "Uz": 30, "UZ": -10, "va": -10, "Va": -50, "VA": -55, "Vc": -30, "VC": -20, "Vd": -30, "Ve": -30, "VE": -20, "vf": 10, "VF": 10, "Vg": -30, "VG": -10, "vi": 10, "Vm": -10, "VM": -30, "Vn": -30, "VN": -10, "Vo": -30, "VO": -10, "Vp": -20, "VP": -20, "Vq": -30, "VQ": -10, "Vr": -20, "Vs": -30, "vt": 10, "VT": 20, "Vu": -30, "VU": -10, "vv": 20, "Vw": -30, "vx": 20, "VX": -20, "vy": 10, "VY": -10, "vz": 10, "VZ": -20, "WA": -20, "Wb": 20, "Wd": -10, "WD": 20, "We": 10, "Wf": 30, "WF": 20, "Wh": 30, "wi": 10, "Wi": 30, "WI": 10, "Wj": 40, "WJ": 20, "Wk": 20, "Wl": 40, "WL": 10, "Wm": 10, "WM": -10, "WS": 10, "Wt": 40, "WT": 30, "Wv": 30, "WV": 10, "wx": 10, "Wx": 20, "WX": -10, "Wy": 20, "WY": 10, "Wz": 30, "WZ": -10, "XA": -25, "XC": -20, "Xe": -10, "XE": -10, "xf": 10, "Xf": 10, "Xg": -10, "XG": -20, "xi": 10, "Xi": 10, "XI": -10, "Xj": 30, "xk": 10, "Xk": 10, "xl": 10, "Xl": 20, "Xm": 10, "XM": -25, "xn": -10, "XN": -10, "Xo": -10, "XO": -20, "xp": 10, "Xp": 10, "XP": -10, "xq": -10, "Xq": -40, "XQ": -25, "XS": -20, "xu": -5, "Xu": -30, "XU": -20, "xv": 10, "Xv": -20, "Xw": -30, "xx": 15, "Xx": 10, "XX": -30, "xy": -10, "Xy": -20, "XY": -20, "xz": 10, "Xz": 30, "ya": -10, "Ya": -70, "YA": -55, "Yc": -60, "YC": -30, "yd": -10, "Yd": -60, "YD": 10, "ye": 10, "Ye": -60, "YE": -30, "YF": 20, "Yg": -60, "YG": -30, "YH": -10, "YI": 10, "YJ": 10, "Ym": -30, "YM": -35, "yn": -10, "Yn": -60, "Yo": -60, "YO": -20, "Yp": -50, "YP": -10, "Yq": -60, "YQ": -10, "Yr": -60, "YR": -10, "Ys": -60, "YS": -10, "yt": 10, "YT": -15, "yu": -10, "Yu": -60, "yv": 10, "Yv": -20, "Yw": -50, "yx": 10, "Yx": -50, "YX": -30, "Yy": -40, "YY": -10, "Yz": -30, "YZ": -40, "Za": -20, "ZA": -20, "Zb": -10, "ZB": -10, "Zc": -10, "ZC": -20, "Zd": -30, "ZD": -10, "Ze": -40, "ZE": -20, "zf": 10, "Zg": -40, "ZG": -20, "zi": 10, "Zj": 10, "Zk": 10, "ZL": -10, "Zm": -10, "Zn": -50, "Zo": -30, "ZO": -30, "Zp": -10, "ZP": -10, "Zq": -50, "ZQ": -10, "Zr": -40, "ZR": -10, "Zs": -30, "ZS": -20, "zt": 10, "Zt": -10, "Zu": -30, "ZU": -10, "zv": 10, "Zv": -20, "Zw": -40, "ZW": -10, "zx": 10, "Zx": -10, "ZX": -10, "Zy": -30, "ZY": -20, "zz": 20, "Zz": 10, "ZZ": -10 }, "leading": 0, "w": { " ": 242, "_": 446, "-": 326, "\u2013": 446, "\u2014": 566, ",": 198, ";": 198, ":": 198, "!": 210, "?": 374, ".": 198, "\u2026": 594, "\xB7": 187, "'": 117, "\u2018": 117, "\u2019": 117, '"': 237, "\u201C": 267, "\u201D": 267, "(": 330, ")": 330, "[": 330, "]": 330, "{": 330, "}": 330, "@": 643, "*": 363, "/": 330, "\\": 330, "&": 564, "#": 559, "%": 600, "\u2022": 187, "`": 353, "^": 446, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 446, "\xD7": 446, "<": 446, "=": 446, ">": 446, "|": 330, "~": 446, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 450, "0": 450, "1": 450, "2": 450, "3": 450, "4": 450, "5": 434, "6": 471, "7": 446, "8": 450, "9": 438, "a": 446, "A": 511, "b": 444, "B": 523, "c": 364, "C": 477, "d": 402, "D": 587, "e": 334, "E": 534, "\xE9": 325, "f": 300, "F": 466, "g": 364, "G": 494, "h": 473, "H": 574, "i": 196, "I": 409, "j": 213, "J": 315, "k": 374, "K": 508, "l": 178, "L": 426, "m": 569, "M": 729, "n": 459, "N": 619, "o": 362, "O": 505, "p": 378, "P": 468, "q": 377, "Q": 492, "r": 360, "R": 544, "s": 350, "S": 495, "t": 331, "T": 458, "u": 370, "U": 482, "v": 331, "V": 490, "w": 517, "W": 720, "x": 343, "X": 524, "y": 341, "Y": 504, "z": 315, "Z": 522 } }, "regular": { "ascent": 0.9600067138671875, "descent": 0.3000030517578125, "k": { "AC": -20, "AE": -10, "AG": -10, "AH": -10, "AI": 10, "Aj": 10, "AJ": 10, "AL": -10, "AM": 10, "An": -10, "AO": -20, "AP": -10, "Aq": -10, "AQ": -20, "Ar": -10, "As": -10, "AS": -35, "AT": -50, "Au": -10, "AU": -20, "av": -20, "Av": -5, "AV": -40, "aw": -10, "AW": -20, "Ax": 10, "AX": -10, "ay": -20, "Ay": -10, "AY": -65, "Az": 20, "AZ": -10, "ba": -10, "bc": -10, "BC": -20, "bd": -10, "Bf": 10, "BF": -20, "Bg": 10, "bh": -5, "Bi": 10, "BI": -10, "bj": -5, "Bj": 10, "BJ": -10, "Bk": 10, "Bl": 10, "Bm": 10, "BP": -10, "BR": -10, "BS": -20, "BT": -40, "bu": -10, "BU": -20, "BV": -50, "BW": -50, "bx": -10, "Bx": 10, "BX": -40, "by": -10, "BY": -65, "Bz": 40, "BZ": -30, "CA": -20, "Cc": -5, "CC": -10, "Cd": -10, "CE": -10, "CG": -10, "Cj": 10, "CJ": -10, "CK": -10, "cl": 10, "Cl": 5, "Cn": -5, "CO": -10, "CP": -10, "CQ": -20, "Cs": -10, "CS": -10, "Ct": 10, "CT": -20, "Cu": -10, "CU": -10, "Cv": -20, "CV": -20, "cw": -10, "Cw": -10, "CW": -20, "Cx": 20, "CX": -30, "cy": -5, "CY": -35, "Cz": 20, "CZ": -40, "DA": -10, "Db": 10, "Dc": 10, "De": 10, "Df": 20, "DF": -10, "Dg": 10, "Dh": 10, "Di": 15, "DI": -10, "Dj": 5, "DJ": -10, "Dk": 10, "Dl": 10, "Dm": 20, "DM": -5, "dn": -10, "Do": 10, "Dp": 10, "Dq": 10, "Dr": 10, "Ds": 10, "dt": 10, "Dt": 20, "DT": -40, "du": -10, "Dv": 30, "DV": -30, "Dw": 20, "DW": -10, "Dx": 20, "DX": -50, "Dy": 10, "DY": -50, "Dz": 30, "DZ": -30, "EC": -10, "ED": -10, "EG": -10, "EJ": -10, "el": 10, "EO": -10, "EQ": -20, "ES": -40, "ET": -10, "EU": -20, "Ev": -10, "EV": -25, "Ew": -10, "EW": -30, "Ex": 10, "EX": -40, "Ey": -10, "EY": -50, "Ez": 20, "EZ": -20, "fa": -10, "Fa": -30, "FA": -40, "Fc": -20, "FC": -10, "Fd": -20, "FD": 20, "Fe": -15, "ff": 10, "Ff": 10, "FF": 20, "Fg": -10, "fh": 10, "Fh": 20, "fi": 10, "Fi": 10, "FI": 10, "fj": 10, "Fj": 10, "FJ": 20, "Fk": 10, "fl": 20, "Fl": 20, "FL": 10, "fm": 10, "FM": -10, "Fn": -20, "FN": 10, "Fo": -20, "FO": 10, "Fp": -10, "FP": -10, "Fq": -10, "FQ": 10, "Fr": -10, "FS": 10, "ft": 40, "Ft": 10, "FT": -30, "Fu": -10, "fv": 10, "Fv": 10, "FV": 10, "FW": 10, "fy": 10, "FY": 10, "Fz": 10, "FZ": -10, "GA": -10, "Gf": 10, "Gh": 10, "gi": 10, "Gi": 10, "GI": -10, "Gj": 10, "GJ": -10, "Gk": 10, "Gl": 10, "Gm": 10, "GM": -10, "GN": 10, "GP": -20, "GS": -10, "Gt": 10, "GU": -10, "Gv": 10, "GV": -10, "GW": -20, "Gx": 10, "GX": -40, "gy": 10, "GY": -40, "Gz": 10, "GZ": -20, "Hb": 10, "hf": -10, "Hf": 10, "hg": -20, "Hh": 10, "Hi": 10, "Hj": 20, "Hk": 10, "Hl": 10, "Hm": 10, "hq": -10, "hs": -10, "Ht": 20, "hv": -30, "Hv": 10, "hw": -15, "Hx": 20, "hy": -30, "Hy": 10, "Hz": 20, "Ia": -10, "IA": 10, "Ib": 10, "Ic": -10, "Id": -10, "ID": 30, "Ie": -10, "if": 10, "If": 20, "IF": 40, "Ig": -10, "Ih": 30, "Ii": 20, "II": 30, "Ij": 30, "IJ": 40, "Ik": 20, "IK": 10, "Il": 20, "IL": 10, "IM": 30, "In": -10, "IN": 20, "Io": -10, "Ip": 10, "Iq": -20, "Ir": -10, "IR": 10, "Is": -10, "It": 10, "Iu": -10, "IU": 10, "iv": 10, "Iv": -20, "IV": 30, "Iw": -25, "IW": 20, "Ix": 10, "IX": 10, "Iy": -10, "IY": 30, "Iz": 20, "IZ": 20, "Ja": -10, "Jb": 10, "Jc": -10, "Jd": -10, "Je": -10, "Jf": 10, "Jh": 10, "Ji": 10, "JI": -10, "Jj": 20, "JJ": 10, "Jk": 10, "Jl": 20, "Jn": -10, "Jo": -10, "JO": -10, "Jp": 10, "JP": -10, "Jq": -10, "JQ": -10, "JR": -10, "jt": 10, "Jt": 20, "JT": 10, "ju": -10, "Ju": -20, "JU": -10, "jx": 10, "JX": -25, "jy": 10, "JY": -20, "jz": 10, "Jz": 10, "JZ": -20, "Ka": -40, "kc": 20, "Kc": -40, "KC": -10, "Kd": -40, "KD": 10, "ke": 10, "Ke": -40, "kf": 20, "Kf": 10, "KF": 20, "Kg": -40, "KG": -10, "kh": 10, "Kh": 10, "ki": 10, "Ki": 10, "Kj": 40, "KJ": 20, "kk": 20, "Kk": 10, "kl": 20, "Kl": 10, "km": 10, "KM": 20, "Kn": -40, "ko": 10, "Ko": -50, "KO": -10, "Kp": 10, "Kq": -50, "kr": 10, "Ks": -40, "kt": 10, "Kt": 10, "KT": -10, "ku": 10, "Ku": -60, "kv": 10, "Kv": -30, "Kw": -40, "Kx": -10, "KX": -10, "ky": -10, "Ky": -30, "kz": 10, "Lb": -10, "LC": -20, "LE": -20, "Lf": 10, "Lg": -10, "LG": -20, "Lh": -10, "Li": 10, "LI": -40, "Lj": 20, "Lk": 10, "ll": 10, "Ll": 10, "LL": -20, "Ln": -20, "LO": -25, "Lp": 10, "Lq": -40, "LQ": -30, "Ls": -10, "LS": -65, "lt": 10, "Lt": -10, "LT": -70, "Lu": -40, "LU": -45, "Lv": -60, "LV": -70, "Lw": -40, "LW": -40, "Lx": 10, "Ly": -20, "LY": -90, "lz": 20, "Lz": 30, "LZ": -10, "Mb": 10, "md": 10, "Mf": 10, "Mh": 10, "Mi": 10, "MJ": 10, "Mk": 10, "Ml": 10, "mo": 20, "Mp": 10, "MP": -10, "Mq": -10, "MQ": -10, "MS": -20, "Mt": 20, "MT": -30, "Mu": -10, "MU": -20, "mv": -15, "Mv": 10, "MV": -20, "mw": -10, "MW": -30, "Mx": 10, "MX": -10, "my": -10, "My": -10, "MY": -50, "Mz": 10, "MZ": -10, "nb": -15, "Nb": 10, "Ne": 10, "Nf": 10, "Ng": 10, "Nh": 10, "Ni": 20, "Nj": 20, "Nk": 20, "Nl": 20, "Nm": 10, "Nq": 10, "ns": -5, "nt": -10, "Nt": 20, "nu": -10, "nv": -20, "Nv": 30, "nw": -20, "NW": -10, "Nx": 30, "NX": -20, "ny": -20, "Ny": 10, "NY": -20, "Nz": 40, "NZ": -10, "OA": -10, "OD": -10, "Of": 20, "Og": 20, "Oh": 10, "Oi": 20, "OI": -10, "oj": -5, "Oj": 20, "Ok": 10, "Ol": 20, "OL": 10, "Om": 20, "Oo": 10, "Op": 10, "Oq": 10, "OQ": 10, "Os": 10, "Ot": 20, "OT": -10, "ou": -10, "ov": 5, "Ov": 30, "OV": -10, "ow": -10, "Ow": 10, "OW": -10, "Ox": 30, "OX": -40, "oy": -10, "Oy": 20, "OY": -40, "Oz": 30, "OZ": -20, "Pa": -40, "PA": -40, "Pc": -30, "Pd": -40, "PD": -10, "Pe": -20, "Pf": 10, "Pg": -10, "Ph": 10, "Pi": 10, "PI": -10, "Pj": 20, "PJ": -10, "Pk": 10, "Pl": 10, "Pm": 10, "PM": -30, "pn": -10, "Pn": -10, "PN": -10, "Po": -30, "Pq": -30, "Ps": -20, "PS": 10, "Pt": 20, "pu": -10, "Pu": -30, "Pv": 10, "Px": 10, "PX": -35, "py": -10, "PY": -20, "Pz": 10, "PZ": -50, "Qb": 10, "Qf": 20, "Qg": 20, "qh": -10, "Qh": 10, "Qi": 20, "qj": 10, "Qj": 90, "QJ": 80, "Qk": 10, "Ql": 20, "Qm": 20, "qn": -10, "qo": -10, "Qp": 20, "Qt": 30, "QT": -10, "qu": -10, "Qv": 20, "QV": -10, "QW": -10, "Qx": 20, "QX": -20, "Qy": 50, "QY": -30, "Qz": 40, "QZ": -10, "ra": -5, "Ra": -10, "RA": -25, "RB": -10, "Rc": -10, "RC": -20, "Rd": -10, "RD": 10, "Re": -10, "RE": -20, "Rf": 20, "RF": 10, "Rg": -10, "RG": -10, "ri": 5, "RI": -10, "Rj": 30, "RJ": 30, "RL": -10, "RM": -20, "Rn": -10, "RN": 10, "Ro": -10, "RO": -10, "Rp": 20, "Rq": -30, "RQ": -10, "Rr": -10, "Rs": -10, "Rt": 10, "RT": -10, "Ru": -30, "RU": -20, "rv": 20, "RV": -10, "Rw": -10, "RW": -10, "Rx": 10, "RX": -20, "Ry": 10, "RY": -30, "Rz": 20, "RZ": -45, "Sa": -10, "Sb": 10, "Sc": -20, "Sd": -25, "SD": 20, "Se": -20, "SE": -10, "sf": 10, "Sf": 20, "SF": 30, "Sg": -20, "Sh": 20, "Si": 20, "SI": 10, "Sj": 30, "SJ": 30, "Sk": 10, "Sl": 20, "SL": 20, "Sn": -20, "SN": 10, "So": -10, "SO": 10, "Sq": -20, "Sr": -10, "Ss": -10, "st": 10, "St": 20, "Su": -20, "sv": 20, "Sv": -50, "SV": 20, "Sw": -30, "SW": 10, "sx": 15, "Sx": 10, "Sy": -15, "SY": 10, "sz": 20, "Sz": 20, "SZ": -10, "Ta": -90, "TA": -50, "Tc": -80, "TC": -10, "Td": -110, "TD": 10, "Te": -90, "TE": -10, "Tf": 20, "TF": 30, "Tg": -80, "TG": -10, "Th": 20, "ti": 5, "TI": 10, "Tj": 20, "Tk": 10, "Tl": 20, "Tm": -50, "TM": -30, "Tn": -90, "To": -90, "Tp": -80, "Tq": -120, "Tr": -80, "Ts": -80, "Tt": 10, "TT": -30, "Tu": -90, "tv": 10, "Tv": -70, "TV": 10, "Tw": -100, "tx": 20, "Tx": -60, "TX": -10, "Ty": -50, "tz": 30, "Tz": -40, "TZ": -10, "ub": -10, "Ub": 20, "UE": 10, "uf": 10, "Uf": 30, "UF": 10, "Ug": 10, "Uh": 30, "ui": 10, "Ui": 30, "Uj": 40, "uk": 10, "Uk": 20, "ul": 10, "Ul": 30, "Um": 30, "Up": 10, "UQ": 30, "Ur": 10, "UR": 10, "Us": 10, "Ut": 50, "UT": 20, "Uu": 10, "UU": 10, "Uv": 50, "UV": 10, "Uw": 10, "ux": 10, "Ux": 30, "UX": -10, "Uy": 10, "UY": -10, "uz": 30, "Uz": 30, "UZ": -10, "va": -10, "Va": -50, "VA": -55, "Vc": -30, "VC": -20, "Vd": -30, "Ve": -30, "VE": -20, "vf": 10, "VF": 10, "Vg": -30, "VG": -10, "vi": 10, "Vm": -10, "VM": -30, "Vn": -30, "VN": -10, "Vo": -30, "VO": -10, "Vp": -20, "VP": -20, "Vq": -30, "VQ": -10, "Vr": -20, "Vs": -30, "vt": 10, "VT": 20, "Vu": -30, "VU": -10, "vv": 20, "Vw": -30, "vx": 20, "VX": -20, "vy": 10, "VY": -10, "vz": 10, "VZ": -20, "WA": -20, "Wb": 20, "Wd": -10, "WD": 20, "We": 10, "Wf": 30, "WF": 20, "Wh": 30, "wi": 10, "Wi": 30, "WI": 10, "Wj": 40, "WJ": 20, "Wk": 20, "Wl": 40, "WL": 10, "Wm": 10, "WM": -10, "WS": 10, "Wt": 40, "WT": 30, "Wv": 30, "WV": 10, "wx": 10, "Wx": 20, "WX": -10, "Wy": 20, "WY": 10, "Wz": 30, "WZ": -10, "XA": -25, "XC": -20, "Xe": -10, "XE": -10, "xf": 10, "Xf": 10, "Xg": -10, "XG": -20, "xi": 10, "Xi": 10, "XI": -10, "Xj": 30, "xk": 10, "Xk": 10, "xl": 10, "Xl": 20, "Xm": 10, "XM": -25, "xn": -10, "XN": -10, "Xo": -10, "XO": -20, "xp": 10, "Xp": 10, "XP": -10, "xq": -10, "Xq": -40, "XQ": -25, "XS": -20, "xu": -5, "Xu": -30, "XU": -20, "xv": 10, "Xv": -20, "Xw": -30, "xx": 15, "Xx": 10, "XX": -30, "xy": -10, "Xy": -20, "XY": -20, "xz": 10, "Xz": 30, "ya": -10, "Ya": -70, "YA": -55, "Yc": -60, "YC": -30, "yd": -10, "Yd": -60, "YD": 10, "ye": 10, "Ye": -60, "YE": -30, "YF": 20, "Yg": -60, "YG": -30, "YH": -10, "YI": 10, "YJ": 10, "Ym": -30, "YM": -35, "yn": -10, "Yn": -60, "Yo": -60, "YO": -20, "Yp": -50, "YP": -10, "Yq": -60, "YQ": -10, "Yr": -60, "YR": -10, "Ys": -60, "YS": -10, "yt": 10, "YT": -15, "yu": -10, "Yu": -60, "yv": 10, "Yv": -20, "Yw": -50, "yx": 10, "Yx": -50, "YX": -30, "Yy": -40, "YY": -10, "Yz": -30, "YZ": -40, "Za": -20, "ZA": -20, "Zb": -10, "ZB": -10, "Zc": -10, "ZC": -20, "Zd": -30, "ZD": -10, "Ze": -40, "ZE": -20, "zf": 10, "Zg": -40, "ZG": -20, "zi": 10, "Zj": 10, "Zk": 10, "ZL": -10, "Zm": -10, "Zn": -50, "Zo": -30, "ZO": -30, "Zp": -10, "ZP": -10, "Zq": -50, "ZQ": -10, "Zr": -40, "ZR": -10, "Zs": -30, "ZS": -20, "zt": 10, "Zt": -10, "Zu": -30, "ZU": -10, "zv": 10, "Zv": -20, "Zw": -40, "ZW": -10, "zx": 10, "Zx": -10, "ZX": -10, "Zy": -30, "ZY": -20, "zz": 20, "Zz": 10, "ZZ": -10 }, "leading": 0, "w": { " ": 242, "_": 446, "-": 326, "\u2013": 446, "\u2014": 566, ",": 198, ";": 198, ":": 198, "!": 210, "?": 374, ".": 198, "\u2026": 594, "\xB7": 187, "'": 117, "\u2018": 117, "\u2019": 117, '"': 237, "\u201C": 267, "\u201D": 267, "(": 330, ")": 330, "[": 330, "]": 330, "{": 330, "}": 330, "@": 643, "*": 363, "/": 330, "\\": 330, "&": 564, "#": 559, "%": 600, "\u2022": 187, "`": 353, "^": 446, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 446, "\xD7": 446, "<": 446, "=": 446, ">": 446, "|": 330, "~": 446, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 450, "0": 450, "1": 450, "2": 450, "3": 450, "4": 450, "5": 450, "6": 450, "7": 450, "8": 450, "9": 450, "a": 437, "A": 502, "b": 435, "B": 520, "c": 355, "C": 472, "d": 393, "D": 578, "e": 325, "E": 529, "\xE9": 325, "f": 291, "F": 454, "g": 355, "G": 487, "h": 464, "H": 563, "i": 187, "I": 400, "j": 204, "J": 306, "k": 365, "K": 498, "l": 169, "L": 426, "m": 560, "M": 720, "n": 450, "N": 599, "o": 353, "O": 496, "p": 378, "P": 464, "q": 377, "Q": 502, "r": 360, "R": 537, "s": 341, "S": 486, "t": 331, "T": 458, "u": 370, "U": 482, "v": 331, "V": 490, "w": 517, "W": 720, "x": 343, "X": 524, "y": 341, "Y": 504, "z": 315, "Z": 522 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } }, "Helvetica Neue": { "faces": { "bold": { "ascent": 0.975006103515625, "descent": 0.2169952392578125, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -30, "fi": 20, "fl": 20, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0290069580078125, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 278, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 463, "\u201C": 463, "\u201D": 463, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 371, "\\": 371, "&": 685, "#": 556, "%": 1e3, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 223, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 704, "c": 574, "C": 741, "d": 611, "D": 741, "e": 574, "E": 648, "\xE9": 574, "f": 333, "F": 593, "g": 611, "G": 759, "h": 593, "H": 741, "i": 258, "I": 295, "j": 278, "J": 556, "k": 574, "K": 722, "l": 258, "L": 593, "m": 906, "M": 907, "n": 593, "N": 741, "o": 611, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 537, "S": 649, "t": 352, "T": 611, "u": 593, "U": 741, "v": 520, "V": 630, "w": 814, "W": 944, "x": 537, "X": 667, "y": 519, "Y": 667, "z": 519, "Z": 648 } }, "boldItalic": { "ascent": 0.975006103515625, "descent": 0.2169952392578125, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -68, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0290069580078125, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 296, "?": 574, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 481, "\u201C": 481, "\u201D": 481, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 389, "\\": 389, "&": 685, "#": 556, "%": 963, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 722, "c": 556, "C": 741, "d": 611, "D": 741, "e": 574, "E": 667, "\xE9": 574, "f": 352, "F": 593, "g": 611, "G": 759, "h": 611, "H": 741, "i": 259, "I": 296, "j": 259, "J": 556, "k": 556, "K": 722, "l": 259, "L": 574, "m": 907, "M": 907, "n": 611, "N": 741, "o": 593, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 519, "S": 648, "t": 370, "T": 611, "u": 611, "U": 741, "v": 519, "V": 630, "w": 815, "W": 944, "x": 519, "X": 667, "y": 519, "Y": 648, "z": 500, "Z": 648 } }, "italic": { "ascent": 0.957000732421875, "descent": 0.2129974365234375, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "fi": 1, "fl": 1, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0279998779296875, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 926, "\u2022": 500, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 519, "A": 667, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 481, "K": 667, "l": 222, "L": 556, "m": 852, "M": 870, "n": 556, "N": 722, "o": 574, "O": 759, "p": 593, "P": 648, "q": 593, "Q": 759, "r": 333, "R": 685, "s": 481, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 481, "V": 611, "w": 759, "W": 926, "x": 481, "X": 611, "y": 481, "Y": 611, "z": 444, "Z": 611 } }, "regular": { "ascent": 0.951995849609375, "descent": 0.2129974365234375, "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "leading": 0.0279998779296875, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 1e3, "\u2022": 350, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 537, "A": 648, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 519, "K": 667, "l": 222, "L": 556, "m": 853, "M": 871, "n": 556, "N": 722, "o": 574, "O": 760, "p": 593, "P": 648, "q": 593, "Q": 760, "r": 333, "R": 685, "s": 500, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 500, "V": 611, "w": 758, "W": 926, "x": 518, "X": 611, "y": 500, "Y": 648, "z": 480, "Z": 611 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } }, "Patrick Hand": { "faces": { "regular": { "ascent": 1.0420074462890625, "descent": 0.3119964599609375, "k": {}, "leading": 0, "w": { " ": 230, "_": 571, "-": 404, "\u2013": 420, "\u2014": 648, ",": 202, ";": 232, ":": 232, "!": 247, "?": 368, ".": 214, "\u2026": 571, "\xB7": 200, "'": 164, "\u2018": 190, "\u2019": 220, '"': 303, "\u201C": 315, "\u201D": 303, "(": 334, ")": 364, "[": 303, "]": 296, "{": 339, "}": 328, "@": 550, "*": 404, "/": 423, "\\": 420, "&": 530, "#": 457, "%": 643, "\u2022": 352, "`": 220, "^": 370, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 480, "\xD7": 490, "<": 396, "=": 572, ">": 400, "|": 176, "~": 529, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 507, "0": 448, "1": 363, "2": 468, "3": 448, "4": 375, "5": 423, "6": 399, "7": 495, "8": 433, "9": 367, "a": 392, "A": 488, "b": 412, "B": 507, "c": 388, "C": 548, "d": 390, "D": 475, "e": 398, "E": 442, "\xE9": 398, "f": 359, "F": 375, "g": 445, "G": 480, "h": 420, "H": 468, "i": 224, "I": 235, "j": 235, "J": 370, "k": 415, "K": 523, "l": 266, "L": 372, "m": 680, "M": 595, "n": 452, "N": 532, "o": 403, "O": 556, "p": 428, "P": 481, "q": 463, "Q": 655, "r": 385, "R": 454, "s": 385, "S": 459, "t": 344, "T": 468, "u": 400, "U": 550, "v": 400, "V": 562, "w": 463, "W": 616, "x": 448, "X": 601, "y": 423, "Y": 442, "z": 428, "Z": 507 } } }, "fallback": { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] } } };
549
+
550
+ // src/text.ts
551
+ var DEFAULT_FAMILY = "Helvetica Neue";
552
+ var CSS_FALLBACK = "Helvetica Neue, Helvetica, Arial, sans-serif";
553
+ var BUNDLED_FONTS = Object.keys(families).filter((f) => f !== DEFAULT_FAMILY).sort();
554
+ function bundledFamily(font) {
555
+ if (!font) return null;
556
+ const lower = font.toLowerCase();
557
+ return BUNDLED_FONTS.find((f) => f.toLowerCase() === lower) ?? null;
558
+ }
559
+ function familyMetrics(font) {
560
+ return families[bundledFamily(font) ?? DEFAULT_FAMILY];
561
+ }
562
+ function faceOf(fam, bold, italic) {
563
+ const want = bold ? italic ? "boldItalic" : "bold" : italic ? "italic" : "regular";
564
+ return fam.faces[want] ? want : "regular";
565
+ }
566
+ function cssFamily(font) {
567
+ if (!font) return CSS_FALLBACK;
568
+ const name = [...bundledFamily(font) ?? font].filter((c) => !`"'<>&;{}\\`.includes(c)).join("");
569
+ if (name === "") return CSS_FALLBACK;
570
+ return `${/^[\p{L}\p{N} -]+$/u.test(name) ? name : `'${name}'`}, ${CSS_FALLBACK}`;
571
+ }
572
+ function measure(s, fontSize, face = "regular", font) {
573
+ const fam = familyMetrics(font);
574
+ const f = fam.faces[face] ?? fam.faces.regular;
575
+ const fallback = f.w["n"];
576
+ let w = 0;
577
+ let prev = "";
578
+ for (const ch of s) {
579
+ w += f.w[ch] ?? fallback;
580
+ if (prev) w += f.k[prev + ch] ?? 0;
581
+ prev = ch;
582
+ }
583
+ return w * fontSize / 1e3;
584
+ }
585
+ function lineHeights(fontSize, font) {
586
+ const m = familyMetrics(font).faces.regular;
587
+ const a = Math.round(m.ascent * fontSize), d = Math.round(m.descent * fontSize), l = Math.round(m.leading * fontSize);
588
+ return [a + Math.ceil(m.descent * fontSize - 1e-9), a + d + l];
589
+ }
590
+ function breaksAfter(ch, next) {
591
+ if (ch === " ") return true;
592
+ return (ch === "/" || ch === "-") && next !== "" && !/[\d\s/-]/.test(next);
593
+ }
594
+ function pieces(para) {
595
+ const chars = [...para];
596
+ const out = [];
597
+ let cur = "";
598
+ chars.forEach((ch, i) => {
599
+ cur += ch;
600
+ const next = chars[i + 1] ?? "";
601
+ if (breaksAfter(ch, next) && next !== " ") {
602
+ out.push(cur);
603
+ cur = "";
604
+ }
605
+ });
606
+ if (cur || out.length === 0) out.push(cur);
607
+ return out;
608
+ }
609
+ function wrap(s, fontSize, maxWidth, face = "regular", font) {
610
+ const width = (t) => measure(t, fontSize, face, font);
611
+ const out = [];
612
+ for (const para of s.split(/\r\n|\n|\r|\u2028|\u2029/)) {
613
+ let line2 = "";
614
+ for (const piece of pieces(para)) {
615
+ const candidate = line2 + piece;
616
+ if (line2 === "" || width(candidate.trimEnd()) <= maxWidth) {
617
+ line2 = candidate;
618
+ } else {
619
+ out.push(line2);
620
+ line2 = piece;
621
+ }
622
+ while (width(line2.trimEnd()) > maxWidth && [...line2.trimEnd()].length > 1) {
623
+ const chars = [...line2];
624
+ let n = chars.length - 1;
625
+ while (n > 1 && width(chars.slice(0, n).join("")) > maxWidth) n--;
626
+ out.push(chars.slice(0, n).join(""));
627
+ line2 = chars.slice(n).join("");
628
+ }
629
+ }
630
+ out.push(line2);
631
+ }
632
+ return out;
633
+ }
634
+ function textSize(s, fontSize, maxWidth, font) {
635
+ if (s === "") return { width: 0, height: 0 };
636
+ const lines = wrap(s, fontSize, maxWidth, "regular", font);
637
+ const width = Math.max(...lines.map((l) => measure(l.trimEnd(), fontSize, "regular", font)));
638
+ const [first, next] = lineHeights(fontSize, font);
639
+ return { width: Math.ceil(width - 1e-9), height: Math.ceil(first + next * (lines.length - 1) - 1e-9) };
640
+ }
641
+
642
+ // src/fonts.ts
643
+ var FACES = ["bold", "boldItalic", "italic", "regular"];
644
+ function fontFile(family, face) {
645
+ return `${family.toLowerCase().replaceAll(" ", "-")}-${face}.woff2`;
646
+ }
647
+ function fontFaces(family) {
648
+ return FACES.filter((f) => families[family]?.faces[f] !== void 0);
649
+ }
650
+ function usedFonts(page) {
651
+ const used = /* @__PURE__ */ new Set();
652
+ const add2 = (es) => {
653
+ for (const e of es) {
654
+ const b = bundledFamily(e.style.font);
655
+ if (b) used.add(b);
656
+ }
657
+ };
658
+ add2(page.elements);
659
+ for (const s of page.symbols ?? []) add2(s.elements);
660
+ return BUNDLED_FONTS.filter((f) => used.has(f));
661
+ }
662
+ function defaultBase() {
663
+ try {
664
+ const script = typeof document === "undefined" ? null : document.currentScript;
665
+ if (script?.src) return new URL("fonts/", script.src).href;
666
+ const here = import.meta.url;
667
+ return here ? new URL("fonts/", here).href : null;
668
+ } catch {
669
+ return null;
670
+ }
671
+ }
672
+ var base = defaultBase();
673
+ var added = /* @__PURE__ */ new Set();
674
+ function setFontBase(url) {
675
+ base = url.endsWith("/") ? url : `${url}/`;
676
+ }
677
+ function addFonts(fonts, data = {}) {
678
+ if (typeof document === "undefined" || typeof FontFace === "undefined" || !document.fonts) return;
679
+ for (const name of fonts) {
680
+ const family = bundledFamily(name);
681
+ if (!family || added.has(family)) continue;
682
+ const own = data[family];
683
+ if (!own && !base) continue;
684
+ added.add(family);
685
+ for (const face of fontFaces(family)) {
686
+ const encoded = own?.[face];
687
+ let source;
688
+ if (encoded) source = Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
689
+ else if (!own) source = `url(${JSON.stringify(base + fontFile(family, face))}) format("woff2")`;
690
+ else continue;
691
+ const descriptors = { weight: face.startsWith("bold") ? "bold" : "normal", style: face === "italic" || face === "boldItalic" ? "italic" : "normal" };
692
+ document.fonts.add(new FontFace(family, source, descriptors));
693
+ }
694
+ }
695
+ }
696
+
520
697
  // src/path.ts
521
698
  var KAPPA = 0.5522847498307936;
522
699
  var Path = class _Path {
@@ -775,13 +952,19 @@ function rotatedBounds(e) {
775
952
  return { x, y, width: Math.max(...xs) - x, height: Math.max(...ys) - y };
776
953
  }
777
954
  function resolvingInk(e, ink) {
778
- if (!isAutomaticInk(e.style.stroke)) return e;
955
+ const text = e.style.textColor !== null && isAutomaticInk(e.style.textColor);
956
+ if (!isAutomaticInk(e.style.stroke) && !text) return e;
779
957
  const copy = cloneElement(e);
780
958
  const covers = e.style.fillStyle === "solid" || e.style.fillStyle === "grid";
781
959
  const onLightFill = covers && e.style.fill.a >= 0.5 && luminance(e.style.fill) > 0.5;
782
- copy.style.stroke = luminance(ink) > 0.5 && onLightFill ? { ...black } : { ...ink };
960
+ const resolved2 = luminance(ink) > 0.5 && onLightFill ? black : ink;
961
+ if (isAutomaticInk(e.style.stroke)) copy.style.stroke = { ...resolved2 };
962
+ if (text) copy.style.textColor = { ...resolved2 };
783
963
  return copy;
784
964
  }
965
+ function labelColor(e) {
966
+ return e.kind === "text" || e.kind === "note" ? e.style.stroke : e.style.textColor ?? e.style.stroke;
967
+ }
785
968
  function shapeContours(e) {
786
969
  if (e.kind !== "path" || !e.subpaths) return [];
787
970
  const out = [];
@@ -875,34 +1058,93 @@ function resolve(ep, other, index) {
875
1058
  function endpoints(e, index) {
876
1059
  const c = e.connector;
877
1060
  if (!c) return [{ x: 0, y: 0 }, { x: 0, y: 0 }];
878
- return [resolve(c.start, reference(c.end, index), index), resolve(c.end, reference(c.start, index), index)];
1061
+ const w = c.waypoints ?? [];
1062
+ return [
1063
+ resolve(c.start, w.length > 0 ? w[0] : reference(c.end, index), index),
1064
+ resolve(c.end, w.length > 0 ? w[w.length - 1] : reference(c.start, index), index)
1065
+ ];
879
1066
  }
880
1067
  function routePoints(r) {
881
1068
  if (r.kind === "polyline") return r.points;
882
- const out = [];
883
- for (let i = 0; i <= 24; i++) {
884
- const t = i / 24, u = 1 - t;
885
- out.push({
886
- x: u * u * u * r.a.x + 3 * u * u * t * r.b.x + 3 * u * t * t * r.c.x + t * t * t * r.d.x,
887
- y: u * u * u * r.a.y + 3 * u * u * t * r.b.y + 3 * u * t * t * r.c.y + t * t * t * r.d.y
888
- });
1069
+ const out = [], p = r.points;
1070
+ for (let s = 0; s < Math.floor((p.length - 1) / 3); s++) {
1071
+ const a = p[3 * s], b = p[3 * s + 1], c = p[3 * s + 2], d = p[3 * s + 3];
1072
+ for (let i = s === 0 ? 0 : 1; i <= 24; i++) {
1073
+ const t = i / 24, u = 1 - t;
1074
+ out.push({
1075
+ x: u * u * u * a.x + 3 * u * u * t * b.x + 3 * u * t * t * c.x + t * t * t * d.x,
1076
+ y: u * u * u * a.y + 3 * u * u * t * b.y + 3 * u * t * t * c.y + t * t * t * d.y
1077
+ });
1078
+ }
889
1079
  }
890
1080
  return out;
891
1081
  }
1082
+ var vertical = (p) => p === null ? null : p === "top" || p === "bottom";
1083
+ function simplified(pts) {
1084
+ const out = [];
1085
+ for (const q of pts) {
1086
+ const l = out[out.length - 1];
1087
+ if (l && Math.abs(l.x - q.x) < 0.5 && Math.abs(l.y - q.y) < 0.5) continue;
1088
+ if (out.length >= 2) {
1089
+ const p = out[out.length - 2], m = out[out.length - 1];
1090
+ if (Math.abs(p.x - m.x) < 0.5 && Math.abs(m.x - q.x) < 0.5 || Math.abs(p.y - m.y) < 0.5 && Math.abs(m.y - q.y) < 0.5) {
1091
+ out[out.length - 1] = q;
1092
+ continue;
1093
+ }
1094
+ }
1095
+ out.push(q);
1096
+ }
1097
+ return out.length >= 2 ? out : pts;
1098
+ }
1099
+ function routeThrough(p, c) {
1100
+ switch (c.routing) {
1101
+ case "straight":
1102
+ return { kind: "polyline", points: p };
1103
+ case "curved": {
1104
+ const out = [p[0]];
1105
+ for (let i = 0; i < p.length - 1; i++) {
1106
+ const p0 = p[Math.max(i - 1, 0)], p1 = p[i], p2 = p[i + 1], p3 = p[Math.min(i + 2, p.length - 1)];
1107
+ out.push({ x: p1.x + (p2.x - p0.x) / 6, y: p1.y + (p2.y - p0.y) / 6 });
1108
+ out.push({ x: p2.x - (p3.x - p1.x) / 6, y: p2.y - (p3.y - p1.y) / 6 });
1109
+ out.push(p2);
1110
+ }
1111
+ return { kind: "curve", points: out };
1112
+ }
1113
+ case "elbow": {
1114
+ const a = p[0], first = p[1];
1115
+ let goVertical = vertical(c.start.port) ?? Math.abs(first.y - a.y) > Math.abs(first.x - a.x);
1116
+ const endV = vertical(c.end.port);
1117
+ const out = [a];
1118
+ for (let i = 1; i < p.length; i++) {
1119
+ const q = p[i], cur = out[out.length - 1];
1120
+ const alignedX = Math.abs(cur.x - q.x) < 0.5, alignedY = Math.abs(cur.y - q.y) < 0.5;
1121
+ if (alignedX || alignedY) {
1122
+ out.push(q);
1123
+ if (alignedX !== alignedY) goVertical = !alignedX;
1124
+ continue;
1125
+ }
1126
+ const up = i === p.length - 1 && endV !== null ? !endV : goVertical;
1127
+ out.push(up ? { x: cur.x, y: q.y } : { x: q.x, y: cur.y }, q);
1128
+ goVertical = up;
1129
+ }
1130
+ return { kind: "polyline", points: simplified(out) };
1131
+ }
1132
+ }
1133
+ }
892
1134
  function route(e, index) {
893
1135
  const c = e.connector;
894
1136
  if (!c) return { kind: "polyline", points: [] };
895
1137
  const [a, b] = endpoints(e, index);
1138
+ if (c.waypoints && c.waypoints.length > 0) return routeThrough([a, ...c.waypoints.map((w) => ({ x: w.x, y: w.y })), b], c);
896
1139
  const dx = b.x - a.x, dy = b.y - a.y;
897
1140
  const horizontal = Math.abs(dx) >= Math.abs(dy);
898
1141
  switch (c.routing) {
899
1142
  case "straight":
900
1143
  return { kind: "polyline", points: [a, b] };
901
1144
  case "curved":
902
- if (horizontal) return { kind: "cubic", a, b: { x: a.x + dx / 2, y: a.y }, c: { x: b.x - dx / 2, y: b.y }, d: b };
903
- return { kind: "cubic", a, b: { x: a.x, y: a.y + dy / 2 }, c: { x: b.x, y: b.y - dy / 2 }, d: b };
1145
+ if (horizontal) return { kind: "curve", points: [a, { x: a.x + dx / 2, y: a.y }, { x: b.x - dx / 2, y: b.y }, b] };
1146
+ return { kind: "curve", points: [a, { x: a.x, y: a.y + dy / 2 }, { x: b.x, y: b.y - dy / 2 }, b] };
904
1147
  case "elbow": {
905
- const vertical = (p) => p === null ? null : p === "top" || p === "bottom";
906
1148
  const startV = vertical(c.start.port) ?? !horizontal;
907
1149
  const endV = vertical(c.end.port) ?? !horizontal;
908
1150
  if (startV && endV) {
@@ -1482,10 +1724,12 @@ function dashPattern(dash, width) {
1482
1724
  return [0.01, Math.max(5, width * 2.6)];
1483
1725
  }
1484
1726
  }
1485
- function connectorParts(e, index) {
1727
+ function connectorParts(e, index, page) {
1486
1728
  const c = e.connector;
1487
1729
  if (!c) return [new Path(), new Path()];
1488
1730
  const [a, b] = endpoints(e, index);
1731
+ const r = route(e, index);
1732
+ const hops = c.hops === true && page ? hopCrossings(e, r, page, index) : [];
1489
1733
  const key = [
1490
1734
  e.seed,
1491
1735
  e.style.roughness,
@@ -1499,28 +1743,166 @@ function connectorParts(e, index) {
1499
1743
  a.x,
1500
1744
  a.y,
1501
1745
  b.x,
1502
- b.y
1746
+ b.y,
1747
+ JSON.stringify(c.waypoints),
1748
+ JSON.stringify(hops)
1503
1749
  ].join("|");
1504
- return connectors.get(key, () => computeConnector(e, index));
1750
+ return connectors.get(key, () => computeConnector(e, r, hops));
1751
+ }
1752
+ function hopRadius(strokeWidth) {
1753
+ return Math.max(8, strokeWidth * 4);
1754
+ }
1755
+ function hopSamples(r) {
1756
+ const pts = r.points, out = [];
1757
+ if (r.kind === "polyline") {
1758
+ for (let i = 0; i < pts.length - 1; i++) out.push([pts[i], pts[i + 1]]);
1759
+ return out;
1760
+ }
1761
+ for (let s = 0; s < Math.floor((pts.length - 1) / 3); s++) {
1762
+ const seg = pts.slice(3 * s, 3 * s + 4), samples = [];
1763
+ for (let i = 0; i <= 24; i++) samples.push(cubicPoint(seg, i / 24));
1764
+ out.push(samples);
1765
+ }
1766
+ return out;
1767
+ }
1768
+ function runningLengths(samples) {
1769
+ const out = [0];
1770
+ for (let i = 1; i < samples.length; i++) out.push(out[i - 1] + Math.hypot(samples[i].x - samples[i - 1].x, samples[i].y - samples[i - 1].y));
1771
+ return out;
1505
1772
  }
1506
- function computeConnector(e, index) {
1773
+ function cubicPoint(p, t) {
1774
+ const u = 1 - t;
1775
+ return {
1776
+ x: u * u * u * p[0].x + 3 * u * u * t * p[1].x + 3 * u * t * t * p[2].x + t * t * t * p[3].x,
1777
+ y: u * u * u * p[0].y + 3 * u * u * t * p[1].y + 3 * u * t * t * p[2].y + t * t * t * p[3].y
1778
+ };
1779
+ }
1780
+ function subCubic(p, t0, t1) {
1781
+ const split = (q, t) => {
1782
+ const lerp = (a, b) => ({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });
1783
+ const ab = lerp(q[0], q[1]), bc = lerp(q[1], q[2]), cd = lerp(q[2], q[3]);
1784
+ const abc = lerp(ab, bc), bcd = lerp(bc, cd), m = lerp(abc, bcd);
1785
+ return [[q[0], ab, abc, m], [m, bcd, cd, q[3]]];
1786
+ };
1787
+ const left = split(p, t1)[0];
1788
+ return t1 > 0 ? split(left, t0 / t1)[1] : [p[0], p[0], p[0], p[0]];
1789
+ }
1790
+ function hopCrossings(e, r, page, index) {
1791
+ const segments = hopSamples(r);
1792
+ if (segments.length === 0) return [];
1793
+ const visible = new Set(page.layers.filter((l) => l.visible).map((l) => l.id));
1794
+ const beneath = [];
1795
+ for (const o of orderedElements(page)) {
1796
+ if (o.id === e.id) break;
1797
+ if (o.kind !== "connector" || !visible.has(o.layerID)) continue;
1798
+ beneath.push(routePoints(route(o, index)));
1799
+ }
1800
+ const rad = hopRadius(e.style.strokeWidth);
1801
+ const out = [];
1802
+ for (const samples of segments) {
1803
+ const along = runningLengths(samples);
1804
+ const length = along[along.length - 1];
1805
+ const found = [];
1806
+ for (let i = 0; i < samples.length - 1; i++) {
1807
+ const p = samples[i], q = samples[i + 1];
1808
+ const dx = q.x - p.x, dy = q.y - p.y;
1809
+ for (const line2 of beneath) {
1810
+ for (let k = 0; k < line2.length - 1; k++) {
1811
+ const a = line2[k], b = line2[k + 1];
1812
+ const ex = b.x - a.x, ey = b.y - a.y;
1813
+ const det = dx * ey - dy * ex;
1814
+ if (Math.abs(det) < 1e-9) continue;
1815
+ const wx = a.x - p.x, wy = a.y - p.y;
1816
+ const t = (wx * ey - wy * ex) / det, s = (wx * dy - wy * dx) / det;
1817
+ if (t > 0 && t < 1 && s >= 0 && s <= 1) found.push(along[i] + t * (along[i + 1] - along[i]));
1818
+ }
1819
+ }
1820
+ }
1821
+ const kept = [];
1822
+ for (const at of found.sort((x, y) => x - y)) {
1823
+ if (at < rad + 2 || at > length - rad - 2) continue;
1824
+ if (kept.length > 0 && at - kept[kept.length - 1] < 2 * rad + 2) continue;
1825
+ kept.push(at);
1826
+ }
1827
+ out.push(kept);
1828
+ }
1829
+ return out;
1830
+ }
1831
+ function computeConnector(e, r, hops) {
1507
1832
  const c = e.connector;
1508
1833
  const rng = new SeededRNG(e.seed);
1509
1834
  const rough = e.style.roughness, bow = e.style.bowing;
1510
1835
  const path = new Path(), solid = new Path();
1511
- const r = route(e, index);
1836
+ const w = rough * 3;
1837
+ const j = () => rng.signed() * w;
1838
+ const hop = (s, t, u, rad2) => {
1839
+ let n = { x: u.y, y: -u.x };
1840
+ if (n.y > 1e-9 || Math.abs(n.y) <= 1e-9 && n.x > 0) n = { x: -n.x, y: -n.y };
1841
+ const k = rad2 * 0.5523;
1842
+ const m = { x: (s.x + t.x) / 2, y: (s.y + t.y) / 2 };
1843
+ const top = { x: m.x + n.x * rad2, y: m.y + n.y * rad2 };
1844
+ path.moveTo(s);
1845
+ const a1x = s.x + n.x * k + j(), a1y = s.y + n.y * k + j(), a2x = top.x - u.x * k + j(), a2y = top.y - u.y * k + j();
1846
+ path.curveTo(top, { x: a1x, y: a1y }, { x: a2x, y: a2y });
1847
+ const b1x = top.x + u.x * k + j(), b1y = top.y + u.y * k + j(), b2x = t.x + n.x * k + j(), b2y = t.y + n.y * k + j();
1848
+ path.curveTo(t, { x: b1x, y: b1y }, { x: b2x, y: b2y });
1849
+ };
1850
+ const rad = hopRadius(e.style.strokeWidth);
1512
1851
  if (r.kind === "polyline") {
1513
1852
  const pts2 = r.points;
1853
+ const straight = (p, q) => {
1854
+ if (rough <= 0) path.moveTo(p).lineTo(q);
1855
+ else line(p, q, rng, rough, bow, true, path);
1856
+ };
1514
1857
  for (let i = 0; i < Math.max(pts2.length - 1, 0); i++) {
1515
- if (rough <= 0) path.moveTo(pts2[i]).lineTo(pts2[i + 1]);
1516
- else line(pts2[i], pts2[i + 1], rng, rough, bow, true, path);
1858
+ const p = pts2[i], q = pts2[i + 1];
1859
+ const length = Math.hypot(q.x - p.x, q.y - p.y);
1860
+ const u = length > 0 ? { x: (q.x - p.x) / length, y: (q.y - p.y) / length } : { x: 0, y: 0 };
1861
+ const at = (d) => ({ x: p.x + u.x * d, y: p.y + u.y * d });
1862
+ let from = p;
1863
+ for (const d of i < hops.length ? hops[i] : []) {
1864
+ const s = at(d - rad), t = at(d + rad);
1865
+ straight(from, s);
1866
+ hop(s, t, u, rad);
1867
+ from = t;
1868
+ }
1869
+ straight(from, q);
1517
1870
  }
1518
1871
  } else {
1519
- path.moveTo(r.a);
1520
- const w = rough * 3;
1521
- const j = () => rng.signed() * w;
1522
- const c1x = r.b.x + j(), c1y = r.b.y + j(), c2x = r.c.x + j(), c2y = r.c.y + j();
1523
- path.curveTo(r.d, { x: c1x, y: c1y }, { x: c2x, y: c2y });
1872
+ const pts2 = r.points;
1873
+ const samples = hopSamples(r);
1874
+ path.moveTo(pts2[0]);
1875
+ for (let s = 0; s < Math.floor((pts2.length - 1) / 3); s++) {
1876
+ const b = pts2[3 * s + 1], c2 = pts2[3 * s + 2], d = pts2[3 * s + 3];
1877
+ const c1x = b.x + j(), c1y = b.y + j(), c2x = c2.x + j(), c2y = c2.y + j();
1878
+ const here = s < hops.length ? hops[s] : [];
1879
+ if (here.length === 0) {
1880
+ path.curveTo(d, { x: c1x, y: c1y }, { x: c2x, y: c2y });
1881
+ continue;
1882
+ }
1883
+ const cubic = [pts2[3 * s], { x: c1x, y: c1y }, { x: c2x, y: c2y }, d];
1884
+ const along = runningLengths(samples[s]);
1885
+ const param = (at) => {
1886
+ let i = 0;
1887
+ while (i < along.length - 2 && along[i + 1] < at) i++;
1888
+ const span = along[i + 1] - along[i];
1889
+ return (i + (span > 0 ? (at - along[i]) / span : 0)) / 24;
1890
+ };
1891
+ let from = 0;
1892
+ for (const at of here) {
1893
+ const t0 = param(at - rad), t1 = param(at + rad);
1894
+ const piece = subCubic(cubic, from, t0);
1895
+ if (s > 0 || from > 0) path.moveTo(piece[0]);
1896
+ path.curveTo(piece[3], piece[1], piece[2]);
1897
+ const a = cubicPoint(cubic, t0), z = cubicPoint(cubic, t1);
1898
+ const width = Math.hypot(z.x - a.x, z.y - a.y);
1899
+ const u = width > 0 ? { x: (z.x - a.x) / width, y: (z.y - a.y) / width } : { x: 0, y: 0 };
1900
+ hop(a, z, u, width / 2);
1901
+ from = t1;
1902
+ }
1903
+ const rest = subCubic(cubic, from, 1);
1904
+ path.moveTo(rest[0]).curveTo(rest[3], rest[1], rest[2]);
1905
+ }
1524
1906
  }
1525
1907
  const pts = routePoints(r);
1526
1908
  const size = Math.max(10, e.style.strokeWidth * 5);
@@ -1542,10 +1924,10 @@ function computeConnector(e, index) {
1542
1924
  solid.moveTo(tip).lineTo(w1).lineTo(w2).close();
1543
1925
  break;
1544
1926
  case "dot": {
1545
- const rad = size * 0.32;
1927
+ const rad2 = size * 0.32;
1546
1928
  const ang = Math.atan2(tip.y - from.y, tip.x - from.x);
1547
- const cx = tip.x - rad * Math.cos(ang), cy = tip.y - rad * Math.sin(ang);
1548
- solid.addEllipse({ x: cx - rad, y: cy - rad, width: 2 * rad, height: 2 * rad });
1929
+ const cx = tip.x - rad2 * Math.cos(ang), cy = tip.y - rad2 * Math.sin(ang);
1930
+ solid.addEllipse({ x: cx - rad2, y: cy - rad2, width: 2 * rad2, height: 2 * rad2 });
1549
1931
  break;
1550
1932
  }
1551
1933
  case "bar": {
@@ -1625,7 +2007,7 @@ function localTime(track, t) {
1625
2007
  }
1626
2008
  return t;
1627
2009
  }
1628
- function value(track, t, get, base, lerp) {
2010
+ function value(track, t, get, base2, lerp) {
1629
2011
  t = localTime(track, t);
1630
2012
  let before, after;
1631
2013
  for (const k of track.keys) {
@@ -1636,7 +2018,7 @@ function value(track, t, get, base, lerp) {
1636
2018
  break;
1637
2019
  }
1638
2020
  }
1639
- if (!before && !after) return base;
2021
+ if (!before && !after) return base2;
1640
2022
  if (before && !after) return get(before);
1641
2023
  if (!before && after) return get(after);
1642
2024
  const b = before, a = after;
@@ -1651,8 +2033,8 @@ var lerpColor = (a, b, u) => ({
1651
2033
  b: mix01(a.b, b.b, u),
1652
2034
  a: mix01(a.a, b.a, u)
1653
2035
  });
1654
- function num2(track, t, p, base) {
1655
- return value(track, t, (k) => k[p], base, lerpNum);
2036
+ function num2(track, t, p, base2) {
2037
+ return value(track, t, (k) => k[p], base2, lerpNum);
1656
2038
  }
1657
2039
  function isChanging(track, t) {
1658
2040
  t = localTime(track, t);
@@ -2012,7 +2394,12 @@ function placed(inner, instance, symbol) {
2012
2394
  const q = point(p);
2013
2395
  return { elementID: null, port: p.port, x: q.x, y: q.y };
2014
2396
  };
2015
- e.connector = { ...inner.connector, start: end(inner.connector.start), end: end(inner.connector.end) };
2397
+ e.connector = {
2398
+ ...inner.connector,
2399
+ start: end(inner.connector.start),
2400
+ end: end(inner.connector.end),
2401
+ waypoints: inner.connector.waypoints?.map(point) ?? null
2402
+ };
2016
2403
  }
2017
2404
  return e;
2018
2405
  }
@@ -2117,25 +2504,6 @@ var CLICK_STYLE = `
2117
2504
  .dottie-b:active .dottie-d, .dottie-b.dottie-press .dottie-d { display: inline; }
2118
2505
  `;
2119
2506
 
2120
- // src/metrics.ts
2121
- var ascent = 0.951995849609375;
2122
- var descent = 0.2129974365234375;
2123
- var leading = 0.0279998779296875;
2124
- var boldAscent = 0.975006103515625;
2125
- var boldDescent = 0.2169952392578125;
2126
- var boldLeading = 0.0290069580078125;
2127
- var italicAscent = 0.957000732421875;
2128
- var italicDescent = 0.2129974365234375;
2129
- var italicLeading = 0.0279998779296875;
2130
- var boldItalicAscent = 0.975006103515625;
2131
- var boldItalicDescent = 0.2169952392578125;
2132
- var boldItalicLeading = 0.0290069580078125;
2133
- var monoAdvance = 0.60205078125;
2134
- var monoAscent = 0.92822265625;
2135
- var monoDescent = 0.23583984375;
2136
- var fonts = { "bold": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -30, "fi": 20, "fl": 20, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 278, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 463, "\u201C": 463, "\u201D": 463, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 371, "\\": 371, "&": 685, "#": 556, "%": 1e3, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 223, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 704, "c": 574, "C": 741, "d": 611, "D": 741, "e": 574, "E": 648, "\xE9": 574, "f": 333, "F": 593, "g": 611, "G": 759, "h": 593, "H": 741, "i": 258, "I": 295, "j": 278, "J": 556, "k": 574, "K": 722, "l": 258, "L": 593, "m": 906, "M": 907, "n": 593, "N": 741, "o": 611, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 537, "S": 649, "t": 352, "T": 611, "u": 593, "U": 741, "v": 520, "V": 630, "w": 814, "W": 944, "x": 537, "X": 667, "y": 519, "Y": 667, "z": 519, "Z": 648 } }, "boldItalic": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -68, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 407, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 296, "?": 574, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 481, "\u201C": 481, "\u201D": 481, "(": 296, ")": 296, "[": 333, "]": 333, "{": 333, "}": 333, "@": 800, "*": 407, "/": 389, "\\": 389, "&": 685, "#": 556, "%": 963, "\u2022": 350, "`": 259, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 722.66, "\u2193": 722.66, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 608.4, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 574, "A": 685, "b": 611, "B": 722, "c": 556, "C": 741, "d": 611, "D": 741, "e": 574, "E": 667, "\xE9": 574, "f": 352, "F": 593, "g": 611, "G": 759, "h": 611, "H": 741, "i": 259, "I": 296, "j": 259, "J": 556, "k": 556, "K": 722, "l": 259, "L": 574, "m": 907, "M": 907, "n": 611, "N": 741, "o": 593, "O": 778, "p": 611, "P": 667, "q": 611, "Q": 778, "r": 389, "R": 722, "s": 519, "S": 648, "t": 370, "T": 611, "u": 611, "U": 741, "v": 519, "V": 630, "w": 815, "W": 944, "x": 519, "X": 667, "y": 519, "Y": 648, "z": 500, "Z": 648 } }, "italic": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "fi": 1, "fl": 1, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 926, "\u2022": 500, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 519, "A": 667, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 481, "K": 667, "l": 222, "L": 556, "m": 852, "M": 870, "n": 556, "N": 722, "o": 574, "O": 759, "p": 593, "P": 648, "q": 593, "Q": 759, "r": 333, "R": 685, "s": 481, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 481, "V": 611, "w": 759, "W": 926, "x": 481, "X": 611, "y": 481, "Y": 611, "z": 444, "Z": 611 } }, "regular": { "k": { "\u2018\u2018": -95, "\u2019\u2019": -95, "\u2019s": -74, "\u2019t": -18, "A\u2019": -74, "AT": -92, "Av": -18, "AV": -46, "Aw": -18, "AW": -24, "Ay": -18, "AY": -74, "F,": -157, "F.": -157, "f\u2019": 18, "FA": -55, "ff": -15, "L\u2019": -74, "LT": -92, "LV": -92, "LW": -55, "Ly": -37, "LY": -111, "P,": -179, "P.": -179, "PA": -74, "r-": -55, "r,": -92, "r.": -92, "rc": -18, "rd": -18, "re": -18, "rg": -28, "rn": 18, "ro": -18, "rq": -18, "RT": -18, "RV": -18, "RW": -18, "RY": -37, "T-": -129, "T,": -111, "T;": -111, "T:": -111, "T.": -111, "Ta": -111, "TA": -92, "Tc": -111, "Te": -111, "To": -111, "Tr": -92, "Ts": -111, "Tu": -92, "Tw": -111, "Ty": -111, "V-": -55, "v,": -74, "V,": -129, "V;": -46, "V:": -46, "v.": -74, "V.": -129, "Va": -55, "VA": -46, "Ve": -55, "Vi": -18, "Vo": -55, "Vr": -37, "Vu": -37, "Vy": -18, "w,": -55, "W,": -74, "W;": -18, "W:": -18, "w.": -55, "W.": -74, "Wa": -37, "WA": -24, "We": -57, "Wo": -57, "Wr": -18, "Wu": -18, "Y-": -111, "y,": -74, "Y,": -139, "Y;": -92, "Y:": -92, "y.": -74, "Y.": -139, "Ya": -92, "YA": -74, "Ye": -111, "Yi": -37, "Yo": -111, "Yp": -74, "Yq": -92, "Yu": -74, "Yv": -55 }, "w": { " ": 278, "_": 500, "-": 389, "\u2013": 500, "\u2014": 1e3, ",": 278, ";": 278, ":": 278, "!": 259, "?": 556, ".": 278, "\u2026": 1e3, "\xB7": 278, "'": 278, "\u2018": 278, "\u2019": 278, '"': 426, "\u201C": 426, "\u201D": 426, "(": 259, ")": 259, "[": 259, "]": 259, "{": 333, "}": 333, "@": 800, "*": 352, "/": 333, "\\": 333, "&": 630, "#": 556, "%": 1e3, "\u2022": 350, "`": 222, "^": 600, "\u2190": 1e3, "\u2192": 1e3, "\u2191": 645.02, "\u2193": 645.02, "+": 600, "\xD7": 600, "<": 600, "=": 600, ">": 600, "|": 222, "~": 600, "\u25E6": 578.13, "\u2610": 830.08, "\u2611": 830.08, "\u2713": 764.16, "$": 556, "0": 556, "1": 556, "2": 556, "3": 556, "4": 556, "5": 556, "6": 556, "7": 556, "8": 556, "9": 556, "a": 537, "A": 648, "b": 593, "B": 685, "c": 537, "C": 722, "d": 593, "D": 704, "e": 537, "E": 611, "\xE9": 537, "f": 296, "F": 574, "g": 574, "G": 759, "h": 556, "H": 722, "i": 222, "I": 259, "j": 222, "J": 519, "k": 519, "K": 667, "l": 222, "L": 556, "m": 853, "M": 871, "n": 556, "N": 722, "o": 574, "O": 760, "p": 593, "P": 648, "q": 593, "Q": 760, "r": 333, "R": 685, "s": 500, "S": 648, "t": 315, "T": 574, "u": 556, "U": 722, "v": 500, "V": 611, "w": 758, "W": 926, "x": 518, "X": 611, "y": 500, "Y": 648, "z": 480, "Z": 611 } } };
2137
- var fallbackMetrics = { "\u2190": [0.966796875, 0.2109375, 0], "\u2192": [0.966796875, 0.2109375, 0], "\u2191": [0.966796875, 0.2109375, 0], "\u2193": [0.966796875, 0.2109375, 0], "\u25E6": [0.966796875, 0.2109375, 0], "\u2610": [0.66650390625, 0.25, 0.08349609375], "\u2611": [0.66650390625, 0.25, 0.08349609375], "\u2713": [0.966796875, 0.2109375, 0] };
2138
-
2139
2507
  // src/svg-util.ts
2140
2508
  function color(c) {
2141
2509
  const h = (v) => Math.round(Math.min(Math.max(v, 0), 1) * 255).toString(16).padStart(2, "0");
@@ -2145,74 +2513,6 @@ function escapeXML(s) {
2145
2513
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2146
2514
  }
2147
2515
 
2148
- // src/text.ts
2149
- function measure(s, fontSize, face2 = "regular") {
2150
- const f = fonts[face2];
2151
- const fallback = f.w["n"];
2152
- let w = 0;
2153
- let prev = "";
2154
- for (const ch of s) {
2155
- w += f.w[ch] ?? fallback;
2156
- if (prev) w += f.k[prev + ch] ?? 0;
2157
- prev = ch;
2158
- }
2159
- return w * fontSize / 1e3;
2160
- }
2161
- function lineHeights(fontSize) {
2162
- const a = Math.round(ascent * fontSize), d = Math.round(descent * fontSize), l = Math.round(leading * fontSize);
2163
- return [a + d, a + d + l];
2164
- }
2165
- function breaksAfter(ch, next) {
2166
- if (ch === " ") return true;
2167
- return (ch === "/" || ch === "-") && next !== "" && !/[\d\s/-]/.test(next);
2168
- }
2169
- function pieces(para) {
2170
- const chars = [...para];
2171
- const out = [];
2172
- let cur = "";
2173
- chars.forEach((ch, i) => {
2174
- cur += ch;
2175
- const next = chars[i + 1] ?? "";
2176
- if (breaksAfter(ch, next) && next !== " ") {
2177
- out.push(cur);
2178
- cur = "";
2179
- }
2180
- });
2181
- if (cur || out.length === 0) out.push(cur);
2182
- return out;
2183
- }
2184
- function wrap(s, fontSize, maxWidth, face2 = "regular") {
2185
- const out = [];
2186
- for (const para of s.split(/\r\n|\n|\r|\u2028|\u2029/)) {
2187
- let line2 = "";
2188
- for (const piece of pieces(para)) {
2189
- const candidate = line2 + piece;
2190
- if (line2 === "" || measure(candidate.trimEnd(), fontSize, face2) <= maxWidth) {
2191
- line2 = candidate;
2192
- } else {
2193
- out.push(line2);
2194
- line2 = piece;
2195
- }
2196
- while (measure(line2.trimEnd(), fontSize, face2) > maxWidth && [...line2.trimEnd()].length > 1) {
2197
- const chars = [...line2];
2198
- let n = chars.length - 1;
2199
- while (n > 1 && measure(chars.slice(0, n).join(""), fontSize, face2) > maxWidth) n--;
2200
- out.push(chars.slice(0, n).join(""));
2201
- line2 = chars.slice(n).join("");
2202
- }
2203
- }
2204
- out.push(line2);
2205
- }
2206
- return out;
2207
- }
2208
- function textSize(s, fontSize, maxWidth) {
2209
- if (s === "") return { width: 0, height: 0 };
2210
- const lines = wrap(s, fontSize, maxWidth);
2211
- const width = Math.max(...lines.map((l) => measure(l.trimEnd(), fontSize)));
2212
- const [first, next] = lineHeights(fontSize);
2213
- return { width: Math.ceil(width - 1e-9), height: Math.ceil(first + next * (lines.length - 1) - 1e-9) };
2214
- }
2215
-
2216
2516
  // src/note.ts
2217
2517
  var PADDING = 12;
2218
2518
  var SEP = "\u2028";
@@ -2468,35 +2768,36 @@ function underlineBareURLs(runs) {
2468
2768
  return out;
2469
2769
  });
2470
2770
  }
2471
- function face(r) {
2472
- return r.bold ? r.italic ? "boldItalic" : "bold" : r.italic ? "italic" : "regular";
2771
+ function famOf(r, fam) {
2772
+ return r.mono ? families[DEFAULT_FAMILY] : fam;
2473
2773
  }
2474
- function charWidth(ch, r) {
2475
- if (r.mono && fallbackMetrics[ch] === void 0) return monoAdvance * r.size;
2476
- const f = fonts[face(r)];
2477
- return (f.w[ch] ?? fonts.regular.w[ch] ?? f.w["n"]) * r.size / 1e3;
2774
+ function charWidth(ch, r, fam) {
2775
+ const f = famOf(r, fam);
2776
+ if (r.mono && f.fallback[ch] === void 0) return monoAdvance * r.size;
2777
+ const face = f.faces[faceOf(f, r.bold, r.italic)];
2778
+ return (face.w[ch] ?? f.faces.regular.w[ch] ?? face.w["n"]) * r.size / 1e3;
2478
2779
  }
2479
- function kern(a, b, r) {
2780
+ function kern(a, b, r, fam) {
2480
2781
  if (r.mono) return 0;
2481
- return (fonts[face(r)].k[a + b] ?? 0) * r.size / 1e3;
2782
+ return (fam.faces[faceOf(fam, r.bold, r.italic)].k[a + b] ?? 0) * r.size / 1e3;
2482
2783
  }
2483
- function metrics(ch, r) {
2484
- const fb = fallbackMetrics[ch];
2784
+ function metrics(ch, r, fam) {
2785
+ const fb = famOf(r, fam).fallback[ch];
2485
2786
  if (fb) return [fb[0] * r.size, fb[1] * r.size, fb[2] * r.size];
2486
2787
  if (r.mono) return [monoAscent * r.size, monoDescent * r.size, 0];
2487
- if (r.bold && r.italic) return [boldItalicAscent * r.size, boldItalicDescent * r.size, boldItalicLeading * r.size];
2488
- if (r.bold) return [boldAscent * r.size, boldDescent * r.size, boldLeading * r.size];
2489
- if (r.italic) return [italicAscent * r.size, italicDescent * r.size, italicLeading * r.size];
2490
- return [ascent * r.size, descent * r.size, leading * r.size];
2788
+ const m = fam.faces[faceOf(fam, r.bold, r.italic)];
2789
+ return [m.ascent * r.size, m.descent * r.size, m.leading * r.size];
2491
2790
  }
2492
2791
  var Builder = class {
2493
- constructor(fontSize, width) {
2792
+ constructor(fontSize, width, fam) {
2494
2793
  __publicField(this, "paras", []);
2495
2794
  __publicField(this, "nextSpacing", null);
2496
2795
  __publicField(this, "fontSize");
2497
2796
  __publicField(this, "width");
2797
+ __publicField(this, "fam");
2498
2798
  this.fontSize = fontSize;
2499
2799
  this.width = width;
2800
+ this.fam = fam;
2500
2801
  }
2501
2802
  get gap() {
2502
2803
  return this.fontSize * 0.5;
@@ -2504,13 +2805,13 @@ var Builder = class {
2504
2805
  spacing(normal) {
2505
2806
  return this.paras.length === 0 ? 0 : this.nextSpacing ?? normal;
2506
2807
  }
2507
- run(i, size, alpha, base = {}) {
2808
+ run(i, size, alpha, base2 = {}) {
2508
2809
  const mono = !!i.mono;
2509
2810
  return {
2510
2811
  text: i.text,
2511
2812
  size: mono ? size * 0.9 : size,
2512
- bold: !!(i.bold || base.bold),
2513
- italic: !!(i.italic || base.italic),
2813
+ bold: !!(i.bold || base2.bold),
2814
+ italic: !!(i.italic || base2.italic),
2514
2815
  mono,
2515
2816
  strike: !!i.strike,
2516
2817
  underline: !!i.link,
@@ -2543,7 +2844,7 @@ var Builder = class {
2543
2844
  break;
2544
2845
  case "list": {
2545
2846
  const markers = b.items.map((it, i) => it.checkbox === true ? "\u2611" : it.checkbox === false ? "\u2610" : b.ordered !== null ? `${b.ordered + i}.` : ctx.listDepth % 2 === 0 ? "\u2022" : "\u25E6");
2546
- const plain = (s) => measureRun({ text: s, size: this.fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 });
2847
+ const plain = (s) => measureRun({ text: s, size: this.fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 }, this.fam);
2547
2848
  const widest = Math.max(0, ...markers.map(plain));
2548
2849
  const hang = ctx.indent + Math.max(widest + this.fontSize * 0.45, this.fontSize * 1.2);
2549
2850
  b.items.forEach((item, i) => {
@@ -2588,7 +2889,7 @@ var Builder = class {
2588
2889
  const widths = (size2) => {
2589
2890
  const w2 = new Array(columns).fill(0);
2590
2891
  for (const row of rows) row.cells.forEach((c, i) => {
2591
- if (i < columns) w2[i] = Math.max(w2[i], cell(c, row.header, size2).reduce((s, r) => s + measureRun(r), 0));
2892
+ if (i < columns) w2[i] = Math.max(w2[i], cell(c, row.header, size2).reduce((s, r) => s + measureRun(r, this.fam), 0));
2592
2893
  });
2593
2894
  return w2;
2594
2895
  };
@@ -2632,17 +2933,17 @@ var Builder = class {
2632
2933
  });
2633
2934
  }
2634
2935
  };
2635
- function measureRun(r) {
2936
+ function measureRun(r, fam) {
2636
2937
  let w = 0, prev = "";
2637
2938
  for (const ch of r.text) {
2638
- w += charWidth(ch, r);
2639
- if (prev) w += kern(prev, ch, r);
2939
+ w += charWidth(ch, r, fam);
2940
+ if (prev) w += kern(prev, ch, r, fam);
2640
2941
  prev = ch;
2641
2942
  }
2642
2943
  return w;
2643
2944
  }
2644
2945
  var TAB_INTERVAL = 28;
2645
- function layoutLines(paras, width, height, fontSize) {
2946
+ function layoutLines(paras, width, height, fontSize, fam) {
2646
2947
  const lines = [];
2647
2948
  let baseline = 0;
2648
2949
  let prev = null;
@@ -2676,7 +2977,7 @@ function layoutLines(paras, width, height, fontSize) {
2676
2977
  let seg = 0, prevCh = "";
2677
2978
  for (let q = end + 1; q < chars.length && chars[q].ch !== " " && chars[q].ch !== "\n" && chars[q].ch !== SEP; q++) {
2678
2979
  const rr = runs[chars[q].run];
2679
- seg += charWidth(chars[q].ch, rr) + (prevCh ? kern(prevCh, chars[q].ch, rr) : 0);
2980
+ seg += charWidth(chars[q].ch, rr, fam) + (prevCh ? kern(prevCh, chars[q].ch, rr, fam) : 0);
2680
2981
  prevCh = chars[q].ch;
2681
2982
  }
2682
2983
  tx = Math.max(x, stop.align === "right" ? stop.x - seg : stop.x - seg / 2);
@@ -2687,12 +2988,12 @@ function layoutLines(paras, width, height, fontSize) {
2687
2988
  continue;
2688
2989
  }
2689
2990
  const prevGlyph = glyphs[glyphs.length - 1];
2690
- const kx = prevGlyph && prevGlyph.run === run && prevGlyph.ch !== " " ? kern(prevGlyph.ch, ch, r) : 0;
2991
+ const kx = prevGlyph && prevGlyph.run === run && prevGlyph.ch !== " " ? kern(prevGlyph.ch, ch, r, fam) : 0;
2691
2992
  if (prevGlyph) {
2692
2993
  prevGlyph.w += kx;
2693
2994
  x += kx;
2694
2995
  }
2695
- const w = charWidth(ch, r);
2996
+ const w = charWidth(ch, r, fam);
2696
2997
  if (ch !== " " && x + w > maxX2 + 0.01 && glyphs.some((g) => g.ch !== " ")) {
2697
2998
  if (lastSpace >= 0) {
2698
2999
  glyphs.length = lastSpace + 1;
@@ -2707,17 +3008,17 @@ function layoutLines(paras, width, height, fontSize) {
2707
3008
  }
2708
3009
  if (glyphs.length === 0 && end === k && k < chars.length) {
2709
3010
  const { ch, run } = chars[k];
2710
- glyphs.push({ ch, run, x: start, w: charWidth(ch, runs[run]) });
3011
+ glyphs.push({ ch, run, x: start, w: charWidth(ch, runs[run], fam) });
2711
3012
  end = k + 1;
2712
3013
  }
2713
3014
  let asc = 0, desc = 0, lead = 0;
2714
3015
  for (const g of glyphs) {
2715
- const [a, d, l] = metrics(g.ch, runs[g.run]);
3016
+ const [a, d, l] = metrics(g.ch, runs[g.run], fam);
2716
3017
  asc = Math.max(asc, a);
2717
3018
  desc = Math.max(desc, d);
2718
3019
  lead = Math.max(lead, l);
2719
3020
  }
2720
- if (glyphs.length === 0) [asc, desc, lead] = metrics(" ", runs[0] ?? { text: " ", size: fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 });
3021
+ if (glyphs.length === 0) [asc, desc, lead] = metrics(" ", runs[0] ?? { text: " ", size: fontSize, bold: false, italic: false, mono: false, strike: false, underline: false, alpha: 1 }, fam);
2721
3022
  baseline = prev ? baseline + Math.round(prev.desc) + Math.round(prev.lead) + (firstLine ? p.spacing : 0) + Math.round(asc) : Math.round(asc);
2722
3023
  if (baseline + desc > height + 0.5) return;
2723
3024
  const line2 = { glyphs, asc, desc, lead, baseline, para: p, first: firstLine };
@@ -2736,9 +3037,10 @@ function layoutLines(paras, width, height, fontSize) {
2736
3037
  function noteMarkup(source, e) {
2737
3038
  const rect2 = textRect({ x: e.x, y: e.y, width: e.width, height: e.height });
2738
3039
  if (!(rect2.width > 1 && rect2.height > 1)) return "";
2739
- const b = new Builder(e.style.fontSize, rect2.width);
3040
+ const fam = familyMetrics(e.style.font);
3041
+ const b = new Builder(e.style.fontSize, rect2.width, fam);
2740
3042
  for (const block of parseBlocks(source)) b.block(block, { indent: 0, marker: null, quote: null, listDepth: 0 });
2741
- const lines = layoutLines(b.paras, rect2.width, rect2.height, e.style.fontSize);
3043
+ const lines = layoutLines(b.paras, rect2.width, rect2.height, e.style.fontSize, fam);
2742
3044
  const ink = color(e.style.stroke);
2743
3045
  let s = "";
2744
3046
  const marks = [];
@@ -2757,8 +3059,8 @@ function noteMarkup(source, e) {
2757
3059
  const r = gs[i].r;
2758
3060
  let j = i;
2759
3061
  let text = "";
2760
- const font = fontOf(gs[i].ch);
2761
- while (j < gs.length && sameStyle(gs[j].r, r) && gs[j].ch !== " " && fontOf(gs[j].ch) === font) {
3062
+ const font = fontOf(gs[i].ch, famOf(r, fam));
3063
+ while (j < gs.length && sameStyle(gs[j].r, r) && gs[j].ch !== " " && fontOf(gs[j].ch, famOf(r, fam)) === font) {
2762
3064
  text += gs[j].ch;
2763
3065
  j++;
2764
3066
  }
@@ -2766,20 +3068,21 @@ function noteMarkup(source, e) {
2766
3068
  if (shown.trim() !== "") {
2767
3069
  let a = `font-size="${fmt(r.size)}"`;
2768
3070
  if (r.mono) a += ` font-family="Menlo, Consolas, monospace"`;
2769
- if (r.bold) a += ` font-weight="bold"`;
2770
- if (r.italic) a += ` font-style="italic"`;
3071
+ const face = r.mono ? "regular" : faceOf(fam, r.bold, r.italic);
3072
+ if (r.mono ? r.bold : face === "bold" || face === "boldItalic") a += ` font-weight="bold"`;
3073
+ if (r.mono ? r.italic : face === "italic" || face === "boldItalic") a += ` font-style="italic"`;
2771
3074
  if (r.underline) a += ` text-decoration="underline"`;
2772
3075
  if (r.alpha < 1) a += ` fill-opacity="${fmt(r.alpha * e.style.stroke.a)}"`;
2773
3076
  spans += `<tspan x="${fmt(rect2.x + gs[i].x)}" ${a}>${escapeXML(shown)}</tspan>`;
2774
3077
  }
2775
3078
  if (r.strike && j > i) {
2776
- const y = l.baseline - metrics(gs[i].ch, r)[0] * 0.32;
3079
+ const y = l.baseline - metrics(gs[i].ch, r, fam)[0] * 0.32;
2777
3080
  marks.push([rect2.x + gs[i].x, rect2.y + y, rect2.x + gs[j - 1].x + gs[j - 1].w, rect2.y + y]);
2778
3081
  }
2779
3082
  if (j === i) j++;
2780
3083
  i = j;
2781
3084
  }
2782
- if (spans) s += `<text y="${fmt(rect2.y + l.baseline)}" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" fill="${ink}" xml:space="preserve">${spans}</text>
3085
+ if (spans) s += `<text y="${fmt(rect2.y + l.baseline)}" font-family="${cssFamily(e.style.font)}" fill="${ink}" xml:space="preserve">${spans}</text>
2783
3086
  `;
2784
3087
  }
2785
3088
  const width = fmt(Math.max(1, e.style.fontSize / 14));
@@ -2789,8 +3092,8 @@ function noteMarkup(source, e) {
2789
3092
  }
2790
3093
  return s;
2791
3094
  }
2792
- function fontOf(ch) {
2793
- return fallbackMetrics[ch] ? `fb:${ch}` : "";
3095
+ function fontOf(ch, fam) {
3096
+ return fam.fallback[ch] ? `fb:${ch}` : "";
2794
3097
  }
2795
3098
  function sameStyle(a, b) {
2796
3099
  return a === b || a.size === b.size && a.bold === b.bold && a.italic === b.italic && a.mono === b.mono && a.strike === b.strike && a.underline === b.underline && a.alpha === b.alpha;
@@ -2872,7 +3175,7 @@ function svgParts(page, background, fixed, links = false) {
2872
3175
  if (!visible.has(e.layerID)) continue;
2873
3176
  const alpha = Math.min(Math.max(e.style.opacity ?? 1, 0), 1);
2874
3177
  if (alpha <= 0) continue;
2875
- let body = svgElement(e, index, bg);
3178
+ let body = svgElement(e, index, bg, d);
2876
3179
  if (angle(e) !== 0 && e.kind !== "connector") {
2877
3180
  body = `<g transform="rotate(${fmt(angle(e) * 180 / Math.PI)} ${fmt(midX(frame(e)))} ${fmt(midY(frame(e)))})">
2878
3181
  ${body}</g>
@@ -2896,7 +3199,7 @@ function svg(page, background = { r: 1, g: 1, b: 1, a: 1 }, fixed) {
2896
3199
  function labelRect(e, index) {
2897
3200
  const m = midpoint(e, index);
2898
3201
  const text = e.text ?? "";
2899
- const size = textSize(text === "" ? "Label" : text, e.style.fontSize, 200);
3202
+ const size = textSize(text === "" ? "Label" : text, e.style.fontSize, 200, e.style.font);
2900
3203
  const w = Math.max(size.width + 12, 44), h = size.height + 6;
2901
3204
  return { x: m.x - w / 2, y: m.y - h / 2, width: w, height: h };
2902
3205
  }
@@ -2907,7 +3210,7 @@ function typed(s, progress) {
2907
3210
  function revealProgress(e) {
2908
3211
  return e.reveal !== null && e.reveal < 1 ? Math.max(0, e.reveal) : null;
2909
3212
  }
2910
- function svgElement(e, index, labelBackground) {
3213
+ function svgElement(e, index, labelBackground, page) {
2911
3214
  const stroke = color(e.style.stroke);
2912
3215
  let strokeAttrs = `stroke="${stroke}" stroke-width="${fmt(e.style.strokeWidth)}" stroke-linecap="round" stroke-linejoin="round"`;
2913
3216
  const dash = dashPattern(e.style.dash, e.style.strokeWidth);
@@ -2918,7 +3221,7 @@ function svgElement(e, index, labelBackground) {
2918
3221
  if (r !== null) {
2919
3222
  if (e.kind === "text") text = typed(text ?? "", r);
2920
3223
  else if (e.kind === "connector") {
2921
- return `<path d="${connectorParts(e, index)[0].trimmed(r).data()}" fill="none" ${strokeAttrs}/>
3224
+ return `<path d="${connectorParts(e, index, page)[0].trimmed(r).data()}" fill="none" ${strokeAttrs}/>
2922
3225
  `;
2923
3226
  } else {
2924
3227
  return `<path d="${outline(e).trimmed(r).data()}" fill="none" ${strokeAttrs}/>
@@ -2927,7 +3230,7 @@ function svgElement(e, index, labelBackground) {
2927
3230
  }
2928
3231
  switch (e.kind) {
2929
3232
  case "connector": {
2930
- const [line2, filled2] = connectorParts(e, index);
3233
+ const [line2, filled2] = connectorParts(e, index, page);
2931
3234
  let s = `<path d="${line2.data()}" fill="none" ${strokeAttrs}/>
2932
3235
  `;
2933
3236
  if (!filled2.isEmpty) s += `<path d="${filled2.data()}" fill="${stroke}" stroke="none"/>
@@ -3010,7 +3313,7 @@ function textElement(text, f, e, centered) {
3010
3313
  const total = lineHeight * lines.length;
3011
3314
  const x = centered ? midX(f) : f.x;
3012
3315
  const top = centered ? midY(f) - total / 2 : f.y;
3013
- let s = `<text x="${fmt(x)}" font-family="Helvetica Neue, Helvetica, Arial, sans-serif" font-size="${fmt(size)}" fill="${color(e.style.stroke)}"${centered ? ` text-anchor="middle"` : ""}>`;
3316
+ let s = `<text x="${fmt(x)}" font-family="${cssFamily(e.style.font)}" font-size="${fmt(size)}" fill="${color(labelColor(e))}"${centered ? ` text-anchor="middle"` : ""}>`;
3014
3317
  lines.forEach((line2, i) => {
3015
3318
  s += `<tspan x="${fmt(x)}" y="${fmt(top + lineHeight * (i + 0.8))}">${escapeXML(line2)}</tspan>`;
3016
3319
  });
@@ -3077,6 +3380,7 @@ var Playback = class {
3077
3380
  __publicField(this, "frame", -1);
3078
3381
  __publicField(this, "onFrame", null);
3079
3382
  this.page = options.clean ? withRoughness(page, 0) : page;
3383
+ addFonts(usedFonts(this.page));
3080
3384
  this.plan = plan(this.page);
3081
3385
  this.clicks = clickTargets(page, options.file);
3082
3386
  const table = symbolTable(this.page);
@@ -3238,16 +3542,16 @@ var Playback = class {
3238
3542
  const s = keys.map((k) => m2.get(k) ?? "").join("");
3239
3543
  return s === "" ? null : s;
3240
3544
  };
3241
- const base = join(normal) ?? "";
3545
+ const base2 = join(normal) ?? "";
3242
3546
  const instance = pose.elements.find((e) => e.id === o && e.kind === "symbol");
3243
3547
  const overLook = instance ? join(over) : join(hover);
3244
3548
  const downLook = instance ? join(down) : null;
3245
- const shownOver = overLook !== null && overLook !== base ? overLook : null;
3246
- const shownDown = downLook !== null && downLook !== (overLook ?? base) ? downLook : null;
3247
- if (!instance && shownOver === null) return { key: o, markup: base, button: false };
3549
+ const shownOver = overLook !== null && overLook !== base2 ? overLook : null;
3550
+ const shownDown = downLook !== null && downLook !== (overLook ?? base2) ? downLook : null;
3551
+ if (!instance && shownOver === null) return { key: o, markup: base2, button: false };
3248
3552
  const still2 = instance ? ` pointer-events="none"` : "";
3249
3553
  let m = `<g class="dottie-n"${still2}>
3250
- ${base}</g>
3554
+ ${base2}</g>
3251
3555
  `;
3252
3556
  if (shownOver !== null) m += `<g class="dottie-h"${still2}>
3253
3557
  ${shownOver}</g>
@@ -3658,6 +3962,7 @@ function inspectFrame(page, t) {
3658
3962
  d.strokeWidth = r4(e.style.strokeWidth);
3659
3963
  d.stroke = rgba2(e.style.stroke);
3660
3964
  d.fill = rgba2(e.style.fill);
3965
+ if (e.style.textColor !== null) d.textColor = rgba2(e.style.textColor);
3661
3966
  if (e.kind === "connector") {
3662
3967
  const [a, b] = endpoints(e, index);
3663
3968
  d.start = pt(a);
@@ -3701,13 +4006,14 @@ function render(source, options = {}) {
3701
4006
  function isFile(v) {
3702
4007
  return typeof v === "object" && v !== null && Array.isArray(v.pages) && Array.isArray(v.warnings);
3703
4008
  }
3704
- var VERSION = "0.6.1";
4009
+ var VERSION = "0.6.3";
3705
4010
 
3706
4011
  // src/player-entry.ts
3707
4012
  definePlayer();
3708
4013
  globalThis.Dottie ?? (globalThis.Dottie = index_exports);
3709
4014
  export {
3710
4015
  BOIL_DRAWINGS,
4016
+ BUNDLED_FONTS,
3711
4017
  DottieFormatError,
3712
4018
  DottiePlayer,
3713
4019
  KINDS,
@@ -3717,6 +4023,7 @@ export {
3717
4023
  Playback,
3718
4024
  SUPPORTED_VERSION,
3719
4025
  VERSION,
4026
+ addFonts,
3720
4027
  allowedURL,
3721
4028
  black,
3722
4029
  bounds,
@@ -3728,6 +4035,8 @@ export {
3728
4035
  cloneElement,
3729
4036
  definePlayer,
3730
4037
  elementIndex,
4038
+ fontFaces,
4039
+ fontFile,
3731
4040
  frameTimes,
3732
4041
  inkOnDark,
3733
4042
  inspect,
@@ -3746,6 +4055,7 @@ export {
3746
4055
  sameColor,
3747
4056
  sampleTimes,
3748
4057
  sceneAt,
4058
+ setFontBase,
3749
4059
  stableSortBy,
3750
4060
  still,
3751
4061
  svg,
@@ -3753,6 +4063,7 @@ export {
3753
4063
  themeNamed,
3754
4064
  themes,
3755
4065
  transientElements,
4066
+ usedFonts,
3756
4067
  webLink,
3757
4068
  withRoughness
3758
4069
  };