From a344257e2c9b9e180921ed456b93a8fe8fe279a1 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 23 Sep 2026 10:04:14 +0200 Subject: [PATCH 1/6] Build the site with Docspire The pages move under docs/, Docspire's input directory, and its layouts, navigation and page outline replace the hand-rolled 11ty setup. - Prism v2 highlights in the browser, on every page, as it did before: the site's plugin loads /assets/prism.js. Docspire's build-time markdown-it-prism is off, since it runs Prism v1. A fence's attributes go on its
, where
  Prism's plugins read them.
- Prism's catalog is plain global data (data/prism.js), read by the download,
  examples and FAQ pages.
- postinstall clones Prism v2 into .prism, not node_modules/prismjs: Docspire's
  markdown-it-prism needs the v1 package there. The plugin READMEs it copies are
  pages of their own, listed in the sidebar, with edit links into the Prism repo.
- A plugin page loads the plugin, then its own demo, from the `resources` its
  README lists. A content.end slot renders them.
- Prism in the browser reads a page's `body_classes` off , and brand.css
  its page-specific rules off `data-inputpath`.
- netlify.toml sends themes, languages and plugin files to the v2 build. A file
  the site has wins, so one rule per URL shape does. The rules are not in
  _redirects, because on Netlify nudeps writes its own rules to that file.
- typedoc writes the API docs into _site/api.
- The example files stay in examples/, outside docs/: the examples page finds
  them by that path in the repo's tree. The build copies them to /examples/.
- Links follow the new /page/ URLs, and point at /api/ instead of the v1 docs.

Co-Authored-By: Claude Opus 5.5 
---
 .gitignore                                    |   13 +-
 README.json                                   |    4 -
 _build/copy-plugins.mjs                       |   46 -
 _build/eleventy.js                            |   88 -
 _build/filters.js                             |   20 +-
 _build/postinstall.mjs                        |   21 +-
 _data/eleventyComputed.js                     |   70 -
 _layouts/home.njk                             |   28 -
 _layouts/page.njk                             |  102 -
 _redirects.njk                                |   22 -
 assets/style.css                              |  918 --------
 data/prism.js                                 |    7 +
 {assets => docs/assets}/download.js           |    2 +
 {assets => docs/assets}/examples.js           |   29 +-
 {assets => docs/assets}/faq.js                |    0
 .../assets}/img/failures/coy-overlap.png      |  Bin
 {assets => docs/assets}/img/logo-ala.png      |  Bin
 .../assets}/img/logo-css-tricks.png           |  Bin
 {assets => docs/assets}/img/logo-drupal.png   |  Bin
 {assets => docs/assets}/img/logo-mdn.png      |  Bin
 {assets => docs/assets}/img/logo-mysql.png    |  Bin
 {assets => docs/assets}/img/logo-react.png    |  Bin
 .../assets}/img/logo-sitepoint.png            |  Bin
 {assets => docs/assets}/img/logo-smashing.png |  Bin
 {assets => docs/assets}/img/logo-stripe.png   |  Bin
 {assets => docs/assets}/img/spectrum.png      |  Bin
 docs/assets/prism.js                          |   19 +
 {assets => docs/assets}/test-drive.js         |    4 +-
 {assets => docs/assets}/theme-switcher.js     |    0
 {assets => docs/assets}/util.js               |    0
 .../assets}/vendor/FileSaver.min.js           |    0
 {assets => docs/assets}/vendor/jszip.min.js   |    0
 benchmark.md => docs/benchmark.md             |   11 +-
 download.njk => docs/download.njk             |   12 +-
 examples.md => docs/examples.md               |    8 +-
 extending.md => docs/extending.md             |  452 ++--
 faq.md => docs/faq.md                         |   21 +-
 README.md => docs/index.md                    |  123 +-
 known-failures.md => docs/known-failures.md   |    3 +-
 docs/plugins.md                               |   20 +
 docs/plugins/plugins.11tydata.js              |   25 +
 test-suite.md => docs/test-suite.md           |    2 -
 test.md => docs/test.md                       |    7 +-
 tokens.md => docs/tokens.md                   |   11 +-
 docspire.config.js                            |   97 +
 netlify.toml                                  |   35 +
 package-lock.json                             | 2020 ++++++++++++-----
 package.json                                  |   11 +-
 templates/page-title.njk                      |    9 +
 templates/resources.njk                       |    3 +
 typedoc.json                                  |   11 +-
 51 files changed, 2051 insertions(+), 2223 deletions(-)
 delete mode 100644 README.json
 delete mode 100644 _build/copy-plugins.mjs
 delete mode 100644 _build/eleventy.js
 delete mode 100644 _data/eleventyComputed.js
 delete mode 100644 _layouts/home.njk
 delete mode 100644 _layouts/page.njk
 delete mode 100644 _redirects.njk
 delete mode 100644 assets/style.css
 create mode 100644 data/prism.js
 rename {assets => docs/assets}/download.js (99%)
 rename {assets => docs/assets}/examples.js (81%)
 rename {assets => docs/assets}/faq.js (100%)
 rename {assets => docs/assets}/img/failures/coy-overlap.png (100%)
 rename {assets => docs/assets}/img/logo-ala.png (100%)
 rename {assets => docs/assets}/img/logo-css-tricks.png (100%)
 rename {assets => docs/assets}/img/logo-drupal.png (100%)
 rename {assets => docs/assets}/img/logo-mdn.png (100%)
 rename {assets => docs/assets}/img/logo-mysql.png (100%)
 rename {assets => docs/assets}/img/logo-react.png (100%)
 rename {assets => docs/assets}/img/logo-sitepoint.png (100%)
 rename {assets => docs/assets}/img/logo-smashing.png (100%)
 rename {assets => docs/assets}/img/logo-stripe.png (100%)
 rename {assets => docs/assets}/img/spectrum.png (100%)
 create mode 100644 docs/assets/prism.js
 rename {assets => docs/assets}/test-drive.js (98%)
 rename {assets => docs/assets}/theme-switcher.js (100%)
 rename {assets => docs/assets}/util.js (100%)
 rename {assets => docs/assets}/vendor/FileSaver.min.js (100%)
 rename {assets => docs/assets}/vendor/jszip.min.js (100%)
 rename benchmark.md => docs/benchmark.md (97%)
 rename download.njk => docs/download.njk (86%)
 rename examples.md => docs/examples.md (88%)
 rename extending.md => docs/extending.md (60%)
 rename faq.md => docs/faq.md (88%)
 rename README.md => docs/index.md (72%)
 rename known-failures.md => docs/known-failures.md (98%)
 create mode 100644 docs/plugins.md
 create mode 100644 docs/plugins/plugins.11tydata.js
 rename test-suite.md => docs/test-suite.md (99%)
 rename test.md => docs/test.md (85%)
 rename tokens.md => docs/tokens.md (97%)
 create mode 100644 docspire.config.js
 create mode 100644 netlify.toml
 create mode 100644 templates/page-title.njk
 create mode 100644 templates/resources.njk

diff --git a/.gitignore b/.gitignore
index 3bed9a90..a6ebc2b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,13 +3,12 @@ node_modules
 Thumbs.db
 
 # Generated files
-*.html
-!examples/*.html
-api
-plugins
-components.json
-file-sizes.json
-_redirects
+.prism
+docs/plugins/*
+!docs/plugins/plugins.11tydata.js
+docs/components.json
+docs/file-sizes.json
+_site
 
 # Cache
 .cache
diff --git a/README.json b/README.json
deleted file mode 100644
index 4abebb76..00000000
--- a/README.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-	"layout": "home.njk",
-	"resources": ["/plugins/keep-markup.js { type=module }", "/languages/bash.js { type=module }"]
-}
diff --git a/_build/copy-plugins.mjs b/_build/copy-plugins.mjs
deleted file mode 100644
index e175f8ec..00000000
--- a/_build/copy-plugins.mjs
+++ /dev/null
@@ -1,46 +0,0 @@
-import fs from "fs/promises";
-import path from "path";
-import { fileURLToPath } from "url";
-
-const __dirname = path.dirname(fileURLToPath(import.meta.url));
-
-const sourcePath = path.resolve(__dirname, "../node_modules/prismjs/src/plugins");
-const destPath = path.resolve(__dirname, "../plugins");
-
-async function copy () {
-	// We need { recursive: true } so the script doesn't fail if the folder already exists
-	await fs.mkdir(destPath, { recursive: true });
-
-	let plugins = await fs.readdir(sourcePath, { withFileTypes: true });
-	for (let plugin of plugins) {
-		if (!plugin.isDirectory()) {
-			continue;
-		}
-
-		let source = path.join(sourcePath, plugin.name);
-		let dest = path.join(destPath, plugin.name);
-		await fs.mkdir(dest, { recursive: true });
-
-		let files = await fs.readdir(source, { withFileTypes: true });
-		for (let file of files) {
-			if (!file.isFile()) {
-				continue;
-			}
-
-			let filename = path.parse(file.name).base;
-			if (["README.md", "demo.md"].includes(filename)) {
-				await fs.copyFile(path.join(source, file.name), path.join(dest, file.name));
-			}
-		}
-	}
-}
-
-await copy();
-
-// Create plugins.json in the plugins folder with global data
-let json = {
-	permalink: "{{ page.filePathStem.replace('README', '/index') }}.html",
-	tags: ["plugin"],
-};
-
-await fs.writeFile(path.join(destPath, "plugins.json"), JSON.stringify(json, null, "\t"));
diff --git a/_build/eleventy.js b/_build/eleventy.js
deleted file mode 100644
index 85d81cba..00000000
--- a/_build/eleventy.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import markdownItAnchor from "markdown-it-anchor";
-import markdownItAttrs from "markdown-it-attrs";
-import markdownItDeflist from "markdown-it-deflist";
-import pluginTOC from "eleventy-plugin-toc";
-import * as filters from "./filters.js";
-
-import components from "../components.json" with { type: "json" };
-import file_sizes from "../file-sizes.json" with { type: "json" };
-
-/** @param {import("@11ty/eleventy").UserConfig} config */
-export default config => {
-	let data = {
-		components,
-		file_sizes,
-		layout: "page.njk",
-		theme_switcher: true,
-		toc: true,
-		permalink: `{{ "index" if page.filePathStem == "/README" else page.filePathStem }}.html`,
-	};
-
-	for (let p in data) {
-		config.addGlobalData(p, data[p]);
-	}
-
-	for (let f in filters) {
-		config.addFilter(f, filters[f]);
-	}
-
-	let mdLib;
-	config.amendLibrary("md", md => {
-		mdLib = md;
-		md.options.typographer = true;
-		md.options.linkify = true;
-		md.use(markdownItAnchor, {
-			permalink: markdownItAnchor.permalink.headerLink(),
-		});
-		md.use(markdownItAttrs);
-		md.use(markdownItDeflist);
-
-		// Allow setting attributes on the outer 
, not the inner 
-		md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
-			let token = tokens[idx];
-			let lang = token.info ? `class="language-${token.info}"` : "";
-			let content = md.utils.escapeHtml(token.content).trim();
-			return `
${content}
`; - }; - }); - - config.addFilter("md", function (content) { - if (typeof content !== "string") { - return content; - } - - let ret = mdLib.renderInline(content); - let safeFilter = this.env?.filters?.safe; - return safeFilter ? safeFilter(ret) : ret; - }); - - config.addPairedShortcode("md", content => { - if (typeof content !== "string") { - if (content instanceof String) { - content = content + ""; - } - else { - return content; - } - } - - return mdLib.render(content); - }); - - config.addPlugin(pluginTOC, { - tags: ["h1", "h2", "h3"], - ul: true, - }); - - // Don't ignore the folders that are gitignored (plugins, examples, themes, etc.) - config.setUseGitIgnore(false); - - return { - markdownTemplateEngine: "njk", - templateFormats: ["md", "njk"], - dir: { - layouts: "_layouts", - output: ".", - }, - }; -}; diff --git a/_build/filters.js b/_build/filters.js index 5681b3f0..0be06e01 100644 --- a/_build/filters.js +++ b/_build/filters.js @@ -1,23 +1,5 @@ -import * as path from "path"; - -export function relative (page) { - if (!page.url) { - return ""; - } - - let pagePath = page.url.replace(/[^/]+$/, ""); - let ret = path.relative(pagePath, "/"); - - return ret || "."; -} - -export function back_to_top (content) { - // Add “↑ Back to top” at the end of each `
` - return content.replace(/<\/section>/g, `

↑ Back to top

`); -} - export function pretty_size (size) { - return Math.round(100 * size / 1024) / 100 + "KB"; + return Math.round((100 * size) / 1024) / 100 + "KB"; } export function parse_resources (resources = []) { diff --git a/_build/postinstall.mjs b/_build/postinstall.mjs index b0933cd1..b4733f3e 100644 --- a/_build/postinstall.mjs +++ b/_build/postinstall.mjs @@ -5,8 +5,10 @@ import { execSync } from "child_process"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const root = path.resolve(__dirname, "../node_modules"); -const prismPath = path.join(root, "prismjs"); +// Not node_modules/prismjs: markdown-it-prism, which highlights the docs, resolves the real +// `prismjs` package from there, and it needs v1 +const root = path.resolve(__dirname, ".."); +const prismPath = path.join(root, ".prism"); let sourcePath, destPath; @@ -14,7 +16,7 @@ let sourcePath, destPath; console.log("[postinstall] Cloning Prism..."); // Ensure we work with a fresh copy await fs.rm(prismPath, { recursive: true, force: true }); -execSync("git clone https://github.com/PrismJS/prism.git prismjs", { +execSync("git clone https://github.com/PrismJS/prism.git .prism", { cwd: root, stdio: "inherit", }); @@ -33,7 +35,7 @@ execSync("npm run build", { // --- Working with plugins --- sourcePath = path.join(prismPath, "src/plugins"); -destPath = path.resolve(__dirname, "../plugins"); +destPath = path.resolve(__dirname, "../docs/plugins"); async function copy () { // We need { recursive: true } so the script doesn't fail if the folder already exists @@ -71,18 +73,9 @@ catch (error) { console.error(`[postinstall] Failed to copy Prism plugins docs: ${error.message}`); } -// Create plugins.json in the plugins folder with global data -console.log("[postinstall] Creating plugins.json..."); -let json = { - permalink: "{{ page.filePathStem.replace('README', '/index') }}.html", - tags: ["plugin"], -}; - -await fs.writeFile(path.join(destPath, "plugins.json"), JSON.stringify(json, null, "\t")); - // --- Copying other files (components.json, file-sizes.json, etc.) --- sourcePath = path.join(prismPath, "dist"); -destPath = path.resolve(__dirname, ".."); +destPath = path.resolve(__dirname, "../docs"); let filenames = ["components.json", "file-sizes.json"]; for (let file of filenames) { diff --git a/_data/eleventyComputed.js b/_data/eleventyComputed.js deleted file mode 100644 index 1c8cfd26..00000000 --- a/_data/eleventyComputed.js +++ /dev/null @@ -1,70 +0,0 @@ -export default { - components (data) { - return { ...data.components }; - }, - themes (data) { - let themes = { ...data.components.themes }; - delete themes.meta; - return themes; - }, - languages (data) { - let languages = { ...data.components.languages }; - delete languages.meta; - - for (let id in languages) { - let ret = [id]; - let alias = Object.keys(languages[id].aliasTitles ?? {}); - if (alias) { - ret = ret.concat(Array.isArray(alias) ? alias : [alias]); - } - languages[id].alias = ret; - } - - return languages; - }, - // Plugin id - id (data) { - let parts = data.page.inputPath.slice(2).split("/"); - if (parts[0] === "plugins") { - // Folder name ↔ plugin id - return parts[1]; - } - }, - title (data) { - if (data.title) { - return data.title; - } - - let path = data.page.inputPath; - path = path.slice(2); - - let title = path.replace(".md", ""); - if (title === "README") { - return; - } - - title = title.replace(/-/g, " "); - - return title[0].toUpperCase() + title.slice(1); - }, - resources (data) { - let { id, resources = [] } = data; - let ret = []; - - resources = Array.isArray(resources) ? resources : [resources]; - ret.push(...resources); - - if (!id) { - return ret; - } - - // We are working with plugin resources - ret.push(`/plugins/${id}.js { type="module" }`); - - if (!data.noCSS) { - ret.push(`/plugins/${id}.css`); - } - - return ret; - }, -}; diff --git a/_layouts/home.njk b/_layouts/home.njk deleted file mode 100644 index dd139050..00000000 --- a/_layouts/home.njk +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "./page.njk" %} - -{% block head_extra -%} - -{%- endblock %} - -{% block header_extra -%} -{% md %} - -- **Dead simple** - Include prism.css and prism.js, use proper HTML5 code tags (`code.language-xxxx`), done! -- **Intuitive** - Language classes are inherited so you can only define the language once for multiple code snippets. -- **Light as a feather** - The core is 2KB minified & gzipped. Languages add 0.3-0.5KB each, themes are around 1KB. -- **Blazing fast** - Supports parallelism with Web Workers, if available. -- **Extensible** - Define new languages or extend existing ones. Add new features thanks to Prism's plugin architecture. -- **Easy styling** - All styling is done through CSS, with sensible class names like `.comment`, `.string`, `.property` etc. -{ id="features" } - -{% endmd %} -{%- endblock %} diff --git a/_layouts/page.njk b/_layouts/page.njk deleted file mode 100644 index e36f9b5a..00000000 --- a/_layouts/page.njk +++ /dev/null @@ -1,102 +0,0 @@ - - - - {% if base %} - - {% endif -%} - - {%- set main_title = title | md | striptags or subdomain | capitalize %} - {{ main_title }}{{ " ▲" if main_title }} Prism {{ subdomain if subdomain | capitalize != main_title }} - - - - - - - - - - {% block head_extra -%}{%- endblock -%} - - - -
-
-

Prism {{ subdomain }}

- - Download - -

- Prism is a lightweight, extensible syntax highlighter, built with modern web standards in mind. - It’s used in millions of websites, including some of those you visit daily. -

-
- - {% if theme_switcher -%} -
-

Theme:

- {%- for id, theme in themes %} - - - {%- endfor %} -
- {%- endif %} - - {% block header_extra -%}{%- endblock -%} - - {% if title -%} -

{{ title | md }}

-

{{ (tagline or description) | md }}

- {%- endif %} -
- - {% if toc and content | toc -%} - - {%- endif %} - -
- {% if back_to_top -%} - {{ content | back_to_top | safe }} - {%- else -%} - {{ content | safe }} - {%- endif %} -
- - - - - - {% if theme_switcher -%} - - {%- endif %} - - {%- for resource in resources | parse_resources %} - {{ resource | safe -}} - {%- endfor %} - - diff --git a/_redirects.njk b/_redirects.njk deleted file mode 100644 index 12022bee..00000000 --- a/_redirects.njk +++ /dev/null @@ -1,22 +0,0 @@ ---- -permalink: _redirects -layout: null -eleventyExcludeFromCollections: true ---- - -# Themes and languages -/themes/:file https://v2.dev.prismjs.com/dist/themes/:file 301 -/languages/:file https://v2.dev.prismjs.com/dist/languages/:file 301 - -# Plugins -{% for plugin in collections.plugin -%} -{%- set id = plugin.data.id -%} -/plugins/{{ id }}.js https://v2.dev.prismjs.com/dist/plugins/{{ id }}.js 301 -/plugins/{{ id }}/{{ id }}.js https://v2.dev.prismjs.com/src/plugins/{{ id }}/{{ id }}.js 301 -{% if not meta.noCSS -%} -/plugins/{{ id }}.css https://v2.dev.prismjs.com/dist/plugins/{{ id }}.css 301 -/plugins/{{ id }}/{{ id }}.css https://v2.dev.prismjs.com/src/plugins/{{ id }}/{{ id }}.css 301 -{% endif -%} -{% endfor -%} -/plugins/:plugin/demo.js https://v2.dev.prismjs.com/src/plugins/:plugin/demo.js 301 -/plugins/:plugin/demo.css https://v2.dev.prismjs.com/src/plugins/:plugin/demo.css 301 diff --git a/assets/style.css b/assets/style.css deleted file mode 100644 index 3998db82..00000000 --- a/assets/style.css +++ /dev/null @@ -1,918 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Questrial); -@import url(https://fonts.googleapis.com/css?family=Arvo); - -/* - Shared styles - */ - -section h1, -#features li strong, -header h2, -footer p { - font: 100% Rockwell, Arvo, serif; -} - -/* - Styles - */ - -* { - margin: 0; - padding: 0; -} - -body { - font: 100%/1.5 Questrial, sans-serif; - tab-size: 4; - hyphens: auto; -} - -a { - color: inherit; -} - -section h1 { - font-size: 250%; -} - - section section h1 { - font-size: 150%; - } - - section h1 code { - font-style: normal; - } - - section h1 > a, - section h2[id] > a { - text-decoration: none; - } - - section h1 > a:before, - section h2[id] > a:before { - content: '§'; - position: absolute; - padding: 0 .2em; - margin-left: -1em; - border-radius: .2em; - color: silver; - text-shadow: 0 1px white; - } - - section h1 > a:hover:before, - section h2[id] > a:hover:before { - color: black; - background: #f1ad26; - } - -p { - margin: 1em 0; -} - -section h1, -h2, -h3 { - margin: 1em 0 .3em; -} - -h2, -h3 { - font-weight: normal; - - > a { - text-decoration: none; - } -} - -dt { - margin: 1em 0 0 0; - font-size: 130%; -} - - dt:after { - content: ':'; - } - -dd { - margin-left: 2em; -} - -code, pre { - font-family: Consolas, Monaco, 'Andale Mono', 'Lucida Console', monospace; - hyphens: none; -} - -pre { - max-height: 30em; - overflow: auto; -} - -mark { - outline: .4em solid red; - outline-offset: .4em; - margin: .4em 0; - background-color: transparent; - display: inline-block; -} - -header, -body > main { - display: block; - max-width: 900px; - margin: auto; -} - -header, footer { - position: relative; - padding: 30px -webkit-calc(50% - 450px); /* Workaround for bug */ - padding: 30px calc(50% - 450px); - color: white; - text-shadow: 0 -1px 2px black, 0 0 4px black, - 0 -1px 0 black, 0 1px 0 black, -1px 0 0 black, 1px 0 0 black; - background: linear-gradient(transparent, rgba(0, 0, 0, 0.6)), url(img/spectrum.png) fixed; -} - -header:before, -footer:before { - content: ''; - position: absolute; - bottom: 0; left: 0; right: 0; - height: 20px; - background-size: 20px 40px; - background-repeat: repeat-x; - background-image: linear-gradient(45deg, transparent 34%, white 34%, white 66%, transparent 66%), - linear-gradient(135deg, transparent 34%, white 34%, white 66%, transparent 66%); -} - - header .intro, - html.simple header { - overflow: hidden; - } - - header h1 { - float: left; - margin-right: 30px; - color: #7fab14; - text-align: center; - font-size: 140%; - text-transform: uppercase; - letter-spacing: .25em; - } - - header h2 { - margin-top: .5em; - color: #f1ad26; - } - - header h1 a { - text-decoration: none; - } - - header img { - display: block; - width: 150px; - height: 128px; - margin-bottom: .3em; - border: 0; - } - - header h2 { - font-size: 300%; - } - - header .intro p { - margin: 0; - font: 150%/1.4 Questrial, sans-serif; - font-size: 150%; - } - - #features { - margin-top: 1.6em; - } - - #features li { - margin: 0 0 1.6em 0; - list-style: none; - display: inline-block; - width: 49%; - box-sizing: border-box; - vertical-align: top; - } - - #features li:nth-child(odd) { - padding-right: 2em; - } - #features li:nth-child(even) { - padding-left: 2em; - } - - #features li:before { - content: '✓'; - float: left; - margin-left: -.8em; - color: #7fab14; - font-size: 320%; - line-height: 1; - } - - #features li strong { - display: block; - margin-bottom: .1em; - font-size: 160%; - } - - header .download-button { - float: right; - margin: 0 0 .5em .5em; - } - - #theme { - position: relative; - z-index: 1; - float: right; - margin-right: -9em; - text-align: center; - text-transform: uppercase; - letter-spacing: .2em; - text-shadow: 0 -1px 2px black; - } - - #theme > p { - position: absolute; - left: 100%; - transform: translateX(50%) rotate(90deg) ; - transform-origin: top left; - font-size: 130%; - } - - #theme > label { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 8.5em; - height: 8.5em; - line-height: 1em; - border-radius: 50%; - background: hsla(0,0%,100%,.5); - cursor: pointer; - font-size: 90%; - padding: 0; - } - - #theme > label:before { - content: ''; - position: absolute; - top: 0; right: 0; bottom: 0; left: 0; - z-index: -1; - border-radius: inherit; - background: url(img/spectrum.png) fixed; - } - - #theme > label:nth-of-type(n+2) { - margin-top: -2.5em; - } - - #theme > input:not(:checked) + label:hover { - background: hsla(77, 80%, 60%, .5); - } - - #theme > input { - position: absolute; - left: 0; - clip: rect(0,0,0,0); - } - - #theme > input:checked + label { - background: #7fab14; - } - - @media (max-width: 1300px) and (min-width: 1051px) { - #theme { - position: relative; - z-index: 1; - float: left; - margin: 1em 0; - width: 100%; - } - #theme + * { - clear: both; - } - - #theme > p { - margin-top: .5em; - } - - #theme > label { - float: left; - font-size: 82.6%; - } - - #theme > label:before { - display: none; - } - - #theme > label:nth-of-type(n+2) { - margin-top: 0; - } - } - - @media (max-width: 1050px) { - #theme { - position: relative; - z-index: 1; - float: left; - margin: 1em 0; - } - #theme + * { - clear: both; - } - - #theme > p { - left: inherit; - right: -1em; - } - - #theme > label { - float: left; - } - - #theme > label:before { - display: none; - } - - #theme > label:nth-of-type(n+2) { - margin-top: 0; - } - #theme > label:nth-of-type(n+5) { - margin-top: -2.5em; - } - #theme > label:nth-of-type(4n+1) { - margin-left: 12.5em; - } - } - - @media (max-width: 800px) { - #theme > label:nth-of-type(4) { - margin-right: 4em; - } - #theme > label:nth-of-type(4n+1) { - margin-left: 4em; - } - } - - -footer { - margin-top: 2em; - background-position: bottom; - color: white; -} - - footer:before { - bottom: auto; - top: 0; - background-position: bottom; - } - - footer p { - font-size: 150%; - } - - footer ul { - column-count: 3; - } - -.download-button { - display: block; - padding: .2em .8em .1em; - border: 1px solid rgba(0,0,0,0.5); - border-radius: 10px; - background: #39a1cf; - box-shadow: 0 2px 10px black, - inset 0 1px hsla(0,0%,100%,.3), - inset 0 .4em hsla(0,0%,100%,.2), - inset 0 10px 20px hsla(0,0%,100%,.25), - inset 0 -15px 30px rgba(0,0,0,0.3); - color: white; - text-shadow: 0 -1px 2px black; - text-align: center; - font-size: 250%; - line-height: 1.5; - text-transform: uppercase; - text-decoration: none; - hyphens: manual; -} - -.download-button:hover { - background-color: #7fab14; -} - -.download-button:active { - box-shadow: inset 0 2px 8px rgba(0,0,0,.8); -} - -#toc { - position: fixed; - bottom: 15px; - max-width: calc(50% - 450px - 40px); - font-size: 80%; - z-index: 999; - background: white; - color: rgba(0,0,0,.5); - padding: 0 10px 10px; - border-radius: 0 3px 3px 0; - box-sizing: border-box; - - &:hover { - color: rgba(0,0,0,1); - } - - h2 { - font-family: Rockwell, Arvo, serif; - font-size: 180%; - margin-top: .75rem; - } - - li { - list-style: none; - line-height: 1.2; - padding: .2em 0; - - a { - padding: .2em 0; - } - } - - > nav.toc { - li > ul { - margin-inline-start: .5rem; - } - } - - &:has(+ main .back-to-top) { - position: static; - max-width: 900px; - margin-inline: auto; - font-size: 100%; - color: black; - - :is([data-inputpath="known-failures.md"] &) > .toc { - column-count: 4; - - li > ul { - /* Show top-level headings only */ - display: none; - } - } - } - - @media (max-width: 1200px) { - &:not(:has(+ main .back-to-top)) { - display: none; - } - } -} - - -#logo { - float: right; - margin-block-start: 3.5em; - margin-inline-start: .5em; - height: 5em; - filter: brightness(0) invert(1); -} - -.used-by-logos { - overflow: hidden; -} - .used-by-logos > a { - float: left; - width: 33.33%; - height: 100px; - text-align: center; - background: #F5F2F0; - box-sizing: border-box; - border: 5px solid white; - position: relative; - } - .used-by-logos > a > img { - max-height: 100%; - max-width: 100%; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - -label a.owner { - margin: 0 .5em; -} - -label a.owner:not(:hover) { - text-decoration: none; - color: #aaa; -} - -#languages-list { - column-count: 3; - column-gap: 2em; - - li { - padding: .2em; - } - - li[data-id="javascript"] { - border-bottom: 1px solid #aaa; - padding-bottom: 1em; - margin-bottom: 1em; - margin-right: 1em; - } -} - -ul.plugin-list { - column-count: 2; - column-gap: 2em; - - > li { - break-inside: avoid; - page-break-inside: avoid; - - > a { - font-size: 110%; - } - - > div { - margin-bottom: .5em; - } - } -} - -[data-inputpath="examples.md"] { - #languages { - column-count: 4; - - > h1 { - margin-top: 0; - column-span: all; - } - - label { - display: block; - padding: .2em; - - &[data-id="javascript"] { - border-bottom: 1px solid #aaa; - padding-bottom: 1em; - margin-bottom: 1em; - } - } - - .unavailable { - color: #aaa; - } - - input { - margin-right: .7em; - } - } - - #examples { - > section { - display: block; - margin: auto; - max-width: 900px; - } - - h3 { - margin: 1em 0 0.3em; - } - } - - main ul { - padding-left: 40px; - } -} - -[data-inputpath="known-failures.md"] { - main h2 { - font-size: 1.2em; - - &[id] > a::before { - content: ""; - } - } -} - -[data-inputpath="tokens.md"] { - table.styled { - border: 1px solid #ccc; - border-spacing: 0; - - tr:not(:first-child) > * { - border-top: 1px solid #ccc; - } - - tr > *:not(:first-child) { - border-left: 1px solid #ccc; - } - - tr:nth-child(2n + 1) { - background-color: #F8F8F8; - } - - tr > * { - padding: .5em .75em; - } - - tr > th { - text-align: left; - } - } -} - -[data-inputpath="extending.md"] { - ol.indent { - margin: 1em 0; - padding-left: 2em; - } - - table.stylish { - border-collapse: collapse; - - &, tr, td, th { - border: 1px solid #CCC; - } - - td, th { - padding: .5em .75em; - } - - th, td:first-child { - background-color: #F8F8F8; - } - } -} - -[data-inputpath="test.md"] { - textarea { - width: 100%; - height: 10em; - padding: 1em; - box-sizing: border-box; - margin: .5em 0; - background: #f5f2f0; - color: black; - text-shadow: 0 1px white; - tab-size: 4; - font: 100% Consolas, Monaco, monospace; - white-space: pre; - word-wrap: normal; - resize: vertical; - } - - #language { - column-count: 4; - - label { - display: block; - padding: .2em; - } - - label[data-id="javascript"] { - border-bottom: 1px solid #aaa; - padding-bottom: 1em; - margin-bottom: 1em; - } - - input { - margin-right: 1em; - } - - strong { - display: block; - column-span: all; - } - } - - pre.show-tokens { - line-height: calc(1.5em + 12px); - } - - .show-tokens { - .token:not(:first-child) { - margin-left: 1px; - } - - .token:empty { - background: red; - } - - .token:empty::before { - color: white; - content: 'empty'; - font-style: italic; - text-shadow: black 0 0 .3em; - } - - .token { - border: 1px solid; - padding: 6px 1px; - } - - .token > .token { - padding: 4px 1px; - } - - .token > .token > .token { - padding: 2px 1px; - } - - .token > .token > .token > .token { - padding: 0 1px; - } - - .token > .token > .token > .token > .token { - border: none; - border-left: 1px solid; - border-right: 1px solid; - padding: 0; - margin: 0 1px; - } - } - - #options { - position: relative; - } - - .link-wrapper { - position: absolute; - top: 0; - right: 0; - background-color: white; - - .hidden-wrapper { - display: none; - } - - &:hover { - top: -.5em; - right: -1em; - width: 300px; - padding: .5em 1em; - outline: 1px solid #888; - - .hidden-wrapper { - display: block; - } - } - - input { - width: 100%; - box-sizing: border-box; - } - - button { - border: none; - background: none; - font: inherit; - text-decoration: underline; - cursor: pointer; - } - } -} - -[data-inputpath^="download"] { - form label { - display: block; - padding: .2em; - padding-left: 1.9em; - page-break-inside: avoid; - break-inside: avoid; - - .name { - margin-right: .3em; - } - - a.owner { - margin-left: 0; - hyphens: none; - } - - input { - margin-right: .7em; - margin-left: -1.7em; - } - } - - - form > p:first-of-type > label { - font-size: 150%; - - input { - vertical-align: .3em; - } - } - - - .filesize:empty { - display: none; - } - - #components { - overflow: hidden; - } - - section.options { - width: 33.3%; - width: calc(100% / 3); - float: left; - - label[data-id^="check-all-"] { - border-bottom: 1px solid #aaa; - padding-bottom: 1em; - margin-bottom: 1em; - } - } - - section.options#category-languages, - section.options#category-plugins { - width: 100%; - float: none; - column-count: 3; - padding-top: 2em; - overflow: visible; - - label { - break-inside: avoid; - } - - > h1 { - margin-top: 0; - column-span: all; - } - - label[data-id="javascript"] { - border-bottom: 1px solid #aaa; - padding-bottom: 1em; - margin-bottom: 1em; - } - } - - - section.options#category-themes { - width: 66.6%; - width: calc(100% * 2/3); - column-count: 2; - overflow: visible; - float: none; - - > h1 { - column-span: all; - } - } - - - section.download { - width: 50%; - float: left; - } - - #download { - overflow: hidden; - padding: .3em; - .error { - color: #B61500; - display: none; - } - pre { - height: 20em; - } - .download-button { - cursor: pointer; - width: 100%; - } - - } - - #download-js .download-button { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - - #download-css .download-button { - background-color: #dc9e23; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } -} - -/* Decorate only the first link in headings */ -section :is(h1, h2, h3)[id] { - a:not(:first-of-type) { - text-decoration: revert; - - &::before { - display: none; - } - } -} diff --git a/data/prism.js b/data/prism.js new file mode 100644 index 00000000..ac18fc2f --- /dev/null +++ b/data/prism.js @@ -0,0 +1,7 @@ +import components from "../docs/components.json" with { type: "json" }; +import file_sizes from "../docs/file-sizes.json" with { type: "json" }; + +// Every category keeps a `meta` entry among its components +let { meta, ...languages } = components.languages; + +export default { components, file_sizes, languages }; diff --git a/assets/download.js b/docs/assets/download.js similarity index 99% rename from assets/download.js rename to docs/assets/download.js index a38d1c76..ff9d6997 100644 --- a/assets/download.js +++ b/docs/assets/download.js @@ -2,6 +2,7 @@ * Manage downloads */ +import Prism from "./prism.js"; import { getFileContents, toArray } from "./util.js"; let components = await (await fetch("/components.json")).json(); @@ -486,6 +487,7 @@ function buildCode (promises) { * @returns {Promise} */ async function getVersion () { + // FIXME: Drop “v2” from the host when Prism v2 is released let packageJSON = await getFileContents("https://v2.dev.prismjs.com/package.json"); return JSON.parse(packageJSON).version; } diff --git a/assets/examples.js b/docs/assets/examples.js similarity index 81% rename from assets/examples.js rename to docs/assets/examples.js index 1acae9c8..babc5f99 100644 --- a/assets/examples.js +++ b/docs/assets/examples.js @@ -2,6 +2,7 @@ * Manage examples */ +import Prism from "./prism.js"; import { toArray, getFileContents } from "./util.js"; let components = await (await fetch("/components.json")).json(); @@ -22,7 +23,7 @@ async function fileExists (filepath) { // on localhost: The missing example might be for a new language if (location.hostname === "localhost" || location.hostname === "127.0.0.1") { try { - await getFileContents(filepath); + await getFileContents("/" + filepath); return true; } catch (error) { @@ -34,7 +35,8 @@ async function fileExists (filepath) { function buildContentsHeader (id) { let language = languages[id]; - let header = `

${language.title}

`; + // h2: the page already has its own

, and this sits inside a section of it + let header = `

${language.title}

`; if (language.aliasTitles) { let alias = Object.keys(language.aliasTitles); header += "

To use this language, use one of the following classes:

"; @@ -62,7 +64,7 @@ function buildContentsHeader (id) { } if (deps.length) { header += "

"; - header += `Dependencies:`; + header += `Dependencies:`; header += " This component"; if (deps.length === 1) { header += ` ${deps[0]}.`; @@ -83,22 +85,21 @@ function buildContentsHeader (id) { async function update (id) { let language = languages[id]; if (language.enabled) { - let contents = await getFileContents(language.examplesPath); - examples[id].innerHTML = buildContentsHeader(id) + contents; + // Leading slash: examplesPath is a repo path, and this page is served from /examples/ + let contents = await getFileContents("/" + language.examplesPath); /** @type {HTMLElement} */ let container = examples[id]; container.innerHTML = buildContentsHeader(id) + contents; - // the current language might be an extension of a language - // so to be safe, we explicitly add a dependency to the current language - container.querySelectorAll("pre").forEach( - /** @param {HTMLElement} pre */ pre => { - let dependencies = (pre.getAttribute("data-dependencies") || "").trim(); - dependencies = dependencies ? dependencies + "," + id : id; - pre.setAttribute("data-dependencies", dependencies); - }, - ); + for (let pre of container.querySelectorAll("pre")) { + // An example file may name its own language, as OpenCL's does with cpp + let language = pre.className.match(/language-([\w-]+)/)?.[1] ?? id; + + // The language might extend another, so depend on the current one explicitly + pre.dataset.dependencies = [pre.dataset.dependencies, id].filter(Boolean).join(","); + pre.className = `language-${language}`; + } Prism.highlightAll({ root: container }); } diff --git a/assets/faq.js b/docs/assets/faq.js similarity index 100% rename from assets/faq.js rename to docs/assets/faq.js diff --git a/assets/img/failures/coy-overlap.png b/docs/assets/img/failures/coy-overlap.png similarity index 100% rename from assets/img/failures/coy-overlap.png rename to docs/assets/img/failures/coy-overlap.png diff --git a/assets/img/logo-ala.png b/docs/assets/img/logo-ala.png similarity index 100% rename from assets/img/logo-ala.png rename to docs/assets/img/logo-ala.png diff --git a/assets/img/logo-css-tricks.png b/docs/assets/img/logo-css-tricks.png similarity index 100% rename from assets/img/logo-css-tricks.png rename to docs/assets/img/logo-css-tricks.png diff --git a/assets/img/logo-drupal.png b/docs/assets/img/logo-drupal.png similarity index 100% rename from assets/img/logo-drupal.png rename to docs/assets/img/logo-drupal.png diff --git a/assets/img/logo-mdn.png b/docs/assets/img/logo-mdn.png similarity index 100% rename from assets/img/logo-mdn.png rename to docs/assets/img/logo-mdn.png diff --git a/assets/img/logo-mysql.png b/docs/assets/img/logo-mysql.png similarity index 100% rename from assets/img/logo-mysql.png rename to docs/assets/img/logo-mysql.png diff --git a/assets/img/logo-react.png b/docs/assets/img/logo-react.png similarity index 100% rename from assets/img/logo-react.png rename to docs/assets/img/logo-react.png diff --git a/assets/img/logo-sitepoint.png b/docs/assets/img/logo-sitepoint.png similarity index 100% rename from assets/img/logo-sitepoint.png rename to docs/assets/img/logo-sitepoint.png diff --git a/assets/img/logo-smashing.png b/docs/assets/img/logo-smashing.png similarity index 100% rename from assets/img/logo-smashing.png rename to docs/assets/img/logo-smashing.png diff --git a/assets/img/logo-stripe.png b/docs/assets/img/logo-stripe.png similarity index 100% rename from assets/img/logo-stripe.png rename to docs/assets/img/logo-stripe.png diff --git a/assets/img/spectrum.png b/docs/assets/img/spectrum.png similarity index 100% rename from assets/img/spectrum.png rename to docs/assets/img/spectrum.png diff --git a/docs/assets/prism.js b/docs/assets/prism.js new file mode 100644 index 00000000..201ff1ab --- /dev/null +++ b/docs/assets/prism.js @@ -0,0 +1,19 @@ +/** + * The one Prism instance the site runs on. + */ +// FIXME: Drop “v2” from the host when Prism v2 is released +import Prism from "https://v2.dev.prismjs.com/dist/index.js"; +// Pages use

 without loading the plugin themselves
+import "/plugins/file-highlight.js";
+
+// Core waits for the document only when loaded by a deferred classic 
+
+If you’re still not sold, you can [view more examples](/examples/) or [try it out for yourself](/test/).
 
 
 
@@ -48,17 +88,17 @@ If you’re still not sold, you can [view more examples](examples.html) or [try
 - **Only 2KB** minified & gzipped (core). Each language definition adds roughly 300-500 bytes.
 - Encourages good author practices. Other highlighters encourage or even force you to use elements that are semantically wrong, like `
` (on its own) or `
@@ -135,9 +175,9 @@ window.Prism.manual = true;
 
 ```
 
-## Usage with CDNs { #basic-usage-cdn }
+# Usage with CDNs { #basic-usage-cdn }
 
-In combination with CDNs, we recommend using the [Autoloader plugin](plugins/autoloader) which automatically loads languages when necessary.
+In combination with CDNs, we recommend using the [Autoloader plugin](/plugins/autoloader) which automatically loads languages when necessary.
 
 The setup of the Autoloader, will look like the following. You can also add your own themes of course.
 
@@ -145,12 +185,12 @@ The setup of the Autoloader, will look like the following. You can also add your
 <html>
 <head>
 	...
-	<link href="https://{{cdn}}/prismjs@v1.x/themes/prism.css" rel="stylesheet" />
+	<link href="https://{% raw %}{{cdn}}{% endraw %}/prismjs@v1.x/themes/prism.css" rel="stylesheet" />
 </head>
 <body>
 	...
-	<script src="https://{{cdn}}/prismjs@v1.x/components/prism-core.min.js"></script>
-<script src="https://{{cdn}}/prismjs@v1.x/plugins/autoloader/prism-autoloader.min.js"></script>
+	<script src="https://{% raw %}{{cdn}}{% endraw %}/prismjs@v1.x/components/prism-core.min.js"></script>
+<script src="https://{% raw %}{{cdn}}{% endraw %}/prismjs@v1.x/plugins/autoloader/prism-autoloader.min.js"></script>
 </body>
 </html>
@@ -158,7 +198,7 @@ Please note that links in the above code sample serve as placeholders. You have CDNs which provide PrismJS are e.g. [cdnjs](https://cdnjs.com/libraries/prism), [jsDelivr](https://www.jsdelivr.com/package/npm/prismjs), and [UNPKG](https://unpkg.com/browse/prismjs@1/). -## Usage with Webpack, Browserify, & Other Bundlers { #basic-usage-bundlers } +# Usage with Webpack, Browserify, & Other Bundlers { #basic-usage-bundlers } If you want to use Prism with a bundler, install Prism with `npm`: @@ -169,25 +209,25 @@ $ npm install prismjs You can then `import` into your bundle: ```js -import Prism from 'prismjs'; +import Prism from "prismjs"; ``` To make it easy to configure your Prism instance with only the languages and plugins you need, use the babel plugin, [babel-plugin-prismjs](https://github.com/mAAdhaTTah/babel-plugin-prismjs). This will allow you to load the minimum number of languages and plugins to satisfy your needs. See that plugin's documentation for configuration details. -## Usage with Node { #basic-usage-node } +# Usage with Node { #basic-usage-node } If you want to use Prism on the server or through the command line, Prism can be used with Node.js as well. This might be useful if you're trying to generate static HTML pages with highlighted code for environments that don't support browser-side JS, like [AMP pages](https://www.ampproject.org/). Example: ```js -const Prism = require('prismjs'); +const Prism = require("prismjs"); // The code snippet you want to highlight, as a string const code = `var data = 1;`; // Returns a highlighted HTML string -const html = Prism.highlight(code, Prism.languages.javascript, 'javascript'); +const html = Prism.highlight(code, Prism.languages.javascript, "javascript"); ``` Requiring `prismjs` will load the default languages: `markup`, `css`, `clike` and `javascript`. You can load more languages with the `loadLanguages()`{ .language-javascript } utility, which will automatically handle any required dependencies. @@ -195,15 +235,15 @@ Requiring `prismjs` will load the default languages: `markup`, `css`, `clike` an Example: ```js -const Prism = require('prismjs'); -const loadLanguages = require('prismjs/components/'); -loadLanguages(['haml']); +const Prism = require("prismjs"); +const loadLanguages = require("prismjs/components/"); +loadLanguages(["haml"]); // The code snippet you want to highlight, as a string const code = `= ['hi', 'there', 'reader!'].join " "`; // Returns a highlighted HTML string -const html = Prism.highlight(code, Prism.languages.haml, 'haml'); +const html = Prism.highlight(code, Prism.languages.haml, "haml"); ``` **Note**: Do _not_ use `loadLanguages()`{ .language-javascript } with Webpack or another bundler, as this will cause Webpack to include all languages and plugins. Use the babel plugin described above. @@ -216,14 +256,14 @@ const html = Prism.highlight(code, Prism.languages.haml, 'haml'); # Supported languages -This is the list of all {{ languages | length }} languages currently supported by Prism, with their corresponding alias, to use in place of `xxxx` in the `language-xxxx` (or `lang-xxxx`) class: +This is the list of all {{ prism.languages | length }} languages currently supported by Prism, with their corresponding alias, to use in place of `xxxx` in the `language-xxxx` (or `lang-xxxx`) class:
    - {% for id, language in languages -%} + {% for id, language in prism.languages -%}
  • - {{ language.title }} — - {%- for alias in language.alias -%} - {{ alias }}{{ ", " if not loop.last }} + {{ language.title }} —{{ id }} + {%- for alias, title in language.aliasTitles -%} + , {{ alias }} {%- endfor %}
  • {% endfor %} @@ -243,15 +283,15 @@ Plugins are additional scripts (and CSS code) that extend Prism’s functionalit {% for plugin in collections.plugin -%} {%- set meta = plugin.data -%}
  • - {{ meta.title | md }} + {{ meta.title | md }}
    {{ meta.description | md }}
  • {% endfor -%}
-No assembly required to use them. Just select them in the [download](download.html) page. +No assembly required to use them. Just select them in the [download](/download/) page. -It’s very easy to [write your own Prism plugins](extending.html#writing-plugins). Did you write a plugin for Prism that you want added to this list? [Send a pull request](https://github.com/PrismJS/plugins/)! +It’s very easy to [write your own Prism plugins](/extending/#writing-plugins). Did you write a plugin for Prism that you want added to this list? [Send a pull request](https://github.com/PrismJS/plugins/)! @@ -277,11 +317,9 @@ Several tutorials have been written by members of the community to help you inte - [How To Re-Run Prism.js On AJAX Content](https://schier.co/blog/2013/01/07/how-to-re-run-prismjs-on-ajax-content.html) - [Highlight your code syntax with Prism.js](https://www.semisedlak.com/highlight-your-code-syntax-with-prismjs) - [A code snippet content element powered by Prism.js for TYPO3 CMS](https://usetypo3.com/fs-code-snippet.html) - - [Code syntax highlighting in Gutenberg, WordPress block editor](https://mkaz.blog/wordpress/code-syntax-highlighting-in-gutenberg/) - [Code Highlighting with Prism.js in Drupal](https://karlkaufmann.com/writing/technotes/code-highlighting-prism-drupal) - [Code highlighting in React using Prism.js](https://betterstack.dev/blog/code-highlighting-in-react-using-prismjs/) - - [PrismJS Tutorial | Implement Prism in HTML and React](https://itsmycode.com/prismjs-tutorial/) - Code syntax highlighting in Pug with [:highlight](https://webdiscus.github.io/pug-loader/pug-filters/highlight.html) and [:markdown](https://webdiscus.github.io/pug-loader/pug-filters/markdown.html) filters using [pug-loader](https://github.com/webdiscus/pug-loader) and Prism.js @@ -298,7 +336,6 @@ Have you written a tutorial about Prism that’s not already included here? Send - Special thanks to [Michael Schmidt](https://github.com/RunDevelopment), [James DiGioia](https://github.com/mAAdhaTTah), [Golmote](https://github.com/Golmote) and [Jannik Zschiesche](https://github.com/apfelbox) for their contributions and for being **amazing maintainers**. Prism would not have been able to keep up without their help. - To [Roman Komarov](https://twitter.com/kizmarh) for his contributions, feedback and testing. - To [Zachary Forrest](https://twitter.com/zdfs) for [coming up with the name “Prism”](https://twitter.com/zdfs/statuses/217834980871639041). -- To [stellarr](https://stellarr.deviantart.com/) for the [spectrum background](https://stellarr.deviantart.com/art/Spectra-Wallpaper-Pack-97785901) used on this page. - To [Jason Hobbs](https://twitter.com/thecodezombie) for [encouraging me](https://twitter.com/thecodezombie/status/217663703825399809) to release this script as standalone. diff --git a/known-failures.md b/docs/known-failures.md similarity index 98% rename from known-failures.md rename to docs/known-failures.md index 1ca2bb5f..da408e61 100644 --- a/known-failures.md +++ b/docs/known-failures.md @@ -2,7 +2,6 @@ tagline: A list of rare edge cases where Prism highlights code incorrectly. back_to_top: true body_classes: language-none -resources: /plugins/autoloader.js { type="module" } --- There are certain edge cases where Prism will fail. There are always such cases in every regex-based syntax highlighter. @@ -459,7 +458,7 @@ Some of our themes are not compatible with certain layouts. Coy's shadows and background might not wrap around the code correctly if combined with float of flexbox layouts. -![](assets/img/failures/coy-overlap.png) +![](/assets/img/failures/coy-overlap.png) ## Workarounds diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 00000000..fa8c5073 --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,20 @@ +--- +title: Plugins +tagline: Additional scripts and styles that extend Prism’s functionality. Many are official, released separately to keep Prism core small for those who don’t need them. +permalink: /plugins/ +parentOf: plugin +--- + +
    + {% for plugin in collections.plugin -%} + {%- set meta = plugin.data -%} +
  • + {{ meta.title | md }} +
    {{ meta.description | md }}
    +
  • + {% endfor -%} +
+ +No assembly required to use them. Just select them in the [download](/download/) page. + +It’s very easy to [write your own Prism plugins](/extending/#writing-plugins). Did you write a plugin for Prism that you want added to this list? [Send a pull request](https://github.com/PrismJS/plugins/)! diff --git a/docs/plugins/plugins.11tydata.js b/docs/plugins/plugins.11tydata.js new file mode 100644 index 00000000..5205ac61 --- /dev/null +++ b/docs/plugins/plugins.11tydata.js @@ -0,0 +1,25 @@ +export default { + tags: ["plugin"], + eleventyComputed: { + // The directory postinstall copied the page into + id: data => data.page.filePathStem.split("/")[2], + + // The plugin comes before the page's own demo.js, which builds on it + resources: data => [ + `/plugins/${data.id}.js { type="module" }`, + ...(data.noCSS ? [] : [`/plugins/${data.id}.css`]), + ...[data.resources ?? []].flat(), + ], + + // A README is the plugin's page; a demo keeps the .html URL its README fetches it by + permalink: data => + data.page.fileSlug === "README" + ? data.page.filePathStem.replace(/README$/, "index.html") + : `${data.page.filePathStem}.html`, + + // These pages are copied from the Prism repo by postinstall, so that is where edits go + // FIXME: Switch to the main branch when Prism v2 is released + editLink: data => + `https://github.com/PrismJS/prism/edit/v2/src/plugins/${data.page.inputPath.split("/plugins/").pop()}`, + }, +}; diff --git a/test-suite.md b/docs/test-suite.md similarity index 99% rename from test-suite.md rename to docs/test-suite.md index 7d7bc3bd..402cd0b3 100644 --- a/test-suite.md +++ b/docs/test-suite.md @@ -1,8 +1,6 @@ --- title: Running the test suite tagline: Prism has a test suite, that ensures that the correct tokens are matched. -body_classes: language-javascript -resources: /languages/bash.js { type="module" } ---
diff --git a/test.md b/docs/test.md similarity index 85% rename from test.md rename to docs/test.md index efc0ebd7..394586dd 100644 --- a/test.md +++ b/docs/test.md @@ -2,11 +2,10 @@ title: Test drive tagline: Take Prism for a spin! resources: - - /assets/test-drive.js - - /plugins/autoloader.js { type="module" } + - /assets/test-drive.js { type="module" } + - /plugins/autoloader.js { type="module" } --- -

@@ -26,7 +25,7 @@ resources:

Language: - {% for id, language in languages -%} + {% for id, language in prism.languages -%} diff --git a/tokens.md b/docs/tokens.md similarity index 97% rename from tokens.md rename to docs/tokens.md index fcce673d..aa94d11a 100644 --- a/tokens.md +++ b/docs/tokens.md @@ -3,12 +3,11 @@ title: Prism tokens tagline: Prism identifies tokens in your code, which are in turn styled by CSS to produce the syntax highlighting. This page provides an overview of the standard tokens and corresponding examples. body_classes: language-none resources: - - /plugins/line-highlight.css - - /plugins/toolbar.css - - /plugins/line-highlight.js { type="module" } - - /plugins/toolbar.js { type="module" } - - /plugins/show-language.js { type="module" } - - /plugins/autoloader.js { type="module" } + - /plugins/line-highlight.css + - /plugins/toolbar.css + - /plugins/line-highlight.js { type="module" } + - /plugins/toolbar.js { type="module" } + - /plugins/show-language.js { type="module" } ---

diff --git a/docspire.config.js b/docspire.config.js new file mode 100644 index 00000000..81c3a0da --- /dev/null +++ b/docspire.config.js @@ -0,0 +1,97 @@ +import * as path from "path"; +import markdownItDeflist from "markdown-it-deflist"; +import landing from "docspire/plugins/landing"; +import { parse_resources, pretty_size } from "./_build/filters.js"; + +// Each page's `body_classes`, by input path. The page transform that edits can't read +// front matter, only the page's path. So a content read, which can, stores them here first. +const bodyClasses = new Map(); + +export default { + title: "Prism", + description: "A lightweight, robust, and elegant syntax highlighting library.", + logo: "/assets/logo.svg", + icon: "/assets/logo.svg", + repo: "https://github.com/PrismJS/prism", + editLink: { + pattern: "https://github.com/PrismJS/website/edit/main/:path", + }, + deleteOutput: true, + // markdown-it-prism highlights with Prism v1. Prism v2 highlights in the browser instead. + md: { prism: false }, + plugins: [ + landing, + { + url: import.meta.url, + scripts: "/assets/prism.js", + slotted: { "content.start": "page-title", "content.end": "resources" }, + plugin (config) { + // 11ty skips gitignored files, and the plugin docs are generated. + config.setUseGitIgnore(false); + + config.addPageTransform(function (tree) { + let bodyClass = bodyClasses.get(this.inputPath); + + tree.match("body", node => { + node.attrs ??= {}; + + // Prism reads the language it inherits off an ancestor + if (bodyClass) { + node.attrs.class = [node.attrs.class, bodyClass] + .filter(Boolean) + .join(" "); + } + + // What brand.css hooks its page-specific rules on: the input path, as in + // "plugins/toolbar/README.md". The stem is relative to the input directory + node.attrs["data-inputpath"] = + this.page.filePathStem.slice(1) + path.extname(this.inputPath); + + return node; + }); + }); + + // Netlify reads _headers at the publish root, and it lives outside docs/ + config.addPassthroughCopy({ _headers: "_headers" }); + + // The html-relative passthrough that ships the rest skips root-relative URLs + config.addPassthroughCopy({ "docs/assets": "assets" }); + + // Fetched at runtime, so nothing else copies them: 11ty reads .json as data, + // and .html is not a template format here + config.addPassthroughCopy({ + "docs/components.json": "components.json", + "docs/file-sizes.json": "file-sizes.json", + // Outside docs/: the examples page finds them by this path in the repo's tree + examples: "examples", + }); + + config.addFilter("pretty_size", pretty_size); + config.addFilter("parse_resources", parse_resources); + + config.amendLibrary("md", md => { + md.use(markdownItDeflist); + + // A fence's attributes go on the
, where Prism's plugins read them:
+					// ```html { data-line="2" } → 

+					let fence = md.renderer.rules.fence;
+					md.renderer.rules.fence = (tokens, index, options, env, renderer) => {
+						let token = tokens[index];
+						let attrs = renderer.renderAttrs(token);
+						token.attrs = null;
+
+						return fence(tokens, index, options, env, renderer).replace(
+							"=12"
+				"node": ">=0.12"
 			},
 			"funding": {
-				"url": "https://github.com/sponsors/jonschlinkert"
+				"url": "https://github.com/fb55/entities?sponsor=1"
 			}
 		},
 		"node_modules/@11ty/lodash-custom": {
@@ -218,22 +215,637 @@
 				"slash": "^3.0.0"
 			},
 			"engines": {
-				"node": ">=18"
+				"node": ">=18"
+			}
+		},
+		"node_modules/@babel/code-frame": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+			"integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-validator-identifier": "^7.29.7",
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.1.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/compat-data": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+			"integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/core": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+			"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/code-frame": "^7.29.7",
+				"@babel/generator": "^7.29.7",
+				"@babel/helper-compilation-targets": "^7.29.7",
+				"@babel/helper-module-transforms": "^7.29.7",
+				"@babel/helpers": "^7.29.7",
+				"@babel/parser": "^7.29.7",
+				"@babel/template": "^7.29.7",
+				"@babel/traverse": "^7.29.7",
+				"@babel/types": "^7.29.7",
+				"@jridgewell/remapping": "^2.3.5",
+				"convert-source-map": "^2.0.0",
+				"debug": "^4.1.0",
+				"gensync": "^1.0.0-beta.2",
+				"json5": "^2.2.3",
+				"semver": "^6.3.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/babel"
+			}
+		},
+		"node_modules/@babel/core/node_modules/semver": {
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+			"dev": true,
+			"license": "ISC",
+			"bin": {
+				"semver": "bin/semver.js"
+			}
+		},
+		"node_modules/@babel/generator": {
+			"version": "7.29.8",
+			"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+			"integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/parser": "^7.29.8",
+				"@babel/types": "^7.29.8",
+				"@jridgewell/gen-mapping": "^0.3.12",
+				"@jridgewell/trace-mapping": "^0.3.28",
+				"jsesc": "^3.0.2"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-annotate-as-pure": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+			"integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-compilation-targets": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+			"integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/compat-data": "^7.29.7",
+				"@babel/helper-validator-option": "^7.29.7",
+				"browserslist": "^4.24.0",
+				"lru-cache": "^5.1.1",
+				"semver": "^6.3.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+			"dev": true,
+			"license": "ISC",
+			"bin": {
+				"semver": "bin/semver.js"
+			}
+		},
+		"node_modules/@babel/helper-create-class-features-plugin": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
+			"integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-annotate-as-pure": "^7.29.7",
+				"@babel/helper-member-expression-to-functions": "^7.29.7",
+				"@babel/helper-optimise-call-expression": "^7.29.7",
+				"@babel/helper-replace-supers": "^7.29.7",
+				"@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+				"@babel/traverse": "^7.29.7",
+				"semver": "^6.3.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0"
+			}
+		},
+		"node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+			"dev": true,
+			"license": "ISC",
+			"bin": {
+				"semver": "bin/semver.js"
+			}
+		},
+		"node_modules/@babel/helper-globals": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+			"integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-member-expression-to-functions": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
+			"integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/traverse": "^7.29.7",
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-module-imports": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+			"integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/traverse": "^7.29.7",
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-module-transforms": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+			"integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-module-imports": "^7.29.7",
+				"@babel/helper-validator-identifier": "^7.29.7",
+				"@babel/traverse": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0"
+			}
+		},
+		"node_modules/@babel/helper-optimise-call-expression": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
+			"integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-plugin-utils": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+			"integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-replace-supers": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
+			"integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-member-expression-to-functions": "^7.29.7",
+				"@babel/helper-optimise-call-expression": "^7.29.7",
+				"@babel/traverse": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0"
+			}
+		},
+		"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
+			"integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/traverse": "^7.29.7",
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-string-parser": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+			"integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-validator-identifier": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+			"integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-validator-option": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+			"integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helpers": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+			"integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/template": "^7.29.7",
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/parser": {
+			"version": "7.29.9",
+			"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz",
+			"integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/types": "^7.29.8"
+			},
+			"bin": {
+				"parser": "bin/babel-parser.js"
+			},
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@babel/plugin-syntax-import-attributes": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz",
+			"integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-plugin-utils": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0-0"
+			}
+		},
+		"node_modules/@babel/plugin-syntax-jsx": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+			"integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-plugin-utils": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0-0"
+			}
+		},
+		"node_modules/@babel/plugin-syntax-typescript": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+			"integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-plugin-utils": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0-0"
+			}
+		},
+		"node_modules/@babel/plugin-transform-modules-commonjs": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz",
+			"integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-module-transforms": "^7.29.7",
+				"@babel/helper-plugin-utils": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0-0"
+			}
+		},
+		"node_modules/@babel/plugin-transform-typescript": {
+			"version": "7.29.9",
+			"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.9.tgz",
+			"integrity": "sha512-FFwIwzU+7SCOuxxV4YtJql6T9981ZVTm+FHO5GhVsRqCTdy0WwrEZh3l42ARpXruJUDGOptdduHW6Zr7pNPLNg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-annotate-as-pure": "^7.29.7",
+				"@babel/helper-create-class-features-plugin": "^7.29.7",
+				"@babel/helper-plugin-utils": "^7.29.7",
+				"@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+				"@babel/plugin-syntax-typescript": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0-0"
+			}
+		},
+		"node_modules/@babel/preset-typescript": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz",
+			"integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-plugin-utils": "^7.29.7",
+				"@babel/helper-validator-option": "^7.29.7",
+				"@babel/plugin-syntax-jsx": "^7.29.7",
+				"@babel/plugin-transform-modules-commonjs": "^7.29.7",
+				"@babel/plugin-transform-typescript": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			},
+			"peerDependencies": {
+				"@babel/core": "^7.0.0-0"
+			}
+		},
+		"node_modules/@babel/template": {
+			"version": "7.29.7",
+			"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+			"integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/code-frame": "^7.29.7",
+				"@babel/parser": "^7.29.7",
+				"@babel/types": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/traverse": {
+			"version": "7.29.8",
+			"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+			"integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/code-frame": "^7.29.7",
+				"@babel/generator": "^7.29.8",
+				"@babel/helper-globals": "^7.29.7",
+				"@babel/parser": "^7.29.8",
+				"@babel/template": "^7.29.7",
+				"@babel/types": "^7.29.8",
+				"debug": "^4.3.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/types": {
+			"version": "7.29.8",
+			"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+			"integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@babel/helper-string-parser": "^7.29.7",
+				"@babel/helper-validator-identifier": "^7.29.7"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@gerrit0/mini-shiki": {
+			"version": "3.23.0",
+			"resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz",
+			"integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@shikijs/engine-oniguruma": "^3.23.0",
+				"@shikijs/langs": "^3.23.0",
+				"@shikijs/themes": "^3.23.0",
+				"@shikijs/types": "^3.23.0",
+				"@shikijs/vscode-textmate": "^10.0.2"
+			}
+		},
+		"node_modules/@jridgewell/gen-mapping": {
+			"version": "0.3.13",
+			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+			"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/sourcemap-codec": "^1.5.0",
+				"@jridgewell/trace-mapping": "^0.3.24"
+			}
+		},
+		"node_modules/@jridgewell/remapping": {
+			"version": "2.3.5",
+			"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+			"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/gen-mapping": "^0.3.5",
+				"@jridgewell/trace-mapping": "^0.3.24"
+			}
+		},
+		"node_modules/@jridgewell/resolve-uri": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+			"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/sourcemap-codec": {
+			"version": "1.6.0",
+			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+			"integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@jridgewell/trace-mapping": {
+			"version": "0.3.31",
+			"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+			"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/resolve-uri": "^3.1.0",
+				"@jridgewell/sourcemap-codec": "^1.4.14"
+			}
+		},
+		"node_modules/@jspm/fetch": {
+			"version": "0.1.0",
+			"resolved": "https://registry.npmjs.org/@jspm/fetch/-/fetch-0.1.0.tgz",
+			"integrity": "sha512-R749VLq+2zRvaYOrBz8JQaeahWmjOQH9tnvp6896WHhcsFwV7bJOEXiz56EMi34DxJZTLdFUFkrtjOC5Pw3zXQ==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@jspm/generator": {
+			"version": "2.16.3",
+			"resolved": "https://registry.npmjs.org/@jspm/generator/-/generator-2.16.3.tgz",
+			"integrity": "sha512-OmtKanpTl2aVhVq2sOFIm4zBtPABASA/TmOrsJMcaR8zJnwVBo6QZiS+OuEM95c/JXGiLehKYQ6JBLCqQ/ROyg==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"dependencies": {
+				"@babel/core": "^7.24.7",
+				"@babel/plugin-syntax-import-attributes": "^7.24.7",
+				"@babel/preset-typescript": "^7.24.7",
+				"@jspm/fetch": "^0.1.0",
+				"@jspm/import-map": "^1.5.0",
+				"es-module-lexer": "^2.1.0",
+				"minimatch": "^10.0.1",
+				"pako": "^2.1.0",
+				"sver": "^2.0.1",
+				"tar-stream": "^3.1.6"
+			}
+		},
+		"node_modules/@jspm/generator/node_modules/balanced-match": {
+			"version": "4.0.4",
+			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+			"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": "18 || 20 || >=22"
+			}
+		},
+		"node_modules/@jspm/generator/node_modules/brace-expansion": {
+			"version": "5.0.12",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
+			"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"balanced-match": "^4.0.2"
+			},
+			"engines": {
+				"node": "20 || >=22"
+			}
+		},
+		"node_modules/@jspm/generator/node_modules/minimatch": {
+			"version": "10.2.6",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+			"integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+			"dev": true,
+			"license": "BlueOak-1.0.0",
+			"dependencies": {
+				"brace-expansion": "^5.0.8"
+			},
+			"engines": {
+				"node": "18 || 20 || >=22"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/isaacs"
 			}
 		},
-		"node_modules/@gerrit0/mini-shiki": {
-			"version": "3.23.0",
-			"resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz",
-			"integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==",
+		"node_modules/@jspm/import-map": {
+			"version": "1.5.0",
+			"resolved": "https://registry.npmjs.org/@jspm/import-map/-/import-map-1.5.0.tgz",
+			"integrity": "sha512-wvjrSEB2MCrpicc/tA0mYEsQ1Jgusnz+4ALwbp5IqGFcnxcTamU/VaVbodmEXFFg4GaPmC2LupUl7Bks6nWOhg==",
 			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"@shikijs/engine-oniguruma": "^3.23.0",
-				"@shikijs/langs": "^3.23.0",
-				"@shikijs/themes": "^3.23.0",
-				"@shikijs/types": "^3.23.0",
-				"@shikijs/vscode-textmate": "^10.0.2"
-			}
+			"license": "MIT"
+		},
+		"node_modules/@jspm/overrides": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@jspm/overrides/-/overrides-1.0.0.tgz",
+			"integrity": "sha512-mpEyGz2Edd9fNioCw1sO2t+ngKXF5e0BOQgBTecKPu+bHue52xrqP0qYFgd+F8TFia8vsSTILkVGGQOFLIikxw==",
+			"dev": true,
+			"license": "Apache-2.0"
+		},
+		"node_modules/@nudeui/color": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/@nudeui/color/-/color-0.0.1.tgz",
+			"integrity": "sha512-CDZHWsa+uq8WXR9za1kToDmJ2EZWj5xgKemkHdxPOSkXkB/VVo3hINscneUSVpWNMFvWVDtX6eyVaVhpNzR8wg==",
+			"dev": true,
+			"license": "MIT"
 		},
 		"node_modules/@shikijs/engine-oniguruma": {
 			"version": "3.23.0",
@@ -328,29 +940,29 @@
 			}
 		},
 		"node_modules/@types/linkify-it": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
-			"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+			"version": "3.0.5",
+			"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz",
+			"integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==",
 			"dev": true,
 			"license": "MIT",
 			"peer": true
 		},
 		"node_modules/@types/markdown-it": {
-			"version": "14.1.2",
-			"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
-			"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+			"version": "13.0.9",
+			"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.9.tgz",
+			"integrity": "sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==",
 			"dev": true,
 			"license": "MIT",
 			"peer": true,
 			"dependencies": {
-				"@types/linkify-it": "^5",
-				"@types/mdurl": "^2"
+				"@types/linkify-it": "^3",
+				"@types/mdurl": "^1"
 			}
 		},
 		"node_modules/@types/mdurl": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
-			"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz",
+			"integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==",
 			"dev": true,
 			"license": "MIT",
 			"peer": true
@@ -383,9 +995,9 @@
 			}
 		},
 		"node_modules/acorn-walk": {
-			"version": "8.3.4",
-			"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
-			"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+			"version": "8.3.5",
+			"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
+			"integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
@@ -409,6 +1021,19 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/anymatch/node_modules/picomatch": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+			"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
 		"node_modules/argparse": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -423,6 +1048,21 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/b4a": {
+			"version": "1.9.0",
+			"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.9.0.tgz",
+			"integrity": "sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"peerDependencies": {
+				"react-native-b4a": "*"
+			},
+			"peerDependenciesMeta": {
+				"react-native-b4a": {
+					"optional": true
+				}
+			}
+		},
 		"node_modules/balanced-match": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -430,10 +1070,108 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/bare-events": {
+			"version": "2.9.2",
+			"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.2.tgz",
+			"integrity": "sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"peerDependencies": {
+				"bare-abort-controller": "*"
+			},
+			"peerDependenciesMeta": {
+				"bare-abort-controller": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/bare-fs": {
+			"version": "4.8.1",
+			"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.1.tgz",
+			"integrity": "sha512-N1nnXdHZAOSstz0XiHikGS4HGMH4CnSwhqWdGQQMqqdvp4Jybm9sE3R1WVnpWVd4SFkc8ryPDBLViNLwiEqECg==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"dependencies": {
+				"bare-events": "^2.5.4",
+				"bare-path": "^3.0.0",
+				"bare-stream": "^2.6.4",
+				"bare-url": "^2.2.2",
+				"fast-fifo": "^1.3.2"
+			},
+			"engines": {
+				"bare": ">=1.28.0"
+			},
+			"peerDependencies": {
+				"bare-buffer": "*"
+			},
+			"peerDependenciesMeta": {
+				"bare-buffer": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/bare-path": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.2.tgz",
+			"integrity": "sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw==",
+			"dev": true,
+			"license": "Apache-2.0"
+		},
+		"node_modules/bare-stream": {
+			"version": "2.13.4",
+			"resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.4.tgz",
+			"integrity": "sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"dependencies": {
+				"b4a": "^1.8.1",
+				"streamx": "^2.25.0",
+				"teex": "^1.0.1"
+			},
+			"peerDependencies": {
+				"bare-abort-controller": "*",
+				"bare-buffer": "*",
+				"bare-events": "*"
+			},
+			"peerDependenciesMeta": {
+				"bare-abort-controller": {
+					"optional": true
+				},
+				"bare-buffer": {
+					"optional": true
+				},
+				"bare-events": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/bare-url": {
+			"version": "2.5.4",
+			"resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.4.tgz",
+			"integrity": "sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"dependencies": {
+				"bare-path": "^3.0.0"
+			}
+		},
+		"node_modules/baseline-browser-mapping": {
+			"version": "2.11.25",
+			"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.25.tgz",
+			"integrity": "sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"bin": {
+				"baseline-browser-mapping": "dist/cli.cjs"
+			},
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
 		"node_modules/bcp-47": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz",
-			"integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==",
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.1.tgz",
+			"integrity": "sha512-KLw+H/gd2p4zly1X7Yh/qziuyae5/w/QFnvTng9eZL5fvszL7Whl3MBoWF8yxL7ksUjBfOD+OxkytiqbBpG+Fw==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
@@ -485,12 +1223,12 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/boolbase": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
-			"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+		"node_modules/blissful-hooks": {
+			"version": "0.0.2",
+			"resolved": "https://registry.npmjs.org/blissful-hooks/-/blissful-hooks-0.0.2.tgz",
+			"integrity": "sha512-kQ0Ixlf79zdOS8X2hmvtvjYB4EM55tS6leM6MM0CcLZ3wmYKPsSjmnQgrXSOt3nVCjpeIcZWxouYmcn/8jxVnw==",
 			"dev": true,
-			"license": "ISC"
+			"license": "MIT"
 		},
 		"node_modules/brace-expansion": {
 			"version": "1.1.21",
@@ -516,200 +1254,73 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/camelcase": {
-			"version": "8.0.0",
-			"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
-			"integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=16"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
-			}
-		},
-		"node_modules/cheerio": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
-			"integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"cheerio-select": "^2.1.0",
-				"dom-serializer": "^2.0.0",
-				"domhandler": "^5.0.3",
-				"domutils": "^3.1.0",
-				"encoding-sniffer": "^0.2.0",
-				"htmlparser2": "^9.1.0",
-				"parse5": "^7.1.2",
-				"parse5-htmlparser2-tree-adapter": "^7.0.0",
-				"parse5-parser-stream": "^7.1.2",
-				"undici": "^6.19.5",
-				"whatwg-mimetype": "^4.0.0"
-			},
-			"engines": {
-				"node": ">=18.17"
-			},
-			"funding": {
-				"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
-			}
-		},
-		"node_modules/cheerio-select": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
-			"integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"boolbase": "^1.0.0",
-				"css-select": "^5.1.0",
-				"css-what": "^6.1.0",
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.3",
-				"domutils": "^3.0.1"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/fb55"
-			}
-		},
-		"node_modules/cheerio-select/node_modules/dom-serializer": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
-			"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+		"node_modules/browserslist": {
+			"version": "4.29.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.0.tgz",
+			"integrity": "sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==",
 			"dev": true,
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/browserslist"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/browserslist"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
 			"license": "MIT",
 			"dependencies": {
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.2",
-				"entities": "^4.2.0"
-			},
-			"funding": {
-				"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
-			}
-		},
-		"node_modules/cheerio-select/node_modules/domhandler": {
-			"version": "5.0.3",
-			"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
-			"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"domelementtype": "^2.3.0"
-			},
-			"engines": {
-				"node": ">= 4"
+				"baseline-browser-mapping": "^2.11.23",
+				"caniuse-lite": "^1.0.30001810",
+				"electron-to-chromium": "^1.5.427",
+				"node-releases": "^2.0.55",
+				"update-browserslist-db": "^1.3.3"
 			},
-			"funding": {
-				"url": "https://github.com/fb55/domhandler?sponsor=1"
-			}
-		},
-		"node_modules/cheerio-select/node_modules/domutils": {
-			"version": "3.2.2",
-			"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
-			"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"dom-serializer": "^2.0.0",
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.3"
+			"bin": {
+				"browserslist": "cli.js"
 			},
-			"funding": {
-				"url": "https://github.com/fb55/domutils?sponsor=1"
-			}
-		},
-		"node_modules/cheerio-select/node_modules/entities": {
-			"version": "4.5.0",
-			"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-			"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
-			"dev": true,
-			"license": "BSD-2-Clause",
 			"engines": {
-				"node": ">=0.12"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/entities?sponsor=1"
+				"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
 			}
 		},
-		"node_modules/cheerio/node_modules/dom-serializer": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
-			"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+		"node_modules/camelcase": {
+			"version": "8.0.0",
+			"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
+			"integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.2",
-				"entities": "^4.2.0"
-			},
-			"funding": {
-				"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
-			}
-		},
-		"node_modules/cheerio/node_modules/domhandler": {
-			"version": "5.0.3",
-			"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
-			"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"domelementtype": "^2.3.0"
-			},
-			"engines": {
-				"node": ">= 4"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/domhandler?sponsor=1"
-			}
-		},
-		"node_modules/cheerio/node_modules/domutils": {
-			"version": "3.2.2",
-			"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
-			"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"dom-serializer": "^2.0.0",
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.3"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/domutils?sponsor=1"
-			}
-		},
-		"node_modules/cheerio/node_modules/entities": {
-			"version": "4.5.0",
-			"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-			"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
-			"dev": true,
-			"license": "BSD-2-Clause",
 			"engines": {
-				"node": ">=0.12"
+				"node": ">=16"
 			},
 			"funding": {
-				"url": "https://github.com/fb55/entities?sponsor=1"
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/cheerio/node_modules/htmlparser2": {
-			"version": "9.1.0",
-			"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
-			"integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
+		"node_modules/caniuse-lite": {
+			"version": "1.0.30001810",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+			"integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
 			"dev": true,
 			"funding": [
-				"https://github.com/fb55/htmlparser2?sponsor=1",
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/browserslist"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+				},
 				{
 					"type": "github",
-					"url": "https://github.com/sponsors/fb55"
+					"url": "https://github.com/sponsors/ai"
 				}
 			],
-			"license": "MIT",
-			"dependencies": {
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.3",
-				"domutils": "^3.1.0",
-				"entities": "^4.5.0"
-			}
+			"license": "CC-BY-4.0"
 		},
 		"node_modules/chokidar": {
 			"version": "3.6.0",
@@ -736,110 +1347,48 @@
 				"fsevents": "~2.3.2"
 			}
 		},
-		"node_modules/commander": {
-			"version": "10.0.1",
-			"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
-			"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=14"
-			}
-		},
-		"node_modules/concat-map": {
+		"node_modules/cjs-browser-shim": {
 			"version": "0.0.1",
-			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-			"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+			"resolved": "https://registry.npmjs.org/cjs-browser-shim/-/cjs-browser-shim-0.0.1.tgz",
+			"integrity": "sha512-IsxqeKjAVt1l1xRSu+7rplW6EcvN2MfGjvu4xt5y+VKySI/p64b6PvhZ5tD41vJMNiUUs2mMik4e6CkgKkFwIA==",
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/css-select": {
-			"version": "5.1.0",
-			"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
-			"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"boolbase": "^1.0.0",
-				"css-what": "^6.1.0",
-				"domhandler": "^5.0.2",
-				"domutils": "^3.0.1",
-				"nth-check": "^2.0.1"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/fb55"
-			}
-		},
-		"node_modules/css-select/node_modules/dom-serializer": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
-			"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.2",
-				"entities": "^4.2.0"
-			},
-			"funding": {
-				"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
-			}
-		},
-		"node_modules/css-select/node_modules/domhandler": {
-			"version": "5.0.3",
-			"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
-			"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+		"node_modules/commander": {
+			"version": "10.0.1",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+			"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
 			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"domelementtype": "^2.3.0"
-			},
+			"license": "MIT",
 			"engines": {
-				"node": ">= 4"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/domhandler?sponsor=1"
+				"node": ">=14"
 			}
 		},
-		"node_modules/css-select/node_modules/domutils": {
-			"version": "3.2.2",
-			"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
-			"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+		"node_modules/concat-map": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+			"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
 			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"dom-serializer": "^2.0.0",
-				"domelementtype": "^2.3.0",
-				"domhandler": "^5.0.3"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/domutils?sponsor=1"
-			}
+			"license": "MIT"
 		},
-		"node_modules/css-select/node_modules/entities": {
-			"version": "4.5.0",
-			"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-			"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+		"node_modules/convert-source-map": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+			"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
 			"dev": true,
-			"license": "BSD-2-Clause",
-			"engines": {
-				"node": ">=0.12"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/entities?sponsor=1"
-			}
+			"license": "MIT"
 		},
-		"node_modules/css-what": {
-			"version": "6.1.0",
-			"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
-			"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+		"node_modules/cssesc": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+			"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
 			"dev": true,
-			"license": "BSD-2-Clause",
-			"engines": {
-				"node": ">= 6"
+			"license": "MIT",
+			"bin": {
+				"cssesc": "bin/cssesc"
 			},
-			"funding": {
-				"url": "https://github.com/sponsors/fb55"
+			"engines": {
+				"node": ">=4"
 			}
 		},
 		"node_modules/debug": {
@@ -890,6 +1439,108 @@
 				"node": ">=0.3.1"
 			}
 		},
+		"node_modules/docspire": {
+			"version": "0.0.4",
+			"resolved": "https://registry.npmjs.org/docspire/-/docspire-0.0.4.tgz",
+			"integrity": "sha512-V8+iEcSPs3Y31X9lLmgEOBaPeGbo3zu5txEBEGQG1JHAbHz+4XCfVPBdXSaAal6Vkn34Nz64VQXHTisc+3iuGA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@11ty/eleventy": "^3.1.5",
+				"@nudeui/color": "^0.0.1",
+				"eleventy-plugin-nav": "latest",
+				"markdown-it-attrs": "^4.3.1",
+				"markdown-it-callouts": "^1.1.0",
+				"markdown-it-container": "^4.0.0",
+				"markdown-it-directive": "^2.0.6",
+				"markdown-it-prism": "^3.0.1",
+				"nudeps": "^0.4.0",
+				"postcss": "^8.5.26",
+				"postcss-selector-transform": "^0.0.1",
+				"slugify": "^1.6.9",
+				"style-observer": "^0.1.2"
+			},
+			"bin": {
+				"docspire": "src/cli.js"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/docspire"
+			},
+			"peerDependencies": {
+				"nunjucks": "latest"
+			}
+		},
+		"node_modules/docspire/node_modules/entities": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+			"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
+			"dev": true,
+			"license": "BSD-2-Clause",
+			"peer": true,
+			"engines": {
+				"node": ">=0.12"
+			},
+			"funding": {
+				"url": "https://github.com/fb55/entities?sponsor=1"
+			}
+		},
+		"node_modules/docspire/node_modules/linkify-it": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
+			"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
+			"dev": true,
+			"license": "MIT",
+			"peer": true,
+			"dependencies": {
+				"uc.micro": "^1.0.1"
+			}
+		},
+		"node_modules/docspire/node_modules/markdown-it": {
+			"version": "13.0.2",
+			"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
+			"integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
+			"dev": true,
+			"license": "MIT",
+			"peer": true,
+			"dependencies": {
+				"argparse": "^2.0.1",
+				"entities": "~3.0.1",
+				"linkify-it": "^4.0.1",
+				"mdurl": "^1.0.1",
+				"uc.micro": "^1.0.5"
+			},
+			"bin": {
+				"markdown-it": "bin/markdown-it.js"
+			}
+		},
+		"node_modules/docspire/node_modules/markdown-it-directive": {
+			"version": "2.0.6",
+			"resolved": "https://registry.npmjs.org/markdown-it-directive/-/markdown-it-directive-2.0.6.tgz",
+			"integrity": "sha512-yTjIan0I3LRMooa9uPNTs1DlcNVx/NqRjrEd3eipe286I8t3z+xzSSstrQ3OGDmKJkDSjg0rShO1t3uMN04U3Q==",
+			"dev": true,
+			"license": "MIT",
+			"peerDependencies": {
+				"@types/markdown-it": "^12.0.0 || ^13.0.0",
+				"markdown-it": "^12.0.0 || ^13.0.0"
+			}
+		},
+		"node_modules/docspire/node_modules/mdurl": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+			"integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+			"dev": true,
+			"license": "MIT",
+			"peer": true
+		},
+		"node_modules/docspire/node_modules/uc.micro": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+			"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+			"dev": true,
+			"license": "MIT",
+			"peer": true
+		},
 		"node_modules/dom-serializer": {
 			"version": "1.4.1",
 			"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -966,14 +1617,21 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/eleventy-plugin-toc": {
-			"version": "1.1.5",
-			"resolved": "https://registry.npmjs.org/eleventy-plugin-toc/-/eleventy-plugin-toc-1.1.5.tgz",
-			"integrity": "sha512-Fo5AZZSBH8CKvz0axJQA9nmnTFOflAMFrngaKER4rOz3C6oDwqxK8N+kNFepmIsieTPkrH+iREWLJ+/9j5JjUg==",
+		"node_modules/electron-to-chromium": {
+			"version": "1.5.434",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.434.tgz",
+			"integrity": "sha512-7EeFW9OLf1NN9NKQP9xdOE/XKqjxv7JDPP6AEAkHli11+Fae1OaLoNuAf13hQv1PPNtuES0pLQSPk2+fS3s8ww==",
 			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"cheerio": "^1.0.0-rc.10"
+			"license": "ISC"
+		},
+		"node_modules/eleventy-plugin-nav": {
+			"version": "0.0.5",
+			"resolved": "https://registry.npmjs.org/eleventy-plugin-nav/-/eleventy-plugin-nav-0.0.5.tgz",
+			"integrity": "sha512-YiwrJzOLVmCak62Npmll3rb4HzBP6q86VF1MItFhAzP614Efcb8Iodm+tTegnJHUY00fi1vON7kY2GPc1g37oA==",
+			"dev": true,
+			"license": "MIT",
+			"peerDependencies": {
+				"@11ty/eleventy": "^3"
 			}
 		},
 		"node_modules/encodeurl": {
@@ -986,33 +1644,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/encoding-sniffer": {
-			"version": "0.2.0",
-			"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
-			"integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"iconv-lite": "^0.6.3",
-				"whatwg-encoding": "^3.1.1"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
-			}
-		},
-		"node_modules/entities": {
-			"version": "6.0.1",
-			"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
-			"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"engines": {
-				"node": ">=0.12"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/entities?sponsor=1"
-			}
-		},
 		"node_modules/errno": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz",
@@ -1026,6 +1657,23 @@
 				"errno": "cli.js"
 			}
 		},
+		"node_modules/es-module-lexer": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz",
+			"integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/escalade": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+			"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			}
+		},
 		"node_modules/escape-html": {
 			"version": "1.0.3",
 			"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -1047,13 +1695,13 @@
 			}
 		},
 		"node_modules/esm-import-transformer": {
-			"version": "3.0.3",
-			"resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.3.tgz",
-			"integrity": "sha512-Wj9kBIA9vKZRYAQzhe229M7wmWb2f3vTu86CkszZUy2/iiVCYljXm/EkwJtWKc0vup30WHhxbm3rpkysBKczxQ==",
+			"version": "3.0.5",
+			"resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.5.tgz",
+			"integrity": "sha512-1GKLvfuMnnpI75l8c6sHoz0L3Z872xL5akGuBudgqTDPv4Vy6f2Ec7jEMKTxlqWl/3kSvNbHELeimJtnqgYniw==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"acorn": "^8.11.2"
+				"acorn": "^8.15.0"
 			}
 		},
 		"node_modules/esprima": {
@@ -1090,6 +1738,16 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/events-universal": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
+			"integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"dependencies": {
+				"bare-events": "^2.7.0"
+			}
+		},
 		"node_modules/extend-shallow": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
@@ -1103,6 +1761,31 @@
 				"node": ">=0.10.0"
 			}
 		},
+		"node_modules/fast-fifo": {
+			"version": "1.3.2",
+			"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+			"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/fdir": {
+			"version": "6.5.0",
+			"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+			"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=12.0.0"
+			},
+			"peerDependencies": {
+				"picomatch": "^3 || ^4"
+			},
+			"peerDependenciesMeta": {
+				"picomatch": {
+					"optional": true
+				}
+			}
+		},
 		"node_modules/filesize": {
 			"version": "10.1.6",
 			"resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz",
@@ -1127,18 +1810,18 @@
 			}
 		},
 		"node_modules/finalhandler": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
-			"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+			"version": "1.3.2",
+			"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
+			"integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
 				"debug": "2.6.9",
 				"encodeurl": "~2.0.0",
 				"escape-html": "~1.0.3",
-				"on-finished": "2.4.1",
+				"on-finished": "~2.4.1",
 				"parseurl": "~1.3.3",
-				"statuses": "2.0.1",
+				"statuses": "~2.0.2",
 				"unpipe": "~1.0.0"
 			},
 			"engines": {
@@ -1187,6 +1870,16 @@
 				"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
 			}
 		},
+		"node_modules/gensync": {
+			"version": "1.0.0-beta.2",
+			"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+			"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
 		"node_modules/glob-parent": {
 			"version": "5.1.2",
 			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -1227,9 +1920,9 @@
 			}
 		},
 		"node_modules/gray-matter/node_modules/js-yaml": {
-			"version": "3.14.1",
-			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-			"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+			"version": "3.15.2",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz",
+			"integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
@@ -1284,33 +1977,24 @@
 			}
 		},
 		"node_modules/http-errors": {
-			"version": "2.0.0",
-			"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
-			"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+			"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"depd": "2.0.0",
-				"inherits": "2.0.4",
-				"setprototypeof": "1.2.0",
-				"statuses": "2.0.1",
-				"toidentifier": "1.0.1"
+				"depd": "~2.0.0",
+				"inherits": "~2.0.4",
+				"setprototypeof": "~1.2.0",
+				"statuses": "~2.0.2",
+				"toidentifier": "~1.0.1"
 			},
 			"engines": {
 				"node": ">= 0.8"
-			}
-		},
-		"node_modules/iconv-lite": {
-			"version": "0.6.3",
-			"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-			"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"safer-buffer": ">= 2.1.2 < 3.0.0"
 			},
-			"engines": {
-				"node": ">=0.10.0"
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/express"
 			}
 		},
 		"node_modules/inherits": {
@@ -1421,15 +2105,22 @@
 			}
 		},
 		"node_modules/iso-639-1": {
-			"version": "3.1.5",
-			"resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz",
-			"integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==",
+			"version": "3.1.6",
+			"resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.6.tgz",
+			"integrity": "sha512-ZFar/L4ngX7wZh2QX+Fiftmuf0igWJsrJtfizrovWifF1gAWkfmRa5Z1m0LQZbm0hKCHRDYhLRSLFrSqNe4EJA==",
 			"dev": true,
 			"license": "MIT",
 			"engines": {
 				"node": ">=6.0"
 			}
 		},
+		"node_modules/js-tokens": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+			"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+			"dev": true,
+			"license": "MIT"
+		},
 		"node_modules/js-yaml": {
 			"version": "4.3.2",
 			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
@@ -1453,6 +2144,32 @@
 				"js-yaml": "bin/js-yaml.js"
 			}
 		},
+		"node_modules/jsesc": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+			"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+			"dev": true,
+			"license": "MIT",
+			"bin": {
+				"jsesc": "bin/jsesc"
+			},
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/json5": {
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+			"dev": true,
+			"license": "MIT",
+			"bin": {
+				"json5": "lib/cli.js"
+			},
+			"engines": {
+				"node": ">=6"
+			}
+		},
 		"node_modules/junk": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
@@ -1531,6 +2248,16 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/lru-cache": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+			"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+			"dev": true,
+			"license": "ISC",
+			"dependencies": {
+				"yallist": "^3.0.2"
+			}
+		},
 		"node_modules/lunr": {
 			"version": "2.3.9",
 			"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
@@ -1576,17 +2303,6 @@
 				"markdown-it": "bin/markdown-it.mjs"
 			}
 		},
-		"node_modules/markdown-it-anchor": {
-			"version": "9.2.1",
-			"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.1.tgz",
-			"integrity": "sha512-p6APiLJDFAW2GEvaavDvhIBn7jrX2jLv77NkBGgNacFTurbORYc4pyYySg/mI6mpR6cHQuAtzKtmqgQr4K8dsQ==",
-			"dev": true,
-			"license": "Unlicense",
-			"peerDependencies": {
-				"@types/markdown-it": "*",
-				"markdown-it": "*"
-			}
-		},
 		"node_modules/markdown-it-attrs": {
 			"version": "4.5.0",
 			"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.5.0.tgz",
@@ -1600,6 +2316,20 @@
 				"markdown-it": ">= 9.0.0"
 			}
 		},
+		"node_modules/markdown-it-callouts": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/markdown-it-callouts/-/markdown-it-callouts-1.1.0.tgz",
+			"integrity": "sha512-hSdLu2QjSOjAyDUfqeUZtBsbb+hcB4X7XH0eSltXPvcIQ9hBbpDAkPJirNZaTzVo3KU//HLuH31WEv2b/LyccA==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/markdown-it-container": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-4.0.0.tgz",
+			"integrity": "sha512-HaNccxUH0l7BNGYbFbjmGpf5aLHAMTinqRZQAEQbMr2cdD3z91Q6kIo1oUn1CQndkT03jat6ckrdRYuwwqLlQw==",
+			"dev": true,
+			"license": "MIT"
+		},
 		"node_modules/markdown-it-deflist": {
 			"version": "3.0.1",
 			"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-3.0.1.tgz",
@@ -1607,6 +2337,22 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/markdown-it-prism": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/markdown-it-prism/-/markdown-it-prism-3.0.1.tgz",
+			"integrity": "sha512-JVnVGW8Gjw1TUtArXApnb/paeWye9TZW0kWzV2iqIUp1bxw+Rjh0WGg/BschKxn6fd1lCfv4FebSPMlcviGYSQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"prismjs": "1.30.0"
+			},
+			"engines": {
+				"node": ">=20.0.0"
+			},
+			"peerDependencies": {
+				"markdown-it": ">=7.0.1 <15.0.0"
+			}
+		},
 		"node_modules/markdown-it/node_modules/entities": {
 			"version": "4.5.0",
 			"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -1651,16 +2397,20 @@
 			}
 		},
 		"node_modules/mime-types": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
-			"integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+			"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
 				"mime-db": "^1.54.0"
 			},
 			"engines": {
-				"node": ">= 0.6"
+				"node": ">=18"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/express"
 			}
 		},
 		"node_modules/minimatch": {
@@ -1687,11 +2437,11 @@
 			}
 		},
 		"node_modules/minipass": {
-			"version": "7.1.2",
-			"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
-			"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+			"version": "7.1.3",
+			"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+			"integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
 			"dev": true,
-			"license": "ISC",
+			"license": "BlueOak-1.0.0",
 			"engines": {
 				"node": ">=16 || 14 >=14.17"
 			}
@@ -1704,18 +2454,47 @@
 			"license": "BSD-3-Clause"
 		},
 		"node_modules/morphdom": {
-			"version": "2.7.5",
-			"resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.5.tgz",
-			"integrity": "sha512-z6bfWFMra7kBqDjQGHud1LSXtq5JJC060viEkQFMBX6baIecpkNr2Ywrn2OQfWP3rXiNFQRPoFjD8/TvJcWcDg==",
+			"version": "2.7.8",
+			"resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz",
+			"integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==",
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/ms": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-			"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+		"node_modules/ms": {
+			"version": "2.1.3",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+			"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/nanoid": {
+			"version": "3.3.19",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz",
+			"integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"bin": {
+				"nanoid": "bin/nanoid.cjs"
+			},
+			"engines": {
+				"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+			}
+		},
+		"node_modules/node-releases": {
+			"version": "2.0.56",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.56.tgz",
+			"integrity": "sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A==",
 			"dev": true,
-			"license": "MIT"
+			"license": "MIT",
+			"engines": {
+				"node": ">=18"
+			}
 		},
 		"node_modules/node-retrieve-globals": {
 			"version": "6.0.1",
@@ -1739,17 +2518,28 @@
 				"node": ">=0.10.0"
 			}
 		},
-		"node_modules/nth-check": {
-			"version": "2.1.1",
-			"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
-			"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+		"node_modules/nudeps": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/nudeps/-/nudeps-0.4.1.tgz",
+			"integrity": "sha512-WUG2RQobAVAYwa2kfC+Dc8b7F4REW3JZxCldvIi1s/Jc80aGZFOum7S5s6lcOnuFUrq+Ovtwws82+mZgWE2hcQ==",
 			"dev": true,
-			"license": "BSD-2-Clause",
+			"funding": [
+				{
+					"type": "individual",
+					"url": "https://github.com/sponsors/LeaVerou"
+				}
+			],
+			"license": "MIT",
 			"dependencies": {
-				"boolbase": "^1.0.0"
+				"@jspm/generator": "^2.16.1",
+				"@jspm/overrides": "^1.0.0",
+				"blissful-hooks": "^0.0.2",
+				"cjs-browser-shim": "latest",
+				"minimist": "^1.2.8",
+				"sver": "^2.0.1"
 			},
-			"funding": {
-				"url": "https://github.com/fb55/nth-check?sponsor=1"
+			"bin": {
+				"nudeps": "src/cli/index.js"
 			}
 		},
 		"node_modules/nunjucks": {
@@ -1801,6 +2591,23 @@
 				"node": ">= 0.8"
 			}
 		},
+		"node_modules/pako": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/pako/-/pako-2.2.0.tgz",
+			"integrity": "sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/puzrin"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/nodeca"
+				}
+			],
+			"license": "(MIT AND Zlib)"
+		},
 		"node_modules/parse-srcset": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
@@ -1808,106 +2615,103 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/parse5": {
-			"version": "7.2.1",
-			"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
-			"integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
+		"node_modules/parseurl": {
+			"version": "1.3.3",
+			"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+			"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"entities": "^4.5.0"
-			},
-			"funding": {
-				"url": "https://github.com/inikulin/parse5?sponsor=1"
+			"engines": {
+				"node": ">= 0.8"
 			}
 		},
-		"node_modules/parse5-htmlparser2-tree-adapter": {
-			"version": "7.1.0",
-			"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
-			"integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+		"node_modules/picocolors": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+			"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
 			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"domhandler": "^5.0.3",
-				"parse5": "^7.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/inikulin/parse5?sponsor=1"
-			}
+			"license": "ISC"
 		},
-		"node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
-			"version": "5.0.3",
-			"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
-			"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+		"node_modules/picomatch": {
+			"version": "4.0.7",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+			"integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
 			"dev": true,
-			"license": "BSD-2-Clause",
-			"dependencies": {
-				"domelementtype": "^2.3.0"
-			},
+			"license": "MIT",
 			"engines": {
-				"node": ">= 4"
+				"node": ">=12"
 			},
 			"funding": {
-				"url": "https://github.com/fb55/domhandler?sponsor=1"
+				"url": "https://github.com/sponsors/jonschlinkert"
 			}
 		},
-		"node_modules/parse5-parser-stream": {
-			"version": "7.1.2",
-			"resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
-			"integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+		"node_modules/please-upgrade-node": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+			"integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"parse5": "^7.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/inikulin/parse5?sponsor=1"
-			}
-		},
-		"node_modules/parse5/node_modules/entities": {
-			"version": "4.5.0",
-			"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-			"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
-			"dev": true,
-			"license": "BSD-2-Clause",
-			"engines": {
-				"node": ">=0.12"
-			},
-			"funding": {
-				"url": "https://github.com/fb55/entities?sponsor=1"
+				"semver-compare": "^1.0.0"
 			}
 		},
-		"node_modules/parseurl": {
-			"version": "1.3.3",
-			"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
-			"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+		"node_modules/postcss": {
+			"version": "8.5.28",
+			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+			"integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
 			"dev": true,
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/postcss/"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/postcss"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
 			"license": "MIT",
+			"dependencies": {
+				"nanoid": "^3.3.18",
+				"picocolors": "^1.1.1",
+				"source-map-js": "^1.2.1"
+			},
 			"engines": {
-				"node": ">= 0.8"
+				"node": "^10 || ^12 || >=14"
 			}
 		},
-		"node_modules/picomatch": {
-			"version": "2.3.1",
-			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+		"node_modules/postcss-selector-parser": {
+			"version": "7.1.6",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+			"integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
 			"dev": true,
 			"license": "MIT",
-			"engines": {
-				"node": ">=8.6"
+			"dependencies": {
+				"cssesc": "^3.0.0",
+				"util-deprecate": "^1.0.2"
 			},
-			"funding": {
-				"url": "https://github.com/sponsors/jonschlinkert"
+			"engines": {
+				"node": ">=4"
 			}
 		},
-		"node_modules/please-upgrade-node": {
-			"version": "3.2.0",
-			"resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
-			"integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+		"node_modules/postcss-selector-transform": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/postcss-selector-transform/-/postcss-selector-transform-0.0.1.tgz",
+			"integrity": "sha512-hBleoiHeqIPmFngzUghHgJlpGifhxXoLqg2DNpNySyeyLe8eDAV6v4POl04JP7ADc3W35lNuZyZogAMrpkUnBw==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"semver-compare": "^1.0.0"
+				"postcss-selector-parser": "^7.1.5"
+			},
+			"engines": {
+				"node": ">=22"
+			},
+			"peerDependencies": {
+				"postcss": "^8.0.0"
 			}
 		},
 		"node_modules/posthtml": {
@@ -2035,6 +2839,16 @@
 				"prettier": ">=3.0.0"
 			}
 		},
+		"node_modules/prismjs": {
+			"version": "1.30.0",
+			"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+			"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			}
+		},
 		"node_modules/prr": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -2053,13 +2867,17 @@
 			}
 		},
 		"node_modules/range-parser": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
-			"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
+			"integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
 			"dev": true,
 			"license": "MIT",
 			"engines": {
 				"node": ">= 0.6"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/express"
 			}
 		},
 		"node_modules/readdirp": {
@@ -2075,12 +2893,18 @@
 				"node": ">=8.10.0"
 			}
 		},
-		"node_modules/safer-buffer": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-			"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+		"node_modules/readdirp/node_modules/picomatch": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+			"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
 			"dev": true,
-			"license": "MIT"
+			"license": "MIT",
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
 		},
 		"node_modules/section-matter": {
 			"version": "1.0.0",
@@ -2117,26 +2941,30 @@
 			"license": "MIT"
 		},
 		"node_modules/send": {
-			"version": "1.2.0",
-			"resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
-			"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+			"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"debug": "^4.3.5",
+				"debug": "^4.4.3",
 				"encodeurl": "^2.0.0",
 				"escape-html": "^1.0.3",
 				"etag": "^1.8.1",
 				"fresh": "^2.0.0",
-				"http-errors": "^2.0.0",
-				"mime-types": "^3.0.1",
+				"http-errors": "^2.0.1",
+				"mime-types": "^3.0.2",
 				"ms": "^2.1.3",
 				"on-finished": "^2.4.1",
 				"range-parser": "^1.2.1",
-				"statuses": "^2.0.1"
+				"statuses": "^2.0.2"
 			},
 			"engines": {
 				"node": ">= 18"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/express"
 			}
 		},
 		"node_modules/setprototypeof": {
@@ -2166,6 +2994,16 @@
 				"node": ">=8.0.0"
 			}
 		},
+		"node_modules/source-map-js": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+			"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+			"dev": true,
+			"license": "BSD-3-Clause",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
 		"node_modules/sprintf-js": {
 			"version": "1.0.3",
 			"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -2187,15 +3025,27 @@
 			}
 		},
 		"node_modules/statuses": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
-			"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+			"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
 			"dev": true,
 			"license": "MIT",
 			"engines": {
 				"node": ">= 0.8"
 			}
 		},
+		"node_modules/streamx": {
+			"version": "2.28.1",
+			"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.1.tgz",
+			"integrity": "sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"events-universal": "^1.0.0",
+				"fast-fifo": "^1.3.2",
+				"text-decoder": "^1.1.0"
+			}
+		},
 		"node_modules/strip-bom-string": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
@@ -2206,6 +3056,63 @@
 				"node": ">=0.10.0"
 			}
 		},
+		"node_modules/style-observer": {
+			"version": "0.1.2",
+			"resolved": "https://registry.npmjs.org/style-observer/-/style-observer-0.1.2.tgz",
+			"integrity": "sha512-VdGkVx7dGqEzosau63CI33vRJsAGKPJCXyS9f5ze7gFbgsXm0wt5liXUNB9+YjyfhMyD+iTwNa7sM4cvpP3N9Q==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "individual",
+					"url": "https://github.com/sponsors/LeaVerou"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/leaverou"
+				}
+			],
+			"license": "MIT"
+		},
+		"node_modules/sver": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/sver/-/sver-2.0.1.tgz",
+			"integrity": "sha512-zqIx4tK5+gR8xE8VgLNr+IA0mqKDgMNdsfX86DTfNNnVKyuVUhjGdz6KA0rO3q445WUfGpEeJym1m3Xym7ot6w==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/tar-stream": {
+			"version": "3.2.1",
+			"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.1.tgz",
+			"integrity": "sha512-nqsEO8zLZJvrOMdEwkA0QdCLFbetHMn95Zqu4fKwX+hkaTWJPZZOrxx/PwtxoK0MMGQmBQNRW3CPs8IFYQz4cQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"b4a": "^1.6.4",
+				"bare-fs": "^4.5.5",
+				"fast-fifo": "^1.2.0",
+				"streamx": "^2.15.0"
+			}
+		},
+		"node_modules/teex": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+			"integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"streamx": "^2.12.5"
+			}
+		},
+		"node_modules/text-decoder": {
+			"version": "1.2.7",
+			"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
+			"integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"dependencies": {
+				"b4a": "^1.6.4"
+			}
+		},
 		"node_modules/tinyglobby": {
 			"version": "0.2.17",
 			"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
@@ -2223,37 +3130,6 @@
 				"url": "https://github.com/sponsors/SuperchupuDev"
 			}
 		},
-		"node_modules/tinyglobby/node_modules/fdir": {
-			"version": "6.5.0",
-			"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
-			"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=12.0.0"
-			},
-			"peerDependencies": {
-				"picomatch": "^3 || ^4"
-			},
-			"peerDependenciesMeta": {
-				"picomatch": {
-					"optional": true
-				}
-			}
-		},
-		"node_modules/tinyglobby/node_modules/picomatch": {
-			"version": "4.0.7",
-			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
-			"integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=12"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/jonschlinkert"
-			}
-		},
 		"node_modules/to-regex-range": {
 			"version": "5.0.1",
 			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -2375,16 +3251,6 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/undici": {
-			"version": "6.21.3",
-			"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
-			"integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=18.17"
-			}
-		},
 		"node_modules/unpipe": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -2395,6 +3261,37 @@
 				"node": ">= 0.8"
 			}
 		},
+		"node_modules/update-browserslist-db": {
+			"version": "1.3.3",
+			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+			"integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/browserslist"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/browserslist"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"escalade": "^3.2.0",
+				"picocolors": "^1.1.1"
+			},
+			"bin": {
+				"update-browserslist-db": "cli.js"
+			},
+			"peerDependencies": {
+				"browserslist": ">= 4.21.0"
+			}
+		},
 		"node_modules/urlpattern-polyfill": {
 			"version": "10.1.0",
 			"resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz",
@@ -2402,33 +3299,17 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/whatwg-encoding": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
-			"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"iconv-lite": "0.6.3"
-			},
-			"engines": {
-				"node": ">=18"
-			}
-		},
-		"node_modules/whatwg-mimetype": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
-			"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+		"node_modules/util-deprecate": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+			"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
 			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=18"
-			}
+			"license": "MIT"
 		},
 		"node_modules/ws": {
-			"version": "8.18.2",
-			"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
-			"integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
+			"version": "8.21.3",
+			"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
+			"integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
 			"dev": true,
 			"license": "MIT",
 			"engines": {
@@ -2447,6 +3328,13 @@
 				}
 			}
 		},
+		"node_modules/yallist": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+			"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+			"dev": true,
+			"license": "ISC"
+		},
 		"node_modules/yaml": {
 			"version": "2.9.1",
 			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
diff --git a/package.json b/package.json
index 191b40db..9f3a2470 100644
--- a/package.json
+++ b/package.json
@@ -6,11 +6,11 @@
 	"scripts": {
 		"postinstall": "node _build/postinstall.mjs",
 		"dev": "netlify dev -p 8844",
-		"serve": "npx @11ty/eleventy --config=_build/eleventy.js --serve --quiet",
-		"build:html": "npx @11ty/eleventy --config=_build/eleventy.js --quiet",
+		"serve": "docspire --serve",
+		"build:html": "docspire",
 		"build:apidocs": "npx typedoc",
 		"build": "npm run build:html && npm run build:apidocs",
-		"watch:html": "npx @11ty/eleventy --config=_build/eleventy.js --watch --quiet --incremental",
+		"watch:html": "docspire --watch",
 		"watch": "npm run watch:html"
 	},
 	"repository": {
@@ -23,10 +23,7 @@
 	"homepage": "https://prismjs.com",
 	"license": "MIT",
 	"devDependencies": {
-		"@11ty/eleventy": "^3.1.6",
-		"eleventy-plugin-toc": "^1.1.5",
-		"markdown-it-anchor": "^9.2.1",
-		"markdown-it-attrs": "^4.5.0",
+		"docspire": "^0.0.4",
 		"markdown-it-deflist": "^3.0.1",
 		"prettier": "^3.9.8",
 		"prettier-plugin-brace-style": "^0.10.3",
diff --git a/templates/page-title.njk b/templates/page-title.njk
new file mode 100644
index 00000000..50b63b61
--- /dev/null
+++ b/templates/page-title.njk
@@ -0,0 +1,9 @@
+{# The page's title and lede. A plugin README carries both in its front matter,
+   as `title` and `description`. #}
+{% if title %}
+
+

{{ title | md }}

+ {% set lede = tagline or description %} + {% if lede %}

{{ lede | md }}

{% endif %} +
+{% endif %} diff --git a/templates/resources.njk b/templates/resources.njk new file mode 100644 index 00000000..000b5b50 --- /dev/null +++ b/templates/resources.njk @@ -0,0 +1,3 @@ +{%- for resource in resources | parse_resources %} +{{ resource | safe }} +{%- endfor %} diff --git a/typedoc.json b/typedoc.json index e55a8dd1..b20b6836 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,14 +1,11 @@ { "$schema": "https://typedoc.org/schema.json", - "out": "./api", - "json": "./api/docs.json", + "out": "./_site/api", + "json": "./_site/api/docs.json", "name": "Prism API", "includeVersion": true, - "entryPoints": ["node_modules/prismjs/src/**/*.js"], - "exclude": [ - "node_modules/prismjs/src/plugins/**/*.js", - "node_modules/prismjs/src/languages/**/*.js" - ], + "entryPoints": [".prism/src/**/*.js", ".prism/src/types.d.ts"], + "exclude": [".prism/src/plugins/**/*.js", ".prism/src/languages/**/*.js"], "externalPattern": ["**/node_modules/**/node_modules/**"], "compilerOptions": { "skipLibCheck": true, From f5cf31b7c9f1831cc0a0b949af6f2511331bd972 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 23 Sep 2026 10:04:27 +0200 Subject: [PATCH 2/6] Restore the brand look brand.css keeps what Docspire's theme does not already cover: the Questrial and Rockwell faces, the logo on a dark ground, headings at normal weight, the used-by logos, the language and plugin lists, and the download, examples, test drive, tokens and known-failures widgets. The download page's categories open at h2, under the page title. The current page and section show in the accent color: Docspire marks them by weight, which Questrial, with its single weight, can't show. Docspire also reads --ui-color-accent without defining it, which left the outline's marker invisible. Code blocks get what Prism's own themes set: a line height and the block's font on , so line numbers stay beside their lines. A code-block pads its
,
where Prism's plugins replace the padding to make room for their gutters. A block
taller than 30em scrolls inside itself, as on the old site.

Co-Authored-By: Claude Opus 5.5 
---
 assets/styles/brand.css | 627 ++++++++++++++++++++++++++++++++++++++++
 docs/download.njk       |   2 +-
 docspire.config.js      |   1 +
 3 files changed, 629 insertions(+), 1 deletion(-)
 create mode 100644 assets/styles/brand.css

diff --git a/assets/styles/brand.css b/assets/styles/brand.css
new file mode 100644
index 00000000..f4a8b43f
--- /dev/null
+++ b/assets/styles/brand.css
@@ -0,0 +1,627 @@
+@import url(https://fonts.googleapis.com/css?family=Questrial);
+@import url(https://fonts.googleapis.com/css?family=Arvo);
+
+/*
+ * What Prism's docs add to the theme: the brand faces and logo, definition lists, the
+ * highlighted-markup `` affordance, and the page-specific widgets below — the language
+ * and plugin lists, the download builder, the test drive, the token tables.
+ */
+
+/* The brand faces */
+:root {
+	--font-body: Questrial, sans-serif;
+	--font-heading: Rockwell, Arvo, serif;
+}
+
+/*
+ * Docspire marks the current page and section by weight alone (600 and 550), which Questrial
+ * can't show: it ships one weight. The accent color marks them instead. Docspire reads
+ * --ui-color-accent but never defines it, so the outline's marker was invisible too.
+ * The outline's variable goes on the element, not :root, where the component's own value would win.
+ */
+:root {
+	/* The tints links use, 45 in light mode and 65 in dark */
+	--ui-color-accent: light-dark(
+		oklch(from var(--color-accent) var(--tint-45)),
+		oklch(from var(--color-accent) var(--tint-65))
+	);
+}
+
+page-outline {
+	--ui-color-text-outline-hover: var(--ui-color-accent);
+}
+
+#sidebar a.current {
+	color: var(--ui-color-accent);
+}
+
+body {
+	tab-size: 4;
+	hyphens: auto;
+}
+
+/* A hyphen dropped into an identifier reads as part of it */
+:is(code, pre, kbd, samp) {
+	hyphens: none;
+}
+
+/* Line numbers are rows beside the code, so a line of code must be exactly as tall as a row.
+   With line-height: normal, its height follows the font a line happens to be drawn in, and the
+    is not even in the block's font. Prism's own themes set both. */
+pre:has(> code) {
+	line-height: 1.5;
+
+	& code {
+		font-family: inherit;
+	}
+}
+
+/* Prism's plugins make room for their gutters with the 
's padding, like line-highlight's
+   `pre[data-line] { padding: 1em 0 1em 3em }`. So a code-block pads its 
, not itself,
+   and a plugin's padding replaces Docspire's there too, instead of adding to it. */
+code-block {
+	padding: 0;
+
+	& > pre {
+		padding: var(--size-l);
+	}
+}
+
+/* A long block, like a whole file fetched by file-highlight, scrolls inside itself */
+pre {
+	max-height: 30em;
+	overflow: auto;
+}
+
+/* FIXME: Drop once Prism's autoloader stops highlighting again a 
 file-highlight took over.
+   That pass replaces the  with bare tokens, and Docspire styles only `pre:has(> code)`. */
+pre[data-src]:not(:has(> code)) {
+	padding: var(--size-l);
+	background: var(--ui-background-code, var(--ui-background-code-default));
+	border-radius: var(--ui-rounding-code, var(--rounding));
+	font: var(--size-s) / 1.5 var(--font-mono);
+}
+
+/*
+ * Nothing here was ever bold: section titles came from `font: 100% Rockwell…` and the rest
+ * from `h2, h3 { font-weight: normal }`. The page title takes h1 now, so those two sets are
+ * h2 and h3/h4. Sizes are the theme's, which already sit under that title.
+ */
+h2,
+h3,
+h4 {
+	font-weight: normal;
+}
+
+/* Below a section title the old stylesheet left headings in the body face */
+h3,
+h4 {
+	font-family: var(--font-body);
+}
+
+/*
+ * logo.svg is a white silhouette drawn for the dark spectrum header the old site had. Give it a
+ * dark ground back wherever it appears, rather than inverting it per color scheme — the shape
+ * then reads the same either way, as it does in the browser tab.
+ */
+:is(header .logo img, .hero .image) {
+	padding: var(--size-6xs);
+	border-radius: var(--rounding);
+	background: black;
+}
+
+/*
+ * Shown large, it gets the spectrum itself: the whole image, squeezed to fit, since cropping it
+ * leaves only the green middle. The dark overlay it used to carry went with the old header,
+ * which needed white text to stay legible over the colors.
+ */
+.hero .image {
+	padding: var(--size-l);
+	background: url("/assets/img/spectrum.png") center / 100% 100%;
+}
+
+/* Title and lede read as one block, and the title is no bolder than any other heading */
+.page-title {
+	margin-block-end: var(--size-xl);
+
+	h1 {
+		font-weight: normal;
+		margin-block-end: var(--size-3xs);
+	}
+
+	p {
+		color: var(--ui-color-text-quiet);
+	}
+}
+
+dt {
+	margin: 1em 0 0 0;
+	font-size: 130%;
+}
+
+dt:after {
+	content: ":";
+}
+
+dd {
+	margin-left: 2em;
+}
+
+mark {
+	outline: 0.4em solid red;
+	outline-offset: 0.4em;
+	margin: 0.4em 0;
+	background-color: transparent;
+	display: inline-block;
+}
+
+.used-by-logos {
+	overflow: hidden;
+}
+.used-by-logos > a {
+	float: left;
+	width: 33.33%;
+	height: 100px;
+	text-align: center;
+	background: #f5f2f0;
+	box-sizing: border-box;
+	border: 5px solid white;
+	position: relative;
+}
+.used-by-logos > a > img {
+	max-height: 100%;
+	max-width: 100%;
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+}
+
+label a.owner {
+	margin: 0 0.5em;
+}
+
+label a.owner:not(:hover) {
+	text-decoration: none;
+	color: #aaa;
+}
+
+#languages-list {
+	column-count: 3;
+	column-gap: 2em;
+
+	li {
+		padding: 0.2em;
+	}
+
+	li[data-id="javascript"] {
+		border-bottom: 1px solid #aaa;
+		padding-bottom: 1em;
+		margin-bottom: 1em;
+		margin-right: 1em;
+	}
+}
+
+ul.plugin-list {
+	column-count: 2;
+	column-gap: 2em;
+
+	> li {
+		break-inside: avoid;
+		page-break-inside: avoid;
+
+		> a {
+			font-size: 110%;
+		}
+
+		> div {
+			margin-bottom: 0.5em;
+		}
+	}
+}
+
+[data-inputpath="examples.md"] {
+	#languages {
+		column-count: 4;
+
+		> h1 {
+			margin-top: 0;
+			column-span: all;
+		}
+
+		label {
+			display: block;
+			padding: 0.2em;
+
+			&[data-id="javascript"] {
+				border-bottom: 1px solid #aaa;
+				padding-bottom: 1em;
+				margin-bottom: 1em;
+			}
+		}
+
+		.unavailable {
+			color: #aaa;
+		}
+
+		input {
+			margin-right: 0.7em;
+		}
+	}
+
+	#examples {
+		/*
+		 * Two kinds of h2: the language name that opens each section, and the titles inside
+		 * the example file below it. Same size, told apart by the face, as before the
+		 * migration — where the language name was the section's h1.
+		 */
+		h2 {
+			font-size: 1.5em;
+			font-family: var(--font-body);
+		}
+
+		> section > h2:first-child {
+			font-family: var(--font-heading);
+		}
+
+		/* Sections lay out as a flex column, where `margin: auto` alone would shrink each
+		   example to its widest line */
+		> section {
+			margin-inline: auto;
+			inline-size: min(100%, 900px);
+
+			/* Every language has one, and the column's gap would space out the ~300 unused */
+			&:empty {
+				display: none;
+			}
+		}
+
+		h3 {
+			margin: 1em 0 0.3em;
+		}
+	}
+
+	main ul {
+		padding-left: 40px;
+	}
+}
+
+[data-inputpath="known-failures.md"] {
+	/* h2 is the language, h3 the failure: keep the failure a label, not a second title */
+	main h3 {
+		font-size: 1.2em;
+
+		&[id] > a::before {
+			content: "";
+		}
+	}
+}
+
+[data-inputpath="tokens.md"] {
+	table.styled {
+		border: 1px solid #ccc;
+		border-spacing: 0;
+
+		tr:not(:first-child) > * {
+			border-top: 1px solid #ccc;
+		}
+
+		tr > *:not(:first-child) {
+			border-left: 1px solid #ccc;
+		}
+
+		/* Between the page and the code surface, so a code block still reads as a block */
+		tr:nth-child(2n + 1) {
+			background-color: color-mix(in oklch, var(--color-bg-soft), var(--color-bg));
+		}
+
+		tr > * {
+			padding: 0.5em 0.75em;
+		}
+
+		tr > th {
+			text-align: left;
+		}
+	}
+}
+
+[data-inputpath="extending.md"] {
+	ol.indent {
+		margin: 1em 0;
+		padding-left: 2em;
+	}
+
+	table.stylish {
+		border-collapse: collapse;
+
+		&,
+		tr,
+		td,
+		th {
+			border: 1px solid #ccc;
+		}
+
+		td,
+		th {
+			padding: 0.5em 0.75em;
+		}
+
+		th,
+		td:first-child {
+			background-color: #f8f8f8;
+		}
+	}
+}
+
+[data-inputpath="test.md"] {
+	textarea {
+		width: 100%;
+		height: 10em;
+		padding: 1em;
+		box-sizing: border-box;
+		margin: 0.5em 0;
+		background: #f5f2f0;
+		color: black;
+		text-shadow: 0 1px white;
+		tab-size: 4;
+		font:
+			100% Consolas,
+			Monaco,
+			monospace;
+		white-space: pre;
+		word-wrap: normal;
+		resize: vertical;
+	}
+
+	#language {
+		column-count: 4;
+
+		label {
+			display: block;
+			padding: 0.2em;
+		}
+
+		label[data-id="javascript"] {
+			border-bottom: 1px solid #aaa;
+			padding-bottom: 1em;
+			margin-bottom: 1em;
+		}
+
+		input {
+			margin-right: 1em;
+		}
+
+		strong {
+			display: block;
+			column-span: all;
+		}
+	}
+
+	pre.show-tokens {
+		line-height: calc(1.5em + 12px);
+	}
+
+	.show-tokens {
+		.token:not(:first-child) {
+			margin-left: 1px;
+		}
+
+		.token:empty {
+			background: red;
+		}
+
+		.token:empty::before {
+			color: white;
+			content: "empty";
+			font-style: italic;
+			text-shadow: black 0 0 0.3em;
+		}
+
+		.token {
+			border: 1px solid;
+			padding: 6px 1px;
+		}
+
+		.token > .token {
+			padding: 4px 1px;
+		}
+
+		.token > .token > .token {
+			padding: 2px 1px;
+		}
+
+		.token > .token > .token > .token {
+			padding: 0 1px;
+		}
+
+		.token > .token > .token > .token > .token {
+			border: none;
+			border-left: 1px solid;
+			border-right: 1px solid;
+			padding: 0;
+			margin: 0 1px;
+		}
+	}
+
+	#options {
+		position: relative;
+	}
+
+	.link-wrapper {
+		position: absolute;
+		top: 0;
+		right: 0;
+		background-color: white;
+
+		.hidden-wrapper {
+			display: none;
+		}
+
+		&:hover {
+			top: -0.5em;
+			right: -1em;
+			width: 300px;
+			padding: 0.5em 1em;
+			outline: 1px solid #888;
+
+			.hidden-wrapper {
+				display: block;
+			}
+		}
+
+		input {
+			width: 100%;
+			box-sizing: border-box;
+		}
+
+		button {
+			border: none;
+			background: none;
+			font: inherit;
+			text-decoration: underline;
+			cursor: pointer;
+		}
+	}
+}
+
+[data-inputpath^="download"] {
+	form label {
+		display: block;
+		padding: 0.2em;
+		padding-left: 1.9em;
+		page-break-inside: avoid;
+		break-inside: avoid;
+
+		.name {
+			margin-right: 0.3em;
+		}
+
+		a.owner {
+			margin-left: 0;
+			hyphens: none;
+		}
+
+		input {
+			margin-right: 0.7em;
+			margin-left: -1.7em;
+		}
+	}
+
+	.filesize:empty {
+		display: none;
+	}
+
+	#components {
+		overflow: hidden;
+	}
+
+	section.options {
+		width: 33.3%;
+		width: calc(100% / 3);
+		float: left;
+
+		label[data-id^="check-all-"] {
+			border-bottom: 1px solid #aaa;
+			padding-bottom: 1em;
+			margin-bottom: 1em;
+		}
+	}
+
+	section.options#category-languages,
+	section.options#category-plugins {
+		width: 100%;
+		float: none;
+		column-count: 3;
+		padding-top: 2em;
+		overflow: visible;
+
+		label {
+			break-inside: avoid;
+		}
+
+		> h2 {
+			margin-top: 0;
+			column-span: all;
+		}
+
+		label[data-id="javascript"] {
+			border-bottom: 1px solid #aaa;
+			padding-bottom: 1em;
+			margin-bottom: 1em;
+		}
+	}
+
+	section.options#category-themes {
+		width: 66.6%;
+		width: calc(100% * 2 / 3);
+		column-count: 2;
+		overflow: visible;
+		float: none;
+
+		> h2 {
+			column-span: all;
+		}
+	}
+
+	section.download {
+		width: 50%;
+		float: left;
+	}
+
+	.download-button {
+		display: block;
+		padding: 0.2em 0.8em 0.1em;
+		border: 1px solid rgba(0, 0, 0, 0.5);
+		border-radius: 10px;
+		background: #39a1cf;
+		box-shadow:
+			0 2px 10px black,
+			inset 0 1px hsla(0, 0%, 100%, 0.3),
+			inset 0 0.4em hsla(0, 0%, 100%, 0.2),
+			inset 0 10px 20px hsla(0, 0%, 100%, 0.25),
+			inset 0 -15px 30px rgba(0, 0, 0, 0.3);
+		color: white;
+		text-shadow: 0 -1px 2px black;
+		text-align: center;
+		font-size: 250%;
+		line-height: 1.5;
+		text-transform: uppercase;
+		text-decoration: none;
+		hyphens: manual;
+
+		&:hover {
+			background-color: #7fab14;
+		}
+
+		&:active {
+			box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);
+		}
+	}
+
+	#download {
+		overflow: hidden;
+		padding: 0.3em;
+		.error {
+			color: #b61500;
+			display: none;
+		}
+		pre {
+			height: 20em;
+		}
+		.download-button {
+			cursor: pointer;
+			width: 100%;
+		}
+	}
+
+	#download-js .download-button {
+		border-top-right-radius: 0;
+		border-bottom-right-radius: 0;
+	}
+
+	#download-css .download-button {
+		background-color: #dc9e23;
+		border-top-left-radius: 0;
+		border-bottom-left-radius: 0;
+	}
+}
diff --git a/docs/download.njk b/docs/download.njk
index 1830a9cf..ecb92f05 100644
--- a/docs/download.njk
+++ b/docs/download.njk
@@ -11,7 +11,7 @@ resources:
 {%- set meta = components.meta -%}
 
 
-

{{ category | capitalize }}

+

{{ category | capitalize }}

{%- if meta.addCheckAll %}