lildocs 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -429,23 +429,23 @@ function ensureUniqueRoutes(pages) {
429
429
  const defaultAlertVariants = [
430
430
  {
431
431
  type: "note",
432
- icon: materialSymbol("info")
432
+ icon: tablerIcon("info-circle")
433
433
  },
434
434
  {
435
435
  type: "tip",
436
- icon: materialSymbol("lightbulb")
436
+ icon: tablerIcon("bulb")
437
437
  },
438
438
  {
439
439
  type: "important",
440
- icon: materialSymbol("feedback")
440
+ icon: tablerIcon("message-report")
441
441
  },
442
442
  {
443
443
  type: "warning",
444
- icon: materialSymbol("warning")
444
+ icon: tablerIcon("alert-triangle")
445
445
  },
446
446
  {
447
447
  type: "caution",
448
- icon: materialSymbol("dangerous")
448
+ icon: tablerIcon("alert-circle")
449
449
  }
450
450
  ];
451
451
  function markedAlert(options = {}) {
@@ -511,8 +511,8 @@ function createSyntaxPattern(type) {
511
511
  function capitalize$1(value) {
512
512
  return value.slice(0, 1).toUpperCase() + value.slice(1).toLowerCase();
513
513
  }
514
- function materialSymbol(name) {
515
- return `<span class="material-symbols-rounded markdown-alert-icon" aria-hidden="true">${name}</span>`;
514
+ function tablerIcon(name) {
515
+ return `<span class="ti ti-${name} markdown-alert-icon" aria-hidden="true"></span>`;
516
516
  }
517
517
  function escapeRegExp(value) {
518
518
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -942,6 +942,7 @@ async function exists$1(filePath) {
942
942
  //#region src/core/theme.ts
943
943
  const MIN_BACKGROUND_CONTRAST = 1.08;
944
944
  const PREFERRED_BACKGROUND_CONTRAST = 1.14;
945
+ const MIN_DARK_BORDER_CONTRAST = 1.35;
945
946
  const MAX_BACKGROUND_CONTRAST_STEPS = 12;
946
947
  const BACKGROUND_LIGHTNESS_STEP = .015;
947
948
  const MAX_BACKGROUND_CHROMA = .03;
@@ -956,6 +957,7 @@ const themes = {
956
957
  border: "#e5e5e5",
957
958
  link: "#2563eb",
958
959
  codeBackground: "#f6f8fa",
960
+ codeForeground: "#24292e",
959
961
  sidebarBackground: "#fafafa"
960
962
  },
961
963
  font: {
@@ -963,7 +965,8 @@ const themes = {
963
965
  body: "system-ui, sans-serif",
964
966
  code: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
965
967
  },
966
- shiki: { theme: "github-light" }
968
+ shiki: { theme: "github-light" },
969
+ background: { gradient: "linear-gradient(180deg, rgb(37 99 235 / 0.045), transparent 220px)" }
967
970
  },
968
971
  minimal: {
969
972
  color: {
@@ -973,6 +976,7 @@ const themes = {
973
976
  border: "#dddddd",
974
977
  link: "#0f766e",
975
978
  codeBackground: "#f7f7f7",
979
+ codeForeground: "#24292e",
976
980
  sidebarBackground: "#ffffff"
977
981
  },
978
982
  font: {
@@ -980,7 +984,8 @@ const themes = {
980
984
  body: "Arial, sans-serif",
981
985
  code: "Menlo, Consolas, monospace"
982
986
  },
983
- shiki: { theme: "github-light" }
987
+ shiki: { theme: "github-light" },
988
+ background: { gradient: "linear-gradient(180deg, rgb(15 118 110 / 0.04), transparent 220px)" }
984
989
  }
985
990
  };
986
991
  async function resolveTheme(options) {
@@ -1056,10 +1061,11 @@ function themeToCssVariables(theme, fontOverrides = {}, linkOptions = {}, naviga
1056
1061
  const navigationDuration = navigationOptions.duration ?? 180;
1057
1062
  const rootVariables = themeToCssVariableBlock(theme.light, fontOverrides);
1058
1063
  const darkVariables = theme.dark ? themeToCssVariableBlock(theme.dark, fontOverrides) : void 0;
1064
+ const rootBackgroundVariables = themeToBackgroundVariableBlock(theme.light);
1065
+ const darkBackgroundVariables = theme.dark ? themeToBackgroundVariableBlock(theme.dark) : void 0;
1059
1066
  return `:root {
1060
1067
  ${theme.dark ? " color-scheme: light dark;\n" : ""}${rootVariables}
1061
- --ld-background-image: none;
1062
- --ld-background-blend-mode: normal;
1068
+ ${rootBackgroundVariables}
1063
1069
  --ld-font-logo: var(--ld-font-heading);
1064
1070
  --ld-link-text-decoration: ${linkDecoration.default};
1065
1071
  --ld-link-hover-text-decoration: ${linkDecoration.hover};
@@ -1069,7 +1075,7 @@ ${theme.dark ? " color-scheme: light dark;\n" : ""}${rootVariables}
1069
1075
 
1070
1076
  @media (prefers-color-scheme: dark) {
1071
1077
  :root {
1072
- ${darkVariables} color-scheme: dark;
1078
+ ${darkVariables}${darkBackgroundVariables} color-scheme: dark;
1073
1079
  }
1074
1080
  }` : ""}`;
1075
1081
  }
@@ -1112,12 +1118,18 @@ function themeToCssVariableBlock(theme, fontOverrides) {
1112
1118
  --ld-color-border: ${color.border};
1113
1119
  --ld-color-link: ${color.link};
1114
1120
  --ld-color-code-background: ${color.codeBackground};
1121
+ --ld-color-code-foreground: ${color.codeForeground ?? color.text};
1115
1122
  --ld-color-sidebar-background: ${color.sidebarBackground ?? color.background};
1116
1123
  --ld-font-heading: ${fonts.heading};
1117
1124
  --ld-font-body: ${fonts.body};
1118
1125
  --ld-font-code: ${fonts.code};
1119
1126
  `;
1120
1127
  }
1128
+ function themeToBackgroundVariableBlock(theme) {
1129
+ return ` --ld-background-image: ${theme.background?.gradient ?? "none"};
1130
+ --ld-background-blend-mode: ${theme.background?.blendMode ?? "normal"};
1131
+ `;
1132
+ }
1121
1133
  function normalizeThemeColors(color) {
1122
1134
  return {
1123
1135
  ...color,
@@ -1141,6 +1153,11 @@ function validateTheme(value, themePath) {
1141
1153
  theme.font?.body,
1142
1154
  theme.font?.code ?? theme.font?.mono
1143
1155
  ].some((item) => typeof item !== "string" || item.length === 0)) throw new LildocsError(`Local theme is missing required color or font string values: ${themePath}`);
1156
+ if (theme.background !== void 0) {
1157
+ if (!theme.background || typeof theme.background !== "object") throw new LildocsError(`Local theme "background" must be an object: ${themePath}`);
1158
+ if (theme.background.gradient !== void 0 && (typeof theme.background.gradient !== "string" || theme.background.gradient.length === 0)) throw new LildocsError(`Local theme "background.gradient" must be a non-empty string: ${themePath}`);
1159
+ if (theme.background.blendMode !== void 0 && (typeof theme.background.blendMode !== "string" || theme.background.blendMode.length === 0)) throw new LildocsError(`Local theme "background.blendMode" must be a non-empty string: ${themePath}`);
1160
+ }
1144
1161
  return theme;
1145
1162
  }
1146
1163
  function mapShikiThemeToTheme(shikiTheme, themeName) {
@@ -1156,27 +1173,30 @@ function mapShikiThemeToTheme(shikiTheme, themeName) {
1156
1173
  "foreground",
1157
1174
  "sideBar.foreground"
1158
1175
  ], shikiTheme.fg ?? (shikiTheme.type === "dark" ? "#f5f5f5" : "#111111"));
1176
+ const mutedText = pickColor(colors, [
1177
+ "descriptionForeground",
1178
+ "breadcrumb.foreground",
1179
+ "editorLineNumber.foreground",
1180
+ "sideBar.foreground"
1181
+ ], tokenForeground(tokenColors, "comment") ?? text);
1182
+ const border = pickColor(colors, [
1183
+ "panel.border",
1184
+ "sideBar.border",
1185
+ "editorGroup.border",
1186
+ "tab.border"
1187
+ ], shikiTheme.type === "dark" ? "#333333" : "#e5e5e5");
1188
+ const link = pickColor(colors, [
1189
+ "textLink.foreground",
1190
+ "terminal.ansiBlue",
1191
+ "activityBarBadge.background"
1192
+ ], tokenForeground(tokenColors, "markup.inline.raw") ?? (shikiTheme.type === "dark" ? "#79b8ff" : "#2563eb"));
1159
1193
  return {
1160
1194
  color: {
1161
1195
  background,
1162
1196
  text,
1163
- mutedText: pickColor(colors, [
1164
- "descriptionForeground",
1165
- "breadcrumb.foreground",
1166
- "editorLineNumber.foreground",
1167
- "sideBar.foreground"
1168
- ], tokenForeground(tokenColors, "comment") ?? text),
1169
- border: pickColor(colors, [
1170
- "panel.border",
1171
- "sideBar.border",
1172
- "editorGroup.border",
1173
- "tab.border"
1174
- ], shikiTheme.type === "dark" ? "#333333" : "#e5e5e5"),
1175
- link: pickColor(colors, [
1176
- "textLink.foreground",
1177
- "terminal.ansiBlue",
1178
- "activityBarBadge.background"
1179
- ], tokenForeground(tokenColors, "markup.inline.raw") ?? (shikiTheme.type === "dark" ? "#79b8ff" : "#2563eb")),
1197
+ mutedText,
1198
+ border,
1199
+ link,
1180
1200
  codeBackground: ensureBackgroundContrast({
1181
1201
  background,
1182
1202
  candidate: pickColor(colors, [
@@ -1187,6 +1207,7 @@ function mapShikiThemeToTheme(shikiTheme, themeName) {
1187
1207
  ], background),
1188
1208
  isDark: shikiTheme.type === "dark"
1189
1209
  }),
1210
+ codeForeground: text,
1190
1211
  sidebarBackground: pickColor(colors, [
1191
1212
  "sideBar.background",
1192
1213
  "activityBar.background",
@@ -1198,7 +1219,8 @@ function mapShikiThemeToTheme(shikiTheme, themeName) {
1198
1219
  body: "system-ui, sans-serif",
1199
1220
  code: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
1200
1221
  },
1201
- shiki: { theme: themeName }
1222
+ shiki: { theme: themeName },
1223
+ background: { gradient: shikiTheme.type === "dark" ? `linear-gradient(180deg, color-mix(in srgb, ${link} 16%, transparent), transparent 240px)` : `linear-gradient(180deg, color-mix(in srgb, ${link} 9%, transparent), transparent 220px)` }
1202
1224
  };
1203
1225
  }
1204
1226
  function pickColor(colors, keys, fallback) {
@@ -1285,9 +1307,11 @@ function ensureDarkBorderLightness(options) {
1285
1307
  const textOklch = toOklch(text);
1286
1308
  const candidateOklch = toOklch(candidate);
1287
1309
  if (!backgroundOklch || !textOklch || !candidateOklch || typeof backgroundOklch.l !== "number" || typeof textOklch.l !== "number" || typeof candidateOklch.l !== "number") return options.candidate;
1288
- if (backgroundOklch.l >= textOklch.l || candidateOklch.l > backgroundOklch.l) return options.candidate;
1310
+ if (backgroundOklch.l >= textOklch.l) return options.candidate;
1311
+ const currentContrast = wcagContrast(background, candidate);
1312
+ if (candidateOklch.l > backgroundOklch.l && currentContrast >= MIN_DARK_BORDER_CONTRAST) return options.candidate;
1289
1313
  let bestColor = options.candidate;
1290
- let bestLightness = candidateOklch.l;
1314
+ let bestContrast = currentContrast;
1291
1315
  for (let step = 1; step <= MAX_BACKGROUND_CONTRAST_STEPS; step += 1) {
1292
1316
  const clampedColor = clampToRgb({
1293
1317
  ...candidateOklch,
@@ -1297,13 +1321,15 @@ function ensureDarkBorderLightness(options) {
1297
1321
  if (!clampedColor) continue;
1298
1322
  const adjustedColor = formatHex(clampedColor);
1299
1323
  const adjustedParsedColor = parse(adjustedColor);
1300
- const adjustedOklch = adjustedParsedColor ? toOklch(adjustedParsedColor) : void 0;
1324
+ if (!adjustedParsedColor) continue;
1325
+ const adjustedOklch = toOklch(adjustedParsedColor);
1301
1326
  if (!adjustedOklch || typeof adjustedOklch.l !== "number") continue;
1302
- if (adjustedOklch.l > bestLightness) {
1327
+ const adjustedContrast = wcagContrast(background, adjustedParsedColor);
1328
+ if (adjustedOklch.l > backgroundOklch.l && adjustedContrast > bestContrast) {
1303
1329
  bestColor = adjustedColor;
1304
- bestLightness = adjustedOklch.l;
1330
+ bestContrast = adjustedContrast;
1305
1331
  }
1306
- if (adjustedOklch.l > backgroundOklch.l) return adjustedColor;
1332
+ if (adjustedOklch.l > backgroundOklch.l && adjustedContrast >= MIN_DARK_BORDER_CONTRAST) return adjustedColor;
1307
1333
  }
1308
1334
  return bestColor;
1309
1335
  }
@@ -1374,10 +1400,6 @@ function Layout({ page, nav, pageNavigation, css, searchIndexJson, logo, favicon
1374
1400
  rel: "icon",
1375
1401
  href: assetSrc(page.route, favicon)
1376
1402
  }) : null,
1377
- /* @__PURE__ */ jsx("link", {
1378
- rel: "stylesheet",
1379
- href: "https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20,400,0,0&display=block"
1380
- }),
1381
1403
  /* @__PURE__ */ jsx("link", {
1382
1404
  rel: "stylesheet",
1383
1405
  href: rootRelativeUrl(page.route, "assets/lildocs.css")
@@ -1411,9 +1433,8 @@ function Layout({ page, nav, pageNavigation, css, searchIndexJson, logo, favicon
1411
1433
  id: "lildocs-search-root",
1412
1434
  className: "searchBox",
1413
1435
  children: [/* @__PURE__ */ jsx("span", {
1414
- className: "searchIcon material-symbols-rounded",
1415
- "aria-hidden": "true",
1416
- children: "search"
1436
+ className: "searchIcon ti ti-search",
1437
+ "aria-hidden": "true"
1417
1438
  }), /* @__PURE__ */ jsx("input", {
1418
1439
  id: "lildocs-search-input",
1419
1440
  type: "search",
@@ -1597,6 +1618,7 @@ async function buildSite(options) {
1597
1618
  fonts: configOptions.fonts
1598
1619
  });
1599
1620
  const baseCss = await readRenderAsset("styles.css");
1621
+ const tablerIconsCss = await readTablerIconsCss();
1600
1622
  const searchScript = await readRenderAsset("search.js");
1601
1623
  const copyCodeScript = await readRenderAsset("copy-code.js");
1602
1624
  const navigationScript = await readRenderAsset("navigation.js");
@@ -1616,8 +1638,9 @@ async function buildSite(options) {
1616
1638
  defaultText: packageName,
1617
1639
  favicon: configOptions.favicon
1618
1640
  });
1619
- const css = `${fontResolution.css}${themeToCssVariables(theme, fontResolution.themeFonts, configOptions.link, configOptions.navigation)}\n${backgroundResolution.css}${logoResolution.css}${baseCss}`;
1641
+ const css = `${tablerIconsCss}${fontResolution.css}${themeToCssVariables(theme, fontResolution.themeFonts, configOptions.link, configOptions.navigation)}\n${backgroundResolution.css}${logoResolution.css}${baseCss}`;
1620
1642
  const assets = [
1643
+ ...tablerIconFontAssets(outDir),
1621
1644
  ...fontResolution.assets,
1622
1645
  ...backgroundResolution.assets,
1623
1646
  ...logoResolution.assets
@@ -1717,6 +1740,20 @@ async function readRenderAsset(name) {
1717
1740
  async function readSwupAsset() {
1718
1741
  return readFile(path.join(path.dirname(require.resolve("swup")), "Swup.umd.js"), "utf8");
1719
1742
  }
1743
+ async function readTablerIconsCss() {
1744
+ return readFile(require.resolve("@tabler/icons-webfont/dist/tabler-icons.css"), "utf8");
1745
+ }
1746
+ function tablerIconFontAssets(outDir) {
1747
+ const fontsDir = path.join(path.dirname(require.resolve("@tabler/icons-webfont/dist/tabler-icons.css")), "fonts");
1748
+ return [
1749
+ "tabler-icons.woff2",
1750
+ "tabler-icons.woff",
1751
+ "tabler-icons.ttf"
1752
+ ].map((name) => ({
1753
+ from: path.join(fontsDir, name),
1754
+ to: path.join(outDir, "assets", "fonts", name)
1755
+ }));
1756
+ }
1720
1757
  function buildPageNavigation(pages) {
1721
1758
  const navigation = /* @__PURE__ */ new Map();
1722
1759
  if (pages.length < 2) return navigation;
@@ -1,8 +1,8 @@
1
1
  (() => {
2
2
  const icons = {
3
- copy: '<span class="material-symbols-rounded copyCodeIcon" aria-hidden="true">content_copy</span>',
4
- check: '<span class="material-symbols-rounded copyCodeIcon" aria-hidden="true">check</span>',
5
- error: '<span class="material-symbols-rounded copyCodeIcon" aria-hidden="true">error</span>',
3
+ copy: '<span class="ti ti-copy copyCodeIcon" aria-hidden="true"></span>',
4
+ check: '<span class="ti ti-copy-check copyCodeIcon" aria-hidden="true"></span>',
5
+ error: '<span class="ti ti-alert-circle copyCodeIcon" aria-hidden="true"></span>',
6
6
  };
7
7
 
8
8
  initCopyCode();
@@ -15,11 +15,13 @@
15
15
  }
16
16
 
17
17
  for (const block of blocks) {
18
- if (block.querySelector(":scope > .copyCodeButton")) {
18
+ if (block.parentElement?.classList.contains("copyCodeBlock")) {
19
19
  continue;
20
20
  }
21
21
 
22
22
  const copyText = block.textContent ?? "";
23
+ const wrapper = document.createElement("div");
24
+ wrapper.className = "copyCodeBlock";
23
25
  const button = document.createElement("button");
24
26
  button.type = "button";
25
27
  button.className = "copyCodeButton";
@@ -45,7 +47,8 @@
45
47
  }
46
48
  });
47
49
 
48
- block.append(button);
50
+ block.before(wrapper);
51
+ wrapper.append(block, button);
49
52
  }
50
53
  }
51
54
  })();
@@ -3082,9 +3082,8 @@ function SearchBox({ anchorElement, index, siteRoot, preloadedUrls }) {
3082
3082
  };
3083
3083
  return /* @__PURE__ */ u(S$1, { children: [
3084
3084
  /* @__PURE__ */ u("span", {
3085
- className: "searchIcon material-symbols-rounded",
3086
- "aria-hidden": "true",
3087
- children: "search"
3085
+ className: "searchIcon ti ti-search",
3086
+ "aria-hidden": "true"
3088
3087
  }),
3089
3088
  /* @__PURE__ */ u("input", {
3090
3089
  ref: inputRef,
@@ -132,7 +132,7 @@ html.is-animating .transition-scale {
132
132
 
133
133
  .content {
134
134
  min-width: 0;
135
- padding-block: 28px 64px;
135
+ padding-block: 0 64px;
136
136
  line-height: 1.65;
137
137
  }
138
138
 
@@ -145,15 +145,28 @@ html.is-animating .transition-scale {
145
145
  font-family: var(--ld-font-heading);
146
146
  }
147
147
 
148
+ .content article :where(h1, h2, h3, h4, h5, h6) {
149
+ margin-block: 1.2em 0.6em;
150
+ }
151
+
148
152
  .content img {
149
153
  max-width: 100%;
150
154
  height: auto;
151
155
  }
152
156
 
157
+ .content article {
158
+ max-width: 60ch;
159
+ font-size: 110%;
160
+ }
161
+
153
162
  .content article li {
154
163
  margin-bottom: 8px;
155
164
  }
156
165
 
166
+ .content article > :first-child {
167
+ margin-top: 0;
168
+ }
169
+
157
170
  .content blockquote {
158
171
  margin: 20px 0;
159
172
  padding: 10px 16px;
@@ -181,7 +194,6 @@ html.is-animating .transition-scale {
181
194
  }
182
195
 
183
196
  .content a,
184
- .toc a,
185
197
  .navList a {
186
198
  color: var(--ld-color-link);
187
199
  }
@@ -279,6 +291,15 @@ html.is-animating .transition-scale {
279
291
  white-space: inherit;
280
292
  }
281
293
 
294
+ .content .copyCodeBlock {
295
+ position: relative;
296
+ margin-block: 1em;
297
+ }
298
+
299
+ .content .copyCodeBlock > pre {
300
+ margin: 0;
301
+ }
302
+
282
303
  .content pre.shiki {
283
304
  color: var(--shiki-light);
284
305
  background: var(--shiki-light-bg);
@@ -310,6 +331,13 @@ html.is-animating .transition-scale {
310
331
  font-size: 0.92em;
311
332
  }
312
333
 
334
+ .content :not(pre) > code {
335
+ padding: 0.16em 0.36em;
336
+ border-radius: 4px;
337
+ background: var(--ld-color-code-background);
338
+ color: var(--ld-color-code-foreground);
339
+ }
340
+
313
341
  .copyCodeButton {
314
342
  position: absolute;
315
343
  top: 10px;
@@ -325,10 +353,19 @@ html.is-animating .transition-scale {
325
353
  background: color-mix(in srgb, var(--ld-color-background) 88%, transparent);
326
354
  color: var(--ld-color-muted-text);
327
355
  line-height: 1;
356
+ opacity: 0;
357
+ pointer-events: none;
358
+ transition: opacity 120ms ease;
328
359
  vertical-align: top;
329
360
  cursor: pointer;
330
361
  }
331
362
 
363
+ .content .copyCodeBlock:hover .copyCodeButton,
364
+ .copyCodeButton:focus-visible {
365
+ opacity: 1;
366
+ pointer-events: auto;
367
+ }
368
+
332
369
  .copyCodeIcon {
333
370
  font-size: 18px;
334
371
  line-height: 1;
@@ -371,6 +408,7 @@ html.is-animating .transition-scale {
371
408
 
372
409
  .markdown-alert-icon {
373
410
  flex: 0 0 auto;
411
+ font-size: 20px;
374
412
  }
375
413
 
376
414
  .markdown-alert-note {
@@ -464,6 +502,7 @@ html.is-animating .transition-scale {
464
502
  }
465
503
 
466
504
  .toc a {
505
+ color: var(--ld-color-muted-text);
467
506
  text-decoration: none;
468
507
  }
469
508
 
@@ -528,21 +567,6 @@ html.is-animating .transition-scale {
528
567
  transform: translateY(-50%);
529
568
  }
530
569
 
531
- .material-symbols-rounded {
532
- font-family: "Material Symbols Rounded";
533
- font-weight: normal;
534
- font-style: normal;
535
- font-size: 20px;
536
- line-height: 1;
537
- letter-spacing: normal;
538
- text-transform: none;
539
- white-space: nowrap;
540
- word-wrap: normal;
541
- direction: ltr;
542
- font-feature-settings: "liga";
543
- -webkit-font-smoothing: antialiased;
544
- }
545
-
546
570
  .searchBox input {
547
571
  box-sizing: border-box;
548
572
  width: 100%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lildocs",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "A lightweight CLI that turns Markdown docs into a static searchable documentation site.",
5
5
  "homepage": "https://aleclarson.github.io/lildocs/",
6
6
  "repository": {
@@ -26,6 +26,7 @@
26
26
  "dependencies": {
27
27
  "@goddard-ai/ui-primitives": "^0.1.1",
28
28
  "@preact/signals": "^2.9.2",
29
+ "@tabler/icons-webfont": "^3.44.0",
29
30
  "beautiful-mermaid": "^1.1.3",
30
31
  "cmd-ts": "^0.15.0",
31
32
  "culori": "^4.0.2",