diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0ea6875a2..f73eb9666 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,12 @@ updates: applies-to: "version-updates" patterns: - "*" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + ci-dependencies: + applies-to: "version-updates" + patterns: + - "*" diff --git a/.github/workflows/docker-build-push.yaml b/.github/workflows/docker-build-push.yaml index f3bd2cdb3..308aee3c6 100644 --- a/.github/workflows/docker-build-push.yaml +++ b/.github/workflows/docker-build-push.yaml @@ -25,7 +25,7 @@ jobs: with: fetch-depth: 1 - name: Inject slug/short variables - uses: rlespinasse/github-slug-action@v4.4.1 + uses: rlespinasse/github-slug-action@v5.0.0 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx diff --git a/docs/features/comments.md b/docs/features/comments.md index 1f11effc4..48037735a 100644 --- a/docs/features/comments.md +++ b/docs/features/comments.md @@ -114,3 +114,14 @@ afterBody: [ }), ], ``` + +#### Conditionally display comments + +Quartz can conditionally display the comment box based on a field `comments` in the frontmatter. By default, all pages will display comments, to disable it for a specific page, set `comments` to `false`. + +``` +--- +title: Comments disabled here! +comments: false +--- +``` diff --git a/docs/features/social images.md b/docs/features/social images.md new file mode 100644 index 000000000..0822651f4 --- /dev/null +++ b/docs/features/social images.md @@ -0,0 +1,401 @@ +--- +title: "Social Media Preview Cards" +--- + +A lot of social media platforms can display a rich preview for your website when sharing a link (most notably, a cover image, a title and a description). Quartz automatically handles most of this for you with reasonable defaults, but for more control, you can customize these by setting [[social images#Frontmatter Properties]]. +Quartz can also dynamically generate and use new cover images for every page to be used in link previews on social media for you. To get started with this, set `generateSocialImages: true` in `quartz.config.ts`. + +## Showcase + +After enabling `generateSocialImages` in `quartz.config.ts`, the social media link preview for [[authoring content | Authoring Content]] looks like this: + +| Light | Dark | +| ----------------------------------- | ---------------------------------- | +| ![[social-image-preview-light.png]] | ![[social-image-preview-dark.png]] | + +For testing, it is recommended to use [opengraph.xyz](https://www.opengraph.xyz/) to see what the link to your page will look like on various platforms (more info under [[social images#local testing]]). + +## Customization + +You can customize how images will be generated in the quartz config. + +For example, here's what the default configuration looks like if you set `generateSocialImages: true`: + +```typescript title="quartz.config.ts" +generateSocialImages: { + colorScheme: "lightMode", // what colors to use for generating image, same as theme colors from config, valid values are "darkMode" and "lightMode" + width: 1200, // width to generate with (in pixels) + height: 630, // height to generate with (in pixels) + excludeRoot: false, // wether to exclude "/" index path to be excluded from auto generated images (false = use auto, true = use default og image) +} +``` + +--- + +### Frontmatter Properties + +> [!tip] Hint +> +> Overriding social media preview properties via frontmatter still works even if `generateSocialImages` is disabled. + +The following properties can be used to customize your link previews: + +| Property | Alias | Summary | +| ------------------- | ---------------- | ----------------------------------- | +| `socialDescription` | `description` | Description to be used for preview. | +| `socialImage` | `image`, `cover` | Link to preview image. | + +The `socialImage` property should contain a link to an image relative to `quartz/static`. If you have a folder for all your images in `quartz/static/my-images`, an example for `socialImage` could be `"my-images/cover.png"`. + +> [!info] Info +> +> The priority for what image will be used for the cover image looks like the following: `frontmatter property > generated image (if enabled) > default image`. +> +> The default image (`quartz/static/og-image.png`) will only be used as a fallback if nothing else is set. If `generateSocialImages` is enabled, it will be treated as the new default per page, but can be overwritten by setting the `socialImage` frontmatter property for that page. + +--- + +### Fully customized image generation + +You can fully customize how the images being generated look by passing your own component to `generateSocialImages.imageStructure`. This component takes html/css + some page metadata/config options and converts it to an image using [satori](https://github.com/vercel/satori). Vercel provides an [online playground](https://og-playground.vercel.app/) that can be used to preview how your html/css looks like as a picture. This is ideal for prototyping your custom design. + +It is recommended to write your own image components in `quartz/util/og.tsx` or any other `.tsx` file, as passing them to the config won't work otherwise. An example of the default image component can be found in `og.tsx` in `defaultImage()`. + +> [!tip] Hint +> +> Satori only supports a subset of all valid CSS properties. All supported properties can be found in their [documentation](https://github.com/vercel/satori#css). + +Your custom image component should have the `SocialImageOptions["imageStructure"]` type, to make development easier for you. Using a component of this type, you will be passed the following variables: + +```ts +imageStructure: ( + cfg: GlobalConfiguration, // global Quartz config (useful for getting theme colors and other info) + userOpts: UserOpts, // options passed to `generateSocialImage` + title: string, // title of current page + description: string, // description of current page + fonts: SatoriOptions["fonts"], // header + body font +) => JSXInternal.Element +``` + +Now, you can let your creativity flow and design your own image component! For reference and some cool tips, you can check how the markup for the default image looks. + +> [!example] Examples +> +> Here are some examples for markup you may need to get started: +> +> - Get a theme color +> +> `cfg.theme.colors[colorScheme].`, where `` corresponds to a key in `ColorScheme` (defined at the top of `quartz/util/theme.ts`) +> +> - Use the page title/description +> +> `

{title}

`/`

{description}

` +> +> - Use a font family +> +> Detailed in the Fonts chapter below + +--- + +### Fonts + +You will also be passed an array containing a header and a body font (where the first entry is header and the second is body). The fonts matches the ones selected in `theme.typography.header` and `theme.typography.body` from `quartz.config.ts` and will be passed in the format required by [`satori`](https://github.com/vercel/satori). To use them in CSS, use the `.name` property (e.g. `fontFamily: fonts[1].name` to use the "body" font family). + +An example of a component using the header font could look like this: + +```tsx title="socialImage.tsx" +export const myImage: SocialImageOptions["imageStructure"] = (...) => { + return

Cool Header!

+} +``` + +> [!example]- Local fonts +> +> For cases where you use a local fonts under `static` folder, make sure to set the correct `@font-face` in `custom.scss` +> +> ```scss title="custom.scss" +> @font-face { +> font-family: "Newsreader"; +> font-style: normal; +> font-weight: normal; +> font-display: swap; +> src: url("/static/Newsreader.woff2") format("woff2"); +> } +> ``` +> +> Then in `quartz/util/og.tsx`, you can load the satori fonts like so: +> +> ```tsx title="quartz/util/og.tsx" +> const headerFont = joinSegments("static", "Newsreader.woff2") +> const bodyFont = joinSegments("static", "Newsreader.woff2") +> +> export async function getSatoriFont(cfg: GlobalConfiguration): Promise { +> const headerWeight: FontWeight = 700 +> const bodyWeight: FontWeight = 400 +> +> const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`) +> +> const [header, body] = await Promise.all( +> [headerFont, bodyFont].map((font) => +> fetch(`${url.toString()}/${font}`).then((res) => res.arrayBuffer()), +> ), +> ) +> +> return [ +> { name: cfg.theme.typography.header, data: header, weight: headerWeight, style: "normal" }, +> { name: cfg.theme.typography.body, data: body, weight: bodyWeight, style: "normal" }, +> ] +> } +> ``` +> +> This font then can be used with your custom structure + +### Local testing + +To test how the full preview of your page is going to look even before deploying, you can forward the port you're serving quartz on. In VSCode, this can easily be achieved following [this guide](https://code.visualstudio.com/docs/editor/port-forwarding) (make sure to set `Visibility` to `public` if testing on external tools like [opengraph.xyz](https://www.opengraph.xyz/)). + +If you have `generateSocialImages` enabled, you can check out all generated images under `public/static/social-images`. + +## Technical info + +Images will be generated as `.webp` files, which helps to keep images small (the average image takes ~`19kB`). They are also compressed further using [sharp](https://sharp.pixelplumbing.com/). + +When using images, the appropriate [Open Graph](https://ogp.me/) and [Twitter](https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started) meta tags will be set to ensure they work and look as expected. + +## Examples + +Besides the template for the default image generation (found under `quartz/util/og.tsx`), you can also add your own! To do this, you can either edit the source code of that file (not recommended) or create a new one (e.g. `customSocialImage.tsx`, source shown below). + +After adding that file, you can update `quartz.config.ts` to use your image generation template as follows: + +```ts +// Import component at start of file +import { customImage } from "./quartz/util/customSocialImage.tsx" + +// In main config +const config: QuartzConfig = { + ... + generateSocialImages: { + ... + imageStructure: customImage, // tells quartz to use your component when generating images + }, +} +``` + +The following example will generate images that look as follows: + +| Light | Dark | +| ------------------------------------------ | ----------------------------------------- | +| ![[custom-social-image-preview-light.png]] | ![[custom-social-image-preview-dark.png]] | + +This example (and the default template) use colors and fonts from your theme specified in the quartz config. Fonts get passed in as a prop, where `fonts[0]` will contain the header font and `fonts[1]` will contain the body font (more info in the [[#fonts]] section). + +```tsx +import { SatoriOptions } from "satori/wasm" +import { GlobalConfiguration } from "../cfg" +import { SocialImageOptions, UserOpts } from "./imageHelper" +import { QuartzPluginData } from "../plugins/vfile" + +export const customImage: SocialImageOptions["imageStructure"] = ( + cfg: GlobalConfiguration, + userOpts: UserOpts, + title: string, + description: string, + fonts: SatoriOptions["fonts"], + fileData: QuartzPluginData, +) => { + // How many characters are allowed before switching to smaller font + const fontBreakPoint = 22 + const useSmallerFont = title.length > fontBreakPoint + + const { colorScheme } = userOpts + return ( +
+
+

+ {title} +

+

+ {description} +

+
+
+
+ ) +} +``` + +> [!example]- Advanced example +> +> The following example includes a customized social image with a custom background and formatted date. +> +> ```typescript title="custom-og.tsx" +> export const og: SocialImageOptions["Component"] = ( +> cfg: GlobalConfiguration, +> fileData: QuartzPluginData, +> { colorScheme }: Options, +> title: string, +> description: string, +> fonts: SatoriOptions["fonts"], +> ) => { +> let created: string | undefined +> let reading: string | undefined +> if (fileData.dates) { +> created = formatDate(getDate(cfg, fileData)!, cfg.locale) +> } +> const { minutes, text: _timeTaken, words: _words } = readingTime(fileData.text!) +> reading = i18n(cfg.locale).components.contentMeta.readingTime({ +> minutes: Math.ceil(minutes), +> }) +> +> const Li = [created, reading] +> +> return ( +>
style={{ +> position: "relative", +> display: "flex", +> flexDirection: "row", +> alignItems: "flex-start", +> height: "100%", +> width: "100%", +> backgroundImage: `url("https://${cfg.baseUrl}/static/og-image.jpeg")`, +> backgroundSize: "100% 100%", +> }} +> > +>
style={{ +> position: "absolute", +> top: 0, +> left: 0, +> right: 0, +> bottom: 0, +> background: "radial-gradient(circle at center, transparent, rgba(0, 0, 0, 0.4) 70%)", +> }} +> /> +>
style={{ +> display: "flex", +> height: "100%", +> width: "100%", +> flexDirection: "column", +> justifyContent: "flex-start", +> alignItems: "flex-start", +> gap: "1.5rem", +> paddingTop: "4rem", +> paddingBottom: "4rem", +> marginLeft: "4rem", +> }} +> > +> src={`"https://${cfg.baseUrl}/static/icon.jpeg"`} +> style={{ +> position: "relative", +> backgroundClip: "border-box", +> borderRadius: "6rem", +> }} +> width={80} +> /> +>
style={{ +> display: "flex", +> flexDirection: "column", +> textAlign: "left", +> fontFamily: fonts[0].name, +> }} +> > +>

style={{ +> color: cfg.theme.colors[colorScheme].light, +> fontSize: "3rem", +> fontWeight: 700, +> marginRight: "4rem", +> fontFamily: fonts[0].name, +> }} +> > +> {title} +>

+>
    style={{ +> color: cfg.theme.colors[colorScheme].gray, +> gap: "1rem", +> fontSize: "1.5rem", +> fontFamily: fonts[1].name, +> }} +> > +> {Li.map((item, index) => { +> if (item) { +> return
  • {item}
  • +> } +> })} +>
+>
+>

style={{ +> color: cfg.theme.colors[colorScheme].light, +> fontSize: "1.5rem", +> overflow: "hidden", +> marginRight: "8rem", +> textOverflow: "ellipsis", +> display: "-webkit-box", +> WebkitLineClamp: 7, +> WebkitBoxOrient: "vertical", +> lineClamp: 7, +> fontFamily: fonts[1].name, +> }} +> > +> {description} +>

+>
+>
+> ) +> } +> ``` diff --git a/docs/hosting.md b/docs/hosting.md index eaeea19b2..8b945a24b 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -247,6 +247,28 @@ server { } ``` +### Using Apache + +Here's an example of how to do this with Apache: + +```apache title=".htaccess" +RewriteEngine On + +ErrorDocument 404 /404.html + +# Rewrite rule for .html extension removal (with directory check) +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI}.html -f +RewriteRule ^(.*)$ $1.html [L] + +# Handle directory requests explicitly +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^(.*)/$ $1/index.html [L] +``` + +Don't forget to activate brotli / gzip compression. + ### Using Caddy Here's and example of how to do this with Caddy: diff --git a/docs/images/custom-social-image-preview-dark.png b/docs/images/custom-social-image-preview-dark.png new file mode 100644 index 000000000..60c4e85c0 Binary files /dev/null and b/docs/images/custom-social-image-preview-dark.png differ diff --git a/docs/images/custom-social-image-preview-light.png b/docs/images/custom-social-image-preview-light.png new file mode 100644 index 000000000..046a40708 Binary files /dev/null and b/docs/images/custom-social-image-preview-light.png differ diff --git a/docs/images/social-image-preview-dark.png b/docs/images/social-image-preview-dark.png new file mode 100644 index 000000000..c12545166 Binary files /dev/null and b/docs/images/social-image-preview-dark.png differ diff --git a/docs/images/social-image-preview-light.png b/docs/images/social-image-preview-light.png new file mode 100644 index 000000000..ca0bdbc75 Binary files /dev/null and b/docs/images/social-image-preview-light.png differ diff --git a/docs/plugins/Latex.md b/docs/plugins/Latex.md index 236cbeca4..9ef37ff5d 100644 --- a/docs/plugins/Latex.md +++ b/docs/plugins/Latex.md @@ -11,9 +11,13 @@ This plugin adds LaTeX support to Quartz. See [[features/Latex|Latex]] for more This plugin accepts the following configuration options: -- `renderEngine`: the engine to use to render LaTeX equations. Can be `"katex"` for [KaTeX](https://katex.org/) or `"mathjax"` for [MathJax](https://www.mathjax.org/) [SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html). Defaults to KaTeX. +- `renderEngine`: the engine to use to render LaTeX equations. Can be `"katex"` for [KaTeX](https://katex.org/), `"mathjax"` for [MathJax](https://www.mathjax.org/) [SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html), or `"typst"` for [Typst](https://typst.app/) (a new way to compose LaTeX equation). Defaults to KaTeX. - `customMacros`: custom macros for all LaTeX blocks. It takes the form of a key-value pair where the key is a new command name and the value is the expansion of the macro. For example: `{"\\R": "\\mathbb{R}"}` +> [!note] Typst support +> +> Currently, typst doesn't support inline-math + ## API - Category: Transformer diff --git a/docs/showcase.md b/docs/showcase.md index 0cdf39dae..67bb755ff 100644 --- a/docs/showcase.md +++ b/docs/showcase.md @@ -9,6 +9,7 @@ Want to see what Quartz can do? Here are some cool community gardens: - [Socratica Toolbox](https://toolbox.socratica.info/) - [Morrowind Modding Wiki](https://morrowind-modding.github.io/) - [Aaron Pham's Garden](https://aarnphm.xyz/) +- [The Pond](https://turntrout.com/welcome) - [Pelayo Arbues' Notes](https://pelayoarbues.com/) - [Stanford CME 302 Numerical Linear Algebra](https://ericdarve.github.io/NLA/) - [A Pattern Language - Christopher Alexander (Architecture)](https://patternlanguage.cc/) diff --git a/package-lock.json b/package-lock.json index a974eb405..1933fa5b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,9 @@ "version": "4.4.0", "license": "MIT", "dependencies": { - "@clack/prompts": "^0.7.0", + "@clack/prompts": "^0.8.1", "@floating-ui/dom": "^1.6.12", + "@myriaddreamin/rehype-typst": "^0.5.0-rc7", "@napi-rs/simple-git": "0.1.19", "@tweenjs/tween.js": "^25.0.0", "async-mutex": "^0.5.0", @@ -32,6 +33,7 @@ "mdast-util-find-and-replace": "^3.0.1", "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", + "mermaid": "^11.4.0", "micromorph": "^0.4.5", "pixi.js": "^8.5.2", "preact": "^10.24.3", @@ -40,7 +42,7 @@ "pretty-time": "^1.1.0", "reading-time": "^1.5.0", "rehype-autolink-headings": "^7.1.0", - "rehype-citation": "^2.2.1", + "rehype-citation": "^2.2.2", "rehype-katex": "^7.0.1", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.14.0", @@ -56,8 +58,10 @@ "remark-smartypants": "^3.0.2", "rfdc": "^1.4.1", "rimraf": "^6.0.1", + "satori": "^0.11.3", "serve-handler": "^6.1.6", - "shiki": "^1.22.2", + "sharp": "^0.33.5", + "shiki": "^1.23.1", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", @@ -76,7 +80,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.8.7", + "@types/node": "^22.9.0", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.13", @@ -91,6 +95,28 @@ "npm": ">=9.3.1" } }, + "node_modules/@antfu/install-pkg": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^0.2.0", + "tinyexec": "^0.3.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@asamuzakjp/dom-selector": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz", @@ -101,12 +127,57 @@ "is-potential-custom-element-name": "^1.0.1" } }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", + "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==", + "license": "MIT" + }, "node_modules/@bufbuild/protobuf": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.0.tgz", "integrity": "sha512-+imAQkHf7U/Rwvu0wk1XWgsP3WnpCWmK7B48f0XqSNzgk64+grljTKC7pnO/xBiEMUziF7vKRfbBnOQhg126qQ==", "peer": true }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "license": "Apache-2.0" + }, "node_modules/@citation-js/core": { "version": "0.7.14", "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.14.tgz", @@ -184,23 +255,23 @@ } }, "node_modules/@clack/core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.3.tgz", - "integrity": "sha512-5ZGyb75BUBjlll6eOa1m/IZBxwk91dooBWhPSL67sWcLS0zt9SnswRL0l26TVdBhb0wnWORRxUn//uH6n4z7+A==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz", + "integrity": "sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==", "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "node_modules/@clack/prompts": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.7.0.tgz", - "integrity": "sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.8.1.tgz", + "integrity": "sha512-I263nEUNbX4lPTX93trl1fkIvGrGlz6nUYkqOddF0ZmjqcxUgUlXmpUIUqfapirRKJrFddvwF+qdZgg8cSqF7g==", "bundleDependencies": [ "is-unicode-supported" ], "dependencies": { - "@clack/core": "^0.3.3", + "@clack/core": "0.3.4", "is-unicode-supported": "*", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" @@ -217,6 +288,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.24.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", @@ -600,6 +681,388 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.33.tgz", + "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^0.4.0", + "@antfu/utils": "^0.7.10", + "@iconify/types": "^2.0.0", + "debug": "^4.3.6", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.0", + "mlly": "^1.7.1" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -616,6 +1079,229 @@ "node": ">=12" } }, + "node_modules/@mermaid-js/parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", + "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", + "license": "MIT", + "dependencies": { + "langium": "3.0.0" + } + }, + "node_modules/@myriaddreamin/rehype-typst": { + "version": "0.5.0-rc7", + "resolved": "https://registry.npmjs.org/@myriaddreamin/rehype-typst/-/rehype-typst-0.5.0-rc7.tgz", + "integrity": "sha512-oIUmJzV8c+PZoV4TZwSupN9e06EaC2i0DpjU6NPe6y0HE7MoPOd35s6i+RjdSNPDguqBdP2MO4VaqnGahQW/ig==", + "license": "MIT", + "dependencies": { + "@myriaddreamin/typst-ts-node-compiler": "^0.5.0-rc7", + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "https-proxy-agent": "^7.0.2", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler/-/typst-ts-node-compiler-0.5.0-rc8.tgz", + "integrity": "sha512-RpMkKYyH7DDJwfX4hMhCkCbby5+rU7UMqRbCe6jmkvrW+FhW5YDxATYnRVEQLgRjbLwGDV5bECLr2/9no+Tn7A==", + "license": "Apache-2.0", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@myriaddreamin/typst-ts-node-compiler-android-arm-eabi": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-android-arm64": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-darwin-arm64": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-darwin-x64": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-linux-arm-gnueabihf": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-linux-arm64-gnu": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-linux-arm64-musl": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-linux-x64-gnu": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-linux-x64-musl": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-win32-arm64-msvc": "0.5.0-rc8", + "@myriaddreamin/typst-ts-node-compiler-win32-x64-msvc": "0.5.0-rc8" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-android-arm-eabi": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-android-arm-eabi/-/typst-ts-node-compiler-android-arm-eabi-0.5.0-rc8.tgz", + "integrity": "sha512-gSd1Nw4FNGixQTRo4isntK2Utupu4yfKRMTgmB6aLn57GVf6Z6NDA4YLw0lQ8dNB4OYceX1wMXmjnoLZGiTk6Q==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-android-arm64": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-android-arm64/-/typst-ts-node-compiler-android-arm64-0.5.0-rc8.tgz", + "integrity": "sha512-1eSqCcLASxbdcicxFtYoXrBz4Rm7uhhWu/0DQ8Qo7bvNkzHuRtc4KkyuCZ6NCb/WzWuR4He20ySJZJRZurpgOQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-darwin-arm64": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-darwin-arm64/-/typst-ts-node-compiler-darwin-arm64-0.5.0-rc8.tgz", + "integrity": "sha512-KKty+9lpfzogptuQs78JaFLijucrIdUxnYrCqWR2wHTgc0rnQaqHyec0HQ0oApNDc6u59xURebglQ/nHAVa+WQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-darwin-x64": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-darwin-x64/-/typst-ts-node-compiler-darwin-x64-0.5.0-rc8.tgz", + "integrity": "sha512-e1P7GkyBV34h9eTDceZDC3qC0stDSN30R1gbZyniHOWu+qIKp0+RgQOLbkMj1Bk+vsOYGtb3zlqRJGEOCImz8w==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-linux-arm-gnueabihf": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-linux-arm-gnueabihf/-/typst-ts-node-compiler-linux-arm-gnueabihf-0.5.0-rc8.tgz", + "integrity": "sha512-HX19C6kWO8aeg+Ki4pQm2TTmYYLZEW653QwZEoCluAlX7O5HoGxCbsFLnE7v3+ag1dwBcoI2oH5czuKLI7GRvA==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-linux-arm64-gnu": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-linux-arm64-gnu/-/typst-ts-node-compiler-linux-arm64-gnu-0.5.0-rc8.tgz", + "integrity": "sha512-ElCka7rGGnB5nmY/Ei6fhS8JWNFRJDTagW1NM2feGvEazpMxDOQDWPg/bUXnUp7RS68L67gyXJSNFlHNWJM6/w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-linux-arm64-musl": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-linux-arm64-musl/-/typst-ts-node-compiler-linux-arm64-musl-0.5.0-rc8.tgz", + "integrity": "sha512-RbaI/i0rVzu2fyCcUPj89Zt/kmpHqJvxS/VRtbXR6xjXBUBisheRLvmWJrDdMMLf2mS0cwRPxQHGKCOSmB6U5A==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-linux-x64-gnu": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-linux-x64-gnu/-/typst-ts-node-compiler-linux-x64-gnu-0.5.0-rc8.tgz", + "integrity": "sha512-Mi2TruUZ97ZP920fMdvebRVYfMBxQZXnt14f0CqCy4tmg9sI7/ymBaGhT0vIo7A01cWr1DeTtoE4qUrOzXcDyA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-linux-x64-musl": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-linux-x64-musl/-/typst-ts-node-compiler-linux-x64-musl-0.5.0-rc8.tgz", + "integrity": "sha512-I/GTNDl3Pb9/TyBRPtJqXuykkZ3d07PrSxnUKo1CelpJCk6S3h1BY0vl/3OwpENWGzy0FJehzkF0F8//3XzCgg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-win32-arm64-msvc": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-win32-arm64-msvc/-/typst-ts-node-compiler-win32-arm64-msvc-0.5.0-rc8.tgz", + "integrity": "sha512-G0c+IqUDPdUDnTKyFl1ajf47oGgV1asc3aYtl23U71RK4R0ILnyycgGjE/5E8hD0CLodq5xMV+zW+17TZ4VX0A==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@myriaddreamin/typst-ts-node-compiler-win32-x64-msvc": { + "version": "0.5.0-rc8", + "resolved": "https://registry.npmjs.org/@myriaddreamin/typst-ts-node-compiler-win32-x64-msvc/-/typst-ts-node-compiler-win32-x64-msvc-0.5.0-rc8.tgz", + "integrity": "sha512-qlZXCfLDUm1btpESBa4onU2ky7ALwdj369dAmgslNKyOl5JN8RYcyf9Hm7fp8WeVlxVjH2/2zJgPysAHf+SSRw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@napi-rs/simple-git": { "version": "0.1.19", "resolved": "https://registry.npmjs.org/@napi-rs/simple-git/-/simple-git-0.1.19.tgz", @@ -898,41 +1584,41 @@ } }, "node_modules/@shikijs/core": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.2.tgz", - "integrity": "sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==", + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.23.1.tgz", + "integrity": "sha512-NuOVgwcHgVC6jBVH5V7iblziw6iQbWWHrj5IlZI3Fqu2yx9awH7OIQkXIcsHsUmY19ckwSgUMgrqExEyP5A0TA==", "dependencies": { - "@shikijs/engine-javascript": "1.22.2", - "@shikijs/engine-oniguruma": "1.22.2", - "@shikijs/types": "1.22.2", + "@shikijs/engine-javascript": "1.23.1", + "@shikijs/engine-oniguruma": "1.23.1", + "@shikijs/types": "1.23.1", "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.3" } }, "node_modules/@shikijs/engine-javascript": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz", - "integrity": "sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==", + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.23.1.tgz", + "integrity": "sha512-i/LdEwT5k3FVu07SiApRFwRcSJs5QM9+tod5vYCPig1Ywi8GR30zcujbxGQFJHwYD7A5BUqagi8o5KS+LEVgBg==", "dependencies": { - "@shikijs/types": "1.22.2", + "@shikijs/types": "1.23.1", "@shikijs/vscode-textmate": "^9.3.0", - "oniguruma-to-js": "0.4.3" + "oniguruma-to-es": "0.4.1" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz", - "integrity": "sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==", + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.23.1.tgz", + "integrity": "sha512-KQ+lgeJJ5m2ISbUZudLR1qHeH3MnSs2mjFg7bnencgs5jDVPeJ2NVDJ3N5ZHbcTsOIh0qIueyAJnwg7lg7kwXQ==", "dependencies": { - "@shikijs/types": "1.22.2", + "@shikijs/types": "1.23.1", "@shikijs/vscode-textmate": "^9.3.0" } }, "node_modules/@shikijs/types": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.2.tgz", - "integrity": "sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==", + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.23.1.tgz", + "integrity": "sha512-98A5hGyEhzzAgQh2dAeHKrWW4HfCMeoFER2z16p5eJ+vmPeF6lZ/elEne6/UCU551F/WqkopqRsr1l2Yu6+A0g==", "dependencies": { "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4" @@ -943,6 +1629,22 @@ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==" }, + "node_modules/@shuding/opentype.js": { + "version": "1.4.0-beta.0", + "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", + "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==", + "license": "MIT", + "dependencies": { + "fflate": "^0.7.3", + "string.prototype.codepointat": "^0.2.1" + }, + "bin": { + "ot": "bin/ot" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", @@ -979,7 +1681,6 @@ "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "dev": true, "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", @@ -1016,14 +1717,12 @@ "node_modules/@types/d3-array": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.5.tgz", - "integrity": "sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==", - "dev": true + "integrity": "sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==" }, "node_modules/@types/d3-axis": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.2.tgz", "integrity": "sha512-uGC7DBh0TZrU/LY43Fd8Qr+2ja1FKmH07q2FoZFHo1eYl8aj87GhfVoY1saJVJiq24rp1+wpI6BvQJMKgQm8oA==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -1032,7 +1731,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.2.tgz", "integrity": "sha512-2TEm8KzUG3N7z0TrSKPmbxByBx54M+S9lHoP2J55QuLU0VSQ9mE96EJSAOVNEqd1bbynMjeTS9VHmz8/bSw8rA==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -1040,20 +1738,17 @@ "node_modules/@types/d3-chord": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.2.tgz", - "integrity": "sha512-abT/iLHD3sGZwqMTX1TYCMEulr+wBd0SzyOQnjYNLp7sngdOHYtNkMRI5v3w5thoN+BWtlHVDx2Osvq6fxhZWw==", - "dev": true + "integrity": "sha512-abT/iLHD3sGZwqMTX1TYCMEulr+wBd0SzyOQnjYNLp7sngdOHYtNkMRI5v3w5thoN+BWtlHVDx2Osvq6fxhZWw==" }, "node_modules/@types/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==", - "dev": true + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" }, "node_modules/@types/d3-contour": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.2.tgz", "integrity": "sha512-k6/bGDoAGJZnZWaKzeB+9glgXCYGvh6YlluxzBREiVo8f/X2vpTEdgPy9DN7Z2i42PZOZ4JDhVdlTSTSkLDPlQ==", - "dev": true, "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" @@ -1062,20 +1757,17 @@ "node_modules/@types/d3-delaunay": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.1.tgz", - "integrity": "sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ==", - "dev": true + "integrity": "sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ==" }, "node_modules/@types/d3-dispatch": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.2.tgz", - "integrity": "sha512-rxN6sHUXEZYCKV05MEh4z4WpPSqIw+aP7n9ZN6WYAAvZoEAghEK1WeVZMZcHRBwyaKflU43PCUAJNjFxCzPDjg==", - "dev": true + "integrity": "sha512-rxN6sHUXEZYCKV05MEh4z4WpPSqIw+aP7n9ZN6WYAAvZoEAghEK1WeVZMZcHRBwyaKflU43PCUAJNjFxCzPDjg==" }, "node_modules/@types/d3-drag": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.2.tgz", "integrity": "sha512-qmODKEDvyKWVHcWWCOVcuVcOwikLVsyc4q4EBJMREsoQnR2Qoc2cZQUyFUPgO9q4S3qdSqJKBsuefv+h0Qy+tw==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -1083,20 +1775,17 @@ "node_modules/@types/d3-dsv": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-76pBHCMTvPLt44wFOieouXcGXWOF0AJCceUvaFkxSZEu4VDUdv93JfpMa6VGNFs01FHfuP4a5Ou68eRG1KBfTw==", - "dev": true + "integrity": "sha512-76pBHCMTvPLt44wFOieouXcGXWOF0AJCceUvaFkxSZEu4VDUdv93JfpMa6VGNFs01FHfuP4a5Ou68eRG1KBfTw==" }, "node_modules/@types/d3-ease": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", - "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==", - "dev": true + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" }, "node_modules/@types/d3-fetch": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.2.tgz", "integrity": "sha512-gllwYWozWfbep16N9fByNBDTkJW/SyhH6SGRlXloR7WdtAaBui4plTP+gbUgiEot7vGw/ZZop1yDZlgXXSuzjA==", - "dev": true, "dependencies": { "@types/d3-dsv": "*" } @@ -1104,20 +1793,17 @@ "node_modules/@types/d3-force": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.4.tgz", - "integrity": "sha512-q7xbVLrWcXvSBBEoadowIUJ7sRpS1yvgMWnzHJggFy5cUZBq2HZL5k/pBSm0GdYWS1vs5/EDwMjSKF55PDY4Aw==", - "dev": true + "integrity": "sha512-q7xbVLrWcXvSBBEoadowIUJ7sRpS1yvgMWnzHJggFy5cUZBq2HZL5k/pBSm0GdYWS1vs5/EDwMjSKF55PDY4Aw==" }, "node_modules/@types/d3-format": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", - "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", - "dev": true + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==" }, "node_modules/@types/d3-geo": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.3.tgz", "integrity": "sha512-bK9uZJS3vuDCNeeXQ4z3u0E7OeJZXjUgzFdSOtNtMCJCLvDtWDwfpRVWlyt3y8EvRzI0ccOu9xlMVirawolSCw==", - "dev": true, "dependencies": { "@types/geojson": "*" } @@ -1125,14 +1811,12 @@ "node_modules/@types/d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-9hjRTVoZjRFR6xo8igAJyNXQyPX6Aq++Nhb5ebrUF414dv4jr2MitM2fWiOY475wa3Za7TOS2Gh9fmqEhLTt0A==", - "dev": true + "integrity": "sha512-9hjRTVoZjRFR6xo8igAJyNXQyPX6Aq++Nhb5ebrUF414dv4jr2MitM2fWiOY475wa3Za7TOS2Gh9fmqEhLTt0A==" }, "node_modules/@types/d3-interpolate": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", - "dev": true, "dependencies": { "@types/d3-color": "*" } @@ -1140,32 +1824,27 @@ "node_modules/@types/d3-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", - "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==", - "dev": true + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" }, "node_modules/@types/d3-polygon": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz", - "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==", - "dev": true + "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==" }, "node_modules/@types/d3-quadtree": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.2.tgz", - "integrity": "sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==", - "dev": true + "integrity": "sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==" }, "node_modules/@types/d3-random": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==", - "dev": true + "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==" }, "node_modules/@types/d3-scale": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.3.tgz", "integrity": "sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==", - "dev": true, "dependencies": { "@types/d3-time": "*" } @@ -1173,20 +1852,17 @@ "node_modules/@types/d3-scale-chromatic": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==", - "dev": true + "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==" }, "node_modules/@types/d3-selection": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.5.tgz", - "integrity": "sha512-xCB0z3Hi8eFIqyja3vW8iV01+OHGYR2di/+e+AiOcXIOrY82lcvWW8Ke1DYE/EUVMsBl4Db9RppSBS3X1U6J0w==", - "dev": true + "integrity": "sha512-xCB0z3Hi8eFIqyja3vW8iV01+OHGYR2di/+e+AiOcXIOrY82lcvWW8Ke1DYE/EUVMsBl4Db9RppSBS3X1U6J0w==" }, "node_modules/@types/d3-shape": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.1.tgz", "integrity": "sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==", - "dev": true, "dependencies": { "@types/d3-path": "*" } @@ -1194,26 +1870,22 @@ "node_modules/@types/d3-time": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", - "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", - "dev": true + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" }, "node_modules/@types/d3-time-format": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.0.tgz", - "integrity": "sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==", - "dev": true + "integrity": "sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==" }, "node_modules/@types/d3-timer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", - "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==", - "dev": true + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" }, "node_modules/@types/d3-transition": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.3.tgz", "integrity": "sha512-/S90Od8Id1wgQNvIA8iFv9jRhCiZcGhPd2qX0bKF/PS+y0W5CrXKgIiELd2CvG1mlQrWK/qlYh3VxicqG1ZvgA==", - "dev": true, "dependencies": { "@types/d3-selection": "*" } @@ -1222,7 +1894,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.3.tgz", "integrity": "sha512-OWk1yYIIWcZ07+igN6BeoG6rqhnJ/pYe+R1qWFM2DtW49zsoSjgb9G5xB0ZXA8hh2jAzey1XuRmMSoXdKw8MDA==", - "dev": true, "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" @@ -1236,6 +1907,15 @@ "@types/ms": "*" } }, + "node_modules/@types/dompurify": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", + "license": "MIT", + "dependencies": { + "@types/trusted-types": "*" + } + }, "node_modules/@types/earcut": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz", @@ -1258,8 +1938,7 @@ "node_modules/@types/geojson": { "version": "7946.0.10", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", - "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", - "dev": true + "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==" }, "node_modules/@types/hast": { "version": "3.0.4", @@ -1307,9 +1986,9 @@ } }, "node_modules/@types/node": { - "version": "22.8.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.7.tgz", - "integrity": "sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "dev": true, "dependencies": { "undici-types": "~6.19.8" @@ -1330,6 +2009,12 @@ "source-map": "^0.6.0" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -1379,6 +2064,18 @@ "node": ">=10.0.0" } }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", @@ -1544,6 +2241,15 @@ "node": ">= 0.8" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -1600,6 +2306,32 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", @@ -1693,6 +2425,19 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1709,6 +2454,16 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/colorjs.io": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", @@ -1748,6 +2503,12 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, "node_modules/content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -1756,6 +2517,15 @@ "node": ">= 0.6" } }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cross-fetch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", @@ -1777,6 +2547,46 @@ "node": ">= 8" } }, + "node_modules/css-background-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz", + "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==", + "license": "MIT" + }, + "node_modules/css-box-shadow": { + "version": "1.0.0-3", + "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", + "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==", + "license": "MIT" + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-gradient-parser": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.16.tgz", + "integrity": "sha512-3O5QdqgFRUbXvK1x5INf1YkBz1UKSWqrd63vWsum8MNHDBYD5urm3QtxZbKU259OrEXNM26lP/MPY3d1IGkBgA==", + "engines": { + "node": ">=16" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -1800,6 +2610,54 @@ "node": ">=18" } }, + "node_modules/cytoscape": { + "version": "3.30.3", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.3.tgz", + "integrity": "sha512-HncJ9gGJbVtw7YXtIs3+6YAFSSiKsom0amWc33Z7QbylbY2JGMrA0yz4EwrdTScZxnwclXeEZHzO5pxoy0ZE4g==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, "node_modules/d3": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", @@ -2061,6 +2919,46 @@ "node": ">=12" } }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, "node_modules/d3-scale": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", @@ -2170,6 +3068,16 @@ "node": ">=12" } }, + "node_modules/dagre-d3-es": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, "node_modules/data-urls": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", @@ -2182,12 +3090,19 @@ "node": ">=18" } }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2262,6 +3177,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/dompurify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", + "license": "(MPL-2.0 OR Apache-2.0)" + }, "node_modules/earcut": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", @@ -2278,6 +3199,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==" + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -2364,6 +3290,12 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -2507,6 +3439,12 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2692,6 +3630,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3038,6 +3982,18 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hex-rgb": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz", + "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -3171,6 +4127,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -3338,13 +4300,14 @@ } }, "node_modules/katex": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.8.tgz", - "integrity": "sha512-ftuDnJbcbOckGY11OO+zg3OofESlbR5DRl2cmN8HeWeeFIV7wTXvAOx8kEjZjobhA+9wh2fbKeO6cdcA9Mnovg==", + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" ], + "license": "MIT", "dependencies": { "commander": "^8.3.0" }, @@ -3360,6 +4323,11 @@ "node": ">= 12" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -3368,6 +4336,34 @@ "node": ">=0.10.0" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "license": "MIT" + }, + "node_modules/langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "license": "MIT", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/lightningcss": { "version": "1.28.1", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.28.1.tgz", @@ -3585,6 +4581,47 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/linebreak": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz", + "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==", + "license": "MIT", + "dependencies": { + "base64-js": "0.0.8", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/linebreak/node_modules/base64-js": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "license": "MIT", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -3611,6 +4648,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", + "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mathjax-full": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz", @@ -3637,36 +4686,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-find-and-replace/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-find-and-replace/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/mdast-util-from-markdown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", @@ -3951,23 +4970,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-phrasing/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/mdast-util-phrasing/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/mdast-util-to-hast": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", @@ -4037,6 +5039,35 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.0.tgz", + "integrity": "sha512-mxCfEYvADJqOiHfGpJXLs4/fAjHz448rH0pfY5fAoxiz70rQiDSzUUy4dNET2T08i46IVpjohPd6WWbzmRHiPA==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.0.1", + "@iconify/utils": "^2.1.32", + "@mermaid-js/parser": "^0.3.0", + "@types/d3": "^7.4.3", + "@types/dompurify": "^3.0.5", + "cytoscape": "^3.29.2", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.10", + "dompurify": "^3.0.11 <3.1.7", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^13.0.2", + "roughjs": "^4.6.6", + "stylis": "^4.3.1", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.1" + } + }, "node_modules/mhchemparser": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz", @@ -4673,15 +5704,28 @@ "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz", "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==" }, + "node_modules/mlly": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", + "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" + } + }, "node_modules/moo": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==" }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/nlcst-to-string": { "version": "4.0.0", @@ -4733,15 +5777,14 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/oniguruma-to-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", - "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "node_modules/oniguruma-to-es": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.4.1.tgz", + "integrity": "sha512-rNcEohFz095QKGRovP/yqPIKc+nP+Sjs4YTHMv33nMePGKrq/r2eu9Yh4646M5XluGJsUnmwoXuiXE69KDs+fQ==", "dependencies": { - "regex": "^4.3.2" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "emoji-regex-xs": "^1.0.0", + "regex": "^5.0.0", + "regex-recursion": "^4.2.1" } }, "node_modules/package-json-from-dist": { @@ -4749,6 +5792,28 @@ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" }, + "node_modules/package-manager-detector": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.2.tgz", + "integrity": "sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==", + "license": "MIT" + }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, + "node_modules/parse-css-color": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz", + "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.1.4", + "hex-rgb": "^4.1.0" + } + }, "node_modules/parse-entities": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", @@ -4812,6 +5877,12 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", @@ -4861,10 +5932,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -4893,6 +5970,39 @@ "parse-svg-path": "^0.1.2" } }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" + } + }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, "node_modules/preact": { "version": "10.24.3", "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", @@ -5008,9 +6118,25 @@ "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" }, "node_modules/regex": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz", - "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/regex/-/regex-5.0.2.tgz", + "integrity": "sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ==", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.2.1.tgz", + "integrity": "sha512-QHNZyZAeKdndD1G3bKAbBEKOSSK4KOHQrAJ01N1LJeb0SoH4DJIeFhp0uUpETgONifS4+P3sOgoA1dhzgrQvhA==", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==" }, "node_modules/rehype-autolink-headings": { "version": "7.1.0", @@ -5030,9 +6156,9 @@ } }, "node_modules/rehype-citation": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/rehype-citation/-/rehype-citation-2.2.1.tgz", - "integrity": "sha512-8Ybq4W0/FeuXSwTrwpDbsZ9v0X0ZeKxDKyA/9s1EI2GMZLgaowPEkFOyXhOjv7Ud2ntK86AWkove38G4U0dRuQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/rehype-citation/-/rehype-citation-2.2.2.tgz", + "integrity": "sha512-a9+njSn4yJ3/bePz+T8AkCLXhSb3fK+HKlG9xEcLJraN3W92jGV91a10XEvSy6gJ5BvRdtDtu3aEd1uqvNDHRQ==", "dependencies": { "@citation-js/core": "^0.7.14", "@citation-js/date": "^0.5.1", @@ -5068,36 +6194,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-katex/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/rehype-katex/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-katex/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/rehype-mathjax": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-6.0.0.tgz", @@ -5117,36 +6213,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-mathjax/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/rehype-mathjax/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-mathjax/node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/rehype-parse": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.0.tgz", @@ -5485,6 +6551,18 @@ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rrweb-cssom": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", @@ -5915,6 +6993,33 @@ "node": ">=14.0.0" } }, + "node_modules/satori": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/satori/-/satori-0.11.3.tgz", + "integrity": "sha512-Wg7sls0iYAEETzi9YYcY16QVIqXjZT06XjkwondC5CGhw1mhmgKBCub8cCmkxdl/naXXQD+m29CFgn8pwtYCnA==", + "dependencies": { + "@shuding/opentype.js": "1.4.0-beta.0", + "css-background-parser": "^0.1.0", + "css-box-shadow": "1.0.0-3", + "css-gradient-parser": "^0.0.16", + "css-to-react-native": "^3.0.0", + "emoji-regex": "^10.2.1", + "escape-html": "^1.0.3", + "linebreak": "^1.1.0", + "parse-css-color": "^0.2.1", + "postcss-value-parser": "^4.2.0", + "yoga-wasm-web": "^0.3.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/satori/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -5938,6 +7043,18 @@ "node": ">=4" } }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serve-handler": { "version": "6.1.6", "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", @@ -5972,6 +7089,54 @@ "node": "*" } }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/sharp/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5992,14 +7157,14 @@ } }, "node_modules/shiki": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.2.tgz", - "integrity": "sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==", + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.23.1.tgz", + "integrity": "sha512-8kxV9TH4pXgdKGxNOkrSMydn1Xf6It8lsle0fiqxf7a1149K1WGtdOu3Zb91T5r1JpvRPxqxU3C2XdZZXQnrig==", "dependencies": { - "@shikijs/core": "1.22.2", - "@shikijs/engine-javascript": "1.22.2", - "@shikijs/engine-oniguruma": "1.22.2", - "@shikijs/types": "1.22.2", + "@shikijs/core": "1.23.1", + "@shikijs/engine-javascript": "1.23.1", + "@shikijs/engine-oniguruma": "1.23.1", + "@shikijs/types": "1.23.1", "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4" } @@ -6015,6 +7180,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -6145,6 +7319,12 @@ "node": ">=8" } }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", + "license": "MIT" + }, "node_modules/stringify-entities": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", @@ -6208,6 +7388,12 @@ "inline-style-parser": "0.2.2" } }, + "node_modules/stylis": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -6251,6 +7437,18 @@ "node": ">=14" } }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6338,6 +7536,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -6782,12 +7989,28 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "license": "MIT" + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "license": "MIT", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -6840,10 +8063,11 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" }, - "node_modules/unist-util-find-after/node_modules/unist-util-is": { + "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -6852,6 +8076,12 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-is/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/unist-util-modify-children": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", @@ -6936,27 +8166,11 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" }, - "node_modules/unist-util-visit/node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/unist-util-visit/node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { + "node_modules/unist-util-visit-parents": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -6966,6 +8180,17 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit-parents/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/unist-util-visit/node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -6983,6 +8208,19 @@ "requires-port": "^1.0.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/varint": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", @@ -7050,6 +8288,55 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "license": "MIT" + }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", @@ -7325,6 +8612,12 @@ "node": ">=8" } }, + "node_modules/yoga-wasm-web": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz", + "integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==", + "license": "MIT" + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index fdd9f8737..11c1c91ea 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,9 @@ "quartz": "./quartz/bootstrap-cli.mjs" }, "dependencies": { - "@clack/prompts": "^0.7.0", + "@clack/prompts": "^0.8.1", "@floating-ui/dom": "^1.6.12", + "@myriaddreamin/rehype-typst": "^0.5.0-rc7", "@napi-rs/simple-git": "0.1.19", "@tweenjs/tween.js": "^25.0.0", "async-mutex": "^0.5.0", @@ -58,6 +59,7 @@ "mdast-util-find-and-replace": "^3.0.1", "mdast-util-to-hast": "^13.2.0", "mdast-util-to-string": "^4.0.0", + "mermaid": "^11.4.0", "micromorph": "^0.4.5", "pixi.js": "^8.5.2", "preact": "^10.24.3", @@ -66,7 +68,7 @@ "pretty-time": "^1.1.0", "reading-time": "^1.5.0", "rehype-autolink-headings": "^7.1.0", - "rehype-citation": "^2.2.1", + "rehype-citation": "^2.2.2", "rehype-katex": "^7.0.1", "rehype-mathjax": "^6.0.0", "rehype-pretty-code": "^0.14.0", @@ -82,8 +84,10 @@ "remark-smartypants": "^3.0.2", "rfdc": "^1.4.1", "rimraf": "^6.0.1", + "satori": "^0.11.3", "serve-handler": "^6.1.6", - "shiki": "^1.22.2", + "sharp": "^0.33.5", + "shiki": "^1.23.1", "source-map-support": "^0.5.21", "to-vfile": "^8.0.0", "toml": "^3.0.0", @@ -99,7 +103,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^22.8.7", + "@types/node": "^22.9.0", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.13", diff --git a/quartz.config.ts b/quartz.config.ts index e96ee4843..dc339d987 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -19,6 +19,7 @@ const config: QuartzConfig = { baseUrl: "quartz.jzhao.xyz", ignorePatterns: ["private", "templates", ".obsidian"], defaultDateType: "created", + generateSocialImages: false, theme: { fontOrigin: "googleFonts", cdnCaching: true, diff --git a/quartz/cfg.ts b/quartz/cfg.ts index 85527a093..135f58499 100644 --- a/quartz/cfg.ts +++ b/quartz/cfg.ts @@ -2,6 +2,7 @@ import { ValidDateType } from "./components/Date" import { QuartzComponent } from "./components/types" import { ValidLocale } from "./i18n" import { PluginTypes } from "./plugins/types" +import { SocialImageOptions } from "./util/og" import { Theme } from "./util/theme" export type Analytics = @@ -60,11 +61,15 @@ export interface GlobalConfiguration { * Quartz will avoid using this as much as possible and use relative URLs most of the time */ baseUrl?: string + /** + * Whether to generate social images (Open Graph and Twitter standard) for link previews + */ + generateSocialImages: boolean | Partial theme: Theme /** * Allow to translate the date in the language of your choice. * Also used for UI translation (default: en-US) - * Need to be formated following BCP 47: https://en.wikipedia.org/wiki/IETF_language_tag + * Need to be formatted following BCP 47: https://en.wikipedia.org/wiki/IETF_language_tag * The first part is the language (en) and the second part is the script/region (US) * Language Codes: https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes * Region Codes: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 diff --git a/quartz/cli/handlers.js b/quartz/cli/handlers.js index 55381523a..6b23d8010 100644 --- a/quartz/cli/handlers.js +++ b/quartz/cli/handlers.js @@ -15,6 +15,7 @@ import { WebSocketServer } from "ws" import { randomUUID } from "crypto" import { Mutex } from "async-mutex" import { CreateArgv } from "./args.js" +import { globby } from "globby" import { exitIfCancel, escapePath, @@ -290,8 +291,8 @@ export async function handleBuild(argv) { } if (cleanupBuild) { - await cleanupBuild() console.log(chalk.yellow("Detected a source code change, doing a hard rebuild...")) + await cleanupBuild() } const result = await ctx.rebuild().catch((err) => { @@ -355,6 +356,15 @@ export async function handleBuild(argv) { source: "**/*.*", headers: [{ key: "Content-Disposition", value: "inline" }], }, + { + source: "**/*.webp", + headers: [{ key: "Content-Type", value: "image/webp" }], + }, + // fixes bug where avif images are displayed as text instead of images (future proof) + { + source: "**/*.avif", + headers: [{ key: "Content-Type", value: "image/avif" }], + }, ], }) const status = res.statusCode @@ -423,13 +433,12 @@ export async function handleBuild(argv) { ), ) console.log("hint: exit with ctrl+c") + const paths = await globby(["**/*.ts", "**/*.tsx", "**/*.scss", "package.json"]) chokidar - .watch(["**/*.ts", "**/*.tsx", "**/*.scss", "package.json"], { - ignoreInitial: true, - }) - .on("all", async () => { - build(clientRefresh) - }) + .watch(paths, { ignoreInitial: true }) + .on("add", () => build(clientRefresh)) + .on("change", () => build(clientRefresh)) + .on("unlink", () => build(clientRefresh)) } else { await build(() => {}) ctx.dispose() diff --git a/quartz/components/Comments.tsx b/quartz/components/Comments.tsx index 44331cc90..5f29860c2 100644 --- a/quartz/components/Comments.tsx +++ b/quartz/components/Comments.tsx @@ -25,7 +25,14 @@ function boolToStringBool(b: boolean): string { } export default ((opts: Options) => { - const Comments: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => { + const Comments: QuartzComponent = ({ displayClass, fileData, cfg }: QuartzComponentProps) => { + // check if comments should be displayed according to frontmatter + const disableComment: boolean = + !fileData.frontmatter?.comments || fileData.frontmatter?.comments === "false" + if (disableComment) { + return <> + } + return (
{ - const Head: QuartzComponent = ({ cfg, fileData, externalResources }: QuartzComponentProps) => { + let fontsPromise: Promise + + let fullOptions: SocialImageOptions + const Head: QuartzComponent = ({ + cfg, + fileData, + externalResources, + ctx, + }: QuartzComponentProps) => { + // Initialize options if not set + if (!fullOptions) { + if (typeof cfg.generateSocialImages !== "boolean") { + fullOptions = { ...defaultOptions, ...cfg.generateSocialImages } + } else { + fullOptions = defaultOptions + } + } + + // Memoize google fonts + if (!fontsPromise && cfg.generateSocialImages) { + fontsPromise = getSatoriFont(cfg.theme.typography.header, cfg.theme.typography.body) + } + + const slug = fileData.filePath + // since "/" is not a valid character in file names, replace with "-" + const fileName = slug?.replaceAll("/", "-") + + // Get file description (priority: frontmatter > fileData > default) + const fdDescription = + fileData.description?.trim() ?? i18n(cfg.locale).propertyDefaults.description const titleSuffix = cfg.pageTitleSuffix ?? "" const title = (fileData.frontmatter?.title ?? i18n(cfg.locale).propertyDefaults.title) + titleSuffix - const description = - fileData.description?.trim() ?? i18n(cfg.locale).propertyDefaults.description + let description = "" + if (fdDescription) { + description = unescapeHTML(fdDescription) + } + + if (fileData.frontmatter?.socialDescription) { + description = fileData.frontmatter?.socialDescription as string + } else if (fileData.frontmatter?.description) { + description = fileData.frontmatter?.description + } + + const fileDir = joinSegments(ctx.argv.output, "static", "social-images") + if (cfg.generateSocialImages) { + // Generate folders for social images (if they dont exist yet) + if (!fs.existsSync(fileDir)) { + fs.mkdirSync(fileDir, { recursive: true }) + } + + if (fileName) { + // Generate social image (happens async) + generateSocialImage( + { + title, + description, + fileName, + fileDir, + fileExt: extension, + fontsPromise, + cfg, + fileData, + }, + fullOptions, + fileDir, + ) + } + } + const { css, js } = externalResources const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`) @@ -18,7 +122,37 @@ export default (() => { const baseDir = fileData.slug === "404" ? path : pathToRoot(fileData.slug!) const iconPath = joinSegments(baseDir, "static/icon.png") - const ogImagePath = `https://${cfg.baseUrl}/static/og-image.png` + + const ogImageDefaultPath = `https://${cfg.baseUrl}/static/og-image.png` + // "static/social-images/slug-filename.md.webp" + const ogImageGeneratedPath = `https://${cfg.baseUrl}/${fileDir.replace( + `${ctx.argv.output}/`, + "", + )}/${fileName}.${extension}` + + // Use default og image if filePath doesnt exist (for autogenerated paths with no .md file) + const useDefaultOgImage = fileName === undefined || !cfg.generateSocialImages + + // Path to og/social image (priority: frontmatter > generated image (if enabled) > default image) + let ogImagePath = useDefaultOgImage ? ogImageDefaultPath : ogImageGeneratedPath + + // TODO: could be improved to support external images in the future + // Aliases for image and cover handled in `frontmatter.ts` + const frontmatterImgUrl = fileData.frontmatter?.socialImage + + // Override with default og image if config option is set + if (fileData.slug === "index") { + ogImagePath = ogImageDefaultPath + } + + // Override with frontmatter url if existing + if (frontmatterImgUrl) { + ogImagePath = `https://${cfg.baseUrl}/static/${frontmatterImgUrl}` + } + + // Url of current page + const socialUrl = + fileData.slug === "404" ? url.toString() : joinSegments(url.toString(), fileData.slug!) return ( @@ -32,11 +166,35 @@ export default (() => { )} + {/* OG/Twitter meta tags */} + + + + + - {cfg.baseUrl && } - - + + + {/* Dont set width and height if unknown (when using custom frontmatter image) */} + {!frontmatterImgUrl && ( + <> + + + + + + )} + + {cfg.baseUrl && ( + <> + + + + + + + )} diff --git a/quartz/components/TagList.tsx b/quartz/components/TagList.tsx index ba48098bd..4a89fbd67 100644 --- a/quartz/components/TagList.tsx +++ b/quartz/components/TagList.tsx @@ -33,7 +33,6 @@ TagList.css = ` gap: 0.4rem; margin: 1rem 0; flex-wrap: wrap; - justify-self: end; } .section-li > .section > .tags { diff --git a/quartz/components/scripts/clipboard.inline.ts b/quartz/components/scripts/clipboard.inline.ts index 87182a154..e16c11299 100644 --- a/quartz/components/scripts/clipboard.inline.ts +++ b/quartz/components/scripts/clipboard.inline.ts @@ -8,7 +8,9 @@ document.addEventListener("nav", () => { for (let i = 0; i < els.length; i++) { const codeBlock = els[i].getElementsByTagName("code")[0] if (codeBlock) { - const source = codeBlock.innerText.replace(/\n\n/g, "\n") + const source = ( + codeBlock.dataset.clipboard ? JSON.parse(codeBlock.dataset.clipboard) : codeBlock.innerText + ).replace(/\n\n/g, "\n") const button = document.createElement("button") button.className = "clipboard-button" button.type = "button" diff --git a/quartz/components/scripts/mermaid.inline.ts b/quartz/components/scripts/mermaid.inline.ts new file mode 100644 index 000000000..77a3ebe75 --- /dev/null +++ b/quartz/components/scripts/mermaid.inline.ts @@ -0,0 +1,242 @@ +import { removeAllChildren } from "./util" +import mermaid from "mermaid" + +interface Position { + x: number + y: number +} + +class DiagramPanZoom { + private isDragging = false + private startPan: Position = { x: 0, y: 0 } + private currentPan: Position = { x: 0, y: 0 } + private scale = 1 + private readonly MIN_SCALE = 0.5 + private readonly MAX_SCALE = 3 + private readonly ZOOM_SENSITIVITY = 0.001 + + constructor( + private container: HTMLElement, + private content: HTMLElement, + ) { + this.setupEventListeners() + this.setupNavigationControls() + } + + private setupEventListeners() { + // Mouse drag events + this.container.addEventListener("mousedown", this.onMouseDown.bind(this)) + document.addEventListener("mousemove", this.onMouseMove.bind(this)) + document.addEventListener("mouseup", this.onMouseUp.bind(this)) + + // Wheel zoom events + this.container.addEventListener("wheel", this.onWheel.bind(this), { passive: false }) + + // Reset on window resize + window.addEventListener("resize", this.resetTransform.bind(this)) + } + + private setupNavigationControls() { + const controls = document.createElement("div") + controls.className = "mermaid-controls" + + // Zoom controls + const zoomIn = this.createButton("+", () => this.zoom(0.1)) + const zoomOut = this.createButton("-", () => this.zoom(-0.1)) + const resetBtn = this.createButton("Reset", () => this.resetTransform()) + + controls.appendChild(zoomOut) + controls.appendChild(resetBtn) + controls.appendChild(zoomIn) + + this.container.appendChild(controls) + } + + private createButton(text: string, onClick: () => void): HTMLButtonElement { + const button = document.createElement("button") + button.textContent = text + button.className = "mermaid-control-button" + button.addEventListener("click", onClick) + window.addCleanup(() => button.removeEventListener("click", onClick)) + return button + } + + private onMouseDown(e: MouseEvent) { + if (e.button !== 0) return // Only handle left click + this.isDragging = true + this.startPan = { x: e.clientX - this.currentPan.x, y: e.clientY - this.currentPan.y } + this.container.style.cursor = "grabbing" + } + + private onMouseMove(e: MouseEvent) { + if (!this.isDragging) return + e.preventDefault() + + this.currentPan = { + x: e.clientX - this.startPan.x, + y: e.clientY - this.startPan.y, + } + + this.updateTransform() + } + + private onMouseUp() { + this.isDragging = false + this.container.style.cursor = "grab" + } + + private onWheel(e: WheelEvent) { + e.preventDefault() + + const delta = -e.deltaY * this.ZOOM_SENSITIVITY + const newScale = Math.min(Math.max(this.scale + delta, this.MIN_SCALE), this.MAX_SCALE) + + // Calculate mouse position relative to content + const rect = this.content.getBoundingClientRect() + const mouseX = e.clientX - rect.left + const mouseY = e.clientY - rect.top + + // Adjust pan to zoom around mouse position + const scaleDiff = newScale - this.scale + this.currentPan.x -= mouseX * scaleDiff + this.currentPan.y -= mouseY * scaleDiff + + this.scale = newScale + this.updateTransform() + } + + private zoom(delta: number) { + const newScale = Math.min(Math.max(this.scale + delta, this.MIN_SCALE), this.MAX_SCALE) + + // Zoom around center + const rect = this.content.getBoundingClientRect() + const centerX = rect.width / 2 + const centerY = rect.height / 2 + + const scaleDiff = newScale - this.scale + this.currentPan.x -= centerX * scaleDiff + this.currentPan.y -= centerY * scaleDiff + + this.scale = newScale + this.updateTransform() + } + + private updateTransform() { + this.content.style.transform = `translate(${this.currentPan.x}px, ${this.currentPan.y}px) scale(${this.scale})` + } + + private resetTransform() { + this.scale = 1 + this.currentPan = { x: 0, y: 0 } + this.updateTransform() + } +} + +const cssVars = [ + "--secondary", + "--tertiary", + "--gray", + "--light", + "--lightgray", + "--highlight", + "--dark", + "--darkgray", + "--codeFont", +] as const + +document.addEventListener("nav", async () => { + const center = document.querySelector(".center") as HTMLElement + const nodes = center.querySelectorAll("code.mermaid") as NodeListOf + if (nodes.length === 0) return + + const computedStyleMap = cssVars.reduce( + (acc, key) => { + acc[key] = getComputedStyle(document.documentElement).getPropertyValue(key) + return acc + }, + {} as Record<(typeof cssVars)[number], string>, + ) + + const darkMode = document.documentElement.getAttribute("saved-theme") === "dark" + mermaid.initialize({ + startOnLoad: false, + securityLevel: "loose", + theme: darkMode ? "dark" : "base", + themeVariables: { + fontFamily: computedStyleMap["--codeFont"], + primaryColor: computedStyleMap["--light"], + primaryTextColor: computedStyleMap["--darkgray"], + primaryBorderColor: computedStyleMap["--tertiary"], + lineColor: computedStyleMap["--darkgray"], + secondaryColor: computedStyleMap["--secondary"], + tertiaryColor: computedStyleMap["--tertiary"], + clusterBkg: computedStyleMap["--light"], + edgeLabelBackground: computedStyleMap["--highlight"], + }, + }) + await mermaid.run({ nodes }) + + for (let i = 0; i < nodes.length; i++) { + const codeBlock = nodes[i] as HTMLElement + const pre = codeBlock.parentElement as HTMLPreElement + const clipboardBtn = pre.querySelector(".clipboard-button") as HTMLButtonElement + const expandBtn = pre.querySelector(".expand-button") as HTMLButtonElement + + const clipboardStyle = window.getComputedStyle(clipboardBtn) + const clipboardWidth = + clipboardBtn.offsetWidth + + parseFloat(clipboardStyle.marginLeft || "0") + + parseFloat(clipboardStyle.marginRight || "0") + + // Set expand button position + expandBtn.style.right = `calc(${clipboardWidth}px + 0.3rem)` + pre.prepend(expandBtn) + + // query popup container + const popupContainer = pre.querySelector("#mermaid-container") as HTMLElement + if (!popupContainer) return + + let panZoom: DiagramPanZoom | null = null + + function showMermaid() { + const container = popupContainer.querySelector("#mermaid-space") as HTMLElement + const content = popupContainer.querySelector(".mermaid-content") as HTMLElement + if (!content) return + removeAllChildren(content) + + // Clone the mermaid content + const mermaidContent = codeBlock.querySelector("svg")!.cloneNode(true) as SVGElement + content.appendChild(mermaidContent) + + // Show container + popupContainer.classList.add("active") + container.style.cursor = "grab" + + // Initialize pan-zoom after showing the popup + panZoom = new DiagramPanZoom(container, content) + } + + function hideMermaid() { + popupContainer.classList.remove("active") + panZoom = null + } + + function handleEscape(e: any) { + if (e.key === "Escape") { + hideMermaid() + } + } + + const closeBtn = popupContainer.querySelector(".close-button") as HTMLButtonElement + + closeBtn.addEventListener("click", hideMermaid) + expandBtn.addEventListener("click", showMermaid) + document.addEventListener("keydown", handleEscape) + + window.addCleanup(() => { + closeBtn.removeEventListener("click", hideMermaid) + expandBtn.removeEventListener("click", showMermaid) + document.removeEventListener("keydown", handleEscape) + }) + } +}) diff --git a/quartz/components/styles/mermaid.inline.scss b/quartz/components/styles/mermaid.inline.scss new file mode 100644 index 000000000..79a1c8495 --- /dev/null +++ b/quartz/components/styles/mermaid.inline.scss @@ -0,0 +1,163 @@ +.expand-button { + position: absolute; + display: flex; + float: right; + padding: 0.4rem; + margin: 0.3rem; + right: 0; // NOTE: right will be set in mermaid.inline.ts + color: var(--gray); + border-color: var(--dark); + background-color: var(--light); + border: 1px solid; + border-radius: 5px; + opacity: 0; + transition: 0.2s; + + & > svg { + fill: var(--light); + filter: contrast(0.3); + } + + &:hover { + cursor: pointer; + border-color: var(--secondary); + } + + &:focus { + outline: 0; + } +} + +pre { + &:hover > .expand-button { + opacity: 1; + transition: 0.2s; + } +} + +#mermaid-container { + position: fixed; + contain: layout; + z-index: 999; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + overflow: hidden; + display: none; + backdrop-filter: blur(4px); + background: rgba(0, 0, 0, 0.5); + + &.active { + display: inline-block; + } + + & > #mermaid-space { + display: grid; + width: 90%; + height: 90vh; + margin: 5vh auto; + background: var(--light); + box-shadow: + 0 14px 50px rgba(27, 33, 48, 0.12), + 0 10px 30px rgba(27, 33, 48, 0.16); + overflow: hidden; + position: relative; + + & > .mermaid-header { + display: flex; + justify-content: flex-end; + padding: 1rem; + border-bottom: 1px solid var(--lightgray); + background: var(--light); + z-index: 2; + max-height: fit-content; + + & > .close-button { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + padding: 0; + background: transparent; + border: none; + border-radius: 4px; + color: var(--darkgray); + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + background: var(--lightgray); + color: var(--dark); + } + } + } + + & > .mermaid-content { + padding: 2rem; + position: relative; + transform-origin: 0 0; + transition: transform 0.1s ease; + overflow: visible; + min-height: 200px; + min-width: 200px; + + pre { + margin: 0; + border: none; + } + + svg { + max-width: none; + height: auto; + } + } + + & > .mermaid-controls { + position: absolute; + bottom: 20px; + right: 20px; + display: flex; + gap: 8px; + padding: 8px; + background: var(--light); + border: 1px solid var(--lightgray); + border-radius: 6px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + z-index: 2; + + .mermaid-control-button { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + padding: 0; + border: 1px solid var(--lightgray); + background: var(--light); + color: var(--dark); + border-radius: 4px; + cursor: pointer; + font-size: 16px; + font-family: var(--bodyFont); + transition: all 0.2s ease; + + &:hover { + background: var(--lightgray); + } + + &:active { + transform: translateY(1px); + } + + // Style the reset button differently + &:nth-child(2) { + width: auto; + padding: 0 12px; + font-size: 14px; + } + } + } + } +} diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts index 2e599aa0e..417b21853 100644 --- a/quartz/plugins/transformers/frontmatter.ts +++ b/quartz/plugins/transformers/frontmatter.ts @@ -71,6 +71,10 @@ export const FrontMatter: QuartzTransformerPlugin> = (userOpts) const cssclasses = coerceToArray(coalesceAliases(data, ["cssclasses", "cssclass"])) if (cssclasses) data.cssclasses = cssclasses + const socialImage = coalesceAliases(data, ["socialImage", "image", "cover"]) + + if (socialImage) data.socialImage = socialImage + // fill in frontmatter file.data.frontmatter = data as QuartzPluginData["frontmatter"] } @@ -93,6 +97,8 @@ declare module "vfile" { lang: string enableToc: string cssclasses: string[] + socialImage: string + comments: boolean | string }> } } diff --git a/quartz/plugins/transformers/latex.ts b/quartz/plugins/transformers/latex.ts index d323b3ee6..26913bac3 100644 --- a/quartz/plugins/transformers/latex.ts +++ b/quartz/plugins/transformers/latex.ts @@ -1,11 +1,20 @@ import remarkMath from "remark-math" import rehypeKatex from "rehype-katex" import rehypeMathjax from "rehype-mathjax/svg" +//@ts-ignore +import rehypeTypst from "@myriaddreamin/rehype-typst" import { QuartzTransformerPlugin } from "../types" +import { KatexOptions } from "katex" +import { Options as MathjaxOptions } from "rehype-mathjax/svg" +//@ts-ignore +import { Options as TypstOptions } from "@myriaddreamin/rehype-typst" interface Options { - renderEngine: "katex" | "mathjax" + renderEngine: "katex" | "mathjax" | "typst" customMacros: MacroType + katexOptions: Omit + mathJaxOptions: Omit + typstOptions: TypstOptions } interface MacroType { @@ -21,32 +30,37 @@ export const Latex: QuartzTransformerPlugin> = (opts) => { return [remarkMath] }, htmlPlugins() { - if (engine === "katex") { - return [[rehypeKatex, { output: "html", macros }]] - } else { - return [[rehypeMathjax, { macros }]] + switch (engine) { + case "katex": { + return [[rehypeKatex, { output: "html", macros, ...(opts?.katexOptions ?? {}) }]] + } + case "typst": { + return [[rehypeTypst, opts?.typstOptions ?? {}]] + } + case "mathjax": { + return [[rehypeMathjax, { macros, ...(opts?.mathJaxOptions ?? {}) }]] + } + default: { + return [[rehypeMathjax, { macros, ...(opts?.mathJaxOptions ?? {}) }]] + } } }, externalResources() { - if (engine === "katex") { - return { - css: [ - { - // base css - content: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css", - }, - ], - js: [ - { - // fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md - src: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/contrib/copy-tex.min.js", - loadTime: "afterDOMReady", - contentType: "external", - }, - ], - } - } else { - return {} + switch (engine) { + case "katex": + return { + css: [{ content: "https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" }], + js: [ + { + // fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md + src: "https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/copy-tex.min.js", + loadTime: "afterDOMReady", + contentType: "external", + }, + ], + } + default: + return { css: [], js: [] } } }, } diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 70dce6016..624308ca4 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -6,11 +6,14 @@ import rehypeRaw from "rehype-raw" import { SKIP, visit } from "unist-util-visit" import path from "path" import { splitAnchor } from "../../util/path" -import { JSResource } from "../../util/resources" +import { JSResource, CSSResource } from "../../util/resources" // @ts-ignore import calloutScript from "../../components/scripts/callout.inline.ts" // @ts-ignore import checkboxScript from "../../components/scripts/checkbox.inline.ts" +// @ts-ignore +import mermaidExtensionScript from "../../components/scripts/mermaid.inline.ts" +import mermaidStyle from "../../components/styles/mermaid.inline.scss" import { FilePath, pathToRoot, slugTag, slugifyFilePath } from "../../util/path" import { toHast } from "mdast-util-to-hast" import { toHtml } from "hast-util-to-html" @@ -114,7 +117,7 @@ export const wikilinkRegex = new RegExp( export const tableRegex = new RegExp(/^\|([^\n])+\|\n(\|)( ?:?-{3,}:? ?\|)+\n(\|([^\n])+\|\n?)+/gm) // matches any wikilink, only used for escaping wikilinks inside tables -export const tableWikilinkRegex = new RegExp(/(!?\[\[[^\]]*?\]\])/g) +export const tableWikilinkRegex = new RegExp(/(!?\[\[[^\]]*?\]\]|\[\^[^\]]*?\])/g) const highlightRegex = new RegExp(/==([^=]+)==/g) const commentRegex = new RegExp(/%%[\s\S]*?%%/g) @@ -279,6 +282,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> // internal link const url = fp + anchor + return { type: "link", url, @@ -515,6 +519,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> node.data = { hProperties: { className: ["mermaid"], + "data-clipboard": JSON.stringify(node.value), }, } } @@ -659,10 +664,138 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> }) } + if (opts.mermaid) { + plugins.push(() => { + return (tree: HtmlRoot, _file) => { + visit(tree, "element", (node: Element, _idx, parent) => { + if ( + node.tagName === "code" && + ((node.properties?.className ?? []) as string[])?.includes("mermaid") + ) { + parent!.children = [ + { + type: "element", + tagName: "button", + properties: { + className: ["expand-button"], + "aria-label": "Expand mermaid diagram", + "aria-hidden": "true", + "data-view-component": true, + }, + children: [ + { + type: "element", + tagName: "svg", + properties: { + width: 16, + height: 16, + viewBox: "0 0 16 16", + fill: "currentColor", + }, + children: [ + { + type: "element", + tagName: "path", + properties: { + fillRule: "evenodd", + d: "M3.72 3.72a.75.75 0 011.06 1.06L2.56 7h10.88l-2.22-2.22a.75.75 0 011.06-1.06l3.5 3.5a.75.75 0 010 1.06l-3.5 3.5a.75.75 0 11-1.06-1.06l2.22-2.22H2.56l2.22 2.22a.75.75 0 11-1.06 1.06l-3.5-3.5a.75.75 0 010-1.06l3.5-3.5z", + }, + children: [], + }, + ], + }, + ], + }, + node, + { + type: "element", + tagName: "div", + properties: { id: "mermaid-container" }, + children: [ + { + type: "element", + tagName: "div", + properties: { id: "mermaid-space" }, + children: [ + { + type: "element", + tagName: "div", + properties: { className: ["mermaid-header"] }, + children: [ + { + type: "element", + tagName: "button", + properties: { + className: ["close-button"], + "aria-label": "close button", + }, + children: [ + { + type: "element", + tagName: "svg", + properties: { + "aria-hidden": "true", + xmlns: "http://www.w3.org/2000/svg", + width: 24, + height: 24, + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round", + }, + children: [ + { + type: "element", + tagName: "line", + properties: { + x1: 18, + y1: 6, + x2: 6, + y2: 18, + }, + children: [], + }, + { + type: "element", + tagName: "line", + properties: { + x1: 6, + y1: 6, + x2: 18, + y2: 18, + }, + children: [], + }, + ], + }, + ], + }, + ], + }, + { + type: "element", + tagName: "div", + properties: { className: ["mermaid-content"] }, + children: [], + }, + ], + }, + ], + }, + ] + } + }) + } + }) + } + return plugins }, externalResources() { const js: JSResource[] = [] + const css: CSSResource[] = [] if (opts.enableCheckbox) { js.push({ @@ -682,32 +815,18 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin> if (opts.mermaid) { js.push({ - script: ` - let mermaidImport = undefined - document.addEventListener('nav', async () => { - if (document.querySelector("code.mermaid")) { - mermaidImport ||= await import('https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs') - const mermaid = mermaidImport.default - const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark' - mermaid.initialize({ - startOnLoad: false, - securityLevel: 'loose', - theme: darkMode ? 'dark' : 'default' - }) - - await mermaid.run({ - querySelector: '.mermaid' - }) - } - }); - `, + script: mermaidExtensionScript, loadTime: "afterDOMReady", moduleType: "module", contentType: "inline", }) + css.push({ + content: mermaidStyle, + inline: true, + }) } - return { js } + return { js, css } }, } } diff --git a/quartz/util/escape.ts b/quartz/util/escape.ts index 197558c7d..ac59cc74d 100644 --- a/quartz/util/escape.ts +++ b/quartz/util/escape.ts @@ -6,3 +6,12 @@ export const escapeHTML = (unsafe: string) => { .replaceAll('"', """) .replaceAll("'", "'") } + +export const unescapeHTML = (html: string) => { + return html + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll(""", '"') + .replaceAll("'", "'") +} diff --git a/quartz/util/og.tsx b/quartz/util/og.tsx new file mode 100644 index 000000000..0430a265d --- /dev/null +++ b/quartz/util/og.tsx @@ -0,0 +1,200 @@ +import { FontWeight, SatoriOptions } from "satori/wasm" +import { GlobalConfiguration } from "../cfg" +import { QuartzPluginData } from "../plugins/vfile" +import { JSXInternal } from "preact/src/jsx" +import { ThemeKey } from "./theme" + +/** + * Get an array of `FontOptions` (for satori) given google font names + * @param headerFontName name of google font used for header + * @param bodyFontName name of google font used for body + * @returns FontOptions for header and body + */ +export async function getSatoriFont(headerFontName: string, bodyFontName: string) { + const headerWeight = 700 as FontWeight + const bodyWeight = 400 as FontWeight + + // Fetch fonts + const headerFont = await fetchTtf(headerFontName, headerWeight) + const bodyFont = await fetchTtf(bodyFontName, bodyWeight) + + // Convert fonts to satori font format and return + const fonts: SatoriOptions["fonts"] = [ + { name: headerFontName, data: headerFont, weight: headerWeight, style: "normal" }, + { name: bodyFontName, data: bodyFont, weight: bodyWeight, style: "normal" }, + ] + return fonts +} + +/** + * Get the `.ttf` file of a google font + * @param fontName name of google font + * @param weight what font weight to fetch font + * @returns `.ttf` file of google font + */ +async function fetchTtf(fontName: string, weight: FontWeight): Promise { + try { + // Get css file from google fonts + const cssResponse = await fetch(`https://fonts.googleapis.com/css?family=${fontName}:${weight}`) + const css = await cssResponse.text() + + // Extract .ttf url from css file + const urlRegex = /url\((https:\/\/fonts.gstatic.com\/s\/.*?.ttf)\)/g + const match = urlRegex.exec(css) + + if (!match) { + throw new Error("Could not fetch font") + } + + // Retrieve font data as ArrayBuffer + const fontResponse = await fetch(match[1]) + + // fontData is an ArrayBuffer containing the .ttf file data (get match[1] due to google fonts response format, always contains link twice, but second entry is the "raw" link) + const fontData = await fontResponse.arrayBuffer() + + return fontData + } catch (error) { + throw new Error(`Error fetching font: ${error}`) + } +} + +export type SocialImageOptions = { + /** + * What color scheme to use for image generation (uses colors from config theme) + */ + colorScheme: ThemeKey + /** + * Height to generate image with in pixels (should be around 630px) + */ + height: number + /** + * Width to generate image with in pixels (should be around 1200px) + */ + width: number + /** + * Whether to use the auto generated image for the root path ("/", when set to false) or the default og image (when set to true). + */ + excludeRoot: boolean + /** + * JSX to use for generating image. See satori docs for more info (https://github.com/vercel/satori) + * @param cfg global quartz config + * @param userOpts options that can be set by user + * @param title title of current page + * @param description description of current page + * @param fonts global font that can be used for styling + * @param fileData full fileData of current page + * @returns prepared jsx to be used for generating image + */ + imageStructure: ( + cfg: GlobalConfiguration, + userOpts: UserOpts, + title: string, + description: string, + fonts: SatoriOptions["fonts"], + fileData: QuartzPluginData, + ) => JSXInternal.Element +} + +export type UserOpts = Omit + +export type ImageOptions = { + /** + * what title to use as header in image + */ + title: string + /** + * what description to use as body in image + */ + description: string + /** + * what fileName to use when writing to disk + */ + fileName: string + /** + * what directory to store image in + */ + fileDir: string + /** + * what file extension to use (should be `webp` unless you also change sharp conversion) + */ + fileExt: string + /** + * header + body font to be used when generating satori image (as promise to work around sync in component) + */ + fontsPromise: Promise + /** + * `GlobalConfiguration` of quartz (used for theme/typography) + */ + cfg: GlobalConfiguration + /** + * full file data of current page + */ + fileData: QuartzPluginData +} + +// This is the default template for generated social image. +export const defaultImage: SocialImageOptions["imageStructure"] = ( + cfg: GlobalConfiguration, + { colorScheme }: UserOpts, + title: string, + description: string, + fonts: SatoriOptions["fonts"], + _fileData: QuartzPluginData, +) => { + // How many characters are allowed before switching to smaller font + const fontBreakPoint = 22 + const useSmallerFont = title.length > fontBreakPoint + + // Setup to access image + const iconPath = `https://${cfg.baseUrl}/static/icon.png` + return ( +
+
+ +

+ {title} +

+
+

+ {description} +

+
+ ) +}