From dabee88878e1a587bd04369f73bcd02a6801a386 Mon Sep 17 00:00:00 2001 From: karthik Ganeshram Date: Mon, 10 Oct 2022 05:06:43 -0700 Subject: [PATCH] WIP: adding search to docs Signed-off-by: karthik Ganeshram --- content/cloud/faq.md | 2 +- content/spin/quickstart.md | 1 + md_parser.mjs | 101 ++ package-lock.json | 1858 ++++++++++++++++++++++++++++------ package.json | 13 +- static/css/styles.css | 287 ++++++ static/css/styles.css.map | 2 +- static/data.json | 1 + static/js/main.js | 335 +++++- static/sass/styles.css | 1 - static/sass/styles.scss | 300 ++++++ templates/content_bottom.hbs | 8 +- templates/content_navbar.hbs | 1 + 13 files changed, 2560 insertions(+), 350 deletions(-) create mode 100644 md_parser.mjs create mode 100644 static/data.json delete mode 100644 static/sass/styles.css diff --git a/content/cloud/faq.md b/content/cloud/faq.md index c7bf0bfc7..02845d79a 100644 --- a/content/cloud/faq.md +++ b/content/cloud/faq.md @@ -1,7 +1,7 @@ title = "FAQ and Known Limitations" template = "cloud_main" date = "2022-10-05T00:00:00Z" -enable_shortcodes=true +enable_shortcodes = true --- diff --git a/content/spin/quickstart.md b/content/spin/quickstart.md index 3849e0d6a..fbf0bd114 100644 --- a/content/spin/quickstart.md +++ b/content/spin/quickstart.md @@ -3,6 +3,7 @@ template = "spin_main" date = "2022-03-14T00:22:56Z" [extra] url = "https://github.com/fermyon/spin/blob/main/docs/content/quickstart.md" +keywords = "quickstart" --- > This is an early preview of the Spin project. It is still experimental code, diff --git a/md_parser.mjs b/md_parser.mjs new file mode 100644 index 000000000..d62b1e9f1 --- /dev/null +++ b/md_parser.mjs @@ -0,0 +1,101 @@ +import glob from 'glob' +import fs from 'fs' +import fm from 'front-matter' +import { unified } from 'unified' +import remarkParse from 'remark-parse' +import args from 'args-parser' + +// Elements that have child elements +const blockElements = ["paragraph", "blockquote", "list", "listItem", "link"] +// Elements who's value is just text +const inlineElements = ["inlineCode", "text", "code"] + +function parseMdFile(file, path) { + let data = fs.readFileSync(file, + { encoding: 'utf8', flag: 'r' }); + let fmIndex = data.indexOf("---") + + // Make the extra section parsable as frontmatter + if (data.slice(0, fmIndex).includes("[extra]")) { + data = data.replace("[extra]", "extra_Section: \"OK\"") + fmIndex += 12 + } + + // Make it valid frontmatter as per jekyll standards + let fmReplace = data.slice(0, fmIndex) + fmReplace = fmReplace.replaceAll("=", ":") + data = fmReplace + data.slice(fmIndex, -1) + data = "---\n\n" + data + + // Parse markdown into json tree + let content = fm(data) + let myResult = unified() + .use(remarkParse) + .parse(content.body); + + // Create default document index for the page + let documentIndex = { project: file.split("/")[2], title: content.attributes["title"], subheading: "", content: "", keywords: content.attributes["keywords"], url: "/" + file.replace(path, "") } + let searchIndex = [] + + // For each heading create a new search index + myResult.children.map(k => { + if (!(k.type == "heading")) { + // If inline element just append content + if (inlineElements.includes(k.type)) { + documentIndex.content = documentIndex.content.concat(k.value) + } else { + if (blockElements.includes(k.type)) { + k.children.map(inlineElement => { + documentIndex.content = documentIndex.content.concat(inlineElement.value) + }) + } + } + } else { + // If new heading create a new index + searchIndex.push(documentIndex) + + let subtitle = k.children.map(k => { + if (k.children) { + return k.children[0].value + } + return k.value + }) + subtitle = subtitle.join(" ") + + documentIndex = { + project: file.split("/")[2], + title: content.attributes["title"], subheading: subtitle, content: "", keywords: content.attributes["keywords"], + url: "/" + file.replace(path, "") + "#" + subtitle.toLowerCase().replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/g, '') + .replace(/ +/g, '-') + } + } + }) + // If there are unpushed document index push it + if (documentIndex.content) { + searchIndex.push(documentIndex) + } + return searchIndex +} + +function main() { + const argparse = args(process.argv) + if (!argparse.dir || !argparse.out) { + console.error("--dir and --out must be specified") + return + } + + let consolidatedSearchIndex = [] + + glob(argparse.dir + '/**/*.md', (err, files) => { + if (err) { + console.log('Error', err) + } else { + files.forEach(file => { + consolidatedSearchIndex = consolidatedSearchIndex.concat(parseMdFile(file, argparse.dir)) + }) + } + fs.writeFileSync(argparse.out, JSON.stringify(consolidatedSearchIndex)); + }) +} + +main() \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2ba6bc2e7..2db6978ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,15 @@ "devDependencies": { "@fermyon/styleguide": "^0.1", "@parcel/transformer-sass": "^2.7.0", + "args-parser": "^1.3.0", + "front-matter": "^4.0.2", + "glob": "^8.0.3", "markdownlint-cli2": "^0.5.1", "nodemon": "^2.0.20", - "sass": "^1.49.9" + "remark-parse": "^10.0.1", + "sass": "^1.49.9", + "unified": "^10.1.2", + "yaml-front-matter": "^4.1.1" } }, "node_modules/@babel/code-frame": { @@ -195,58 +201,6 @@ "@lezer/common": "^0.15.0" } }, - "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", - "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", - "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", - "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", - "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@lmdb/lmdb-linux-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", @@ -260,19 +214,6 @@ "linux" ] }, - "node_modules/@lmdb/lmdb-win32-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", - "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@mischnic/json-sourcemap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", @@ -1427,12 +1368,42 @@ "node": ">=10.13.0" } }, + "node_modules/@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1491,6 +1462,22 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/args-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/args-parser/-/args-parser-1.3.0.tgz", + "integrity": "sha512-If3Zi4BSjlQIJ9fgAhSiKi0oJtgMzSqh0H4wvl7XSeO16FKx7QqaHld8lZeEajPX7y1C5qKKeNgyrfyvmjmjUQ==", + "dev": true + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1619,6 +1606,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -1775,6 +1772,28 @@ "ms": "^2.1.1" } }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dev": true, + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -1787,6 +1806,15 @@ "node": ">=0.10" } }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1923,6 +1951,25 @@ "node": ">=0.8.0" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -1960,20 +2007,21 @@ "node": ">=8" } }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "dependencies": { + "js-yaml": "^3.13.1" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, "node_modules/get-port": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", @@ -1983,6 +2031,25 @@ "node": ">=6" } }, + "node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1995,6 +2062,27 @@ "node": ">= 6" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -2141,6 +2229,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2159,6 +2263,29 @@ "node": ">=8" } }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2195,12 +2322,46 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "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 }, + "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==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -2219,6 +2380,15 @@ "node": ">=6" } }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/lightningcss": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.16.0.tgz", @@ -2245,37 +2415,17 @@ "lightningcss-win32-x64-msvc": "1.16.0" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.16.0.tgz", - "integrity": "sha512-gIhz6eZFwsC4oVMjBGQ3QWDdLQY7vcXFyM/x91PilgHqu63B9uBa10EZA75YoTEkbKhoz0uDCqyHh/EoF1GrkQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { + "node_modules/lightningcss-linux-x64-gnu": { "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.16.0.tgz", - "integrity": "sha512-kLPi+OEpDj3UGY6DC8TfjbcULJDKMP+TVKSlrEkNGn8t1YRzi2g4oy7UVTSB5AnSbT0CusUItzdVjHQ49EdoNA==", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.16.0.tgz", + "integrity": "sha512-gD2eQYD5OFs1p83R0TcMCEc5HRyJES4lR4THmclv7khm3dc9vc+2VT0kFBPxO1L2AwlZuvXaaMan7X1Ul7uSfA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": ">= 12.0.0" @@ -2285,12 +2435,12 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss-linux-arm-gnueabihf": { + "node_modules/lightningcss-linux-x64-musl": { "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.16.0.tgz", - "integrity": "sha512-oSwEbvXUPr//H/ainBRJXTxHerlheee/KgkTTmAQWiVnt8HV+bRohTBWWPBy5ZArgiGLwj7ogv45istgljPN2Q==", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.16.0.tgz", + "integrity": "sha512-HJsKeYxloEvg2WCQhtYPqzZUliLu9JBJNeI5y9cPQeDR/7ayGGLbVhJaotPtzJkElOFL/SaXsS+FRuH4w+yafg==", "cpu": [ - "arm" + "x64" ], "dev": true, "optional": true, @@ -2305,141 +2455,41 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.16.0.tgz", - "integrity": "sha512-Drq9BSVIvmV9zsDJbCZWCulMvKMQWFIlYXPCKV/iwRj+ZAJ1BRngma0cNHB6uW7Wac8Jg04CJN5IA4ELE3J+cQ==", - "cpu": [ - "arm64" - ], + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "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, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "dependencies": { + "uc.micro": "^1.0.1" } }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.16.0.tgz", - "integrity": "sha512-1QXWStnTEo4RFQf0mfGhRyNUeEHilCZ0NA97XgwKwrYr/M7sYKU/1HWY00dPxFJ6GITR2pfJGo9xi3ScSSBxbA==", - "cpu": [ - "arm64" - ], + "node_modules/lmdb": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", + "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "hasInstallScript": true, + "dependencies": { + "msgpackr": "^1.5.4", + "node-addon-api": "^4.3.0", + "node-gyp-build-optional-packages": "5.0.3", + "ordered-binary": "^1.2.4", + "weak-lru-cache": "^1.2.2" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.16.0.tgz", - "integrity": "sha512-gD2eQYD5OFs1p83R0TcMCEc5HRyJES4lR4THmclv7khm3dc9vc+2VT0kFBPxO1L2AwlZuvXaaMan7X1Ul7uSfA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.16.0.tgz", - "integrity": "sha512-HJsKeYxloEvg2WCQhtYPqzZUliLu9JBJNeI5y9cPQeDR/7ayGGLbVhJaotPtzJkElOFL/SaXsS+FRuH4w+yafg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.16.0.tgz", - "integrity": "sha512-h4ayyAlOMLUHV9NdofcIu79aEjmly93adVxcg5wDJpkvMiwDTufEN30M8G4gGcjo1JE5jFjAcyQcRpXYkYcemA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "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, - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/lmdb": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", - "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "msgpackr": "^1.5.4", - "node-addon-api": "^4.3.0", - "node-gyp-build-optional-packages": "5.0.3", - "ordered-binary": "^1.2.4", - "weak-lru-cache": "^1.2.2" - }, - "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "2.5.2", - "@lmdb/lmdb-darwin-x64": "2.5.2", - "@lmdb/lmdb-linux-arm": "2.5.2", - "@lmdb/lmdb-linux-arm64": "2.5.2", - "@lmdb/lmdb-linux-x64": "2.5.2", - "@lmdb/lmdb-win32-x64": "2.5.2" + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "2.5.2", + "@lmdb/lmdb-darwin-x64": "2.5.2", + "@lmdb/lmdb-linux-arm": "2.5.2", + "@lmdb/lmdb-linux-arm64": "2.5.2", + "@lmdb/lmdb-linux-x64": "2.5.2", + "@lmdb/lmdb-win32-x64": "2.5.2" } }, "node_modules/lmdb/node_modules/node-addon-api": { @@ -2516,6 +2566,40 @@ "node": ">= 14" } }, + "node_modules/mdast-util-from-markdown": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz", + "integrity": "sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -2537,6 +2621,472 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", + "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz", + "integrity": "sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", + "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz", + "integrity": "sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz", + "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz", + "integrity": "sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz", + "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz", + "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz", + "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz", + "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz", + "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz", + "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz", + "integrity": "sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz", + "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz", + "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", + "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz", + "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", + "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz", + "integrity": "sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz", + "integrity": "sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.2.tgz", + "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/micromark/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -2562,6 +3112,15 @@ "node": "*" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2721,6 +3280,15 @@ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", "dev": true }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, "node_modules/ordered-binary": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", @@ -2930,6 +3498,21 @@ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, + "node_modules/remark-parse": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz", + "integrity": "sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2972,6 +3555,18 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3079,6 +3674,12 @@ "source-map": "^0.6.0" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -3197,6 +3798,16 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/trough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -3227,6 +3838,38 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", + "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/utility-types": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", @@ -3236,18 +3879,72 @@ "node": ">= 4" } }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/vfile": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", + "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", + "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/weak-lru-cache": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", "dev": true }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, "node_modules/xxhash-wasm": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", @@ -3262,6 +3959,28 @@ "engines": { "node": ">= 6" } + }, + "node_modules/yaml-front-matter": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/yaml-front-matter/-/yaml-front-matter-4.1.1.tgz", + "integrity": "sha512-ULGbghCLsN8Hs8vfExlqrJIe8Hl2TUjD7/zsIGMP8U+dgRXEsDXk4yydxeZJgdGiimP1XB7zhmhOB4/HyfqOyQ==", + "dev": true, + "dependencies": { + "commander": "^6.2.0", + "js-yaml": "^3.14.1" + }, + "bin": { + "yaml-front-matter": "bin/js-yaml-front.js" + } + }, + "node_modules/yaml-front-matter/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } } }, "dependencies": { @@ -3416,34 +4135,6 @@ "@lezer/common": "^0.15.0" } }, - "@lmdb/lmdb-darwin-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", - "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-darwin-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", - "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-linux-arm": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", - "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", - "dev": true, - "optional": true - }, - "@lmdb/lmdb-linux-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", - "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", - "dev": true, - "optional": true - }, "@lmdb/lmdb-linux-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", @@ -3451,13 +4142,6 @@ "dev": true, "optional": true }, - "@lmdb/lmdb-win32-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", - "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", - "dev": true, - "optional": true - }, "@mischnic/json-sourcemap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", @@ -4190,12 +4874,42 @@ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true }, + "@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, + "@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, + "@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -4239,6 +4953,18 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "args-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/args-parser/-/args-parser-1.3.0.tgz", + "integrity": "sha512-If3Zi4BSjlQIJ9fgAhSiKi0oJtgMzSqh0H4wvl7XSeO16FKx7QqaHld8lZeEajPX7y1C5qKKeNgyrfyvmjmjUQ==", + "dev": true + }, + "bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4326,6 +5052,12 @@ "supports-color": "^7.1.0" } }, + "character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -4441,12 +5173,33 @@ "ms": "^2.1.1" } }, + "decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dev": true, + "requires": { + "character-entities": "^2.0.0" + } + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true + }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true }, + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4546,6 +5299,18 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -4577,12 +5342,20 @@ "to-regex-range": "^5.0.1" } }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", "dev": true, - "optional": true + "requires": { + "js-yaml": "^3.13.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "get-port": { "version": "4.2.0", @@ -4590,6 +5363,39 @@ "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", "dev": true }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -4678,6 +5484,22 @@ "resolve-from": "^4.0.0" } }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4693,6 +5515,12 @@ "binary-extensions": "^2.0.0" } }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4720,12 +5548,39 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true + }, "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 }, + "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==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + } + } + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4738,6 +5593,12 @@ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "dev": true }, + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true + }, "lightningcss": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.16.0.tgz", @@ -4755,41 +5616,6 @@ "lightningcss-win32-x64-msvc": "1.16.0" } }, - "lightningcss-darwin-arm64": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.16.0.tgz", - "integrity": "sha512-gIhz6eZFwsC4oVMjBGQ3QWDdLQY7vcXFyM/x91PilgHqu63B9uBa10EZA75YoTEkbKhoz0uDCqyHh/EoF1GrkQ==", - "dev": true, - "optional": true - }, - "lightningcss-darwin-x64": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.16.0.tgz", - "integrity": "sha512-kLPi+OEpDj3UGY6DC8TfjbcULJDKMP+TVKSlrEkNGn8t1YRzi2g4oy7UVTSB5AnSbT0CusUItzdVjHQ49EdoNA==", - "dev": true, - "optional": true - }, - "lightningcss-linux-arm-gnueabihf": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.16.0.tgz", - "integrity": "sha512-oSwEbvXUPr//H/ainBRJXTxHerlheee/KgkTTmAQWiVnt8HV+bRohTBWWPBy5ZArgiGLwj7ogv45istgljPN2Q==", - "dev": true, - "optional": true - }, - "lightningcss-linux-arm64-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.16.0.tgz", - "integrity": "sha512-Drq9BSVIvmV9zsDJbCZWCulMvKMQWFIlYXPCKV/iwRj+ZAJ1BRngma0cNHB6uW7Wac8Jg04CJN5IA4ELE3J+cQ==", - "dev": true, - "optional": true - }, - "lightningcss-linux-arm64-musl": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.16.0.tgz", - "integrity": "sha512-1QXWStnTEo4RFQf0mfGhRyNUeEHilCZ0NA97XgwKwrYr/M7sYKU/1HWY00dPxFJ6GITR2pfJGo9xi3ScSSBxbA==", - "dev": true, - "optional": true - }, "lightningcss-linux-x64-gnu": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.16.0.tgz", @@ -4804,13 +5630,6 @@ "dev": true, "optional": true }, - "lightningcss-win32-x64-msvc": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.16.0.tgz", - "integrity": "sha512-h4ayyAlOMLUHV9NdofcIu79aEjmly93adVxcg5wDJpkvMiwDTufEN30M8G4gGcjo1JE5jFjAcyQcRpXYkYcemA==", - "dev": true, - "optional": true - }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -4904,6 +5723,32 @@ "dev": true, "requires": {} }, + "mdast-util-from-markdown": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz", + "integrity": "sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + } + }, + "mdast-util-to-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", + "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "dev": true + }, "mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -4922,6 +5767,256 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "micromark": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", + "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", + "dev": true, + "requires": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "micromark-core-commonmark": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz", + "integrity": "sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==", + "dev": true, + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "micromark-factory-destination": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", + "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-label": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz", + "integrity": "sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-factory-space": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz", + "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-title": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz", + "integrity": "sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==", + "dev": true, + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-factory-whitespace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz", + "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==", + "dev": true, + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz", + "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-chunked": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz", + "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-classify-character": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz", + "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-combine-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz", + "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==", + "dev": true, + "requires": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz", + "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-decode-string": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz", + "integrity": "sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==", + "dev": true, + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-encode": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz", + "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==", + "dev": true + }, + "micromark-util-html-tag-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz", + "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==", + "dev": true + }, + "micromark-util-normalize-identifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", + "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-resolve-all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz", + "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==", + "dev": true, + "requires": { + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-sanitize-uri": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", + "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-subtokenize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz", + "integrity": "sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==", + "dev": true, + "requires": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-util-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz", + "integrity": "sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==", + "dev": true + }, + "micromark-util-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.2.tgz", + "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==", + "dev": true + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -4941,6 +6036,12 @@ "brace-expansion": "^1.1.7" } }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5063,6 +6164,15 @@ "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", "dev": true }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, "ordered-binary": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", @@ -5214,6 +6324,17 @@ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, + "remark-parse": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz", + "integrity": "sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "unified": "^10.0.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -5235,6 +6356,15 @@ "queue-microtask": "^1.2.2" } }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "requires": { + "mri": "^1.1.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5303,6 +6433,12 @@ "source-map": "^0.6.0" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -5389,6 +6525,12 @@ "nopt": "~1.0.10" } }, + "trough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "dev": true + }, "tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -5413,24 +6555,88 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", + "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0" + } + }, "utility-types": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", "dev": true }, + "uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dev": true, + "requires": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + } + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "vfile": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", + "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + } + }, + "vfile-message": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", + "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + } + }, "weak-lru-cache": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", "dev": true }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, "xxhash-wasm": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", @@ -5442,6 +6648,24 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true + }, + "yaml-front-matter": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/yaml-front-matter/-/yaml-front-matter-4.1.1.tgz", + "integrity": "sha512-ULGbghCLsN8Hs8vfExlqrJIe8Hl2TUjD7/zsIGMP8U+dgRXEsDXk4yydxeZJgdGiimP1XB7zhmhOB4/HyfqOyQ==", + "dev": true, + "requires": { + "commander": "^6.2.0", + "js-yaml": "^3.14.1" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + } + } } } } diff --git a/package.json b/package.json index 833ee63a7..332197073 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,20 @@ "devDependencies": { "@fermyon/styleguide": "^0.1", "@parcel/transformer-sass": "^2.7.0", + "args-parser": "^1.3.0", + "front-matter": "^4.0.2", + "glob": "^8.0.3", "markdownlint-cli2": "^0.5.1", "nodemon": "^2.0.20", - "sass": "^1.49.9" + "remark-parse": "^10.0.1", + "sass": "^1.49.9", + "unified": "^10.1.2", + "yaml-front-matter": "^4.1.1" }, "scripts": { - "spin": "nodemon --watch content --watch static --watch templates --ext md,rhai,hbs,css,js --verbose --legacy-watch --signal SIGINT --exec 'spin up --file spin.toml'", + "spin": "nodemon --watch content --watch static --watch templates --ext md,rhai,hbs,css,js --verbose --legacy-watch --signal SIGINT --exec 'npm run build-index && spin up --file spin.toml'", "styles": "npx parcel build static/sass/styles.scss --dist-dir static/css --no-optimize", - "test": "npx markdownlint-cli2 content/**/*.md \"#node_modules\"" + "test": "npx markdownlint-cli2 content/**/*.md \"#node_modules\"", + "build-index": "node md_parser.mjs --dir=./content/ --out=./static/data.json" } } diff --git a/static/css/styles.css b/static/css/styles.css index 0fa564d3d..fc36eaceb 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -1422,4 +1422,291 @@ html.dark-theme body .content a.anchor-link { max-width: 800px; } +.search-button-container { + height: 100%; + justify-content: center; + align-items: center; + display: flex; +} + +.search-button { + color: #345995; + z-index: 9; + cursor: grab; + background-color: #0000; + border: 1px solid #a8a8a8; + border-radius: .667rem; + justify-content: space-between; + align-items: center; + padding: .8rem; + display: flex; +} + +.search-icon { + color: #a8a8a8; + font-size: .7rem; +} + +.search-placeholder { + padding: 0 1rem; + font-size: .8rem; + font-weight: 600; +} + +.search-command { + color: #345995; + background-color: #e9e1eb; + border-radius: .667rem; + padding: .25em .5em; + font-size: .7rem; +} + +html.dark-theme .search-button { + color: #fff; + border: 1px solid #a8a8a8; +} + +html.dark-theme .search-command { + color: #ece5ee; + background-color: #213762; +} + +html.dark-theme .modal-wrapper { + background-color: #00000040; +} + +html.dark-theme .modal-box { + background: #0d203f; +} + +html.dark-theme input[type="text"].modal-search-bar { + color: #fff; + background-color: #213762; +} + +html.dark-theme input[type="text"].modal-search-bar::placeholder { + color: #989898; +} + +html.dark-theme .result-block { + background-color: #213762; +} + +html.dark-theme .result-block a { + color: #fff; +} + +html.dark-theme .result-block code, html.dark-theme .result-subitem { + background-color: #0d203f; +} + +html.dark-theme .result-subheading-container a { + color: #34e8bd; +} + +html.dark-theme .result-section-container .result-filters code { + color: #da1039; + background-color: #99919b; +} + +html.dark-theme .result-section-container .result-filters code.active { + background-color: #e9e1eb; +} + +html.dark-theme .result-section-container .suggested-project { + background-color: #213762; +} + +html.dark-theme .result-section-container .suggested-project .project-title { + color: #fff; +} + +html.dark-theme .result-section-container .suggested-project .suggested-project-link { + color: #34e8bd; + background-color: #0d203f; +} + +.search-modal-container { + box-sizing: border-box; + width: 100%; + height: 100%; + z-index: 1000; + margin: 0; + display: none; + position: fixed; + top: 0; + left: 0; +} + +.modal-wrapper { + width: 100%; + height: 100%; + -webkit-backdrop-filter: blur(6px); + backdrop-filter: blur(6px); + background-color: #00000080; + justify-content: center; + align-items: center; + display: flex; +} + +.modal-box { + width: 80%; + height: 80%; + max-width: 600px; + max-height: 700px; + background-color: #e9e1eb; + border-radius: .667rem; + flex-direction: column; + align-items: center; + padding: 1rem; + display: flex; +} + +.modal-search-bar { + box-sizing: border-box; + width: 100%; + border: 0; + border-radius: .667rem; + margin-bottom: 1rem; + padding: .8rem; + font-size: 1.2rem; + line-height: 1.5rem; +} + +.modal-search-bar:focus { + outline: none; +} + +.result-section-container { + width: 100%; + flex-direction: column; + flex-grow: 1; + display: flex; + overflow-y: auto; +} + +.result-section-container .suggested-project { + color: #000; + background-color: #f3f3f3; + border-radius: .667rem; + flex-direction: column; + justify-content: center; + align-items: center; + margin: .2rem; + padding: .6rem; + display: flex; +} + +.result-section-container .suggested-project .project-title { + padding: .5em; + font-weight: 600; +} + +.result-section-container .suggested-project .recommended-navs { + width: 100%; + flex-flow: wrap; + justify-content: space-evenly; + align-items: center; + display: flex; +} + +.result-section-container .suggested-project .suggested-project-link { + width: 45%; + color: #345995; + background-color: #fff; + border-radius: .667rem; + justify-content: center; + align-items: center; + margin-bottom: .4rem; + padding: 1rem; + font-size: 1rem; + font-weight: 400; + display: flex; + overflow-y: auto; +} + +.result-section-container .result-section { + width: 100%; + border-radius: .667rem; + flex-grow: 1; + overflow-y: auto; +} + +.result-section-container .result-section::-webkit-scrollbar { + width: 0; +} + +.result-section-container .result-filters { + cursor: grab; + justify-content: space-between; + align-items: center; + padding: 0 .4rem .4rem; + display: flex; +} + +.result-section-container .result-filters .filter-categories { + max-width: 80%; +} + +.result-section-container .result-filters .reset-filter { + font-size: .8rem; +} + +.result-section-container .result-filters code { + color: #f5f5f5; + background-color: #4d407f90; + border-radius: .667rem; + margin-left: .5rem; + font-size: .8rem; +} + +.result-section-container .result-filters code.active { + color: #fff; + background-color: #0d203f; +} + +.result-block { + color: #000; + background-color: #f3f3f3; + border-radius: .667rem; + flex-direction: column; + margin: .2rem; + padding: .6rem; + display: flex; +} + +.result-block a { + color: #363636; +} + +.result-block code { + background-color: #e9e1eb; + border-radius: .667rem; + margin-left: .5rem; + font-size: .8rem; +} + +.result-subheading-container { + padding: 1rem; +} + +.result-subheading-container a { + color: #345995; +} + +.result-subitem { + background-color: #fff; + border-radius: .667rem; + align-items: center; + margin-bottom: .4rem; + font-size: 1rem; + display: flex; + overflow-y: auto; +} + +.result-item-icon { + padding: .4rem; + font-size: 1.5rem; +} + /*# sourceMappingURL=styles.css.map */ diff --git a/static/css/styles.css.map b/static/css/styles.css.map index b16872dab..8d3248e4b 100644 --- a/static/css/styles.css.map +++ b/static/css/styles.css.map @@ -1 +1 @@ -{"mappings":"AEiCA;;;;AAKA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AAGG;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAOA;;;;;AElFH;;;;;AAIA;;;;;AAMA;;;;;AAKA;;;;;;;AAOA;;;;;;;;;;;;;AAYI;;;;;AAKA;;;;;AAKA;;;;;;;;;;AAUA;;;;;AAIA;;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCE;;;;;;;AAOE;;;;;;;;;AAUI;;;;AAKJ;;;;;;;;;;;;;AAYE;;;;;;;;;;;;;AAaF;;;;;;;;;;;;;AAeA;;;;AAKJ;;;;;;AAKI;;;;AAIA;;;;;AAOJ;;;;;;AAOI;;;;;;;;AAOI;;;;;;;;;;;;;;AAeI;;;;;;AAQR;;;;;;;AAMI;;;;;AAQZ;;;;;;AAMQ;EADJ;;;;;;;;;;AAUI;EAVJ;;;;;;;;AAmBI;EADJ;;;;;;;;;;;;;;;AAiBJ;;;;;;;;;;;;;AAYI;;;;AAIA;;;;;AAKA;;;;AAIA;;;;;;;;;AAQI;;;;;AAKA;;;;;;;;;AAQI;;;;;AAKA;;;;AAIA;;;;;AAII;;;;AAQhB;;;;AAIA;;;;AAIA;;;;;AAKA;;;;AAIA;;;;;;;AAMI;;;;;;;;;;;AAaA;;;;;AAII;;;;;;AAKI;;;;;;;;;;;;;AAgBA;;;;;AAMJ;;;;AAKI;;;;;;AAKI;;;;AAOZ;;;;;AAII;;;;;;AAUR;;;;;;AAKI;;;;;;AAMA;;;;;;;;;;;AAUI;;;;;;AAMA;;;;;;;;;AASA;;;;;AAOQ;;;;AAShB;;;;;;;;;;AAUI;;;;AAKA;;;;;;;;AAQA;;;;;;;AAOA;;;;;;AAMA;;;;;AAKA;;;;AAGI;;;;AAMJ;;;;AAGI;;;;;AAII;;;;;;;AAMI;;;;;AAII;;;;AAKJ;;;;AAMR;;;;AAMR;EACI;;;;;;;AAaJ;;;;;AAII;;;;AAIA;;;;;AAKQ;;;;AAIJ;;;;AAGI;;;;;AAMJ;;;;;AAMI;;;;AAIA;;;;AAGI;;;;;AAQJ;;;;;;AAQR;;;;AAMI;;;;AAIA;;;;AAGI;;;;;AAKA;;;;AAOR;;;;AAIA;;;;;;;AAOI;;;;AAIA;;;;AAMA;;;;;AAMI;;;;;AAOA;;;;AAKJ;;;;AAGI;;;;;;AAOJ;;;;;;AAQI;;;;AAMR;;;;;;AAKI;;;;AAIA;;;;AAIA;;;;ACnuBR;;;;;;AAQI;;;;;AAKA;;;;;;AAOI;;;;AAKA;;;;AAKA;;;;AAMA;;;;;;;AAQA;;;;AAGI;;;;;AAOA;;;;AAOR;;;;;;;AAOA;;;;;AAKI;;;;;;;;;;;;;AAaA;;;;AAKJ;;;;;;AAKI;;;;;;;;;;;;AAaA;;;;AAKJ;;;;AAMI;;;;AAMA;;;;;AAMJ;;;;AAMI;;;;AAMA;;;;;AAMJ;;;;AAIA;;;;;;AAKI;;;;;;;;;;;;;;AAcA;;;;;AAII;;;;;;AAMA;;;;;AAOR;;;;;;AAKI;;;;;;;AAQJ;;;;;;;;AAOI;;;;AAIA;;;;;;;;;;;AAYA;;;;AAGI;;;;AAMR;;;;;AAII;;;;;;;;;;;;;;;;;;AAmBA;;;;AAEI;;;;;AAQJ;;;;;;AAKI;;;;AAIA;;;;;;;;AASJ;;;;;AAII;;;;;AAII;;;;AAKJ;;;;AAGI;;;;;AAoBR;;;;;;AAOJ;;;;;;;;;;;AAWI;;;;AAIA;;;;AAGI;;;;AAMR;;;;;;AAMA;;;;AAIA;;;;AAKA;;;;;;AAAwD;;;;AAA0B;;;;;AAAuC;;;;;AAA0D;;;;AAAuD;;;;AAAqF;;;;AAA4B;;;;AAA+F;;;;AAAuJ;;;;AAA4F;;;;AAAwE;;;;AAAiC;;;;AAA6B;;;;AAGvzB;;;;;AAII;;;;AAMI;;;;AAIA;;;;ACjYR;EAIQ;;;;;;EACI;;;;EAWJ;;;;EAIA;;;;EAGI;;;;EAOR;;;;;;EAKI;;;;;;EASA;;;;;;;EASJ;;;;;EAMA;;;;;;EAMA;;;;;EAKA;;;;;;;EAMI;;;;;ANhDP;;;;AAGC;;;;;;AAOC;;;;AAKD;;;;;;;;;AAQC;;;;;AAIA;;;;AAIA;;;;;;;;AAQA;;;;;AAIC;;;;AAIA;;;;AAKD;;;;AAIA;;;;;;;;AAQC;;;;AAKD;;;;AAQF;;;;;;;;;;;AAWC;;;;AAIA;;;;AAKD;;;;AAOC;;;;AAKC;;;;;;;;;;;;;AAkBD;;;;;;;;AAWC;;;;AA+BD;;;;AAKD;;;;AAQE;;;;;AAIC;;;;AAIA;;;;AAOA;;;;AAKD;;;;AASH;EAGG;;;;EAIA;;;;EAIA;;;;;AASH","sources":["static/sass/styles.scss","node_modules/@fermyon/styleguide/scss/fermyon.scss","node_modules/@fermyon/styleguide/scss/fermyon-color.scss","node_modules/@fermyon/styleguide/scss/fermyon-mixins.scss","node_modules/@fermyon/styleguide/scss/fermyon-base.scss","node_modules/@fermyon/styleguide/scss/fermyon-type.scss","node_modules/@fermyon/styleguide/scss/fermyon-responsive.scss"],"sourcesContent":["/* FERMYON SHINY VENEER\n=======================\nFor the benefit of browser-based experiences, websites and application user \ninterfaces. This Sass file should be compiled to a CSS stylesheet and served \nafter a base framework such as Bulma, Bootstrap or similar base grid system.\n\nto generate to css:\nhttps://sass-lang.com/install \n\nthen run:\nsass --watch static/sass/styles.scss static/css/style.css --style compressed\n\n\nTABLE OF CONTENTS\n================= */\n@import \"../../node_modules/@fermyon/styleguide/scss/fermyon\";\n/* \n npm package 'fermyon-styleguide':\n =================================\n 0.1. Brand Colors\n 0.2. Variables and Mixins\n 0.3. Global Layout\n 0.4. Typography\n 0.5. Responsive Media Queries\n\n1.1. Spin: Docs Styles\n*/\n\n/* 1.1 Spin: Docs Styles\n*/\n\n.documentation {\n\t.content {\n\t\tpadding-top: 8.5rem;\n\n\t\th1 {\n\t\t\tmargin-top: 2rem;\n\t\t\tposition: relative;\n\t\t\tpadding-bottom: 2.67rem;\n\t\t}\n\n\t\t&.content-docs-wide {\n\t\t\tp {\n\t\t\t\tline-height: 1.725;\n\t\t\t}\n\t\t}\n\n\t\tdetails {\n\t\t\tfont-size: 1rem;\n\t\t\twidth: 100%;\n\t\t\tbackground: #f4f0f5;\n\t\t\tborder-left: 4px solid #d9dbe8;\n\t\t\tposition: relative;\n\t\t\tmax-width: 800px;\n\n\t\t\t.summary-title {\n\t\t\t\tuser-select: none;\n\t\t\t}\n\n\t\t\t&:hover {\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\n\t\t\t.summary-content {\n\t\t\t\tborder-top: 1px solid #e2e8f0;\n\t\t\t\tcursor: default;\n\t\t\t\tpadding: 1em;\n\t\t\t\tfont-weight: 300;\n\t\t\t\tline-height: 1.5;\n\t\t\t}\n\n\t\t\tsummary {\n\t\t\t\tlist-style: none;\n\t\t\t\tpadding: 1em;\n\n\t\t\t\t&:focus {\n\t\t\t\t\toutline: none;\n\t\t\t\t}\n\n\t\t\t\t&:hover .summary-chevron-up svg {\n\t\t\t\t\topacity: 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.summary-chevron-up svg {\n\t\t\t\topacity: 0.5;\n\t\t\t}\n\n\t\t\t.summary-chevron-up,\n\t\t\t.summary-chevron-down {\n\t\t\t\tpointer-events: none;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 0.75em;\n\t\t\t\tright: 1em;\n\t\t\t\tbackground: #f4f0f5;\n\n\t\t\t\tsvg {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsummary::-webkit-details-marker {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Styles for the copy button on code blocks\n\n\t.copy-code-button {\n\t\tposition: absolute;\n\t\ttop: 0.7rem;\n\t\tright: 0.7rem;\n\t\tborder-radius: 0.67rem;\n\t\tpadding: 0.2rem;\n\t\tcursor: pointer;\n\t\tbackground-color: #ededed25;\n\t\tborder: 2px solid;\n\t\tborder-color: #ededed35;\n\n\t\t>svg {\n\t\t\tfill: #ededed99;\n\t\t}\n\n\t\t&:hover {\n\t\t\tborder-color: #ededed99;\n\t\t}\n\t}\n\n\t.copy-code-button.is-success {\n\t\tborder-color: #18d1a5;\n\t}\n\n\t// Styling for active project in topbar\n\n\t.logo-project {\n\t\ta {\n\t\t\tposition: relative;\n\t\t}\n\n\t\ta.is-active {\n\t\t\t&::after {\n\t\t\t\tcontent: \"\";\n\t\t\t\tdisplay: block;\n\t\t\t\tposition: absolute;\n\t\t\t\tleft: 0;\n\t\t\t\tright: 0;\n\t\t\t\tbottom: -0.5rem;\n\t\t\t\twidth: 90%;\n\t\t\t\tmargin: auto;\n\t\t\t\theight: 3px;\n\t\t\t\tbackground: #0e8fdd;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Styles for anchor linking headers\n\n\t.content {\n\t\ta.anchor-link {\n\t\t\tpadding: 0.3rem;\n\t\t\ttext-decoration: none;\n\t\t\topacity: 0;\n\t\t\tfill: #363636;\n\t\t\tbackground-color: transparent;\n\t\t}\n\t}\n\n\th1 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\th2 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\th3 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\th4 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\ta.anchor-link {\n\t\t&:after {\n\t\t\tcontent: none;\n\t\t}\n\t}\n\n\taside.menu {\n\t\tpadding-bottom: 7.5rem;\n\t}\n}\n\nhtml.dark-theme {\n\tbody {\n\t\t.content {\n\t\t\tdetails {\n\t\t\t\tbackground: #1b2c4f;\n\t\t\t\tborder-left: 4px solid #243c6c;\n\n\t\t\t\t.summary-content {\n\t\t\t\t\tborder-top: 1px solid #243c6c;\n\t\t\t\t}\n\n\t\t\t\t.summary-chevron-up,\n\t\t\t\t.summary-chevron-down {\n\t\t\t\t\tbackground: #1b2c4f;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ta.anchor-link {\n\t\t\t\t&:hover {\n\t\t\t\t\tbackground: transparent !important;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ta.anchor-link {\n\t\t\t\tfill: #fff;\n\t\t\t}\n\t\t}\n\t}\n\n\n}\n\n@media screen and (max-width: 1023px) {\n\t.documentation {\n\t\t.content {\n\t\t\th1 {\n\t\t\t\tfont-size: 6.333vw;\n\t\t\t}\n\n\t\t\th2 {\n\t\t\t\tfont-size: 5vw;\n\t\t\t}\n\n\t\t\th3 {\n\t\t\t\tfont-size: 3.33vw;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// fixing https://github.com/fermyon/developer/issues/54 temporarily\n\n.content pre {\n\tmax-width: 800px;\n}","/* FERMYON SHINY VENEER\n=======================\nFor the benefit of browser-based experiences, websites and application user \ninterfaces. This Sass file should be compiled to a CSS stylesheet and served \nafter a base framework such as Bulma, Bootstrap or similar base grid system.\n\nto generate to css:\nhttps://sass-lang.com/install \n\nthen run:\nsass --watch static/sass/styles.scss static/css/style.css --style compressed\n\n\nTABLE OF CONTENTS\n=================\n0.1. Brand Colors\n0.2. Variables and Mixins\n0.3. Global Layout\n0.4. Typography\n*/\n\n@import \"fermyon-color\";\n@import \"fermyon-mixins\";\n@import \"fermyon-base\";\n@import \"fermyon-type\";\n@import \"fermyon-responsive\";\n","/* 1.\n Brand Colors\n*/\n\n// Core Brand\n$seagreen: #34E8BD;\n$oxfordblue: #0D203F;\n\n// Secondary Accents\n$rust: #EF946C;\n$lavender: #BEA7E5;\n$colablue: #0E8FDD;\n\n// Tertiary Shades\n\n$darkspace: #213762;\n$darkocean: #0A455A;\n$darkolive: #1F7A8C;\n$darkplum: #525776;\n\n$midgreen: #1FBCA0;\n$midblue: #345995;\n\n$lightplum: #D3C3D9;\n$lightgray: #D9DBE8;\n$lightlavender: #ECE5EE;\n$lightlemon: #F9F7EE;\n\n\n// Remapping Bulma Colors\n\n$darkblue: $midblue;\n\n.is-primary, .has-text-primary {\n color: $oxfordblue !important;\n}\n\n\n.is-link, .has-text-link { color: darken($colablue, 12.5%) !important; }\n.is-info, .has-text-info { color: darken($lavender, 10%) !important; }\n.is-success, .has-text-success { color: darken($midgreen, 10%) !important; }\n.is-warning, .has-text-warning { color: $rust !important; }\n.is-danger, .has-text-danger { color: darken($rust, 25%) !important; }\n.is-dark, .has-text-dark { color: $darkspace !important; }\n.is-light, .has-text-light { color: darken($lightplum, 12.5%) !important; }\n\n.button, .tag, .message {\n &.is-primary {\n background-color: darken($seagreen, 10%);\n color: white !important;\n }\n &.is-secondary {\n background-color: lighten($darkspace, 12.5%);\n color: white !important;\n }\n &.is-link {\n background-color: darken($colablue, 12.5%) !important;\n color: white !important;\n }\n &.is-info {\n background-color: darken($lavender, 10%) !important;\n color: white !important;\n }\n &.is-success {\n background-color: darken($midgreen, 10%) !important;\n color: white !important;\n }\n &.is-warning {\n background-color: $rust !important;\n color: white !important;\n }\n &.is-danger {\n background-color: darken($rust, 25%) !important;\n color: white !important;\n }\n &.is-dark {\n background-color: $darkspace;\n color: white !important;\n }\n &.is-light {\n background-color: darken($lightplum, 12.5%);\n color: $oxfordblue !important;\n }\n}\n\n.content {\n .is-active, .is-current {\n color: white;\n background-color: $darkspace;\n }\n}\n","/* 2.\n Variables and Mixins\n*/\n\n$sen: Sen, Europa, Avenir, system, -apple-system, \".SFNSText-Regular\", \"San Francisco\", \"Segoe UI\", \"Helvetica Neue\", \"Lucida Grande\", sans-serif;\n$mono: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;\n\n@mixin transition($property:all, $duration:0.3s, $easing:ease-in-out) {\n transition: $property $duration $easing;\n}\n\n@mixin border-radius($radius1:3px, $radius2:3px) {\n -webkit-border-radius: $radius1 $radius2 $radius1 $radius2;\n -moz-border-radius: $radius1 $radius2 $radius1 $radius2;\n border-radius: $radius1 $radius2 $radius1 $radius2;\n}\n\n@mixin box-shadow($xlength:0, $ylength:2px, $size:0, $color:rgba(30,30,30,0.25)) {\n -webkit-box-shadow: $xlength $ylength $size $color;\n -moz-box-shadow: $xlength $ylength $size $color;\n box-shadow: $xlength $ylength $size $color;\n}\n\n@mixin verticalCenter {\n position: relative;\n top: 50%;\n transform: translateY(-50%);\n}\n\n@mixin sen {\n letter-spacing: 0.025em;\n}","/* 3.\n Global Base\n*/\n\nhtml {\n height: 100%;\n background-color: transparent;\n}\nbody,\nmain {\n min-height: 100vh;\n position: relative;\n}\n\nbody {\n background: lighten($lightlavender, 5%);\n min-height: 100vh;\n}\n\nmain {\n padding: 5.75rem 0 0;\n min-height: 100vh;\n margin-bottom: -12rem;\n z-index: 100;\n}\n\n#topbar.navbar {\n background: lighten($lightlavender, 5%);\n padding-left: 5vw;\n padding-right: 5vw;\n border-bottom: 2px solid rgba(255,255,255,0.98);\n will-change: transform;\n transition: transform 200ms linear;\n position: fixed;\n left: 0;\n right: 0;\n z-index: 1000;\n\n .navbar-burger {\n width: 5.25rem;\n height: 5.25rem;\n }\n\n &.is-wide {\n padding-left: 2.5vw;\n padding-right: 2.5vw;\n }\n\n .dark-mode {\n position: absolute;\n right: 0;\n top: 2rem;\n display: inline-block;\n width: 1.5rem;\n line-height: 1.5;\n fill: $midblue;\n }\n\n &.headroom--pinned {\n margin: 0;\n transform: translateY(0%);\n }\n &.headroom--unpinned {\n transform: translateY(-100%);\n }\n\n @keyframes halfSpin {\n 0% {\n transform: rotate(0);\n }\n\n 25% {\n transform: rotate(180deg);\n opacity: 1;\n }\n\n 38% {\n opacity: 0.75;\n }\n\n 50% {\n transform: rotate(180deg);\n }\n\n 75% {\n transform: rotate(360deg);\n opacity: 1;\n }\n\n 88% {\n opacity: 0.75;\n }\n\n 100% {\n transform: rotate(360deg);\n }\n }\n\n .logo {\n display: inline-block;\n margin-top: 0;\n fill: $oxfordblue;\n position: relative;\n margin-top: 0.35em;\n\n svg {\n max-height: 1.25rem;\n max-width: 10.625rem;\n cursor: pointer;\n position: relative;\n z-index: 500;\n fill: $oxfordblue;\n }\n\n &:hover {\n .spin-back {\n background-color: white;\n }\n }\n\n .spin-front {\n width: 1.133rem;\n height: 1.133rem;\n display: inline-block;\n position: absolute;\n top: 1.25rem;\n right: 1.9125rem;\n border-radius: 50%;\n z-index: 600;\n opacity: 1;\n @include transition;\n\n em {\n width: 0.425rem;\n height: 0.425rem;\n display: inline-block;\n top: 0rem;\n right: 0.05rem;\n background: #28FFCC;\n position: absolute;\n z-index: 700;\n border-radius: 50%;\n @include transition;\n }\n }\n .spin-back {\n width: 1.125rem;\n height: 1.125rem;\n display: inline-block;\n position: absolute;\n top: 1.295rem;\n right: 1.875rem;\n border-radius: 50%;\n z-index: 400;\n background: transparent;\n @include transition;\n }\n }\n\n &:hover {\n .logo .spin-front {\n animation: 4s ease infinite halfSpin;\n }\n }\n\n .logo-project {\n font-weight: bold;\n margin: 2rem 0 0 1.3335rem;\n font-size: 1.125rem;\n\n a {\n color: $darkspace;\n }\n\n .tag {\n margin: -0.5rem 0 0 0.67rem;\n position: relative;\n }\n\n }\n\n a.navbar-item {\n line-height: 3;\n background: transparent;\n font-weight: 700;\n }\n\n .navbar-menu {\n a {\n margin-left: 2vw;\n position: relative;\n color: $oxfordblue;\n @include sen;\n @include transition;\n\n em {\n position: absolute;\n left: 45%;\n right: 45%;\n bottom: -0.15rem;\n height: 0.333rem;\n opacity: 0;\n background-color: $seagreen;\n display: inline-block;\n @include border-radius(1rem, 1rem);\n @include transition;\n content: \" \";\n }\n\n &:hover {\n em {\n left: 25%;\n right: 25%;\n opacity: 1;\n }\n }\n }\n\n .button {\n color: darken($seagreen, 15%);\n border-color: $seagreen;\n margin: 1rem 0 0 2.5rem;\n @include transition;\n\n &:hover {\n color: darken($seagreen, 22.5%);\n background-color: white !important;\n }\n }\n }\n}\n\n.menu-wrap {\n padding: 0 2.5vw;\n width: 17rem;\n background: lighten($lightlavender, 5%);\n\n &.is-fixed-desktop {\n @media screen and (min-width: 1024px) {\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n width: 17.5vw;\n background: lighten($lightlavender, 5%);\n }\n \n @media screen and (max-width: 1023px) {\n position: relative;\n top: auto;\n left: auto;\n right: auto;\n }\n }\n\n &.is-sticky {\n @media screen and (min-width: 1024px) {\n position: sticky;\n left: 2.5vw;\n top: 0;\n width: 15rem;\n padding-left: 0.67rem;\n bottom: 0;\n display: inline-block;\n vertical-align: top;\n max-height: 100vh;\n overflow-y: auto;\n background: lighten($lightlavender, 5%);\n }\n }\n}\n\naside.menu {\n font-size: 1rem;\n position: absolute;\n top: 0;\n bottom: 0;\n overflow-y: scroll;\n padding-top: 6.5rem;\n min-width: 13rem;\n width: 14.5vw;\n border-right: 2px solid transparent;\n @include transition;\n\n &:hover {\n border-right: 2px solid $lightlavender;\n }\n\n .menu-label {\n padding-left: 1.333vw;\n margin: 1.75rem 1.333vw 1rem 0;\n }\n\n ul {\n margin-bottom: 2.5rem;\n }\n\n a {\n padding: 0.6rem 1.25vw;\n margin-bottom: 0rem;\n font-weight: bold;\n display: inline-block;\n @include transition;\n @include border-radius(2rem,2rem);\n\n &:hover {\n background-color: $lightlavender;\n color: $darkspace;\n }\n\n &.button {\n line-height: 2.25;\n margin-top: 1.25rem;\n padding: 0 1.333vw;\n font-size: 1.125rem;\n background: transparent;\n border: 2px solid $seagreen;\n\n svg {\n margin-right: 0.25rem;\n margin-bottom: -1px;\n }\n\n svg, path {\n @include transition;\n }\n\n &:hover {\n background-color: $seagreen;\n color: white;\n\n svg, path {\n fill: white;\n }\n }\n }\n }\n}\n\n.menu-wrap + article.content {\n padding-left: 18.5vw;\n}\n\n.page-wrap {\n position: relative;\n}\n\n.is-fullwidth {\n width: 100vw;\n max-width: 100vw !important;\n}\n\nhr {\n background-color: rgba(100,100,100,.1);\n}\n\nhr.page-break {\n position: relative;\n text-align: center;\n height: 4rem;\n background: transparent;\n \n &:after {\n position: relative;\n width: 12.5%;\n display: inline-block;\n margin: 2.5rem 0 3.5rem;\n content: \" \";\n height: .33rem;\n background: $lavender;\n @include border-radius(0.33rem, 0.33rem);\n }\n}\n\n.documentation {\n .content {\n padding-top: 8.5rem;\n margin-bottom: 5rem;\n\n h1 {\n position: relative;\n padding-bottom: 2.67rem;\n margin: -1.5rem 0 5rem;\n \n &:after {\n position: absolute;\n width: 25%;\n margin: 2rem 0 0;\n display: inline-block;\n margin: 2.5rem 0 0;\n bottom: 0;\n left: 0;\n content: \" \";\n height: .33rem;\n background: $lavender;\n @include border-radius(0.33rem, 0.33rem);\n }\n }\n\n blockquote {\n p {\n font-size: 1rem;\n line-height: 1.4;\n }\n }\n \n .footer-nav {\n border-top: none;\n }\n\n &.content-docs-wide {\n section {\n max-width: 90vw !important;\n margin-left: 5vw;\n margin-right: 5vw;\n\n .content ul, .content ol, .content dl, .content p, .content blockquote {\n max-width: 100%;\n }\n }\n }\n }\n\n footer {\n padding-left: 2.5vw !important;\n padding-right: 2.5vw !important;\n \n .footer-nav {\n padding: 0 0.75rem;\n margin: 0;\n border-top: none;\n }\n }\n}\n\n\n\n.content section {\n margin-left: auto;\n margin-right: auto;\n max-width: 48.5rem;\n\n .box {\n margin-top: 2rem;\n margin-bottom: 3rem;\n padding: 1.67rem 2rem;\n }\n\n table {\n background-color: white;\n min-width: 100%;\n margin-top: 2rem;\n margin-bottom: 4rem;\n border-collapse: collapse;\n border-radius: 0.333em;\n overflow: hidden;\n box-shadow: 0 3px 6px rgba(30,30,30,.125);\n\n th, td {\n padding: 0.67vw 2vw;\n border-bottom: 1px solid $lavender;\n line-height: 1.5;\n }\n\n th {\n font-size: 1.125rem;\n font-weight: bold;\n color: $oxfordblue;\n background-color: $lightlemon;\n line-height: 1.75;\n border-bottom: 1px solid $lavender;\n }\n\n td {\n font-size: 1rem;\n border-bottom-color: $lightlavender;\n }\n\n tr {\n &:last-of-type {\n td {\n border: none;\n }\n }\n }\n }\n}\n\n\nfooter {\n background: white;\n margin: 0 auto 0;\n padding: 1.25rem 0 0;\n min-height: 12rem;\n border-top: 1px solid $lavender;\n position: relative;\n z-index: 1400;\n\n /* top row of links */\n ul,\n p {\n margin: 2rem 0 4rem;\n }\n\n p.lead {\n font-size: 1.25rem;\n max-width: 67%;\n line-height: 1.33;\n margin: -2.5rem 0 0;\n color: $darkocean\n }\n\n h4 {\n margin: 3rem 0 0;\n font-size: 1.25rem;\n font-weight: bold;\n color: $rust;\n }\n\n li {\n line-height: 2;\n list-style: none;\n font-size: 1.125rem;\n }\n\n img {\n max-height: 3rem;\n margin-top: 0;\n }\n\n &.is-shallow {\n min-height: 6.5rem;\n\n img {\n max-height: 2.5rem;\n }\n }\n\n /* bottom row of smaller links */\n .footer-nav {\n border-top: 1px solid $lightgray;\n\n .navbar {\n padding: 0;\n background: transparent;\n\n .navbar-item {\n padding: 0 4rem 0 0;\n font-size: 1rem;\n line-height: 1.33;\n color: $lavender;\n\n a {\n color: darken($lightgray, 12.5%);\n @include transition;\n\n &:hover {\n color: darken($lightgray, 42.5%);\n }\n }\n\n &:last-of-type {\n padding-right: 0;\n }\n }\n }\n\n p {\n margin: 0;\n }\n }\n}\n\n@media (prefers-color-scheme: dark) {\n html {\n background: lighten($lightlavender, 5%);\n color: $oxfordblue;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n html {\n background: $oxfordblue;\n color: white;\n }\n}\n\nhtml.dark-theme > body {\n background: $oxfordblue;\n color: white;\n\n h1, h2, h3, h4, h5, p, li {\n color: white;\n }\n\n #topbar.navbar {\n background: $oxfordblue;\n border-color: $darkocean;\n\n .logo {\n svg, path {\n fill: white !important;\n }\n }\n .logo-project a {\n color: $seagreen;\n\n .tag {\n background-color: $darkspace;\n color: $lavender !important;\n }\n }\n\n .navbar-burger {\n color: $lavender;\n height: 5.75rem;\n }\n\n .navbar-menu {\n a {\n color: $seagreen;\n }\n\n .button {\n border: 3px solid $seagreen;\n\n &:hover {\n background: $seagreen !important;\n color: $oxfordblue;\n }\n }\n }\n\n .dark-mode {\n svg {\n fill: $seagreen;\n transform: rotate(180deg);\n @include transition;\n }\n }\n }\n\n .menu-wrap {\n background: $oxfordblue;\n }\n\n aside.menu {\n\n &:hover {\n border-right: 2px solid darken($lavender, 55%);\n }\n\n a {\n color: white;\n \n &:hover {\n color: $seagreen;\n background-color: $darkspace;\n }\n\n &.button svg,\n &.button path {\n fill: white !important;\n }\n }\n }\n\n pre {\n background: linear-gradient(0, #173564 15%, lighten(desaturate(#173564, 12.5%), 3%) 100%);\n }\n\n .card {\n background: linear-gradient(0, lighten($oxfordblue, 5%), $oxfordblue 100%);\n box-shadow: 0 .5em 1em -.125em rgba(10,10,10,.5),\n 0 0 0 1px rgba(10,10,10,.52);\n outline: 1px solid rgba(255,255,255,0.2);\n color: white;\n\n figure.image {\n border-bottom: 1px solid rgba(255,255,255,0.333);\n }\n\n p {\n color: white;\n }\n }\n\n .content {\n .box {\n background-color: $darkspace;\n color: white;\n }\n \n h1, h2, h3, h4, h5, p, li, th, td, dd {\n code {\n background-color: $darkspace;\n color: $lightlavender;\n }\n }\n\n section {\n table {\n background-color: $darkspace;\n }\n }\n\n blockquote {\n background-color: transparent;\n\n p {\n background-color: darken($darkspace, 5%);\n border-color: lighten($darkspace, 2.5%);\n color: white;\n }\n }\n\n blockquote > blockquote p,\n aside p {\n background-color: lighten($darkspace, 2.5%);\n border-color: lighten($darkspace, 7.5%);\n color: white;\n }\n\n a {\n &:hover {\n background: darken($darkspace, 5%) !important;\n }\n }\n } \n\n footer {\n background: $oxfordblue;\n border-color: $darkocean;\n color: white;\n\n h4 {\n color: white;\n }\n\n .footer-nav {\n border-color: darken($oxfordblue, 7.5%);\n }\n\n p, li, a {\n color: $seagreen;\n }\n }\n}\n","/* 4.\n Typography\n*/\n\nbody {\n font-family: $sen;\n font-size: 16pt;\n color: $oxfordblue;\n}\n\n.content {\n\n h1, h2, h3 {\n font-weight: bold;\n display: block;\n }\n\n ul, ol, dl, p, blockquote {\n margin: 1.67rem 0;\n font-size: 1rem;\n max-width: 800px;\n }\n\n &.size-16 {\n ul, ol, dl, p, blockquote {\n font-size: 1rem;\n }\n }\n &.size-18{\n ul, ol, dl, p, blockquote {\n font-size: 1.125rem;\n }\n }\n &.size-20 {\n ul, ol, dl, p, blockquote {\n font-size: 1.25rem;\n }\n }\n\n ul {\n li {\n list-style: disc;\n list-style-position: outside;\n line-height: 1.636;\n margin: 0 0.5rem 0 1.25rem;\n padding-left: 0.5rem;\n }\n\n &.pagination-list {\n margin: 0;\n \n li {\n list-style: none;\n margin: 0;\n }\n }\n\n &.is-disc {\n li {\n list-style: disc;\n list-style-position: outside;\n }\n }\n }\n\n ol li {\n list-style-position: outside;\n line-height: 1.636;\n margin: 0 0.5rem 0 1.25rem;\n padding-left: 0.5rem;\n }\n\n blockquote > blockquote,\n aside {\n margin-top: 3rem;\n margin-bottom: 3rem;\n\n p {\n line-height: 1.8;\n border: 1px solid $lightgray;\n font-size: 1.2rem;\n background: $lightlemon;\n padding: 1.25rem 1.5rem !important;\n margin: 2.5em auto 5rem !important;\n text-align: left;\n border-radius: .667rem;\n box-shadow: 0 3px 6px rgba(30,30,30,.125);\n color: $oxfordblue;\n }\n\n a {\n color: $colablue;\n }\n }\n\n blockquote {\n padding: 0rem 0 !important;\n margin: 0 !important;\n border-left: none;\n\n p {\n color: darken($darkolive, 25%);\n color: $darkblue;\n font-size: 1.1rem !important;\n line-height: 2;\n padding-right: 0 !important;\n border-left: 4px solid $lightgray;\n background: lighten($lightlavender, 3.5%);\n padding: 0.65rem 5% 0.65rem 2rem !important;\n margin: 1rem auto 1rem !important;\n text-align: left;\n }\n\n a {\n color: $colablue;\n }\n }\n\n pre,\n code {\n margin-bottom: 2rem !important;\n }\n\n pre {\n code {\n margin-bottom: 0 !important;\n }\n }\n\n h1, h2, h3, h4, h5 {\n code {\n font-weight: bold;\n font-size: 1em !important;\n }\n }\n\n pre,\n code {\n margin-bottom: 2rem !important;\n }\n\n pre {\n code {\n margin-bottom: 0 !important;\n }\n }\n\n h1, h2, h3, h4, h5 {\n code {\n font-weight: bold;\n font-size: 1em !important;\n }\n }\n\n strong {\n color: $oxfordblue;\n }\n\n a {\n color: darken($colablue, 12.5%);\n border-radius: 0.333em;\n position: relative;\n\n &:after {\n position: absolute;\n text-align: center;\n background: $colablue;\n height: 0.125rem;\n content: \" \";\n display: inline-block;\n opacity: 0;\n bottom: -0.2rem;\n left: 33%;\n right: 33%;\n @include transition;\n }\n\n &:hover {\n background: rgba(255,255,255,0.67);\n color: $colablue;\n\n &:after {\n opacity: 1;\n left: 5%;\n right: 5%;\n }\n\n img + :after {\n display: none !important;\n margin-top: -4rem;\n }\n }\n }\n\n hr.page-break {\n text-align: left;\n height: 4rem;\n background: transparent;\n \n &:after {\n position: relative;\n width: 12.5%;\n margin: 1.5rem 0 2.5rem;\n height: .33rem;\n }\n }\n\n .copy {\n padding: 0.5rem 1rem;\n position: relative;\n border-radius: 1rem;\n margin-left: -1.5rem;\n margin-right: -1.5rem;\n\n img {\n width: 1em;\n }\n\n .button {\n position: absolute;\n padding: 0;\n line-height: 1;\n top: 0.01rem;\n right: 0.67rem;\n border: none;\n opacity: 0;\n background: transparent;\n \n }\n\n &:hover {\n background: rgba(100,100,100,0.17);\n \n .button {\n opacity: 1;\n }\n }\n }\n\n .copy-button {\n @include transition;\n cursor: pointer;\n\n &:after {\n content: \"Copied\";\n @include transition;\n display: inline-block;\n position: absolute;\n top: 0rem;\n right: 25%;\n top: 75%;\n transform: perspective(1px) translateY(-50%);\n z-index: 860;\n background: rgba(100,100,100,0.75);\n padding: 0.5rem 1rem;\n border-radius: 2rem;\n font-size: 1rem;\n font-weight: bold;\n opacity: 0;\n color: white;\n }\n\n &:active {\n opacity: 0.8;\n &:after {\n top: 50%;\n opacity: 1;\n }\n }\n }\n\n .card {\n p {\n margin: 0;\n line-height: 1.25;\n color: $oxfordblue;\n \n &.title {\n margin-bottom: 0.5rem;\n }\n\n em {\n font-family: $mono;\n font-style: normal;\n opacity: 0.333;\n display: inline-block;\n padding: 0 0.2rem 0 0;\n }\n }\n\n &.card-color {\n border-radius: 0.33rem;\n overflow: hidden;\n\n figure.image {\n border: 5px solid transparent;\n @include transition;\n \n &:hover {\n border-color: white;\n }\n }\n \n .card-content {\n padding: 0.5rem 0.5rem 1rem;\n\n p {\n margin: 0 0 -0.333rem;\n letter-spacing: -0.02em;\n }\n }\n }\n }\n\n /* Code Styling */\n\n h1,\n h2,\n h3, \n h4,\n h5,\n p,\n li,\n td,\n th,\n dd {\n code {\n border-radius: 0.33rem !important;\n background: darken($lightlavender, 1.25%);\n color: $darkblue;\n }\n }\n\n pre,\n code {\n margin-left: 0;\n border-radius: 0.67rem;\n background-color: $oxfordblue;\n background-image: linear-gradient(135deg, $oxfordblue 0%, lighten($oxfordblue, 3.33%) 100%);\n color: white;\n font-size: 0.925rem;\n color: $lavender;\n font-family: $mono;\n\n a {\n color: $colablue;\n }\n\n code.hljs {\n padding: 0 !important;\n\n .hljs-meta {\n color: $seagreen;\n } \n }\n }\n\n pre {\n margin: 1.333rem 0;\n max-width: 100%;\n position: relative;\n }\n\n code {\n border-radius: 0 !important;\n }\n\n .hljs {\n background-color: transparent !important;\n }\n\n /* highlight.js css */\n pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}\n}\n\nhtml.dark-theme > body {\n background: $oxfordblue;\n color: white;\n\n h1, h2, h3, h4, p, li {\n color: white;\n }\n\n .content,\n article {\n a {\n color: $seagreen;\n }\n\n strong {\n color: $lightlavender;\n }\n }\n}","/* \n Responsive Media Queries\n*/\n\n@media screen and (max-width: 1023px) {\n\n // topbar \n #topbar.navbar {\n .logo {\n svg,\n span {\n display: none !important;\n }\n \n width: 3rem;\n height: 3rem;\n background: url(../image/avatar.png) no-repeat 0 0;\n background-size: contain;\n }\n\n .logo-project {\n margin-left: 0.5rem;\n }\n\n .navbar-menu.is-pulled-right {\n text-align: right;\n\n a {\n float: right;\n }\n }\n }\n \n // burger menu\n .menu-wrap {\n z-index: 1400;\n width: 100vw;\n display: none;\n\n &.is-active {\n display: block !important;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n position: fixed;\n }\n\n aside.menu {\n width: 100vw;\n padding-left: 5vw;\n padding-right: 5vw;\n padding-top: 8rem;\n }\n }\n\n // hide weird horizontal scroll on mobile/tablet\n article.content section,\n footer {\n overflow-x: hidden !important;\n max-width: 100vw !important;\n }\n\n main.is-fullwidth {\n max-width: 90vw !important;\n padding-left: 5vw !important;\n padding-right: 5vw !important;\n }\n\n .menu-wrap + article.content {\n padding-left: 0;\n max-width: 85vw !important;\n }\n\n footer.is-shallow .footer-nav {\n max-width: 90vw;\n padding-left: 5vw;\n padding-right: 5vw;\n border-color: transparent !important;\n\n .navbar-item {\n display: inline-block;\n\n } \n } \n}"],"names":[],"version":3,"file":"styles.css.map"} \ No newline at end of file +{"mappings":"AEiCA;;;;AAKA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AACA;;;;AAGG;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAIA;;;;;AAOA;;;;;AElFH;;;;;AAIA;;;;;AAMA;;;;;AAKA;;;;;;;AAOA;;;;;;;;;;;;;AAYI;;;;;AAKA;;;;;AAKA;;;;;;;;;;AAUA;;;;;AAIA;;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCE;;;;;;;AAOE;;;;;;;;;AAUI;;;;AAKJ;;;;;;;;;;;;;AAYE;;;;;;;;;;;;;AAaF;;;;;;;;;;;;;AAeA;;;;AAKJ;;;;;;AAKI;;;;AAIA;;;;;AAOJ;;;;;;AAOI;;;;;;;;AAOI;;;;;;;;;;;;;;AAeI;;;;;;AAQR;;;;;;;AAMI;;;;;AAQZ;;;;;;AAMQ;EADJ;;;;;;;;;;AAUI;EAVJ;;;;;;;;AAmBI;EADJ;;;;;;;;;;;;;;;AAiBJ;;;;;;;;;;;;;AAYI;;;;AAIA;;;;;AAKA;;;;AAIA;;;;;;;;;AAQI;;;;;AAKA;;;;;;;;;AAQI;;;;;AAKA;;;;AAIA;;;;;AAII;;;;AAQhB;;;;AAIA;;;;AAIA;;;;;AAKA;;;;AAIA;;;;;;;AAMI;;;;;;;;;;;AAaA;;;;;AAII;;;;;;AAKI;;;;;;;;;;;;;AAgBA;;;;;AAMJ;;;;AAKI;;;;;;AAKI;;;;AAOZ;;;;;AAII;;;;;;AAUR;;;;;;AAKI;;;;;;AAMA;;;;;;;;;;;AAUI;;;;;;AAMA;;;;;;;;;AASA;;;;;AAOQ;;;;AAShB;;;;;;;;;;AAUI;;;;AAKA;;;;;;;;AAQA;;;;;;;AAOA;;;;;;AAMA;;;;;AAKA;;;;AAGI;;;;AAMJ;;;;AAGI;;;;;AAII;;;;;;;AAMI;;;;;AAII;;;;AAKJ;;;;AAMR;;;;AAMR;EACI;;;;;;;AAaJ;;;;;AAII;;;;AAIA;;;;;AAKQ;;;;AAIJ;;;;AAGI;;;;;AAMJ;;;;;AAMI;;;;AAIA;;;;AAGI;;;;;AAQJ;;;;;;AAQR;;;;AAMI;;;;AAIA;;;;AAGI;;;;;AAKA;;;;AAOR;;;;AAIA;;;;;;;AAOI;;;;AAIA;;;;AAMA;;;;;AAMI;;;;;AAOA;;;;AAKJ;;;;AAGI;;;;;;AAOJ;;;;;;AAQI;;;;AAMR;;;;;;AAKI;;;;AAIA;;;;AAIA;;;;ACnuBR;;;;;;AAQI;;;;;AAKA;;;;;;AAOI;;;;AAKA;;;;AAKA;;;;AAMA;;;;;;;AAQA;;;;AAGI;;;;;AAOA;;;;AAOR;;;;;;;AAOA;;;;;AAKI;;;;;;;;;;;;;AAaA;;;;AAKJ;;;;;;AAKI;;;;;;;;;;;;AAaA;;;;AAKJ;;;;AAMI;;;;AAMA;;;;;AAMJ;;;;AAMI;;;;AAMA;;;;;AAMJ;;;;AAIA;;;;;;AAKI;;;;;;;;;;;;;;AAcA;;;;;AAII;;;;;;AAMA;;;;;AAOR;;;;;;AAKI;;;;;;;AAQJ;;;;;;;;AAOI;;;;AAIA;;;;;;;;;;;AAYA;;;;AAGI;;;;AAMR;;;;;AAII;;;;;;;;;;;;;;;;;;AAmBA;;;;AAEI;;;;;AAQJ;;;;;;AAKI;;;;AAIA;;;;;;;;AASJ;;;;;AAII;;;;;AAII;;;;AAKJ;;;;AAGI;;;;;AAoBR;;;;;;AAOJ;;;;;;;;;;;AAWI;;;;AAIA;;;;AAGI;;;;AAMR;;;;;;AAMA;;;;AAIA;;;;AAKA;;;;;;AAAwD;;;;AAA0B;;;;;AAAuC;;;;;AAA0D;;;;AAAuD;;;;AAAqF;;;;AAA4B;;;;AAA+F;;;;AAAuJ;;;;AAA4F;;;;AAAwE;;;;AAAiC;;;;AAA6B;;;;AAGvzB;;;;;AAII;;;;AAMI;;;;AAIA;;;;ACjYR;EAIQ;;;;;;EACI;;;;EAWJ;;;;EAIA;;;;EAGI;;;;EAOR;;;;;;EAKI;;;;;;EASA;;;;;;;EASJ;;;;;EAMA;;;;;;EAMA;;;;;EAKA;;;;;;;EAMI;;;;;ANhDP;;;;AAGC;;;;;;AAOC;;;;AAKD;;;;;;;;;AAQC;;;;;AAIA;;;;AAIA;;;;;;;;AAQA;;;;;AAIC;;;;AAIA;;;;AAKD;;;;AAIA;;;;;;;;AAQC;;;;AAKD;;;;AAQF;;;;;;;;;;;AAWC;;;;AAIA;;;;AAKD;;;;AAOC;;;;AAKC;;;;;;;;;;;;;AAkBD;;;;;;;;AAWC;;;;AA+BD;;;;AAKD;;;;AAQE;;;;;AAIC;;;;AAIA;;;;AAOA;;;;AAKD;;;;AASH;EAGG;;;;EAIA;;;;EAIA;;;;;AASH;;;;AAIA;;;;;;;AAOA;;;;;;;;;;;;;AAaA;;;;;AAKA;;;;;;AAMA;;;;;;;;AASC;;;;;AAKA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;;AAIC;;;;AAKD;;;;AAGC;;;;AAIA;;;;AAUA;;;;AAQC;;;;;AAKA;;;;AAKD;;;;AAGC;;;;AAIA;;;;;AASH;;;;;;;;;;;;AAYA;;;;;;;;;;;AAUA;;;;;;;;;;;;;AAaA;;;;;;;;;;;AAUC;;;;AAKD;;;;;;;;AAOC;;;;;;;;;;;;AAWC;;;;;AAKA;;;;;;;;AAQA;;;;;;;;;;;;;;;AAgBD;;;;;;;AAMC;;;;AAKD;;;;;;;;AAOC;;;;AAIA;;;;AAIA;;;;;;;;AAQA;;;;;AAOF;;;;;;;;;;AASC;;;;AAIA;;;;;;;AAQD;;;;AAGC;;;;AAKD;;;;;;;;;;AAUA","sources":["static/sass/styles.scss","node_modules/@fermyon/styleguide/scss/fermyon.scss","node_modules/@fermyon/styleguide/scss/fermyon-color.scss","node_modules/@fermyon/styleguide/scss/fermyon-mixins.scss","node_modules/@fermyon/styleguide/scss/fermyon-base.scss","node_modules/@fermyon/styleguide/scss/fermyon-type.scss","node_modules/@fermyon/styleguide/scss/fermyon-responsive.scss"],"sourcesContent":["/* FERMYON SHINY VENEER\n=======================\nFor the benefit of browser-based experiences, websites and application user \ninterfaces. This Sass file should be compiled to a CSS stylesheet and served \nafter a base framework such as Bulma, Bootstrap or similar base grid system.\n\nto generate to css:\nhttps://sass-lang.com/install \n\nthen run:\nsass --watch static/sass/styles.scss static/css/style.css --style compressed\n\n\nTABLE OF CONTENTS\n================= */\n@import \"../../node_modules/@fermyon/styleguide/scss/fermyon\";\n/* \n npm package 'fermyon-styleguide':\n =================================\n 0.1. Brand Colors\n 0.2. Variables and Mixins\n 0.3. Global Layout\n 0.4. Typography\n 0.5. Responsive Media Queries\n\n1.1. Spin: Docs Styles\n*/\n\n/* 1.1 Spin: Docs Styles\n*/\n\n.documentation {\n\t.content {\n\t\tpadding-top: 8.5rem;\n\n\t\th1 {\n\t\t\tmargin-top: 2rem;\n\t\t\tposition: relative;\n\t\t\tpadding-bottom: 2.67rem;\n\t\t}\n\n\t\t&.content-docs-wide {\n\t\t\tp {\n\t\t\t\tline-height: 1.725;\n\t\t\t}\n\t\t}\n\n\t\tdetails {\n\t\t\tfont-size: 1rem;\n\t\t\twidth: 100%;\n\t\t\tbackground: #f4f0f5;\n\t\t\tborder-left: 4px solid #d9dbe8;\n\t\t\tposition: relative;\n\t\t\tmax-width: 800px;\n\n\t\t\t.summary-title {\n\t\t\t\tuser-select: none;\n\t\t\t}\n\n\t\t\t&:hover {\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\n\t\t\t.summary-content {\n\t\t\t\tborder-top: 1px solid #e2e8f0;\n\t\t\t\tcursor: default;\n\t\t\t\tpadding: 1em;\n\t\t\t\tfont-weight: 300;\n\t\t\t\tline-height: 1.5;\n\t\t\t}\n\n\t\t\tsummary {\n\t\t\t\tlist-style: none;\n\t\t\t\tpadding: 1em;\n\n\t\t\t\t&:focus {\n\t\t\t\t\toutline: none;\n\t\t\t\t}\n\n\t\t\t\t&:hover .summary-chevron-up svg {\n\t\t\t\t\topacity: 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.summary-chevron-up svg {\n\t\t\t\topacity: 0.5;\n\t\t\t}\n\n\t\t\t.summary-chevron-up,\n\t\t\t.summary-chevron-down {\n\t\t\t\tpointer-events: none;\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 0.75em;\n\t\t\t\tright: 1em;\n\t\t\t\tbackground: #f4f0f5;\n\n\t\t\t\tsvg {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsummary::-webkit-details-marker {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Styles for the copy button on code blocks\n\n\t.copy-code-button {\n\t\tposition: absolute;\n\t\ttop: 0.7rem;\n\t\tright: 0.7rem;\n\t\tborder-radius: 0.67rem;\n\t\tpadding: 0.2rem;\n\t\tcursor: pointer;\n\t\tbackground-color: #ededed25;\n\t\tborder: 2px solid;\n\t\tborder-color: #ededed35;\n\n\t\t>svg {\n\t\t\tfill: #ededed99;\n\t\t}\n\n\t\t&:hover {\n\t\t\tborder-color: #ededed99;\n\t\t}\n\t}\n\n\t.copy-code-button.is-success {\n\t\tborder-color: #18d1a5;\n\t}\n\n\t// Styling for active project in topbar\n\n\t.logo-project {\n\t\ta {\n\t\t\tposition: relative;\n\t\t}\n\n\t\ta.is-active {\n\t\t\t&::after {\n\t\t\t\tcontent: \"\";\n\t\t\t\tdisplay: block;\n\t\t\t\tposition: absolute;\n\t\t\t\tleft: 0;\n\t\t\t\tright: 0;\n\t\t\t\tbottom: -0.5rem;\n\t\t\t\twidth: 90%;\n\t\t\t\tmargin: auto;\n\t\t\t\theight: 3px;\n\t\t\t\tbackground: #0e8fdd;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Styles for anchor linking headers\n\n\t.content {\n\t\ta.anchor-link {\n\t\t\tpadding: 0.3rem;\n\t\t\ttext-decoration: none;\n\t\t\topacity: 0;\n\t\t\tfill: #363636;\n\t\t\tbackground-color: transparent;\n\t\t}\n\t}\n\n\th1 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\th2 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\th3 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\th4 {\n\t\t&:hover {\n\t\t\t>a.anchor-link {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\t}\n\n\ta.anchor-link {\n\t\t&:after {\n\t\t\tcontent: none;\n\t\t}\n\t}\n\n\taside.menu {\n\t\tpadding-bottom: 7.5rem;\n\t}\n}\n\nhtml.dark-theme {\n\tbody {\n\t\t.content {\n\t\t\tdetails {\n\t\t\t\tbackground: #1b2c4f;\n\t\t\t\tborder-left: 4px solid #243c6c;\n\n\t\t\t\t.summary-content {\n\t\t\t\t\tborder-top: 1px solid #243c6c;\n\t\t\t\t}\n\n\t\t\t\t.summary-chevron-up,\n\t\t\t\t.summary-chevron-down {\n\t\t\t\t\tbackground: #1b2c4f;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ta.anchor-link {\n\t\t\t\t&:hover {\n\t\t\t\t\tbackground: transparent !important;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ta.anchor-link {\n\t\t\t\tfill: #fff;\n\t\t\t}\n\t\t}\n\t}\n\n\n}\n\n@media screen and (max-width: 1023px) {\n\t.documentation {\n\t\t.content {\n\t\t\th1 {\n\t\t\t\tfont-size: 6.333vw;\n\t\t\t}\n\n\t\t\th2 {\n\t\t\t\tfont-size: 5vw;\n\t\t\t}\n\n\t\t\th3 {\n\t\t\t\tfont-size: 3.33vw;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// fixing https://github.com/fermyon/developer/issues/54 temporarily\n\n.content pre {\n\tmax-width: 800px;\n}\n\n.search-button-container {\n\theight: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.search-button {\n\tborder-radius: 0.667rem;\n\tborder: 1px solid #a8a8a8;\n\tcolor: #345995;\n\tpadding: 0.8rem;\n\tbackground-color: transparent;\n\tz-index: 9;\n\tcursor: grab;\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n}\n\n.search-icon {\n\tcolor: #a8a8a8;\n\tfont-size: 0.7rem;\n}\n\n.search-placeholder {\n\tpadding: 0 1rem 0 1rem;\n\tfont-weight: 600;\n\tfont-size: 0.8rem;\n}\n\n.search-command {\n\tbackground-color: #e9e1eb;\n\tcolor: #345995;\n\tpadding: .25em .5em .25em;\n\tfont-size: 0.7rem;\n\tborder-radius: 0.667rem;\n}\n\nhtml.dark-theme {\n\t.search-button {\n\t\tborder: 1px solid #a8a8a8;\n\t\tcolor: white;\n\t}\n\n\t.search-command {\n\t\tbackground-color: #213762;\n\t\tcolor: #ece5ee;\n\t}\n\n\t.modal-wrapper {\n\t\tbackground-color: #00000040;\n\t}\n\n\t.modal-box {\n\t\tbackground: #0d203f;\n\t}\n\n\tinput[type=\"text\"].modal-search-bar {\n\t\tbackground-color: #213762;\n\t\tcolor: white;\n\n\t\t&::placeholder {\n\t\t\tcolor: #989898;\n\t\t}\n\t}\n\n\t.result-block {\n\t\tbackground-color: #213762;\n\n\t\ta {\n\t\t\tcolor: #fff;\n\t\t}\n\n\t\tcode {\n\t\t\tbackground-color: #0d203f;\n\t\t}\n\t}\n\n\t.result-subitem {\n\t\tbackground-color: #0d203f;\n\t}\n\n\t.result-subheading-container {\n\t\ta {\n\t\t\tcolor: #34e8bd;\n\t\t}\n\t}\n\n\t.result-section-container {\n\t\t.result-filters {\n\n\t\t\tcode {\n\t\t\t\tcolor: #da1039;\n\t\t\t\tbackground-color: #99919b;\n\t\t\t}\n\n\t\t\tcode.active {\n\t\t\t\tbackground-color: #e9e1eb;\n\t\t\t}\n\t\t}\n\n\t\t.suggested-project {\n\t\t\tbackground-color: #213762;\n\n\t\t\t.project-title {\n\t\t\t\tcolor: #fff;\n\t\t\t}\n\n\t\t\t.suggested-project-link {\n\t\t\t\tbackground-color: #0d203f;\n\t\t\t\tcolor: #34e8bd;\n\t\t\t}\n\t\t}\n\t}\n\n}\n\n.search-modal-container {\n\tbox-sizing: border-box;\n\tmargin: 0;\n\twidth: 100%;\n\theight: 100%;\n\tz-index: 1000;\n\tposition: fixed;\n\tleft: 0;\n\ttop: 0;\n\tdisplay: none;\n}\n\n.modal-wrapper {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackdrop-filter: blur(6px);\n\tbackground-color: #00000080;\n}\n\n.modal-box {\n\twidth: 80%;\n\theight: 80%;\n\tmax-width: 600px;\n\tmax-height: 700px;\n\tpadding: 1rem;\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tbackground-color: #e9e1eb;\n\tborder-radius: 0.667rem;\n}\n\n.modal-search-bar {\n\tbox-sizing: border-box;\n\tline-height: 1.5rem;\n\twidth: 100%;\n\tpadding: 0.8rem;\n\tfont-size: 1.2rem;\n\tborder-radius: 0.667rem;\n\tborder: 0px;\n\tmargin-bottom: 1rem;\n\n\t&:focus {\n\t\toutline: none;\n\t}\n}\n\n.result-section-container {\n\twidth: 100%;\n\tflex-grow: 1;\n\tdisplay: flex;\n\toverflow-y: auto;\n\tflex-direction: column;\n\n\t.suggested-project {\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tpadding: 0.6rem;\n\t\tborder-radius: 0.667rem;\n\t\tmargin: 0.2rem;\n\t\tbackground-color: #f3f3f3;\n\t\tcolor: black;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\t.project-title {\n\t\t\tpadding: 0.5em;\n\t\t\tfont-weight: 600;\n\t\t}\n\n\t\t.recommended-navs {\n\t\t\twidth: 100%;\n\t\t\tdisplay: flex;\n\t\t\tflex-flow: row wrap;\n\t\t\talign-items: center;\n\t\t\tjustify-content: space-evenly;\n\t\t}\n\n\t\t.suggested-project-link {\n\t\t\twidth: 45%;\n\t\t\tbackground-color: white;\n\t\t\tfont-size: 1rem;\n\t\t\tdisplay: flex;\n\t\t\tjustify-content: center;\n\t\t\talign-items: center;\n\t\t\toverflow-y: auto;\n\t\t\tborder-radius: 0.667rem;\n\t\t\tpadding: 1rem;\n\t\t\tmargin-bottom: 0.4rem;\n\t\t\tfont-weight: 400;\n\t\t\tcolor: #345995;\n\t\t}\n\t}\n\n\t.result-section {\n\t\twidth: 100%;\n\t\tflex-grow: 1;\n\t\toverflow-y: auto;\n\t\tborder-radius: 0.667rem;\n\n\t\t&::-webkit-scrollbar {\n\t\t\twidth: 0px;\n\t\t}\n\t}\n\n\t.result-filters {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\t\tpadding: 0 0.4rem 0.4rem 0.4rem;\n\t\talign-items: center;\n\t\tcursor: grab;\n\n\t\t.filter-categories {\n\t\t\tmax-width: 80%;\n\t\t}\n\n\t\t.reset-filter {\n\t\t\tfont-size: 0.8rem;\n\t\t}\n\n\t\tcode {\n\t\t\tbackground-color: #4d407f90;\n\t\t\tcolor: whitesmoke;\n\t\t\tfont-size: 0.8rem;\n\t\t\tmargin-left: 0.5rem;\n\t\t\tborder-radius: 0.667rem;\n\t\t}\n\n\t\tcode.active {\n\t\t\tbackground-color: #0d203f;\n\t\t\tcolor: white;\n\t\t}\n\t}\n}\n\n.result-block {\n\tpadding: 0.6rem;\n\tborder-radius: 0.667rem;\n\tmargin: 0.2rem;\n\tbackground-color: #f3f3f3;\n\tcolor: black;\n\tdisplay: flex;\n\tflex-direction: column;\n\n\ta {\n\t\tcolor: #363636;\n\t}\n\n\tcode {\n\t\tbackground-color: #e9e1eb;\n\t\tfont-size: 0.8rem;\n\t\tmargin-left: 0.5rem;\n\t\tborder-radius: 0.667rem;\n\t}\n}\n\n.result-subheading-container {\n\tpadding: 1rem;\n\n\ta {\n\t\tcolor: #345995;\n\t}\n}\n\n.result-subitem {\n\tbackground-color: white;\n\tfont-size: 1rem;\n\tdisplay: flex;\n\talign-items: center;\n\toverflow-y: auto;\n\tborder-radius: 0.667rem;\n\tmargin-bottom: 0.4rem;\n}\n\n.result-item-icon {\n\tfont-size: 1.5rem;\n\tpadding: 0.4rem;\n}","/* FERMYON SHINY VENEER\n=======================\nFor the benefit of browser-based experiences, websites and application user \ninterfaces. This Sass file should be compiled to a CSS stylesheet and served \nafter a base framework such as Bulma, Bootstrap or similar base grid system.\n\nto generate to css:\nhttps://sass-lang.com/install \n\nthen run:\nsass --watch static/sass/styles.scss static/css/style.css --style compressed\n\n\nTABLE OF CONTENTS\n=================\n0.1. Brand Colors\n0.2. Variables and Mixins\n0.3. Global Layout\n0.4. Typography\n*/\n\n@import \"fermyon-color\";\n@import \"fermyon-mixins\";\n@import \"fermyon-base\";\n@import \"fermyon-type\";\n@import \"fermyon-responsive\";\n","/* 1.\n Brand Colors\n*/\n\n// Core Brand\n$seagreen: #34E8BD;\n$oxfordblue: #0D203F;\n\n// Secondary Accents\n$rust: #EF946C;\n$lavender: #BEA7E5;\n$colablue: #0E8FDD;\n\n// Tertiary Shades\n\n$darkspace: #213762;\n$darkocean: #0A455A;\n$darkolive: #1F7A8C;\n$darkplum: #525776;\n\n$midgreen: #1FBCA0;\n$midblue: #345995;\n\n$lightplum: #D3C3D9;\n$lightgray: #D9DBE8;\n$lightlavender: #ECE5EE;\n$lightlemon: #F9F7EE;\n\n\n// Remapping Bulma Colors\n\n$darkblue: $midblue;\n\n.is-primary, .has-text-primary {\n color: $oxfordblue !important;\n}\n\n\n.is-link, .has-text-link { color: darken($colablue, 12.5%) !important; }\n.is-info, .has-text-info { color: darken($lavender, 10%) !important; }\n.is-success, .has-text-success { color: darken($midgreen, 10%) !important; }\n.is-warning, .has-text-warning { color: $rust !important; }\n.is-danger, .has-text-danger { color: darken($rust, 25%) !important; }\n.is-dark, .has-text-dark { color: $darkspace !important; }\n.is-light, .has-text-light { color: darken($lightplum, 12.5%) !important; }\n\n.button, .tag, .message {\n &.is-primary {\n background-color: darken($seagreen, 10%);\n color: white !important;\n }\n &.is-secondary {\n background-color: lighten($darkspace, 12.5%);\n color: white !important;\n }\n &.is-link {\n background-color: darken($colablue, 12.5%) !important;\n color: white !important;\n }\n &.is-info {\n background-color: darken($lavender, 10%) !important;\n color: white !important;\n }\n &.is-success {\n background-color: darken($midgreen, 10%) !important;\n color: white !important;\n }\n &.is-warning {\n background-color: $rust !important;\n color: white !important;\n }\n &.is-danger {\n background-color: darken($rust, 25%) !important;\n color: white !important;\n }\n &.is-dark {\n background-color: $darkspace;\n color: white !important;\n }\n &.is-light {\n background-color: darken($lightplum, 12.5%);\n color: $oxfordblue !important;\n }\n}\n\n.content {\n .is-active, .is-current {\n color: white;\n background-color: $darkspace;\n }\n}\n","/* 2.\n Variables and Mixins\n*/\n\n$sen: Sen, Europa, Avenir, system, -apple-system, \".SFNSText-Regular\", \"San Francisco\", \"Segoe UI\", \"Helvetica Neue\", \"Lucida Grande\", sans-serif;\n$mono: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;\n\n@mixin transition($property:all, $duration:0.3s, $easing:ease-in-out) {\n transition: $property $duration $easing;\n}\n\n@mixin border-radius($radius1:3px, $radius2:3px) {\n -webkit-border-radius: $radius1 $radius2 $radius1 $radius2;\n -moz-border-radius: $radius1 $radius2 $radius1 $radius2;\n border-radius: $radius1 $radius2 $radius1 $radius2;\n}\n\n@mixin box-shadow($xlength:0, $ylength:2px, $size:0, $color:rgba(30,30,30,0.25)) {\n -webkit-box-shadow: $xlength $ylength $size $color;\n -moz-box-shadow: $xlength $ylength $size $color;\n box-shadow: $xlength $ylength $size $color;\n}\n\n@mixin verticalCenter {\n position: relative;\n top: 50%;\n transform: translateY(-50%);\n}\n\n@mixin sen {\n letter-spacing: 0.025em;\n}","/* 3.\n Global Base\n*/\n\nhtml {\n height: 100%;\n background-color: transparent;\n}\nbody,\nmain {\n min-height: 100vh;\n position: relative;\n}\n\nbody {\n background: lighten($lightlavender, 5%);\n min-height: 100vh;\n}\n\nmain {\n padding: 5.75rem 0 0;\n min-height: 100vh;\n margin-bottom: -12rem;\n z-index: 100;\n}\n\n#topbar.navbar {\n background: lighten($lightlavender, 5%);\n padding-left: 5vw;\n padding-right: 5vw;\n border-bottom: 2px solid rgba(255,255,255,0.98);\n will-change: transform;\n transition: transform 200ms linear;\n position: fixed;\n left: 0;\n right: 0;\n z-index: 1000;\n\n .navbar-burger {\n width: 5.25rem;\n height: 5.25rem;\n }\n\n &.is-wide {\n padding-left: 2.5vw;\n padding-right: 2.5vw;\n }\n\n .dark-mode {\n position: absolute;\n right: 0;\n top: 2rem;\n display: inline-block;\n width: 1.5rem;\n line-height: 1.5;\n fill: $midblue;\n }\n\n &.headroom--pinned {\n margin: 0;\n transform: translateY(0%);\n }\n &.headroom--unpinned {\n transform: translateY(-100%);\n }\n\n @keyframes halfSpin {\n 0% {\n transform: rotate(0);\n }\n\n 25% {\n transform: rotate(180deg);\n opacity: 1;\n }\n\n 38% {\n opacity: 0.75;\n }\n\n 50% {\n transform: rotate(180deg);\n }\n\n 75% {\n transform: rotate(360deg);\n opacity: 1;\n }\n\n 88% {\n opacity: 0.75;\n }\n\n 100% {\n transform: rotate(360deg);\n }\n }\n\n .logo {\n display: inline-block;\n margin-top: 0;\n fill: $oxfordblue;\n position: relative;\n margin-top: 0.35em;\n\n svg {\n max-height: 1.25rem;\n max-width: 10.625rem;\n cursor: pointer;\n position: relative;\n z-index: 500;\n fill: $oxfordblue;\n }\n\n &:hover {\n .spin-back {\n background-color: white;\n }\n }\n\n .spin-front {\n width: 1.133rem;\n height: 1.133rem;\n display: inline-block;\n position: absolute;\n top: 1.25rem;\n right: 1.9125rem;\n border-radius: 50%;\n z-index: 600;\n opacity: 1;\n @include transition;\n\n em {\n width: 0.425rem;\n height: 0.425rem;\n display: inline-block;\n top: 0rem;\n right: 0.05rem;\n background: #28FFCC;\n position: absolute;\n z-index: 700;\n border-radius: 50%;\n @include transition;\n }\n }\n .spin-back {\n width: 1.125rem;\n height: 1.125rem;\n display: inline-block;\n position: absolute;\n top: 1.295rem;\n right: 1.875rem;\n border-radius: 50%;\n z-index: 400;\n background: transparent;\n @include transition;\n }\n }\n\n &:hover {\n .logo .spin-front {\n animation: 4s ease infinite halfSpin;\n }\n }\n\n .logo-project {\n font-weight: bold;\n margin: 2rem 0 0 1.3335rem;\n font-size: 1.125rem;\n\n a {\n color: $darkspace;\n }\n\n .tag {\n margin: -0.5rem 0 0 0.67rem;\n position: relative;\n }\n\n }\n\n a.navbar-item {\n line-height: 3;\n background: transparent;\n font-weight: 700;\n }\n\n .navbar-menu {\n a {\n margin-left: 2vw;\n position: relative;\n color: $oxfordblue;\n @include sen;\n @include transition;\n\n em {\n position: absolute;\n left: 45%;\n right: 45%;\n bottom: -0.15rem;\n height: 0.333rem;\n opacity: 0;\n background-color: $seagreen;\n display: inline-block;\n @include border-radius(1rem, 1rem);\n @include transition;\n content: \" \";\n }\n\n &:hover {\n em {\n left: 25%;\n right: 25%;\n opacity: 1;\n }\n }\n }\n\n .button {\n color: darken($seagreen, 15%);\n border-color: $seagreen;\n margin: 1rem 0 0 2.5rem;\n @include transition;\n\n &:hover {\n color: darken($seagreen, 22.5%);\n background-color: white !important;\n }\n }\n }\n}\n\n.menu-wrap {\n padding: 0 2.5vw;\n width: 17rem;\n background: lighten($lightlavender, 5%);\n\n &.is-fixed-desktop {\n @media screen and (min-width: 1024px) {\n position: fixed;\n left: 0;\n top: 0;\n bottom: 0;\n width: 17.5vw;\n background: lighten($lightlavender, 5%);\n }\n \n @media screen and (max-width: 1023px) {\n position: relative;\n top: auto;\n left: auto;\n right: auto;\n }\n }\n\n &.is-sticky {\n @media screen and (min-width: 1024px) {\n position: sticky;\n left: 2.5vw;\n top: 0;\n width: 15rem;\n padding-left: 0.67rem;\n bottom: 0;\n display: inline-block;\n vertical-align: top;\n max-height: 100vh;\n overflow-y: auto;\n background: lighten($lightlavender, 5%);\n }\n }\n}\n\naside.menu {\n font-size: 1rem;\n position: absolute;\n top: 0;\n bottom: 0;\n overflow-y: scroll;\n padding-top: 6.5rem;\n min-width: 13rem;\n width: 14.5vw;\n border-right: 2px solid transparent;\n @include transition;\n\n &:hover {\n border-right: 2px solid $lightlavender;\n }\n\n .menu-label {\n padding-left: 1.333vw;\n margin: 1.75rem 1.333vw 1rem 0;\n }\n\n ul {\n margin-bottom: 2.5rem;\n }\n\n a {\n padding: 0.6rem 1.25vw;\n margin-bottom: 0rem;\n font-weight: bold;\n display: inline-block;\n @include transition;\n @include border-radius(2rem,2rem);\n\n &:hover {\n background-color: $lightlavender;\n color: $darkspace;\n }\n\n &.button {\n line-height: 2.25;\n margin-top: 1.25rem;\n padding: 0 1.333vw;\n font-size: 1.125rem;\n background: transparent;\n border: 2px solid $seagreen;\n\n svg {\n margin-right: 0.25rem;\n margin-bottom: -1px;\n }\n\n svg, path {\n @include transition;\n }\n\n &:hover {\n background-color: $seagreen;\n color: white;\n\n svg, path {\n fill: white;\n }\n }\n }\n }\n}\n\n.menu-wrap + article.content {\n padding-left: 18.5vw;\n}\n\n.page-wrap {\n position: relative;\n}\n\n.is-fullwidth {\n width: 100vw;\n max-width: 100vw !important;\n}\n\nhr {\n background-color: rgba(100,100,100,.1);\n}\n\nhr.page-break {\n position: relative;\n text-align: center;\n height: 4rem;\n background: transparent;\n \n &:after {\n position: relative;\n width: 12.5%;\n display: inline-block;\n margin: 2.5rem 0 3.5rem;\n content: \" \";\n height: .33rem;\n background: $lavender;\n @include border-radius(0.33rem, 0.33rem);\n }\n}\n\n.documentation {\n .content {\n padding-top: 8.5rem;\n margin-bottom: 5rem;\n\n h1 {\n position: relative;\n padding-bottom: 2.67rem;\n margin: -1.5rem 0 5rem;\n \n &:after {\n position: absolute;\n width: 25%;\n margin: 2rem 0 0;\n display: inline-block;\n margin: 2.5rem 0 0;\n bottom: 0;\n left: 0;\n content: \" \";\n height: .33rem;\n background: $lavender;\n @include border-radius(0.33rem, 0.33rem);\n }\n }\n\n blockquote {\n p {\n font-size: 1rem;\n line-height: 1.4;\n }\n }\n \n .footer-nav {\n border-top: none;\n }\n\n &.content-docs-wide {\n section {\n max-width: 90vw !important;\n margin-left: 5vw;\n margin-right: 5vw;\n\n .content ul, .content ol, .content dl, .content p, .content blockquote {\n max-width: 100%;\n }\n }\n }\n }\n\n footer {\n padding-left: 2.5vw !important;\n padding-right: 2.5vw !important;\n \n .footer-nav {\n padding: 0 0.75rem;\n margin: 0;\n border-top: none;\n }\n }\n}\n\n\n\n.content section {\n margin-left: auto;\n margin-right: auto;\n max-width: 48.5rem;\n\n .box {\n margin-top: 2rem;\n margin-bottom: 3rem;\n padding: 1.67rem 2rem;\n }\n\n table {\n background-color: white;\n min-width: 100%;\n margin-top: 2rem;\n margin-bottom: 4rem;\n border-collapse: collapse;\n border-radius: 0.333em;\n overflow: hidden;\n box-shadow: 0 3px 6px rgba(30,30,30,.125);\n\n th, td {\n padding: 0.67vw 2vw;\n border-bottom: 1px solid $lavender;\n line-height: 1.5;\n }\n\n th {\n font-size: 1.125rem;\n font-weight: bold;\n color: $oxfordblue;\n background-color: $lightlemon;\n line-height: 1.75;\n border-bottom: 1px solid $lavender;\n }\n\n td {\n font-size: 1rem;\n border-bottom-color: $lightlavender;\n }\n\n tr {\n &:last-of-type {\n td {\n border: none;\n }\n }\n }\n }\n}\n\n\nfooter {\n background: white;\n margin: 0 auto 0;\n padding: 1.25rem 0 0;\n min-height: 12rem;\n border-top: 1px solid $lavender;\n position: relative;\n z-index: 1400;\n\n /* top row of links */\n ul,\n p {\n margin: 2rem 0 4rem;\n }\n\n p.lead {\n font-size: 1.25rem;\n max-width: 67%;\n line-height: 1.33;\n margin: -2.5rem 0 0;\n color: $darkocean\n }\n\n h4 {\n margin: 3rem 0 0;\n font-size: 1.25rem;\n font-weight: bold;\n color: $rust;\n }\n\n li {\n line-height: 2;\n list-style: none;\n font-size: 1.125rem;\n }\n\n img {\n max-height: 3rem;\n margin-top: 0;\n }\n\n &.is-shallow {\n min-height: 6.5rem;\n\n img {\n max-height: 2.5rem;\n }\n }\n\n /* bottom row of smaller links */\n .footer-nav {\n border-top: 1px solid $lightgray;\n\n .navbar {\n padding: 0;\n background: transparent;\n\n .navbar-item {\n padding: 0 4rem 0 0;\n font-size: 1rem;\n line-height: 1.33;\n color: $lavender;\n\n a {\n color: darken($lightgray, 12.5%);\n @include transition;\n\n &:hover {\n color: darken($lightgray, 42.5%);\n }\n }\n\n &:last-of-type {\n padding-right: 0;\n }\n }\n }\n\n p {\n margin: 0;\n }\n }\n}\n\n@media (prefers-color-scheme: dark) {\n html {\n background: lighten($lightlavender, 5%);\n color: $oxfordblue;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n html {\n background: $oxfordblue;\n color: white;\n }\n}\n\nhtml.dark-theme > body {\n background: $oxfordblue;\n color: white;\n\n h1, h2, h3, h4, h5, p, li {\n color: white;\n }\n\n #topbar.navbar {\n background: $oxfordblue;\n border-color: $darkocean;\n\n .logo {\n svg, path {\n fill: white !important;\n }\n }\n .logo-project a {\n color: $seagreen;\n\n .tag {\n background-color: $darkspace;\n color: $lavender !important;\n }\n }\n\n .navbar-burger {\n color: $lavender;\n height: 5.75rem;\n }\n\n .navbar-menu {\n a {\n color: $seagreen;\n }\n\n .button {\n border: 3px solid $seagreen;\n\n &:hover {\n background: $seagreen !important;\n color: $oxfordblue;\n }\n }\n }\n\n .dark-mode {\n svg {\n fill: $seagreen;\n transform: rotate(180deg);\n @include transition;\n }\n }\n }\n\n .menu-wrap {\n background: $oxfordblue;\n }\n\n aside.menu {\n\n &:hover {\n border-right: 2px solid darken($lavender, 55%);\n }\n\n a {\n color: white;\n \n &:hover {\n color: $seagreen;\n background-color: $darkspace;\n }\n\n &.button svg,\n &.button path {\n fill: white !important;\n }\n }\n }\n\n pre {\n background: linear-gradient(0, #173564 15%, lighten(desaturate(#173564, 12.5%), 3%) 100%);\n }\n\n .card {\n background: linear-gradient(0, lighten($oxfordblue, 5%), $oxfordblue 100%);\n box-shadow: 0 .5em 1em -.125em rgba(10,10,10,.5),\n 0 0 0 1px rgba(10,10,10,.52);\n outline: 1px solid rgba(255,255,255,0.2);\n color: white;\n\n figure.image {\n border-bottom: 1px solid rgba(255,255,255,0.333);\n }\n\n p {\n color: white;\n }\n }\n\n .content {\n .box {\n background-color: $darkspace;\n color: white;\n }\n \n h1, h2, h3, h4, h5, p, li, th, td, dd {\n code {\n background-color: $darkspace;\n color: $lightlavender;\n }\n }\n\n section {\n table {\n background-color: $darkspace;\n }\n }\n\n blockquote {\n background-color: transparent;\n\n p {\n background-color: darken($darkspace, 5%);\n border-color: lighten($darkspace, 2.5%);\n color: white;\n }\n }\n\n blockquote > blockquote p,\n aside p {\n background-color: lighten($darkspace, 2.5%);\n border-color: lighten($darkspace, 7.5%);\n color: white;\n }\n\n a {\n &:hover {\n background: darken($darkspace, 5%) !important;\n }\n }\n } \n\n footer {\n background: $oxfordblue;\n border-color: $darkocean;\n color: white;\n\n h4 {\n color: white;\n }\n\n .footer-nav {\n border-color: darken($oxfordblue, 7.5%);\n }\n\n p, li, a {\n color: $seagreen;\n }\n }\n}\n","/* 4.\n Typography\n*/\n\nbody {\n font-family: $sen;\n font-size: 16pt;\n color: $oxfordblue;\n}\n\n.content {\n\n h1, h2, h3 {\n font-weight: bold;\n display: block;\n }\n\n ul, ol, dl, p, blockquote {\n margin: 1.67rem 0;\n font-size: 1rem;\n max-width: 800px;\n }\n\n &.size-16 {\n ul, ol, dl, p, blockquote {\n font-size: 1rem;\n }\n }\n &.size-18{\n ul, ol, dl, p, blockquote {\n font-size: 1.125rem;\n }\n }\n &.size-20 {\n ul, ol, dl, p, blockquote {\n font-size: 1.25rem;\n }\n }\n\n ul {\n li {\n list-style: disc;\n list-style-position: outside;\n line-height: 1.636;\n margin: 0 0.5rem 0 1.25rem;\n padding-left: 0.5rem;\n }\n\n &.pagination-list {\n margin: 0;\n \n li {\n list-style: none;\n margin: 0;\n }\n }\n\n &.is-disc {\n li {\n list-style: disc;\n list-style-position: outside;\n }\n }\n }\n\n ol li {\n list-style-position: outside;\n line-height: 1.636;\n margin: 0 0.5rem 0 1.25rem;\n padding-left: 0.5rem;\n }\n\n blockquote > blockquote,\n aside {\n margin-top: 3rem;\n margin-bottom: 3rem;\n\n p {\n line-height: 1.8;\n border: 1px solid $lightgray;\n font-size: 1.2rem;\n background: $lightlemon;\n padding: 1.25rem 1.5rem !important;\n margin: 2.5em auto 5rem !important;\n text-align: left;\n border-radius: .667rem;\n box-shadow: 0 3px 6px rgba(30,30,30,.125);\n color: $oxfordblue;\n }\n\n a {\n color: $colablue;\n }\n }\n\n blockquote {\n padding: 0rem 0 !important;\n margin: 0 !important;\n border-left: none;\n\n p {\n color: darken($darkolive, 25%);\n color: $darkblue;\n font-size: 1.1rem !important;\n line-height: 2;\n padding-right: 0 !important;\n border-left: 4px solid $lightgray;\n background: lighten($lightlavender, 3.5%);\n padding: 0.65rem 5% 0.65rem 2rem !important;\n margin: 1rem auto 1rem !important;\n text-align: left;\n }\n\n a {\n color: $colablue;\n }\n }\n\n pre,\n code {\n margin-bottom: 2rem !important;\n }\n\n pre {\n code {\n margin-bottom: 0 !important;\n }\n }\n\n h1, h2, h3, h4, h5 {\n code {\n font-weight: bold;\n font-size: 1em !important;\n }\n }\n\n pre,\n code {\n margin-bottom: 2rem !important;\n }\n\n pre {\n code {\n margin-bottom: 0 !important;\n }\n }\n\n h1, h2, h3, h4, h5 {\n code {\n font-weight: bold;\n font-size: 1em !important;\n }\n }\n\n strong {\n color: $oxfordblue;\n }\n\n a {\n color: darken($colablue, 12.5%);\n border-radius: 0.333em;\n position: relative;\n\n &:after {\n position: absolute;\n text-align: center;\n background: $colablue;\n height: 0.125rem;\n content: \" \";\n display: inline-block;\n opacity: 0;\n bottom: -0.2rem;\n left: 33%;\n right: 33%;\n @include transition;\n }\n\n &:hover {\n background: rgba(255,255,255,0.67);\n color: $colablue;\n\n &:after {\n opacity: 1;\n left: 5%;\n right: 5%;\n }\n\n img + :after {\n display: none !important;\n margin-top: -4rem;\n }\n }\n }\n\n hr.page-break {\n text-align: left;\n height: 4rem;\n background: transparent;\n \n &:after {\n position: relative;\n width: 12.5%;\n margin: 1.5rem 0 2.5rem;\n height: .33rem;\n }\n }\n\n .copy {\n padding: 0.5rem 1rem;\n position: relative;\n border-radius: 1rem;\n margin-left: -1.5rem;\n margin-right: -1.5rem;\n\n img {\n width: 1em;\n }\n\n .button {\n position: absolute;\n padding: 0;\n line-height: 1;\n top: 0.01rem;\n right: 0.67rem;\n border: none;\n opacity: 0;\n background: transparent;\n \n }\n\n &:hover {\n background: rgba(100,100,100,0.17);\n \n .button {\n opacity: 1;\n }\n }\n }\n\n .copy-button {\n @include transition;\n cursor: pointer;\n\n &:after {\n content: \"Copied\";\n @include transition;\n display: inline-block;\n position: absolute;\n top: 0rem;\n right: 25%;\n top: 75%;\n transform: perspective(1px) translateY(-50%);\n z-index: 860;\n background: rgba(100,100,100,0.75);\n padding: 0.5rem 1rem;\n border-radius: 2rem;\n font-size: 1rem;\n font-weight: bold;\n opacity: 0;\n color: white;\n }\n\n &:active {\n opacity: 0.8;\n &:after {\n top: 50%;\n opacity: 1;\n }\n }\n }\n\n .card {\n p {\n margin: 0;\n line-height: 1.25;\n color: $oxfordblue;\n \n &.title {\n margin-bottom: 0.5rem;\n }\n\n em {\n font-family: $mono;\n font-style: normal;\n opacity: 0.333;\n display: inline-block;\n padding: 0 0.2rem 0 0;\n }\n }\n\n &.card-color {\n border-radius: 0.33rem;\n overflow: hidden;\n\n figure.image {\n border: 5px solid transparent;\n @include transition;\n \n &:hover {\n border-color: white;\n }\n }\n \n .card-content {\n padding: 0.5rem 0.5rem 1rem;\n\n p {\n margin: 0 0 -0.333rem;\n letter-spacing: -0.02em;\n }\n }\n }\n }\n\n /* Code Styling */\n\n h1,\n h2,\n h3, \n h4,\n h5,\n p,\n li,\n td,\n th,\n dd {\n code {\n border-radius: 0.33rem !important;\n background: darken($lightlavender, 1.25%);\n color: $darkblue;\n }\n }\n\n pre,\n code {\n margin-left: 0;\n border-radius: 0.67rem;\n background-color: $oxfordblue;\n background-image: linear-gradient(135deg, $oxfordblue 0%, lighten($oxfordblue, 3.33%) 100%);\n color: white;\n font-size: 0.925rem;\n color: $lavender;\n font-family: $mono;\n\n a {\n color: $colablue;\n }\n\n code.hljs {\n padding: 0 !important;\n\n .hljs-meta {\n color: $seagreen;\n } \n }\n }\n\n pre {\n margin: 1.333rem 0;\n max-width: 100%;\n position: relative;\n }\n\n code {\n border-radius: 0 !important;\n }\n\n .hljs {\n background-color: transparent !important;\n }\n\n /* highlight.js css */\n pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}\n}\n\nhtml.dark-theme > body {\n background: $oxfordblue;\n color: white;\n\n h1, h2, h3, h4, p, li {\n color: white;\n }\n\n .content,\n article {\n a {\n color: $seagreen;\n }\n\n strong {\n color: $lightlavender;\n }\n }\n}","/* \n Responsive Media Queries\n*/\n\n@media screen and (max-width: 1023px) {\n\n // topbar \n #topbar.navbar {\n .logo {\n svg,\n span {\n display: none !important;\n }\n \n width: 3rem;\n height: 3rem;\n background: url(../image/avatar.png) no-repeat 0 0;\n background-size: contain;\n }\n\n .logo-project {\n margin-left: 0.5rem;\n }\n\n .navbar-menu.is-pulled-right {\n text-align: right;\n\n a {\n float: right;\n }\n }\n }\n \n // burger menu\n .menu-wrap {\n z-index: 1400;\n width: 100vw;\n display: none;\n\n &.is-active {\n display: block !important;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n position: fixed;\n }\n\n aside.menu {\n width: 100vw;\n padding-left: 5vw;\n padding-right: 5vw;\n padding-top: 8rem;\n }\n }\n\n // hide weird horizontal scroll on mobile/tablet\n article.content section,\n footer {\n overflow-x: hidden !important;\n max-width: 100vw !important;\n }\n\n main.is-fullwidth {\n max-width: 90vw !important;\n padding-left: 5vw !important;\n padding-right: 5vw !important;\n }\n\n .menu-wrap + article.content {\n padding-left: 0;\n max-width: 85vw !important;\n }\n\n footer.is-shallow .footer-nav {\n max-width: 90vw;\n padding-left: 5vw;\n padding-right: 5vw;\n border-color: transparent !important;\n\n .navbar-item {\n display: inline-block;\n\n } \n } \n}"],"names":[],"version":3,"file":"styles.css.map"} \ No newline at end of file diff --git a/static/data.json b/static/data.json new file mode 100644 index 000000000..aad272ef5 --- /dev/null +++ b/static/data.json @@ -0,0 +1 @@ +[{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"","content":"undefined","url":"/cloud/cli-reference.md"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Spin","content":"This page documents the Spin Command Line Interface (CLI). Specifically, all of the available Spin Options and Subcommands. You can reproduce this documentation on your machine by using the --help For example:$ spin --help\n\nUSAGE:\n spin \n\nOPTIONS:\n -h, --help Print help information\n -V, --version Print version information\n\nSUBCOMMANDS:\n bindle Commands for publishing applications as bindles\n build Build the Spin application\n deploy Deploy a Spin application\n help Print this message or the help of the given subcommand(s)\n new Scaffold a new application or component based on a template\n plugin Install/uninstall Spin plugins\n templates Commands for working with WebAssembly component templates\n up Start the Spin application","url":"/cloud/cli-reference.md#spin"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Bindle","content":"Adding a subcommand (and again issuing the --help command) will provide information specific to that particular subcommand. For example:$ spin bindle --help\n\nUSAGE:\n spin bindle \n\nOPTIONS:\n -h, --help Print help information\n\nSUBCOMMANDS:\n help Print this message or the help of the given subcommand(s)\n prepare Create a standalone bindle for subsequent publication\n push Publish an application as a bindle","url":"/cloud/cli-reference.md#bindle"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Prepare","content":"Again, adding another related subcommand provides even more specific information. For example:$ spin bindle prepare --help\n\nUSAGE:\n spin bindle prepare [OPTIONS] --staging-dir \n\nOPTIONS:\n --buildinfo Build metadata to append to the bindle version\n -d, --staging-dir Path to create standalone bindle\n -f, --file Path to spin.toml\n -h, --help Print help information","url":"/cloud/cli-reference.md#prepare"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Push","content":"$ spin bindle push --help\n\nUSAGE:\n spin bindle push [OPTIONS] --bindle-server \n\nOPTIONS:\n --bindle-password \n Basic http auth password for the bindle server [env: BINDLE_PASSWORD=]\n\n --bindle-server \n URL of bindle server [env: BINDLE_URL=]\n\n --bindle-username \n Basic http auth username for the bindle server [env: BINDLE_USERNAME=]\n\n --buildinfo \n Build metadata to append to the bindle version\n\n -d, --staging-dir \n Path to assemble the bindle before pushing (defaults to temporary directory)\n\n -f, --file \n Path to spin.toml\n\n -h, --help\n Print help information\n\n -k, --insecure\n Ignore server certificate errors","url":"/cloud/cli-reference.md#push"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Build","content":"$ spin build --help\n\nUSAGE:\n spin build [OPTIONS] [UP_ARGS]...\n\nARGS:\n ... \n\nOPTIONS:\n -f, --file Path to spin.toml\n -h, --help Print help information\n -u, --up Run the application after building","url":"/cloud/cli-reference.md#build"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Deploy","content":"$ spin deploy --help\n\nUSAGE:\n spin deploy [OPTIONS] --bindle-server --hippo-server --hippo-username --hippo-password \n\nOPTIONS:\n --bindle-password \n Basic http auth password for the bindle server [env: BINDLE_PASSWORD=]\n\n --bindle-server \n URL of bindle server [env: BINDLE_URL=]\n\n --bindle-username \n Basic http auth username for the bindle server [env: BINDLE_USERNAME=]\n\n --buildinfo \n Build metadata to append to the bindle version\n\n -d, --staging-dir \n Path to assemble the bindle before pushing (defaults to a temporary directory)\n\n -e, --deploy-existing-bindle\n Deploy existing bindle if it already exists on bindle server\n\n -f, --file \n Path to spin.toml [default: spin.toml]\n\n -h, --help\n Print help information\n\n --hippo-password \n Hippo password [env: HIPPO_PASSWORD=]\n\n --hippo-server \n URL of hippo server [env: HIPPO_URL=]\n\n --hippo-username \n Hippo username [env: HIPPO_USERNAME=]\n\n -k, --insecure\n Ignore server certificate errors from bindle and hippo\n\n --no-buildinfo\n Disable attaching buildinfo [env: SPIN_DEPLOY_NO_BUILDINFO=]\n\n --readiness-timeout \n How long in seconds to wait for a deployed HTTP application to become ready. The default\n is 60 seconds. Set it to 0 to skip waiting for readiness [default: 60]","url":"/cloud/cli-reference.md#deploy"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"New","content":"$ spin new --help\n\nUSAGE:\n spin new [OPTIONS] [ARGS]\n\nARGS:\n The template from which to create the new application or component. Run\n `spin templates list` to see available options\n The name of the new application or component\n\nOPTIONS:\n --accept-defaults An optional argument that allows to skip prompts for the\n manifest file by accepting the defaults if available on the\n template\n -h, --help Print help information\n -o, --output The directory in which to create the new application or\n component. The default is the name argument\n -v, --value Parameter values to be passed to the template (in name=value\n format)\n --values-file A TOML file which contains parameter values in name = \"value\"\n format. Parameters passed as CLI option overwrite parameters\n specified in the file","url":"/cloud/cli-reference.md#new"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Plugin","content":"$ spin plugin --help\n\nUSAGE:\n spin plugin \n\nOPTIONS:\n -h, --help Print help information\n\nSUBCOMMANDS:\n help Print this message or the help of the given subcommand(s)\n install Install plugin from a manifest\n uninstall Remove a plugin from your installation\n update Fetch the latest Spin plugins from the spin-plugins repository\n upgrade Upgrade one or all plugins","url":"/cloud/cli-reference.md#plugin"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Install","content":"$ spin plugin install --help\n\nUSAGE:\n spin plugin install [OPTIONS] [PLUGIN_NAME]\n\nARGS:\n \n Name of Spin plugin\n\nOPTIONS:\n -f, --file \n Path to local plugin manifest\n\n -h, --help\n Print help information\n\n --override-compatibility-check\n Overrides a failed compatibility check of the plugin with the current version of Spin\n\n -u, --url \n URL of remote plugin manifest to install\n\n -v, --version \n Specific version of a plugin to be install from the centralized plugins repository\n\n -y, --yes\n Skips prompt to accept the installation of the plugin","url":"/cloud/cli-reference.md#install"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Uninstall","content":"$ spin plugin uninstall --help\n\nUSAGE:\n spin plugin uninstall \n\nARGS:\n Name of Spin plugin\n\nOPTIONS:\n -h, --help Print help information","url":"/cloud/cli-reference.md#uninstall"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Update","content":"$ spin plugin update --help\n\nFetch the latest Spin plugins from the spin-plugins repository\n\nUSAGE:\n spin plugin update\n\nOPTIONS:\n -h, --help Print help information","url":"/cloud/cli-reference.md#update"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Upgrade","content":"$ spin plugin upgrade --help\n\nUSAGE:\n spin plugin upgrade [OPTIONS] [PLUGIN_NAME]\n\nARGS:\n Name of Spin plugin to upgrade\n\nOPTIONS:\n -a, --all\n Upgrade all plugins\n\n -d, --downgrade\n Allow downgrading a plugin's version\n\n -f, --file \n Path to local plugin manifest\n\n -h, --help\n Print help information\n\n --override-compatibility-check\n Overrides a failed compatibility check of the plugin with the current version of Spin\n\n -u, --url \n Path to remote plugin manifest\n\n -v, --version \n Specific version of a plugin to be install from the centralized plugins repository\n\n -y, --yes\n Skips prompt to accept the installation of the plugin[s]","url":"/cloud/cli-reference.md#upgrade"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Templates","content":"$ spin templates --help\n\nUSAGE:\n spin templates \n\nOPTIONS:\n -h, --help Print help information\n\nSUBCOMMANDS:\n help Print this message or the help of the given subcommand(s)\n install Install templates from a Git repository or local directory\n list List the installed templates\n uninstall Remove a template from your installation","url":"/cloud/cli-reference.md#templates"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Install","content":"$ spin templates install --help\n\nUSAGE:\n spin templates install [OPTIONS]\n\nOPTIONS:\n --branch \n The optional branch of the git repository\n\n --dir \n Local directory containing the template(s) to install\n\n --git \n The URL of the templates git repository. The templates must be in a git repository in a\n \"templates\" directory\n\n -h, --help\n Print help information\n\n --update\n If present, updates existing templates instead of skipping","url":"/cloud/cli-reference.md#install"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"List","content":"$ spin templates list --help\n\nUSAGE:\n spin templates list\n\nOPTIONS:\n -h, --help Print help information","url":"/cloud/cli-reference.md#list"},{"project":"cloud","title":"Spin Command Line Interface (CLI) Reference","subheading":"Uninstall","content":"$ spin templates uninstall --help\n\nUSAGE:\n spin templates uninstall \n\nARGS:\n The template to uninstall\n\nOPTIONS:\n -h, --help Print help information\n``","url":"/cloud/cli-reference.md#uninstall"},{"project":"cloud","title":"Contributing","subheading":"","content":"To contribute to the Fermyon Cloud Documentation, please follow these steps.undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined","url":"/cloud/contributing.md"},{"project":"cloud","title":"Contributing","subheading":"1. Fork the Repository","content":"The first step is to fork the undefined, from Fermyon's GitHub, to your own GitHub account.undefinedEnsure that you are forking the developer repository undefined GitHub account; where you have full editing privileges.","url":"/cloud/contributing.md#1-fork-the-repository"},{"project":"cloud","title":"Contributing","subheading":"2. Clone the Fork","content":"Copy the URL from the UI in readiness for running the git clone command.undefinedGo ahead and clone the new fork that you just created (the one which resides in your own GitHub account):$ cd ~\n$ git clone git@github.com:yourusername/developer.git\n$ cd developer","url":"/cloud/contributing.md#2-clone-the-fork"},{"project":"cloud","title":"Contributing","subheading":"3. Create New Branch","content":"Create a new branch that will house all of your changes for this specific contribution:$ git checkout -b my_new_branch","url":"/cloud/contributing.md#3-create-new-branch"},{"project":"cloud","title":"Contributing","subheading":"4. Add Upstream","content":"Create a new remote for the upstream (a pointer to the original repository to which you are contributing):$ git remote add upstream https://github.com/fermyon/developer","url":"/cloud/contributing.md#4-add-upstream"},{"project":"cloud","title":"Contributing","subheading":"5. Add Changes","content":"Once you are satisfied with your contribution go ahead and add your changes by moving to a top-level directory, under which your changes exist i.e. cd ~/developer.Add your changes using the following command:$ git add","url":"/cloud/contributing.md#5-add-changes"},{"project":"cloud","title":"Contributing","subheading":"6. Commit Changes","content":"Before committing, please ensure that your GitHub installation is configured sufficiently so that you can --signoff as part of the git commit command. For example, please ensure that the user.name and user.email are configured in your terminal. You can check if these are set by typing git config --list.If you need to set these values please use the following commands:$ git config user.name \"yourusername\"\n$ git config user.email \"youremail@somemail.com\"More information can be found at this GitHub documentation page called undefined.Type the following commit command to ensure that you sign off (--signoff), sign the data (-S) - recommended, and also leave a short message (-m):$ git commit -S --signoff -m \"Updating documentation\"undefined","url":"/cloud/contributing.md#6-commit-changes"},{"project":"cloud","title":"Contributing","subheading":"7. Push Changes","content":"At this stage, it is a good idea to just quickly check what GitHub thinks the origin is. For example, if we type git remote -v we can see that the origin is our repo; which we a) forked the original repo into and b) which we then cloned to our local disk so that we could edit:$ git remote -vThe above command will return output similar to the following:origin\tgit@github.com:yourusername/developer.git (fetch)\norigin\tgit@github.com:yourusername/developer.git (push)\nupstream\thttps://github.com/fermyon/developer (fetch)\nupstream\thttps://github.com/fermyon/developer (push)Once you are satisfied go ahead and push your changes:$ git push -u origin my_new_branch","url":"/cloud/contributing.md#7-push-changes"},{"project":"cloud","title":"Contributing","subheading":"8. Create a Pull Request","content":"If you return to your GitHub repository in your browser, you will notice that a PR has automatically been generated for you.Clicking on the green “Compare and pull request” button will allow you to add a title and description as part of the PR.undefinedYou can also add any information in the textbox provided below the title. For example, screen captures and/or code/console/terminal snippets of your contribution working correctly and/or tests passing etc.Once you have finished creating your PR, please keep an eye on the PR; answering any questions as part of the collaboration process.undefinedThanks for contributing","url":"/cloud/contributing.md#8-create-a-pull-request"},{"project":"cloud","title":"FAQ and Known Limitations","subheading":"","content":"This document contains:undefinedundefinedundefined","url":"/cloud/faq.md"},{"project":"cloud","title":"FAQ and Known Limitations","subheading":"Service Limits","content":"The following are the limits of the Fermyon Cloudundefinedundefinedundefinedundefinedundefinedundefined","url":"/cloud/faq.md#service-limits"},{"project":"cloud","title":"FAQ and Known Limitations","subheading":"Known Limitations","content":"The following are known limitations of the Fermyon Cloudundefinedundefinedundefinedundefined","url":"/cloud/faq.md#known-limitations"},{"project":"cloud","title":"FAQ and Known Limitations","subheading":"Frequently Asked Questions","content":"undefinedundefined11:08:13 : Hello from Rust\n11:08:18 : Hello from Rust - updated\n11:08:19 : Hello from Rust\n11:08:23 : Hello from Rust - updated\n11:08:24 : Bad Gateway\n11:08:26 : Hello from Rust - updated\n11:08:27 : Bad Gateway\n11:08:29 : Hello from Rust - updatedundefinedundefinedundefinedundefined","url":"/cloud/faq.md#frequently-asked-questions"},{"project":"cloud","title":"Fermyon Cloud","subheading":"","content":"How is the Fermyon Cloud built?","url":"/cloud/fermyon-cloud.md"},{"project":"cloud","title":"Fermyon Cloud","subheading":"","content":"This is a placeholder for Fermyon Cloud docsHowdy howdy!!","url":"/cloud/index.md"},{"project":"cloud","title":"Let's get started","subheading":"","content":"undefinedundefinedundefinedundefinedundefinedundefinedundefinedThis guide will get you up and running in the Fermyon Cloud in less than two minutes. And to do so, we've already made a Spin application ready for you to deploy.","url":"/cloud/quickstart.md"},{"project":"cloud","title":"Let's get started","subheading":"Install Spin","content":"First, you need to have Spin installed on your computer. Use the below command to install the latest version of Spin.curl https://developer.fermyon.com/downloads/install.sh | bashThis command downloaded and unpacked the latest Spin binary in the current directory. You can now run spin using the command ./spin{{ details \"Learn more\" \"Spin is an open-source project used for creating, developing, building, running, and deploying Spin applications. It is both a CLI tool and a runtime, and provides SDKs for a variety of programming languages, including, but not limited to, Rust, TinyGo, and C#. \\n\\n The Spin project provides installers that are supported on Linux (amd64), macOS (amd64 and arm64), and Windows(amd64). \\n\\n The undefined documentation is a good place to learn more about Spin and how to develop applications.\"}}","url":"/cloud/quickstart.md#install-spin"},{"project":"cloud","title":"Let's get started","subheading":"Log in to the Fermyon cloud","content":"Now, let's log in to the Fermyon cloud. You will be using your GitHub user account to sign in../spin loginThis command will generate an authentication code for your current device to be authorized against the Fermyon Cloud. Follow the instructions in the prompt to complete the authorization.{{ details \"Learn more\" \"The default behavior of spin login is to authenticate with the Fermyon Cloud. The command can authenticate against any instance of the undefined.\" }}","url":"/cloud/quickstart.md#log-in-to-the-fermyon-cloud"},{"project":"cloud","title":"Let's get started","subheading":"Clone the quickstart repo","content":"To make this easy, we've already compiled a Webassembly module and created a Spin application for you to deploy.Let's go ahead and clone the undefined repository to your computer, to get that application.git clone https://github.com/fermyon/cloud-start && cd cloud-startThis command clones the repository into a new directory named cloud-start, and then enters that directory.{{ details \"Learn more\" \"Normally you would start by using the command spin new [template name] [project name] to create a new Spin application. This gives you the option to choose a template, based on your preference of programming language and the trigger you want to use for your first module - e.g., spin new rust-http my_rust_http_trigger. \\n\\n The undefined guides you through creating a Spin application from scratch.\" }}","url":"/cloud/quickstart.md#clone-the-quickstart-repo"},{"project":"cloud","title":"Let's get started","subheading":"Deploy the application","content":"Let's deploy the application../spin deployThe ../spin command will use the Spin binary in the parent directory of the current path and use the Spin application definition file spin.toml in the current directory, to know what application to deploy.{{ details \"Learn more\" \"Deploying a Spin application includes packaging the application in a Bindle and uploading it to a Bindle registry, as well as creating the application in the Fermyon Cloud. \\n\\n You can learn more about the deployment process undefined.\" }}","url":"/cloud/quickstart.md#deploy-the-application"},{"project":"cloud","title":"Let's get started","subheading":"Success","content":"This is what success looks like:Application cloud_start/0.1.0 deployed, running at cloud-start-00000000.fermyon.appYou can CTRL+Click on the link in the terminal to go to the web application you just deployed.Congratulations, you've now deployed your first application to the Fermyon Cloud!","url":"/cloud/quickstart.md#success"},{"project":"cloud","title":"Let's get started","subheading":"Next Steps","content":"undefinedundefined","url":"/cloud/quickstart.md#next-steps"},{"project":"cloud","title":"Rest API","subheading":"","content":"","url":"/cloud/rest-api.md"},{"project":"cloud","title":"Rest API","subheading":"OpenAPI","content":"The undefined project contains automatically generated client libraries for use with the Fermyon Cloud.","url":"/cloud/rest-api.md#openapi"},{"project":"cloud","title":"Rest API","subheading":"Rust Client","content":"To use undefined, go ahead and add a reference to the Fermyon Cloud OpenAPI in your project’s Cargo.toml file, as shown below:cloud-openapi = { git = \"https://github.com/fermyon/cloud-openapi\" }","url":"/cloud/rest-api.md#rust-client"},{"project":"cloud","title":"Rest API","subheading":"Documenting the Fermyon Cloud API","content":"The documentation for each client library is automatically generated and is available in the undefined.","url":"/cloud/rest-api.md#documenting-the-fermyon-cloud-api"},{"project":"cloud","title":"Rest API","subheading":"Related Resources","content":"undefinedundefined","url":"/cloud/rest-api.md#related-resources"},{"project":"cloud","title":"Support","subheading":"","content":"This article contains the following information:undefinedundefined","url":"/cloud/support.md"},{"project":"cloud","title":"Support","subheading":"Engage on Discord","content":"As the Fermyon Cloud is currently a the preview stage, support is being provided through undefined. This link will take you to the undefined channel, which is a good place to start.For support related to undefined, undefined, and other projects, please use the appropriate channels on Discord as well.","url":"/cloud/support.md#engage-on-discord"},{"project":"cloud","title":"Support","subheading":"Report issues on GitHub","content":"To see any know issues and report a specific issue, feel free to use this undefined","url":"/cloud/support.md#report-issues-on-github"},{"project":"index.md","title":"Fermyon Developer Home","subheading":"","content":"This is a placeholder for Fermyon Developer Home","url":"/index.md"},{"project":"index.md","title":"Fermyon Developer Home","subheading":"Spin Docs","content":"","url":"/index.md#spin-docs"},{"project":"spin","title":"Spin architecture and internals","subheading":"","content":"This document aims to offer an overview to the implementation of Spin, as well\nas explain how the code is structured and how all parts fit together. This\ndocument is continuously evolving, and if you want even more detailed\ninformation, make sure to review the code for a given part of Spin.","url":"/spin/architecture.md"},{"project":"spin","title":"Spin architecture and internals","subheading":"How Spin runs an application","content":"A Spin application is defined as a spin.toml file. It can either be run\ndirectly by spin up, passing the manifest file (--file spin.toml), or it can\nbe pushed to the registry then referenced using its remote ID\n(spin bindle push followed by spin up --bindle ).Regardless of the application origin (local file or remote reference from the\nregistry), a Spin application is defined by\nspin_manifest::Application (contained in the\nundefined crate),\nwhich is the canonical representation of a Spin application.The crate responsible for transforming a custom configuration into a canonical\nSpin application is undefined,\nwhich implements loading applications from local spin.toml files and from\nremote Bindle references (and ensures files referenced in the application\nconfiguration are copied and mounted at the location expected in the WebAssembly\nmodule). Once the canonical representation is loaded from an application source,\nit is passed to a trigger.The HTTP trigger (defined in the spin-http crate) takes an\napplication configuration (undefined\nexplores a trigger handling multiple applications), starts an HTTP listener, and\nfor each new request, it routes it to the component configured in the\napplication configuration. Then, it instantiates the WebAssembly module (using a\nspin_engine::ExecutionContext) and uses the appropriate executor (either the\nSpinHttpExecutor or the WagiHttpExecutor, based on the component\nconfiguration) to handle the request and return the response.","url":"/spin/architecture.md#how-spin-runs-an-application"},{"project":"spin","title":"Spin architecture and internals","subheading":"The Spin execution context","content":"The Spin execution context (or \"Spin engine\") is the part of Spin that executes\nWebAssembly components using the\nundefined WebAssembly runtime. It\nis implemented in the spin-engine crate, and serves as\nthe part of Spin that takes a fully formed application configuration and creates\nWasm instances based on the component configurations.There are two important concepts in this crate:undefinedundefined","url":"/spin/architecture.md#the-spin-execution-context"},{"project":"spin","title":"Configuration for Spin applications","subheading":"","content":"Spin applications are comprised of general information (metadata), and a collection\nof at least one undefined. Configuration for a Spin application lives in a TOML\nfile called spin.toml (the undefined). In the example below we can see\na simple HTTP application with a single component executed when the /hello endpoint\nis accessed:spin_version = \"1\"\nname = \"spin-hello-world\"\ndescription = \"A simple application that returns hello world.\"\ntrigger = { type = \"http\", base = \"/\" }\nversion = \"1.0.0\"\n\n[[component]]\nid = \"hello\"\ndescription = \"A simple component that returns hello world.\"\nsource = \"target/wasm32-wasi/release/spinhelloworld.wasm\"\n[component.trigger]\nroute = \"/hello\"\n[component.build]\ncommand = \"cargo build --target wasm32-wasi --release\"","url":"/spin/configuration.md"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Application manifest reference","content":"","url":"/spin/configuration.md#application-manifest-reference"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Application configuration","content":"The following are the fields supported by the spin.toml manifest file:undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined","url":"/spin/configuration.md#application-configuration"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Component configuration","content":"Each component object has the following fields:undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined","url":"/spin/configuration.md#component-configuration"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Custom Configuration","content":"Spin applications may define custom configuration which can be looked up by\ncomponent code via the undefined.","url":"/spin/configuration.md#custom-configuration"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Custom Config Variables","content":"Application-global custom config variables are defined in the top-level [variables]\nsection. These entries aren't accessed directly by components, but are referenced\nby undefined value templates. Each entry must\neither have a default value or be marked as required = true. \"Required\" entries\nmust be undefined with a value.Configuration keys may only contain lowercase letters and underscores between letters.[variables]\napi_host = { default = \"api.example.com\" }\napi_key = { required = true }","url":"/spin/configuration.md#custom-config-variables"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Component Custom Config","content":"The configuration entries available to a component are listed in its\n[component.config] section. Configuration values may reference\nundefined with simple\nundefined-inspired string templates.[[component]]\n# ...\n[component.config]\napi_base_url = \"https://{{ api_host }}/v1\"\napi_key = \"{{ api_key }}\"","url":"/spin/configuration.md#component-custom-config"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Custom Config Providers","content":"undefined values may be set at runtime by\nconfig \"providers\". Currently there is only one provider: the environment\nvariable provider, which gets config values from the spin process's\nenvironment (undefined the component environment). Config keys are translated\nto environment variables by upper-casing and prepending with SPIN_APP_:$ export SPIN_APP_API_KEY = \"1234\" # Sets the `api_key` value.\n$ spin up","url":"/spin/configuration.md#custom-config-providers"},{"project":"spin","title":"Configuration for Spin applications","subheading":"Examples","content":"undefined[[component]]\nsource = \"modules/spin_static_fs.wasm\"\nid = \"fileserver\"\nfiles = [ { source = \"static/\", destination = \"/\" } ]\n[component.trigger]\nroute = \"/static/...\"undefined[[component]]\nsource = \"modules/env_wagi.wasm\"\nid = \"env\"\nfiles = [ \"content/**/*\" , \"templates/*\", \"scripts/*\", \"config/*\"]\n[component.trigger]\nroute = \"/...\"\nexecutor = { type = \"wagi\", argv = \"test ${SCRIPT_NAME} ${ARGS} done\", entrypoint = \"some-other-export-function\" }undefined[[component]]\nid = \"echo-message\"\nsource = \"spinredis.wasm\"\n[component.trigger]\nchannel = \"messages\"","url":"/spin/configuration.md#examples"},{"project":"spin","title":"Contributing to Spin","subheading":"","content":"We are delighted that you are interested in making Spin better! Thank you! This\ndocument will guide you through making your first contribution to the project.First, any contribution and interaction on any Fermyon project MUST follow our\nundefined. Thank you for being\npart of an inclusive and open community!\nWe welcome and appreciate contributions of all types — opening issues, fixing\ntypos, adding examples, one-liner code fixes, tests, or complete features.If you plan on contributing anything complex, please go through the issue and PR\nqueues first to make sure someone else has not started working on it. If it\ndoesn't exist already, please open an issue so you have a chance to get feedback\nfrom the community and the maintainers before you start working on your feature.","url":"/spin/contributing.md"},{"project":"spin","title":"Contributing to Spin","subheading":"Making code contributions to Spin","content":"The following guide is intended to make sure your contribution can get merged as\nsoon as possible. First, make sure you have the following prerequisites\nconfigured:undefinedundefinedundefinedundefinedundefinedundefinedOnce you have set up the prerequisites and identified the contribution you want\nto make to Spin, make sure you can correctly build the project:# clone the repository\n$ git clone https://github.com/fermyon/spin && cd spin\n# add a new remote pointing to your fork of the project\n$ git remote add fork https://github.com//spin\n# create a new branch for your work\n$ git checkout -b \n\n# if you are making a documentation contribution,\n# you can skip compiling and running the tests.\n\n# build a release version of the Spin CLI\n$ cargo build --release\n# make sure compilation is successful\n$ ./target/release/spin --help\n\n# run the tests and make sure they pass\n$ make testNow you should be ready to start making your contribution. To familiarize\nyourself with the Spin project, please read the\nundefined. Since most of Spin is implemented in\nRust, we try to follow the common Rust coding conventions (keep an eye on the\nrecommendations from Clippy!) If applicable, add unit or integration tests to\nensure your contribution is correct.Build the project and run the tests (make build test), and if everything is\nsuccessful, you should be ready to commit your changes. We try to follow the\nundefined\nguidelines for writing commit messages:$ git commit -S -s -m \"\"We try to only keep useful changes as separate commits — if you prefer to commit\noften, please\nundefined\nbefore opening a pull request. Once you are happy with your changes you can push\nthe branch to your fork:# \"fork\" is the name of the git remote pointing to your fork\n$ git push forkNow you are ready to create a pull request. Thank you for your contribution!","url":"/spin/contributing.md#making-code-contributions-to-spin"},{"project":"spin","title":"Deploying Spin applications to Fermyon","subheading":"","content":"undefined is the frictionless WebAssembly platform for deploying\nmicroservices and web apps. With Fermyon, you can deploy your spin applications onto a server in\nmoments.For instructions guiding you through running the Fermyon platform on your development workstation,\nfollow undefined.For instructions guiding you through running the Fermyon platform on AWS, follow\nundefined.","url":"/spin/deploying-to-fermyon.md"},{"project":"spin","title":"Developing Spin applications","subheading":"","content":"The Spin CLI offers a few commands to simplify developing applications.","url":"/spin/developing.md"},{"project":"spin","title":"Developing Spin applications","subheading":"Building Spin applications","content":"A Spin application is made up of one or more components. When developing a\nmulti-component application, it is very common to have multiple directories with\nsource code for components — and when making changes to components, having to\nmanually go into the each component directory, compile the component, then go\nback to the directory with spin.toml can be a very repetitive task.This is why Spin has a top-level command that will execute the build command\nset by each component, spin up:[component.build]\ncommand = \"cargo build --target wasm32-wasi --release --manifest-path http-rust/Cargo.toml\"Then, running spin build will execute, sequentially, each build command:$ RUST_LOG=spin=trace spin build\n2022-04-25T03:01:56.721630Z INFO spin_build: Executing the build command for component rust-hello.\n Finished release [optimized] target(s) in 0.05s\n2022-04-25T03:01:56.832360Z INFO spin_build: Executing the build command for component rust-static-assets.\n Finished release [optimized] target(s) in 0.02s\n2022-04-25T03:01:56.905424Z INFO spin_build: Executing the build command for component rust-outbound-http.\n Finished release [optimized] target(s) in 0.02sThe spin build command is intended to offer a built-in way to build more complex\nSpin applications without needing a separate build process.\nIt is not intended to replace complex build scripts — if\nyou have existing automated ways for building source code, those can be used\ninstead, or the build command can call that process.spin build --up can be used to start the application after the build process\nfinishes for all application components.","url":"/spin/developing.md#building-spin-applications"},{"project":"spin","title":"Developing Spin applications","subheading":"Component workdir","content":"By default, the command to build a component is executed in the manifest's\ndirectory. This can be changed. For example, assume a component is located in\nsubdirectory deep:.\n├── deep\n│   ├── Cargo.toml\n│   └── src\n│   └── lib.rs\n└── spin.tomlTo run the build command in directory deep, set the component's workdir:[component.build]\ncommand = \"cargo build --target wasm32-wasi --release\"\nworkdir = \"deep\"Note that workdir must be a relative path and it operates relative to the\nspin.toml. Specifying an absolute path leads to an error.","url":"/spin/developing.md#component-workdir"},{"project":"spin","title":"Packaging and distributing Spin applications","subheading":"","content":"Packaging and distributing Spin applications is done using undefined,\nan open source aggregate object storage system. This allows the packaging of the\napplication manifest, components, and static assets together, and\ntakes advantage of the features of a modern object storage system.To distribute applications, we first need a Bindle registry. You can\nundefined,\nor use the\nundefined\nVS Code extension (through the Bindle: Start command):$ bindle-server --address 127.0.0.1:8000 --directory . --unauthenticatedLet's push the application from the undefined to the registry:$ export BINDLE_URL=http://localhost:8000/v1\n$ spin bindle push --file spin.toml\npushed: spin-hello-world/1.0.0Now we can run the application using spin up directly from the registry:$ spin up --bindle spin-hello-world/1.0.0undefinedThe application can also be prepared in a local directory before pushing to the\nregistry by running spin bindle prepare.","url":"/spin/distributing-apps.md"},{"project":"spin","title":"Extending and embedding Spin","subheading":"","content":"undefinedSpin currently implements triggers and application models for:undefinedundefinedThe Spin internals and execution context (the part of Spin executing\ncomponents) are agnostic of the event source and application model.\nIn this document we will explore how to extend Spin with custom event sources\n(triggers) and application models built on top of the WebAssembly component\nmodel, as well as how to embed Spin in your application.In this article we will build a Spin trigger to run the applications based on a\ntimer, executing Spin components at configured time interval.The current application types that can be implemented with Spin have entry points\ndefined using\nundefined:// The entry point for an HTTP handler.\nhandle-http-request: function(req: request) -> response\n\n// The entry point for a Redis handler.\nhandle-redis-message: function(msg: payload) -> expected<_, error>The entry point we want to execute for our timer trigger takes a string as its\nonly argument (the trigger will populate that with the current date and time),\nand it expects a string as the only return value. This is purposefully chosen\nto be a simple function signature:// examples/spin-timer/spin-timer.wit\nhandle-timer-request: function(msg: string) -> stringThis is the function that all components executed by the timer trigger must\nimplement, and which is used by the timer executor when instantiating and\ninvoking the component.Let's have a look at building the timer trigger:// examples/spin-timer/src/main.rs\nwit_bindgen_wasmtime::import!({paths: [\"spin-timer.wit\"], async: *});\ntype ExecutionContext = spin_engine::ExecutionContext;\n\n/// A custom timer trigger that executes a component on every interval.\n#[derive(Clone)]\npub struct TimerTrigger {\n /// The interval at which the component is executed.\n pub interval: Duration,\n /// The Spin execution context.\n engine: Arc,\n}A few important things to note from the start:undefinedundefinedundefinedFinally, whenever there is a new event (in the case of our timer-based trigger\nevery n seconds), we execute the entry point of a selected component:/// Execute the first component in the application manifest.\nasync fn handle(&self, msg: String) -> Result<()> {\n // create a new Wasmtime store and instance based on the first component's WebAssembly module.\n let (mut store, instance) =\n self.engine\n .prepare_component(&self.app.components[0].id, None, None, None, None)?;\n\n // spawn a new thread and call the entry point function from the WebAssembly module \n let res = spawn_blocking(move || -> Result {\n // use the auto-generated WIT bindings to get the Wasm exports and call the `handle-timer-request` function.\n let t = spin_timer::SpinTimer::new(&mut store, &instance, |host| {\n host.data.as_mut().unwrap()\n })?;\n Ok(t.handle_timer_request(&mut store, &msg)?)\n })\n .await??;\n // do something with the result.\n log::info!(\"{}\\n\", res);\n Ok(())\n}A few notes:undefinedundefinedundefinedThis is very similar to how the undefined and undefined\ntriggers are implemented, and it is the recommended way to extend Spin with your\nown trigger and application model.Writing components for the new trigger can be done by using the\nundefined from\nRust and other supported languages (see undefined):// automatically generate Rust bindings that help us implement the \n// `handle-timer-request` function that the trigger will execute.\nwit_bindgen_rust::export!(\"../spin-timer.wit\");\n...\nfn handle_timer_request(msg: String) -> String {\n format!(\"ECHO: {}\", msg)\n}Components can be compiled to WebAssembly, then used from a spin.toml\napplication manifest.Embedding the new trigger in a Rust application is done by creating a new trigger\ninstance, then calling its run function:// app() is a utility function that generates a complete application configuration.\nlet trigger = TimerTrigger::new(Duration::from_secs(1), app()).await?;\n// run the trigger indefinitely\ntrigger.run().awaitundefinedIn this example, we built a simple timer trigger — building more complex triggers\nwould also involve updating the Spin application manifest, and extending\nthe application-level trigger configuration, as well as component-level\ntrigger configuration (an example of component-level trigger configuration\nfor this scenario would be each component being able to define its own\nindependent time interval for scheduling the execution).","url":"/spin/extending-and-embedding.md"},{"project":"spin","title":"Extending and embedding Spin","subheading":"Other ways to extend and use Spin","content":"Besides building custom triggers, the internals of Spin could also be used\nindependently:undefinedundefined","url":"/spin/extending-and-embedding.md#other-ways-to-extend-and-use-spin"},{"project":"spin","title":"Building Spin components in Go","subheading":"","content":"undefined is an implementation of the\nundefined for embedded systems and WebAssembly.\nThe Spin SDK for Go uses\nundefined\nto build programs written in Go as Spin components.undefinedundefined","url":"/spin/go-components.md"},{"project":"spin","title":"Building Spin components in Go","subheading":"Versions","content":"TinyGo currently requires Go versions 1.15.x through 1.17.x. The recommendation is to use\nGo version 1.17.9, and TinyGo version 0.22.0. Go 1.18.x support will be added in an upcoming\nTinyGo release 0.22.x.","url":"/spin/go-components.md#versions"},{"project":"spin","title":"Building Spin components in Go","subheading":"HTTP components","content":"In Spin, HTTP components are triggered by the occurrence of an HTTP request, and\nmust return an HTTP response at the end of their execution. Components can be\nbuilt in any language that compiles to WASI, and Go has improved support for\nwriting applications, through its SDK.Building a Spin HTTP component using the Go SDK means writing a single function,\ninit — below is a complete implementation for such a component:// A Spin component written in Go that returns \"Hello, Fermyon!\"\npackage main\n\nimport (\n \"fmt\"\n \"net/http\"\n\n spinhttp \"github.com/fermyon/spin/sdk/go/http\"\n)\n\nfunc init() {\n spinhttp.Handle(func(w http.ResponseWriter, r *http.Request) {\n w.Header().Set(\"Content-Type\", \"text/plain\")\n fmt.Fprintln(w, \"Hello Fermyon!\")\n })\n}\n\nfunc main() {}The important things to note in the implementation above:undefinedundefinedundefined","url":"/spin/go-components.md#http-components"},{"project":"spin","title":"Building Spin components in Go","subheading":"Sending outbound HTTP requests","content":"If allowed, Spin components can send outbound requests to HTTP endpoints. Let's\nsee an example of a component that makes a request to\nundefined and\ninserts a custom header into the response before returning:// A Spin component written in Go that sends a request to an API\n// with random dog facts.\n\npackage main\n\nimport (\n \"bytes\"\n \"fmt\"\n \"net/http\"\n \"os\"\n\n spinhttp \"github.com/fermyon/spin/sdk/go/http\"\n)\n\nfunc init() {\n spinhttp.Handle(func(w http.ResponseWriter, r *http.Request) {\n r, _ := spinhttp.Get(\"https://some-random-api.ml/facts/dog\")\n\n fmt.Fprintln(w, r.Body)\n fmt.Fprintln(w, r.Header.Get(\"content-type\"))\n\n // `spin.toml` is not configured to allow outbound HTTP requests to this host,\n // so this request will fail.\n if _, err := spinhttp.Get(\"https://fermyon.com\"); err != nil {\n fmt.Fprintf(os.Stderr, \"Cannot send HTTP request: %v\", err)\n }\n })\n}\n\nfunc main() {}The component can be built using the tingygo toolchain:$ tinygo build -wasm-abi=generic -target=wasi -no-debug -o main.wasm main.goBefore we can execute this component, we need to add the\nsome-random-api.ml domain to the application manifest allowed_http_hosts\nlist containing the list of domains the component is allowed to make HTTP\nrequests to:# spin.toml\nspin_version = \"1\"\nname = \"spin-hello-tinygo\"\ntrigger = { type = \"http\", base = \"/\" }\nversion = \"1.0.0\"\n\n[[component]]\nid = \"tinygo-hello\"\nsource = \"main.wasm\"\nallowed_http_hosts = [ \"some-random-api.ml\" ]\n[component.trigger]\nroute = \"/hello\"undefinedRunning the application using spin up --file spin.toml will start the HTTP\nlistener locally (by default on localhost:3000), and our component can\nnow receive requests in route /hello:$ curl -i localhost:3000/hello\nHTTP/1.1 200 OK\ncontent-type: text/plain; charset=utf-8\nserver: spin/0.1.0\ncontent-length: 85\ndate: Fri, 18 Mar 2022 23:27:33 GMT\n\n{{\"fact\":\"Seventy percent of people sign their dog's name on their holiday cards.\"}}undefinedundefined","url":"/spin/go-components.md#sending-outbound-http-requests"},{"project":"spin","title":"Building Spin components in Go","subheading":"Redis components","content":"Besides the HTTP trigger, Spin has built-in support for a Redis trigger, which\nwill connect to a Redis instance and will execute components for new messages\non the configured channels.undefinedWriting a Redis component in Go also takes advantage of the SDK:package main\n\nimport (\n \"fmt\"\n\n \"github.com/fermyon/spin/sdk/go/redis\"\n)\n\nfunc init() {\n // redis.Handle() must be called in the init() function.\n redis.Handle(func(payload []byte) error {\n fmt.Println(\"Payload::::\")\n fmt.Println(string(payload))\n return nil\n })\n}\n\n// main function must be included for the compiler but is not executed.\nfunc main() {}The manifest for a Redis application must contain the address of the Redis instance:spin_version = \"1\"\nname = \"spin-redis\"\ntrigger = { type = \"redis\", address = \"redis://localhost:6379\" }\nversion = \"0.1.0\"\n\n[[component]]\nid = \"echo-message\"\nsource = \"main.wasm\"\n[component.trigger]\nchannel = \"messages\"\n[component.build]\ncommand = \"tinygo build -wasm-abi=generic -target=wasi -gc=leaking -no-debug -o main.wasm main.go\"The application will connect to redis://localhost:6379, and for every new message\non the messages channel, the echo-message component will be executed:# first, start redis-server on the default port 6379\n$ redis-server --port 6379\n# then, start the Spin application\n$ spin build --up\nINFO spin_redis_engine: Connecting to Redis server at redis://localhost:6379\nINFO spin_redis_engine: Subscribed component 0 (echo-message) to channel: messagesFor every new message on the messages channel:$ redis-cli\n127.0.0.1:6379> publish messages \"Hello, there!\"Spin will instantiate and execute the component:INFO spin_redis_engine: Received message on channel \"messages\"\nPayload::::\nHello, there!","url":"/spin/go-components.md#redis-components"},{"project":"spin","title":"Building Spin components in Go","subheading":"Storing data in Redis from Go components","content":"Using the Spin's Go SDK, you can use the Redis key/value store to publish\nmessages to Redis channels. This can be used from both HTTP and Redis triggered\ncomponents.Let's see how we can use the Go SDK to connect to Redis:package main\n\nimport (\n \"net/http\"\n \"os\"\n\n spin_http \"github.com/fermyon/spin/sdk/go/http\"\n \"github.com/fermyon/spin/sdk/go/redis\"\n)\n\nfunc init() {\n // handler for the http trigger\n spin_http.Handle(func(w http.ResponseWriter, r *http.Request) {\n\n // addr is the environment variable set in `spin.toml` that points to the\n // address of the Redis server.\n addr := os.Getenv(\"REDIS_ADDRESS\")\n\n // channel is the environment variable set in `spin.toml` that specifies\n // the Redis channel that the component will publish to.\n channel := os.Getenv(\"REDIS_CHANNEL\")\n\n // payload is the data publish to the redis channel.\n payload := []byte(`Hello redis from tinygo!`)\n\n if err := redis.Publish(addr, channel, payload); err != nil {\n http.Error(w, err.Error(), http.StatusInternalServerError)\n return\n }\n\n // set redis `mykey` = `myvalue`\n if err := redis.Set(addr, \"mykey\", []byte(\"myvalue\")); err != nil {\n http.Error(w, err.Error(), http.StatusInternalServerError)\n return\n }\n\n // get redis payload for `mykey`\n if payload, err := redis.Get(addr, \"mykey\"); err != nil {\n http.Error(w, err.Error(), http.StatusInternalServerError)\n } else {\n w.Write([]byte(\"mykey value was: \"))\n w.Write(payload)\n }\n })\n}\n\nfunc main() {}This HTTP component demonstrates fetching a value from Redis by key, setting a\nkey with a value, and publishing a message to a Redis channel. The component is\ntriggered by an HTTP request served on the route configured in the spin.toml:[[component]]\nenvironment = { REDIS_ADDRESS = \"redis://127.0.0.1:6379\", REDIS_CHANNEL = \"messages\" }\n[component.trigger]\nroute = \"/publish\"This HTTP component can be paired with a Redis component, triggered on new\nmessages on the messages Redis channel.undefined","url":"/spin/go-components.md#storing-data-in-redis-from-go-components"},{"project":"spin","title":"Building Spin components in Go","subheading":"Using Go packages in Spin components","content":"Any\nundefined that can be imported in TinyGo and that compiles to\nWASI can be used when implementing a Spin component.undefined","url":"/spin/go-components.md#using-go-packages-in-spin-components"},{"project":"spin","title":"The Spin HTTP trigger","subheading":"","content":"An important workload in event-driven environments is represented by HTTP\napplications, and Spin has built-in support for creating and running HTTP\ncomponents. This document presents an overview of the HTTP trigger, as well as\nsome implementation details around the WebAssembly component model and how it\nis used in Spin.The HTTP trigger in Spin is a web server. It listens for incoming requests and\nbased on the undefined, it routes them to an\nundefined which instantiates the appropriate component, executes its\nentry point function, then returns an HTTP response.Creating an HTTP application is done when undefined\nby defining the top-level application trigger:# spin.toml\ntrigger = { type = \"http\", base = \"/\" }Then, when defining the component (in spin.toml), there are two pieces of\nconfiguration that can be set for the component trigger: the route,\nand the undefined (see details below about executors). For example:undefined[component.trigger]\nroute = \"/hello\"\nexecutor = { type = \"spin\" }undefined[component.trigger]\nroute = \"/goodbye\"\nexecutor = { type = \"wagi\" }","url":"/spin/http-trigger.md"},{"project":"spin","title":"The Spin HTTP trigger","subheading":"Routing","content":"Routing an incoming request to a particular component is done using the\napplication base path (base in spin.toml) and the component defined routes\n(route in the component configuration) by prefixing the application base path\nto all component routes defined for that application.For example, if the application base path is base = /base, and a component\nhas defined route = /foo, that component will be executed for requests on\nhttp(s):///base/foo.Components can either define exact routes, for example route = /bar/baz, where\nthe component will be invoked only for requests on /base/bar/baz, or they\ncan define a wildcard as the last path segment, for example route = /bar/baz/...,\nwhich means the component will be invoked for every request starting with the\n/base/bar/baz/ prefix (such as /base/bar/baz, /base/bar/baz/qux,\n/base/bar/baz/qux/quux and so on).If multiple components could potentially handle the same request based on their\ndefined routes, the last component defined in spin.toml takes precedence.\nIn the following example:# spin.toml\n\ntrigger = { type = \"http\", base = \"/\"}\n\n[[component]]\nid = \"component-1\"\n[component.trigger]\nroute = \"/...\"\n\n[[component]]\nid = \"component-2\"\n[component.trigger]\nroute = \"/foo/...\"Any request starting with the /foo/ prefix will be handled by component-2,\nwhich is the last one defined in spin.toml.Every HTTP application has a special route always configured at /healthz, which\nreturns OK 200 when the Spin instance is healthy.Once Spin selects a component to handle an incoming request based on the route\nconfiguration, it will instantiate and execute that component based on its\ndefined undefined, and the next sections explore the two ways of building\nHTTP components based on the two available executors.","url":"/spin/http-trigger.md#routing"},{"project":"spin","title":"The Spin HTTP trigger","subheading":"The Spin HTTP executor","content":"Spin is built on top of the\nundefined.\nWe undefined believe the component model represents the future of WebAssembly,\nand we are working with the undefined\ncommunity on building exciting new features and tools for it. As a result, the\nSpin HTTP undefined is defined using WebAssembly interfaces.undefinedWe define the HTTP objects as\nundefined\nobjects, currently using undefined:// wit/ephemeral/http-types.wit\n\n// The HTTP status code.\ntype http-status = u16\n// The HTTP body.\ntype body = list\n// The HTTP headers represented as a list of (name, value) pairs.\ntype headers = list>\n// The HTTP parameter queries, represented as a list of (name, value) pairs.\ntype params = list>\n// The HTTP URI of the current request.\ntype uri = string\n// The HTTP method.\nenum method { get, post, put,... }\n\n// An HTTP request.\nrecord request {\n method: method,\n uri: uri,\n headers: headers,\n params: params,\n body: option,\n}\n\n// An HTTP response.\nrecord response {\n status: http-status,\n headers: option,\n body: option,\n}undefinedThen, we define the entry point for a Spin HTTP component:// wit/ephemeral/spin-http.wit\n\nuse * from http-types\n// The entry point for an HTTP handler.\nhandle-http-request: function(req: request) -> responseThis is the function signature that all HTTP components must implement, and\nwhich is used by the Spin HTTP executor when instantiating and invoking the\ncomponent.\nThis interface (spin-http.wit) can be directly used together with the\nundefined\nto build a component that the Spin HTTP executor can invoke.\nThis is exactly how undefined is built, and,\nas more languages add support for the component model, how we plan to add\nsupport for them as well.","url":"/spin/http-trigger.md#the-spin-http-executor"},{"project":"spin","title":"The Spin HTTP trigger","subheading":"The Wagi HTTP executor","content":"The WebAssembly component model proposal is currently in its early stages, which\nmeans only a few programming languages fully implement it. While the language\ncommunities implement toolchain support for the component model (for emitting\ncomponents and for automatically generating bindings for importing other\ncomponents), we want to allow developers to use any language that compiles to\nWASI to build Spin HTTP applications. This is why Spin currently implements an\nHTTP executor based on undefined, or the\nWebAssembly Gateway Interface, a project that implements the\nundefined\nspecification for WebAssembly.undefinedWagi allows a module built in any programming language that compiles to undefined\nto handle an HTTP request by passing the HTTP request information to the module's\nstandard input, environment variables, and arguments, and expecting the HTTP\nresponses through the module's standard output.\nThis means that if a language has support for the WebAssembly System Interface,\nit can be used to build Spin HTTP components.\nThe Wagi model is only used to parse the HTTP request and response. Everything\nelse — defining the application, running it, or undefined\nis done the same way as a component that uses the Spin executor.Building a Wagi component in a particular programming language that can compile\nto wasm32-wasi does not require any special libraries — instead,\nundefined can\nbe done by reading the HTTP request from the standard input and environment\nvariables, and sending the HTTP response to the module's standard output.In pseudo-code, this is the minimum required in a Wagi component:undefinedundefinedundefinedprint(\"content-type: text/html; charset=UTF-8\\n\\n\");\nprint(\"hello world\\n\");The undefined supports the Spin executor.\nHere is another example, written in undefined,\na new programming language that natively targets WebAssembly:import Process from \"sys/process\";\nimport Array from \"array\";\n\nprint(\"content-type: text/plain\\n\");\n\n// This will print all the Wagi env variables\nprint(\"==== Environment: ====\");\nArray.forEach(print, Process.env());\n\n// This will print the route path followed by each query\n// param. So /foo?bar=baz will be [\"/foo\", \"bar=baz\"].\nprint(\"==== Args: ====\");\nArray.forEach(print, Process.argv());undefined","url":"/spin/http-trigger.md#the-wagi-http-executor"},{"project":"spin","title":"The Spin HTTP trigger","subheading":"The default headers set in Spin HTTP components","content":"Spin sets a few default headers on the request based on the base path, component\nroute, and request URI, which will always be available when writing a module:undefinedundefinedundefinedundefinedundefinedundefined","url":"/spin/http-trigger.md#the-default-headers-set-in-spin-http-components"},{"project":"spin","title":"The Spin HTTP trigger","subheading":"The default headers set in Wagi HTTP components","content":"For Wagi HTTP components, the following are set as environment variables for the\nhandler WebAssembly modules:undefinedundefinedundefinedundefinedundefinedundefinedBesides the headers above, components that use the Wagi executor also have set\nundefined.","url":"/spin/http-trigger.md#the-default-headers-set-in-wagi-http-components"},{"project":"spin","title":"Introducing Spin","subheading":"","content":"Spin is a framework for building and running event-driven microservice applications\nwith WebAssembly (Wasm) components. With Spin, we’re trying to make it easier to get\nstarted with using WebAssembly on the server so that we can all take advantage of the\nsecurity, portability, and speed WebAssembly provides when it comes to running\nmicroservices.","url":"/spin/index.md"},{"project":"spin","title":"Introducing Spin","subheading":"Structure of a Spin Application","content":"undefinedundefinedSpin executes the component(s) as a result of events being generated by the trigger(s)\ndefined in the spin.toml file.","url":"/spin/index.md#structure-of-a-spin-application"},{"project":"spin","title":"Introducing Spin","subheading":"Example Spin Application","content":"The following illustrates how to define an HTTP application.","url":"/spin/index.md#example-spin-application"},{"project":"spin","title":"Introducing Spin","subheading":"HTTP Handler","content":"This hello_world function written in Rust defines a component that takes a Request and returns a Result.#[http_component]​\nfn hello_world(_req: Request) -> Result {​\n Ok(http::Response::builder()​\n .status(200)​\n .body(Some(\"Hello, Fermyon!\".into()))?)​\n}​","url":"/spin/index.md#http-handler"},{"project":"spin","title":"Introducing Spin","subheading":"Spin Manifest","content":"Once the code is compiled to a WebAssembly component, it can be referenced in a spin.toml\nfile to create an HTTP application like what you can see below:spin_version = \"1\"\nname = \"spin-hello-world\"\ntrigger = { type = \"http\", base = \"/\" }\nversion = \"1.0.0\"\n\n[[component]]\nid = \"hello\"\nsource = \"\"\n[component.trigger]\nroute = \"/hello\"","url":"/spin/index.md#spin-manifest"},{"project":"spin","title":"Introducing Spin","subheading":"Running a Spin Application","content":"Running this application with the spin CLI is as simple as using the spin up command.\nBecause a trigger type of http is specified in the spin.toml file, spin up will start\na web server:$ spin up\nServing HTTP on address http://127.0.0.1:3000\nAvailable Routes:\n hello: http://127.0.0.1:3000/helloAny time a request is made on the /hello route, it will invoke the\nhello_world function. Adding another component is as simple as adding another [[component]]\nstanza to the spin.toml file.In the next section, we will undefined.","url":"/spin/index.md#running-a-spin-application"},{"project":"spin","title":"Building Spin components in other languages","subheading":"","content":"undefinedundefinedWebAssembly is becoming undefined, and as language toolchains add support for the\nundefined,\nbuilding Spin components will also become supported.As a general rule:undefinedundefinedundefinedundefined","url":"/spin/other-languages.md"},{"project":"spin","title":"Building Spin components in other languages","subheading":"AssemblyScript","content":"undefined is a TypeScript-based language that compiles directly to WebAssembly.\nAssemblyScript has WASI/Wagi support, and so can be used with Spin.undefinedundefinedundefined","url":"/spin/other-languages.md#assemblyscript"},{"project":"spin","title":"Building Spin components in other languages","subheading":"C/C++","content":"C and C++ are both broadly supported in the WebAssembly ecosystem. WASI/Wagi support means that both can be used to write Spin apps.undefinedundefinedundefined","url":"/spin/other-languages.md#cc"},{"project":"spin","title":"Building Spin components in other languages","subheading":"C# and .NET languages","content":".NET has experimental support for WASI, so many (if not all) .NET languages, including C# and F#, can be used to write Spin applications.undefinedundefined","url":"/spin/other-languages.md#c-and-net-languages"},{"project":"spin","title":"Building Spin components in other languages","subheading":"Grain","content":"undefined, a new functional programming language, has WASI/Wagi support and can be used to write Spin apps.undefinedundefinedundefined","url":"/spin/other-languages.md#grain"},{"project":"spin","title":"Building Spin components in other languages","subheading":"Python","content":"Python's interpreter can be compiled to WebAssembly, and it has WASI support. It is known to work for Spin.undefinedundefinedundefinedundefinedundefined","url":"/spin/other-languages.md#python"},{"project":"spin","title":"Building Spin components in other languages","subheading":"Ruby","content":"Upstream undefined officially supports WebAssembly and WASI, and we here at Fermyon have successfully run Ruby apps in Spin.undefinedundefined","url":"/spin/other-languages.md#ruby"},{"project":"spin","title":"Building Spin components in other languages","subheading":"Zig","content":"Zig is a low-level systems language that has support for Wasm and WASI, and can be used to write Spin apps.undefinedundefined","url":"/spin/other-languages.md#zig"},{"project":"spin","title":"Taking Spin for a spin","subheading":"","content":"undefined","keywords":"quickstart","url":"/spin/quickstart.md"},{"project":"spin","title":"Taking Spin for a spin","subheading":"Getting the spin binary","content":"You can install the spin binary using the install.sh script hosted on this site.$ curl https://spin.fermyon.dev/downloads/install.sh | bashTo install a specific version, you can pass arguments to the install script this way:$ curl https://spin.fermyon.dev/downloads/install.sh | bash -s -- -v v0.5.0To install canary version of spin, you should pass the argument -v canary$ curl https://spin.fermyon.dev/downloads/install.sh | bash -s -- -v canaryAt this point, move the spin binary somewhere in your path, so it can be\naccessed from any directory. For example:$ sudo mv ./spin /usr/local/bin/spin","keywords":"quickstart","url":"/spin/quickstart.md#getting-the-spin-binary"},{"project":"spin","title":"Taking Spin for a spin","subheading":"Alternative 1: Building Spin from source","content":"undefined for a detailed guide\non building Spin from source:$ git clone https://github.com/fermyon/spin\n$ cd spin && make build\n$ ./target/release/spin --help","keywords":"quickstart","url":"/spin/quickstart.md#alternative-1-building-spin-from-source"},{"project":"spin","title":"Taking Spin for a spin","subheading":"Alternative 2: Using Cargo to install Spin","content":"If you have undefined, you can clone the repo and install it to your path:$ git clone https://github.com/fermyon/spin -b v0.5.0\n$ cd spin\n$ rustup target add wasm32-wasi\n$ cargo install --locked --path .\n$ spin --help","keywords":"quickstart","url":"/spin/quickstart.md#alternative-2-using-cargo-to-install-spin"},{"project":"spin","title":"Taking Spin for a spin","subheading":"Linux: Additional Libraries","content":"On a fresh Linux installation, you will also need the standard build toolchain\n(gcc, make, etc.), the SSL library headers, and on some distributions you\nmay need pkg-config.On Debian-like distributions, including Ubuntu, you can install these with a\ncommand like this:$ sudo apt-get install build-essential libssl-dev pkg-config","keywords":"quickstart","url":"/spin/quickstart.md#linux-additional-libraries"},{"project":"spin","title":"Taking Spin for a spin","subheading":"Creating a new Spin application from a template","content":"Spin helps you create a new application based on templates:$ spin templates list\nYou have no templates installed. Run\nspin templates install --git https://github.com/fermyon/spin\nto install a starter set.We first need to configure the undefined:$ spin templates install --git https://github.com/fermyon/spin\nCopying remote template source\nInstalling template redis-rust...\nInstalling template http-rust...\nInstalling template http-go...\n+--------------------------------------------------+\n| Name Description |\n+==================================================+\n| http-go HTTP request handler using (Tiny)Go |\n| http-rust HTTP request handler using Rust |\n| redis-rust Redis message handler using Rust |\n| ... |\n+--------------------------------------------------+undefinedLet's create a new Spin application based on the Rust HTTP template:$ spin new http-rust spin-hello-world\nProject description: A simple Spin HTTP component in Rust\nHTTP base: /\nHTTP path: /hello\n$ tree\n├── .cargo\n│   └── config.toml\n├── .gitignore\n├── Cargo.toml\n├── spin.toml\n└── src\n └── lib.rsThis command created all the necessary files we need to build and run our first\nSpin application. Here is spin.toml, the manifest file for a Spin application:spin_version = \"1\"\ndescription = \"A simple Spin HTTP component in Rust\"\nname = \"spin-hello-world\"\ntrigger = { type = \"http\", base = \"/\" }\nversion = \"0.1.0\"\n\n[[component]]\nid = \"spin-hello-world\"\nsource = \"target/wasm32-wasi/release/spin_hello_world.wasm\"\n[component.trigger]\nroute = \"/hello\"\n[component.build]\ncommand = \"cargo build --target wasm32-wasi --release\"This represents a simple Spin HTTP application (triggered by an HTTP request), with\na single component called spin-hello-world. Spin will execute the spin_hello_world.wasm\nWebAssembly module for HTTP requests on the route /hello.\n(See the undefined for a detailed guide on the Spin\napplication manifest.)Now let's have a look at the code. Below is the complete source\ncode for a Spin HTTP component written in Rust — a regular Rust function that\ntakes an HTTP request as a parameter and returns an HTTP response, and it is\nannotated with the http_component macro:use anyhow::Result;\nuse spin_sdk::{\n http::{Request, Response},\n http_component,\n};\n\n/// A simple Spin HTTP component.\n#[http_component]\nfn spin_hello_world(req: Request) -> Result {\n println!(\"{:?}\", req.headers());\n Ok(http::Response::builder()\n .status(200)\n .header(\"foo\", \"bar\")\n .body(Some(\"Hello, Fermyon\".into()))?)\n}undefinedFor Rust templates you need the wasm32-wasi target. You can add it using rustup:rustup target add wasm32-wasi.For TinyGo templates you need the undefined.We can build this component using the regular Rust toolchain, targeting\nwasm32-wasi, which will produce the WebAssembly module and place it at\ntarget/wasm32-wasi/release/spinhelloworld.wasm as referenced in the\nspin.toml. For convenience, we can use the spin build command, which will\nexecute the command defined above in spin.toml and call the Rust toolchain:$ spin build\nExecuting the build command for component spin-hello-world: cargo build --target wasm32-wasi --release\n Compiling spin_hello_world v0.1.0\n Finished release [optimized] target(s) in 0.10s\nSuccessfully ran the build command for the Spin components.undefinedundefinedIf you run into errors, you might want to use rustup check to see if your Rust installation is up-to-date.","keywords":"quickstart","url":"/spin/quickstart.md#creating-a-new-spin-application-from-a-template"},{"project":"spin","title":"Taking Spin for a spin","subheading":"Running the application with spin up","content":"Now that we configured the application and built our component, we can undefined\nthe application (pun intended):$ spin up\nServing HTTP on address http://127.0.0.1:3000\nAvailable Routes:\n spin-hello-world: http://127.0.0.1:3000/helloOptionally, set the RUST_LOG environment variable for detailed logs, before running spin up.$ export RUST_LOG=spin=traceSpin will instantiate all components from the application manifest, and\nwill create the router configuration for the HTTP trigger accordingly. The\ncomponent can now be invoked by making requests to http://localhost:3000/hello\n(see route field in the configuration):$ curl -i localhost:3000/hello\nHTTP/1.1 200 OK\nfoo: bar\ncontent-length: 15\n\nHello, Fermyon!You can add as many components as needed in spin.toml, mount files and\ndirectories, allow granular outbound HTTP connections, or set environment variables\n(see the undefined for a detailed guide on\nthe Spin application manifest) and iterate locally with\nspin up --file spin.toml until you are ready to distribute the application.Congratulations! You just completed building and running your first Spin\napplication!\nNext, check out the undefined or undefined language\nguides, or have a look at undefined.","keywords":"quickstart","url":"/spin/quickstart.md#running-the-application-with-spin-up"},{"project":"spin","title":"The Spin Redis trigger","subheading":"","content":"Spin applications can be triggered by a new message on a undefined.\nSpin will connect to a configured Redis instance and will invoke components for\nnew messages on the configured channels.undefinedThe Redis instance address is specified in the application trigger:# spin.toml\ntrigger = { type = \"redis\", address = \"redis://localhost:6379\" }undefinedThen, all components in the application are triggered when new messages are\npublished to channels in the instance. undefined the channel\nis done by setting the channel field in the component trigger configuration.[component.trigger]\nchannel = \"messages\"","url":"/spin/redis-trigger.md"},{"project":"spin","title":"The Spin Redis trigger","subheading":"The WebAssembly interface","content":"The Redis trigger is built on top of the\nundefined.\nThe current interface is defined using the\nundefined\nformat, and is a function that takes the message payload as its only parameter:// wit/ephemeral/spin-redis.wit\n\n// The message payload.\ntype payload = list\n\n// The entry point for a Redis handler.\nhandle-redis-message: function(msg: payload) -> expected<_, error>undefinedThis is the function that all Redis components must implement, and which is\nused by the Spin Redis executor when instantiating and invoking the component.\nThis interface (spin-redis.wit) can be directly used together with the\nundefined\nto build a component that the Spin HTTP executor can invoke.\nThis is exactly how undefined is built, and,\nas more languages add support for the component model, how we plan to add\nsupport for them as well.undefined","url":"/spin/redis-trigger.md#the-webassembly-interface"},{"project":"spin","title":"Creating a new Spin release","subheading":"","content":"To cut a release of Spin, you will need to do the following:undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedAt this point, you can verify in the GitHub UI that the release was successful.","url":"/spin/release-process.md"},{"project":"spin","title":"Building Spin components in Rust","subheading":"","content":"Spin aims to have best-in-class support for building components in Rust, and\nwriting such components should be familiar for Rust developers.undefinedundefinedIn order to compile Rust programs to Spin components, you also need the\nwasm32-wasi target. You can add it using rustup:$ rustup target add wasm32-wasi","url":"/spin/rust-components.md"},{"project":"spin","title":"Building Spin components in Rust","subheading":"HTTP components","content":"In Spin, HTTP components are triggered by the occurrence of an HTTP request, and\nmust return an HTTP response at the end of their execution. Components can be\nbuilt in any language that compiles to WASI, but Rust has improved support\nfor writing Spin components with the Spin Rust SDK.undefinedBuilding a Spin HTTP component using the Rust SDK means writing a single function\nthat takes an HTTP request as a parameter, and returns an HTTP response — below\nis a complete implementation for such a component:use anyhow::Result;\nuse spin_sdk::{\n http::{Request, Response},\n http_component,\n};\n\n/// A simple Spin HTTP component.\n#[http_component]\nfn hello_world(req: Request) -> Result {\n println!(\"{:?}\", req);\n Ok(http::Response::builder()\n .status(200)\n .header(\"foo\", \"bar\")\n .body(Some(\"Hello, Fermyon!\".into()))?)\n}The important things to note in the implementation above:undefinedundefinedundefined","url":"/spin/rust-components.md#http-components"},{"project":"spin","title":"Building Spin components in Rust","subheading":"Sending outbound HTTP requests","content":"If allowed, Spin components can send outbound HTTP requests.\nLet's see an example of a component that makes a request to\nundefined and\ninserts a custom header into the response before returning:#[http_component]\nfn hello_world(_req: Request) -> Result {\n let mut res = spin_sdk::http::send(\n http::Request::builder()\n .method(\"GET\")\n .uri(\"https://some-random-api.ml/facts/dog\")\n .body(None)?,\n )?;\n\n res.headers_mut()\n .insert(http::header::SERVER, \"spin/0.1.0\".try_into()?);\n\n Ok(res)\n}Before we can execute this component, we need to add the some-random-api.ml\ndomain to the application manifest allowed_http_hosts list containing the list of\ndomains the component is allowed to make HTTP requests to:# spin.toml\nspin_version = \"1\"\nname = \"spin-hello-world\"\ntrigger = { type = \"http\", base = \"/\" }\nversion = \"1.0.0\"\n\n[[component]]\nid = \"hello\"\nsource = \"target/wasm32-wasi/release/spinhelloworld.wasm\"\nallowed_http_hosts = [ \"some-random-api.ml\" ]\n[component.trigger]\nroute = \"/hello\"Running the application using spin up --file spin.toml will start the HTTP\nlistener locally (by default on localhost:3000), and our component can\nnow receive requests in route /hello:$ curl -i localhost:3000/hello\nHTTP/1.1 200 OK\ndate: Fri, 18 Mar 2022 03:54:36 GMT\ncontent-type: application/json; charset=utf-8\ncontent-length: 185\nserver: spin/0.1.0\n\n{\"fact\":\"It's rumored that, at the end of the Beatles song, \n\\\"A Day in the Life,\\\" Paul McCartney recorded an ultrasonic whistle, \naudible only to dogs, just for his Shetland sheepdog.\"}undefinedundefinedWe just built a WebAssembly component that sends an HTTP request to another\nservice, manipulates that result, then responds to the original request.\nThis can be the basis for building components that communicate with external\ndatabases or storage accounts, or even more specialized components like HTTP\nproxies or URL shorteners.","url":"/spin/rust-components.md#sending-outbound-http-requests"},{"project":"spin","title":"Building Spin components in Rust","subheading":"Redis components","content":"Besides the HTTP trigger, Spin has built-in support for a Redis trigger —\nwhich will connect to a Redis instance and will execute Spin components for\nnew messages on the configured channels.undefinedWriting a Redis component in Rust also takes advantage of the SDK:/// A simple Spin Redis component.\n#[redis_component]\nfn on_message(msg: Bytes) -> Result<()> {\n println!(\"{}\", from_utf8(&msg)?);\n Ok(())\n}undefinedundefinedundefinedThe component can be built with Cargo by executing:$ cargo build --target wasm32-wasi --releaseThe manifest for a Redis application must contain the address of the Redis\ninstance the trigger must connect to:spin_version = \"1\"\nname = \"spin-redis\"\ntrigger = { type = \"redis\", address = \"redis://localhost:6379\" }\nversion = \"0.1.0\"\n\n[[component]]\nid = \"echo-message\"\nsource = \"target/wasm32-wasi/release/spinredis.wasm\"\n[component.trigger]\nchannel = \"messages\"This application will connect to redis://localhost:6379, and for every new\nmessage on the messages channel, the echo-message component will be executed.# first, start redis-server on the default port 6379\n$ redis-server --port 6379\n# then, start the Spin application\n$ spin up --file spin.toml\n# the application log file will output the following\nINFO spin_redis_engine: Connecting to Redis server at redis://localhost:6379\nINFO spin_redis_engine: Subscribed component 0 (echo-message) to channel: messagesFor every new message on the messages channel:$ redis-cli\n127.0.0.1:6379> publish messages \"Hello, there!\"Spin will instantiate and execute the component we just built, which will emit the println! message to the application log file:INFO spin_redis_engine: Received message on channel \"messages\"\nHello, there!If you would also like to see the println! messages echoed to the console as they happen, please include the additional --follow-all option, when starting the spin application. For example:spin up --file spin.toml --follow-allundefined","url":"/spin/rust-components.md#redis-components"},{"project":"spin","title":"Building Spin components in Rust","subheading":"Storing data in Redis from Rust components","content":"Using the Spin's Rust SDK, you can use the Redis key/value store and to publish\nmessages to Redis channels. This can be used from both HTTP and Redis triggered\ncomponents.Let's see how we can use the Rust SDK to connect to Redis:#[spin_sdk::http_component]\nfn publish(_req: Request) -> Result {\n let address = std::env::var(REDIS_ADDRESS_ENV)?;\n let channel = std::env::var(REDIS_CHANNEL_ENV)?;\n\n // Get the message to publish from the Redis key \"mykey\"\n let payload = spin_sdk::redis::get(&address, &\"mykey\").map_err(|_| anyhow!(\"Error querying Redis\"))?;\n\n // Set the Redis key \"spin-example\" to value \"Eureka!\"\n spin_sdk::redis::set(&address, &\"spin-example\", &b\"Eureka!\"[..])\n .map_err(|_| anyhow!(\"Error executing Redis command\"))?;\n\n // Publish to Redis\n match spin_sdk::redis::publish(&address, &channel, &payload) {\n Ok(()) => Ok(http::Response::builder().status(200).body(None)?),\n Err(_e) => internal_server_error(),\n }\n}This HTTP component demonstrates fetching a value from Redis by key, setting a\nkey with a value, and publishing a message to a Redis channel. The component is\ntriggered by an HTTP request served on the route configured in the spin.toml:[[component]]\nenvironment = { REDIS_ADDRESS = \"redis://127.0.0.1:6379\", REDIS_CHANNEL = \"messages\" }\n[component.trigger]\nroute = \"/publish\"This HTTP component can be paired with a Redis component, triggered on new\nmessages on the messages Redis channel.undefined","url":"/spin/rust-components.md#storing-data-in-redis-from-rust-components"},{"project":"spin","title":"Building Spin components in Rust","subheading":"Using external crates in Rust components","content":"In Rust, Spin components are regular libraries that contain a function\nannotated using the http_component macro, compiled to the\nundefined.\nThis means that any undefined that compiles to wasm32-wasi can\nbe used when implementing the component.","url":"/spin/rust-components.md#using-external-crates-in-rust-components"},{"project":"spin","title":"Building Spin components in Rust","subheading":"Troubleshooting","content":"Sometimes things can go wrong, especially such early projects. If you bump into\nissues building and running your Rust component:undefinedundefinedundefinedundefinedundefined","url":"/spin/rust-components.md#troubleshooting"},{"project":"spin","title":"Building Spin components in Rust","subheading":"Manually creating new projects with Cargo","content":"The recommended way of creating new Spin projects is by starting from a template.\nThis section shows how to manually create a new project with Cargo.When creating a new Spin projects with Cargo, you should use the --lib flag.$ cargo init --libA Cargo.toml with standard Spin dependencies looks like this:[package]\nname = \"your-app\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[lib]\n# Required to have a `cdylib` (dynamic library) to produce a Wasm module.\ncrate-type = [ \"cdylib\" ]\n\n[dependencies]\n# Useful crate to handle errors.\nanyhow = \"1\"\n# Crate to simplify working with bytes.\nbytes = \"1\"\n# General-purpose crate with common HTTP types.\nhttp = \"0.2\"\n# The Spin SDK.\nspin-sdk = { git = \"https://github.com/fermyon/spin\" }\n# Crate that generates Rust Wasm bindings from a WebAssembly interface.\nwit-bindgen-rust = { git = \"https://github.com/bytecodealliance/wit-bindgen\", rev = \"cb871cfa1ee460b51eb1d144b175b9aab9c50aba\" }At the time of this writing, wit-bindgen must be pinned to a specific rev.\nThis will change in the future.","url":"/spin/rust-components.md#manually-creating-new-projects-with-cargo"},{"project":"spin","title":"Creating Spin templates","subheading":"","content":"Spin templates allow a Spin developer to quickly create the skeleton of an\napplication or component, ready for the application logic to be filled in.A template consists of two directories, content and metadata.undefinedundefinedFor examples of the directory contents, see the templates directory in the\nundefined.Templates must always be shared in a templates directory. This allows the\ninstaller to locate them in repos that contain other content.","url":"/spin/template-authoring.md"},{"project":"spin","title":"Creating Spin templates","subheading":"Authoring the content","content":"Copy all the files that you want to be copied as part of the template into\nthe content directory. If you do nothing more, they will be copied\nverbatim. Often, though, you'll want to allow the user to put their own\nvalues in - for example, a project name, or a HTTP route.To do this, replace the text you want the user to be able to substitute\nwith an expression of the form {{parameter-name}}, where parameter-name\nis an identifier of your choice. undefined - see below.You can reuse a parameter in more than one place - it will be prompted for\nonly once and will get the same value in each place.You can also transform the user value by specifying a filter after a bar:\n{{parameter-name | filter-name}}. This is particularly useful when you\nwant to conform to specific language conventions. The following filters\nare supported:| Name | Effect |\n|---------------|--------|\n| kebab_case | Transforms input into kebab case, e.g. My Application to my-application |\n| snake_case | Transforms input into snake case, e.g. My Application to my_application |\n| pascal_case | Transforms input into Pascal case, e.g. my appplication to MyApplication |","url":"/spin/template-authoring.md#authoring-the-content"},{"project":"spin","title":"Creating Spin templates","subheading":"Authoring the manifest","content":"The template manifest is a TOML file. It must be named spin-template.toml.manifest_version = \"1\"\nid = \"my-application\"\ndescription = \"An application\"\n\n[parameters]\n# Example parameter\nproject-name = { type = \"string\", prompt = \"Project name\" }undefinedundefinedundefinedThe parameters table is where you list the placeholders that you edited\ninto your content for the user to substitute. You should include an entry\nfor each parameter. The key is the parameter name, and the value a JSON\ndocument that contains at minimum a type and prompt. type must\ncurrently be string. prompt is displayed when prompting the user\nfor the value to substitute.The document may also have a default, which will be displayed to the user\nand can be accepted by pressing Enter. It may also specify constraints\non what the user is allowed to enter. The following constraints are\nsupported:| Key | Value and usage |\n|---------------|-----------------|\n| pattern | A regular expression. The user input must match the regular expression to be accepted. |","url":"/spin/template-authoring.md#authoring-the-manifest"},{"project":"spin","title":"Creating Spin templates","subheading":"Hosting templates in Git","content":"You can publish templates in a Git repo. The templates must be in the /templates\ndirectory, with a subdirectory per template.When a user installs templates from your repo, by default Spin looks for a tag\nto identify a compatible version of the templates. This tag is of the\nform spin/templates/vX.Y, where X is the major version, and Y the minor\nversion, of the user's copy of Spin. For example, if the user is on\nSpin 0.3.1, templates will be installed from spin/templates/v0.3. If this\ntag does not exist, Spin installs templates from HEAD.","url":"/spin/template-authoring.md#hosting-templates-in-git"},{"project":"spin","title":"Building a URL shortener with Spin","subheading":"","content":"This tutorial will walk you through building a Spin component that\nredirects short URLs to their configured destinations.\nIn essence, this is a simple HTTP component that returns a response that contains\nredirect information based on the user-defined routes.This is an evolving tutorial. As Spin allows building more complex components\n(through supporting access to services like databases), this tutorial will be\nupdated to reflect that.undefinedFirst, our URL shortener allows users to configure their own final URLs —\ncurrently, that is done through a configuration file that contains multiple\n[[route]] entries, each containing the shortened path as source, and\nthe destination URL:[[route]]\nsource = \"/spin\"\ndestination = \"https://github.com/fermyon/spin\"\n\n[[route]]\nsource = \"/hype\"\ndestination = \"https://www.fermyon.com/blog/how-to-think-about-wasm\"Whenever a request for https:///spin is sent, our component will\nredirect to https://github.com/fermyon/spin. Now that we have a basic\nunderstanding of how the component should behave, let's see how to implement it\nusing Spin.First, we start with undefined:/// A Spin HTTP component that redirects requests \n/// based on the router configuration.\n#[http_component]\nfn redirect(req: Request) -> Result {\n let router = Router::default()?;\n router.redirect(req)\n}All the component does is create a new router based on the default configuration,\nthen use it to redirect the request. Let's see how the router is defined:#[derive(Debug, Deserialize, Serialize)]\npub struct Route {\n pub source: String,\n pub destination: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct Router {\n #[serde(rename = \"route\")]\n pub routes: Vec,\n}The Router structure is a Rust representation of the TOML configuration above.pub fn redirect(self, req: Request) -> Result {\n // read the request path from the `spin-path-info` header\n let path_info = req\n .headers()\n .get(\"spin-path-info\")\n .expect(\"cannot get path info from request headers\");\n // if the path is not present in the router configuration,\n // return 404 Not Found.\n let route = match self.path(path_info.to_str()?) {\n Some(r) => r,\n None => return not_found(),\n };\n // otherwise, return the redirect to the destination\n let res = http::Response::builder()\n .status(http::StatusCode::PERMANENT_REDIRECT)\n .header(http::header::LOCATION, route.destination)\n .body(None)?;\n Ok(res)\n}The redirect function is straightforward — it reads the request path from the\nspin-path-info header (make sure to read the undefined\nfor an overview of the HTTP headers present in Spin components), selects the\ncorresponding destination from the router configuration, then sends the\nHTTP redirect to the new location.At this point, we can build the module with cargo and run it with Spin:$ cargo build --target wasm32-wasi --release\n$ spin up --file spin.tomlAnd the component can now handle incoming requests:# based on the configuration file, a request\n# to /spin should be redirected\n$ curl -i localhost:3000/spin\nHTTP/1.1 308 Permanent Redirect\nlocation: https://github.com/fermyon/spin\ncontent-length: 0\n# based on the configuration file, a request\n# to /hype should be redirected\n$ curl -i localhost:3000/hype\nHTTP/1.1 308 Permanent Redirect\nlocation: https://www.fermyon.com/blog/how-to-think-about-wasm\ncontent-length: 0\n# /abc is not present in the router configuration,\n# so this returns a 404.\n$ curl -i localhost:3000/abc\nHTTP/1.1 404 Not Found\ncontent-length: 9\n\nNot FoundundefinedWe can now undefined (together\nwith router configuration file):$ spin bindle push --file spin.toml\npushed: url-shortener/1.0.0And now we can run the application directly from the registry:$ spin up --bindle url-shortener/1.0.0In this tutorial we built a simple URL shortener as a Spin component.\nIn the future we will expand this tutorial by storing the router configuration\nin a database supported by Spin, and potentially create another component that\ncan be used to add new routes to the configuration.","url":"/spin/url-shortener.md"}] \ No newline at end of file diff --git a/static/js/main.js b/static/js/main.js index 97c89913a..ea2b90bac 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -1,3 +1,7 @@ +const { el, mount, text, list, setChildren, setStyle, setAttr } = redom + +let documents + var header = new Headroom(document.querySelector("#topbar"), { tolerance: 5, offset: 80 @@ -22,32 +26,7 @@ document.querySelectorAll('.modal-button').forEach(function (el) { }); }); -document.addEventListener("DOMContentLoaded", function () { - // Initialize after the DOM. - (function () { - var burger = document.querySelector('.burger'); - var menu = document.querySelector('#' + burger.dataset.target); - burger.addEventListener('click', function () { - burger.classList.toggle('is-active'); - menu.classList.toggle('is-active'); - }); - })(); - header.init(); - hljs.highlightAll(); - if (navigator && navigator.clipboard) { - addCopyButtons(navigator.clipboard); - } - addAnchorLinks() - - if (window.location.hash.length > 0) { - setTimeout(function () { - document.querySelector('a[href="' + window.location.hash + '"]').click() - }, 150) - header.unpin() - } - -}); if (document.body.contains(document.getElementById('blogSlogan'))) { blogAd.init(); @@ -131,3 +110,309 @@ const addAnchorLinks = () => { }) }) } + +let idx + +async function getSearchIndex() { + try { + let res = await fetch('/static/data.json') + return await res.json() + } + catch (err) { + console.Err("cannot load search module") + } +} + +async function setupSearch() { + documents = await getSearchIndex() + idx = lunr(function () { + this.field('title') + this.field('subheading') + this.field('content') + this.field('keywords', { boost: 10 }) + this.ref('url') + + documents.forEach(function (doc) { + this.add(doc) + }, this) + }) + +} + +class SearchButton { + constructor(modal) { + this.modal = modal + this.icon = el("span.search-icon", "🔍") + this.searchPlaceholder = el("span.search-placeholder", "Search") + this.searchCommand = el("span.search-command", "⌘/ctrl + K") + this.el = el("button.search-button", { + onclick: function (e) { + this.modal.open() + }.bind(this) + }, [this.icon, this.searchPlaceholder, this.searchCommand]) + } +} + +class SearchResultSubHeading { + constructor() { + this.itemIcon = el("span.result-item-icon", "#") + this.link = el("span") + this.el = el("a.result-subitem", { onclick: function (e) { searchModal.close() } }, [this.itemIcon, this.link]) + } + update(data) { + this.link.textContent = data.subheading + this.el.href = data.url + } +} + +class SearchResultItem { + constructor() { + this.subheading = list("div.result-subheading-container", SearchResultSubHeading) + this.projectName = el("code.project-name") + this.pageTitle = el("span") + this.title = el("a", this.pageTitle, this.projectName) + this.el = el("div.result-block", [this.title, this.subheading]) + } + update(data) { + this.pageTitle.textContent = data.title + this.projectName.textContent = data.project + this.title.href = data.url + this.subheading.update(data.data) + } +} + +class ResultFilterItem { + constructor() { + this.index + this.active = true + this.parentCallback + this.el = el("code.active", { + onclick: function (e) { + this.toggle() + }.bind(this) + }) + } + update(data, index, item, context) { + this.parentCallback = context.callback + this.index = index + context.reset ? this.active = true : "" + if (this.active) { + this.el.classList.add("active") + } + this.el.textContent = data + } + toggle() { + this.active = !this.active + if (this.active) { + this.el.classList.add("active") + } else { + this.el.classList.remove("active") + } + this.parentCallback(this.index, this.active) + } +} + +class SearchResultFilter { + constructor(categories, callback) { + this.categories = categories + this.parentCallback = callback + this.active = [true, true, true] + this.activefilter = categories.map(k => k.toLowerCase()) + this.filters = list("div.filter-categories", ResultFilterItem) + this.filters.update(this.categories, { callback: this.updateFilterSearch.bind(this) }) + this.resetFilter = el("span.reset-filter", { onclick: function (e) { this.resetFilters() }.bind(this) }, 'Clear filters') + this.el = el("div.result-filters", this.filters, this.resetFilter) + } + updateFilterSearch(index, status) { + console.log(this.active, this.active[index]) + this.active[index] = status + this.activefilter = this.categories.filter((k, i) => { return this.active[i] }).map(k => { return k.toLowerCase() }) + this.parentCallback(this.activefilter) + } + resetFilters() { + this.activefilter = this.categories.map(k => k.toLowerCase()) + this.parentCallback(this.activefilter) + this.filters.update(this.categories, { callback: this.updateFilterSearch.bind(this), reset: true }) + } +} + +class SearchResult { + constructor() { + this.data + this.projects = ["Spin", "Cloud"] + this.resultItems = list("div.result-section", SearchResultItem) + this.resultFilters = new SearchResultFilter(this.projects, this.filter.bind(this)) + this.el = el("div.result-section-container", this.resultFilters, this.resultItems) + } + update(data) { + this.data = data + this.resultItems.update(this.data) + } + filter(filters) { + this.resultItems.update(this.data.filter(k => { + return filters.includes(k.project) + })) + } +} + +class ProjectRecommendations { + constructor() { + this.link1 = el("a.suggested-project-link") + this.link2 = el("a.suggested-project-link") + this.link3 = el("a.suggested-project-link") + this.link4 = el("a.suggested-project-link") + this.projectLinks = el("div.recommended-navs", this.link1, this.link2, this.link3, this.link4) + this.projectTitle = el("div.project-title") + this.el = el("div.suggested-project", this.projectTitle, this.projectLinks) + } + update(data) { + this.projectTitle.textContent = data.project + this.link1.textContent = data.link1[0] + this.link1.href = data.link1[1] + this.link2.textContent = data.link2[0] + this.link2.href = data.link2[1] + this.link3.textContent = data.link3[0] + this.link3.href = data.link3[1] + this.link4.textContent = data.link4[0] + this.link4.href = data.link4[1] + } +} + +class ModalSuggest { + constructor() { + this.projectData = [ + { project: "Spin", link1: ["Quickstart", "/spin/quickstart/"], link2: ["Configure", "/spin/configuration/"], + link3: ["Develop", "/spin/developing"], link4: ["Deploy", "/spin/deploying-to-fermyon/"] }, + { project: "Cloud", link1: ["Quickstart", "#"], link2: ["Filler", "#"], link3: ["Filler", "#"], link4: ["Filler", "#"] }, + ] + this.projectRecommendations = list("div.result-section", ProjectRecommendations) + this.projectRecommendations.update(this.projectData) + this.el = el("div.result-section-container", "Suggested Projects", this.projectRecommendations) + } +} + +class SearchModal { + constructor() { + this.container = document.getElementById("search-modal-container") + this.modalSearchBar = el("input.modal-search-bar", { + type: "text", spellcheck: false, + placeholder: "Search Fermyon Developer Home", oninput: function (e) { + this.updateSearch() + }.bind(this) + }) + this.searchResults = new SearchResult() + this.modalSuggest = new ModalSuggest() + this.modal = el("div.modal-box", { onclick: function (e) { e.stopPropagation() } }) + this.el = el("div.modal-wrapper", { + onclick: function (e) { this.close() }.bind(this), onkeydown: function (e) { + if (e.key != "Escape") { + e.stopPropagation() + } + } + }, this.modal) + } + open() { + setStyle(this.container, { display: "block" }) + setStyle(document.body, { "overflow": "hidden", height: "100%" }) + this.modalSearchBar.value = "" + setChildren(this.modal, [this.modalSearchBar, this.modalSuggest]) + this.modalSearchBar.focus() + } + close() { + setStyle(this.container, { display: "none" }) + setStyle(document.body, { "overflow-y": "auto", height: "auto" }) + setChildren(this.modal, []) + } + updateSearch() { + let query = this.modalSearchBar.value + if (query == "") { + setChildren(this.modal, [this.modalSearchBar, this.modalSuggest]) + return + } + let updatedQuery = query + .split(" ") + .map(word => word + '^2 ' + word + '* ') + .join(' '); + let result = idx.search(updatedQuery) + let matches = {} + let data + result.map(k => { + if (k.score < 0.5) { + return + } + data = documents.find((post) => k.ref === post.url) + let key = data.title.replaceAll(" ", "") + if (!matches[key]) { + matches[key] = {} + matches[key].data = [] + } + if (data.subheading == "") { + matches[key].url = data.url + return + } else { + matches[key].url = data.url.slice(0, data.url.indexOf("#")) + } + matches[key].data.push({ subheading: data.subheading, url: data.url }) + matches[key].title = data.title + matches[key].project = data.project + matches[key].score = matches[key].score ? (matches[key].score > k.score ? matches[key].score : k.score) : k.score + }) + matches = Object.keys(matches).map(k => { + return matches[k] + }).sort(function (a, b) { return b.score - a.score }).filter(k => { return k.title != undefined }) + this.searchResults.update(matches) + setChildren(this.modal, [this.modalSearchBar, this.searchResults]) + } +} + +let searchModal = new SearchModal() +let searchButton = new SearchButton(searchModal) + + +document.addEventListener("DOMContentLoaded", function () { + // Initialize after the DOM. + (function () { + var burger = document.querySelector('.burger'); + var menu = document.querySelector('#' + burger.dataset.target); + burger.addEventListener('click', function () { + burger.classList.toggle('is-active'); + menu.classList.toggle('is-active'); + }); + })(); + + header.init(); + hljs.highlightAll(); + if (navigator && navigator.clipboard) { + addCopyButtons(navigator.clipboard); + } + addAnchorLinks() + + if (window.location.hash.length > 0) { + setTimeout(function () { + document.querySelector('a[href="' + window.location.hash + '"]').click() + }, 150) + header.unpin() + } + + (async function () { + try { + await setupSearch() + mount(document.getElementById("search-button-container"), searchButton); + mount(document.getElementById("search-modal-container"), searchModal); + document.onkeydown = function (e) { + if (e.key == "Escape") { + searchModal.close() + } + if ((e.key == "k" || e.key == "K") && (e.metaKey || e.ctrlKey)) { + e.preventDefault() + e.stopPropagation() + searchModal.open() + } + } + } + catch (err) { + console.err("Could not setup search") + } + })() + +}); \ No newline at end of file diff --git a/static/sass/styles.css b/static/sass/styles.css deleted file mode 100644 index 9c5740350..000000000 --- a/static/sass/styles.css +++ /dev/null @@ -1 +0,0 @@ -.is-primary,.has-text-primary{color:#0d203f !important}.is-link,.has-text-link{color:#0a68a1 !important}.is-info,.has-text-info{color:#a180d9 !important}.is-success,.has-text-success{color:#18907b !important}.is-warning,.has-text-warning{color:#ef946c !important}.is-danger,.has-text-danger{color:#c64b16 !important}.is-dark,.has-text-dark{color:#213762 !important}.is-light,.has-text-light{color:#b69cc0 !important}.button.is-primary,.tag.is-primary,.message.is-primary{background-color:#18d1a5;color:#fff !important}.button.is-secondary,.tag.is-secondary,.message.is-secondary{background-color:#315292;color:#fff !important}.button.is-link,.tag.is-link,.message.is-link{background-color:#0a68a1 !important;color:#fff !important}.button.is-info,.tag.is-info,.message.is-info{background-color:#a180d9 !important;color:#fff !important}.button.is-success,.tag.is-success,.message.is-success{background-color:#18907b !important;color:#fff !important}.button.is-warning,.tag.is-warning,.message.is-warning{background-color:#ef946c !important;color:#fff !important}.button.is-danger,.tag.is-danger,.message.is-danger{background-color:#c64b16 !important;color:#fff !important}.button.is-dark,.tag.is-dark,.message.is-dark{background-color:#213762;color:#fff !important}.button.is-light,.tag.is-light,.message.is-light{background-color:#b69cc0;color:#0d203f !important}.content .is-active,.content .is-current{color:#fff;background-color:#213762}html{height:100%;background-color:rgba(0,0,0,0)}body,main{min-height:100vh;position:relative}body{background:#f7f4f8;min-height:100vh}main{padding:5.75rem 0 0;min-height:100vh;margin-bottom:-12rem;z-index:100}#topbar.navbar{background:#f7f4f8;padding-left:5vw;padding-right:5vw;border-bottom:2px solid rgba(255,255,255,.98);will-change:transform;transition:transform 200ms linear;position:fixed;left:0;right:0;z-index:1000}#topbar.navbar .navbar-burger{width:5.25rem;height:5.25rem}#topbar.navbar.is-wide{padding-left:2.5vw;padding-right:2.5vw}#topbar.navbar .dark-mode{position:absolute;right:0;top:2rem;display:inline-block;width:1.5rem;line-height:1.5;fill:#345995}#topbar.navbar.headroom--pinned{margin:0;transform:translateY(0%)}#topbar.navbar.headroom--unpinned{transform:translateY(-100%)}@keyframes halfSpin{0%{transform:rotate(0)}25%{transform:rotate(180deg);opacity:1}38%{opacity:.75}50%{transform:rotate(180deg)}75%{transform:rotate(360deg);opacity:1}88%{opacity:.75}100%{transform:rotate(360deg)}}#topbar.navbar .logo{display:inline-block;margin-top:0;fill:#0d203f;position:relative;margin-top:.35em}#topbar.navbar .logo svg{max-height:1.25rem;max-width:10.625rem;cursor:pointer;position:relative;z-index:500;fill:#0d203f}#topbar.navbar .logo:hover .spin-back{background-color:#fff}#topbar.navbar .logo .spin-front{width:1.133rem;height:1.133rem;display:inline-block;position:absolute;top:1.25rem;right:1.9125rem;border-radius:50%;z-index:600;opacity:1;transition:all .3s ease-in-out}#topbar.navbar .logo .spin-front em{width:.425rem;height:.425rem;display:inline-block;top:0rem;right:.05rem;background:#28ffcc;position:absolute;z-index:700;border-radius:50%;transition:all .3s ease-in-out}#topbar.navbar .logo .spin-back{width:1.125rem;height:1.125rem;display:inline-block;position:absolute;top:1.295rem;right:1.875rem;border-radius:50%;z-index:400;background:rgba(0,0,0,0);transition:all .3s ease-in-out}#topbar.navbar:hover .logo .spin-front{animation:4s ease infinite halfSpin}#topbar.navbar .logo-project{font-weight:bold;margin:2rem 0 0 1.3335rem;font-size:1.125rem}#topbar.navbar .logo-project a{color:#213762}#topbar.navbar .logo-project .tag{margin:-0.5rem 0 0 .67rem;position:relative}#topbar.navbar a.navbar-item{line-height:3;background:rgba(0,0,0,0);font-weight:700}#topbar.navbar .navbar-menu a{margin-left:2vw;position:relative;color:#0d203f;letter-spacing:.025em;transition:all .3s ease-in-out}#topbar.navbar .navbar-menu a em{position:absolute;left:45%;right:45%;bottom:-0.15rem;height:.333rem;opacity:0;background-color:#34e8bd;display:inline-block;border-radius:1rem 1rem 1rem 1rem;transition:all .3s ease-in-out;content:" "}#topbar.navbar .navbar-menu a:hover em{left:25%;right:25%;opacity:1}#topbar.navbar .navbar-menu .button{color:#15ba93;border-color:#34e8bd;margin:1rem 0 0 2.5rem;transition:all .3s ease-in-out}#topbar.navbar .navbar-menu .button:hover{color:#119878;background-color:#fff !important}.menu-wrap{padding:0 2.5vw;width:17rem;background:#f7f4f8}@media screen and (min-width: 1024px){.menu-wrap.is-fixed-desktop{position:fixed;left:0;top:0;bottom:0;width:17.5vw;background:#f7f4f8}}@media screen and (max-width: 1023px){.menu-wrap.is-fixed-desktop{position:relative;top:auto;left:auto;right:auto}}@media screen and (min-width: 1024px){.menu-wrap.is-sticky{position:sticky;left:2.5vw;top:0;width:15rem;padding-left:.67rem;bottom:0;display:inline-block;vertical-align:top;max-height:100vh;overflow-y:auto;background:#f7f4f8}}aside.menu{font-size:1rem;position:absolute;top:0;bottom:0;overflow-y:scroll;padding-top:6.5rem;min-width:13rem;width:14.5vw;border-right:2px solid rgba(0,0,0,0);transition:all .3s ease-in-out}aside.menu:hover{border-right:2px solid #ece5ee}aside.menu .menu-label{padding-left:1.333vw;margin:1.75rem 1.333vw 1rem 0}aside.menu ul{margin-bottom:2.5rem}aside.menu a{padding:.6rem 1.25vw;margin-bottom:0rem;font-weight:bold;display:inline-block;transition:all .3s ease-in-out;border-radius:2rem 2rem 2rem 2rem}aside.menu a:hover{background-color:#ece5ee;color:#213762}aside.menu a.button{line-height:2.25;margin-top:1.25rem;padding:0 1.333vw;font-size:1.125rem;background:rgba(0,0,0,0);border:2px solid #34e8bd}aside.menu a.button svg{margin-right:.25rem;margin-bottom:-1px}aside.menu a.button svg,aside.menu a.button path{transition:all .3s ease-in-out}aside.menu a.button:hover{background-color:#34e8bd;color:#fff}aside.menu a.button:hover svg,aside.menu a.button:hover path{fill:#fff}.menu-wrap+article.content{padding-left:18.5vw}.page-wrap{position:relative}.is-fullwidth{width:100vw;max-width:100vw !important}hr{background-color:rgba(100,100,100,.1)}hr.page-break{position:relative;text-align:center;height:4rem;background:rgba(0,0,0,0)}hr.page-break:after{position:relative;width:12.5%;display:inline-block;margin:2.5rem 0 3.5rem;content:" ";height:.33rem;background:#bea7e5;border-radius:.33rem .33rem .33rem .33rem}.documentation .content{padding-top:8.5rem;margin-bottom:5rem}.documentation .content h1{position:relative;padding-bottom:2.67rem;margin:-1.5rem 0 5rem}.documentation .content h1:after{position:absolute;width:25%;margin:2rem 0 0;display:inline-block;margin:2.5rem 0 0;bottom:0;left:0;content:" ";height:.33rem;background:#bea7e5;border-radius:.33rem .33rem .33rem .33rem}.documentation .content blockquote p{font-size:1rem;line-height:1.4}.documentation .content .footer-nav{border-top:none}.documentation .content.content-docs-wide section{max-width:90vw !important;margin-left:5vw;margin-right:5vw}.documentation .content.content-docs-wide section .content ul,.documentation .content.content-docs-wide section .content ol,.documentation .content.content-docs-wide section .content dl,.documentation .content.content-docs-wide section .content p,.documentation .content.content-docs-wide section .content blockquote{max-width:100%}.documentation footer{padding-left:2.5vw !important;padding-right:2.5vw !important}.documentation footer .footer-nav{padding:0 .75rem;margin:0;border-top:none}.content section{margin-left:auto;margin-right:auto;max-width:48.5rem}.content section .box{margin-top:2rem;margin-bottom:3rem;padding:1.67rem 2rem}.content section table{background-color:#fff;min-width:100%;margin-top:2rem;margin-bottom:4rem;border-collapse:collapse;border-radius:.333em;overflow:hidden;box-shadow:0 3px 6px rgba(30,30,30,.125)}.content section table th,.content section table td{padding:.67vw 2vw;border-bottom:1px solid #bea7e5;line-height:1.5}.content section table th{font-size:1.125rem;font-weight:bold;color:#0d203f;background-color:#f9f7ee;line-height:1.75;border-bottom:1px solid #bea7e5}.content section table td{font-size:1rem;border-bottom-color:#ece5ee}.content section table tr:last-of-type td{border:none}footer{background:#fff;margin:0 auto 0;padding:1.25rem 0 0;min-height:12rem;border-top:1px solid #bea7e5;position:relative;z-index:1400}footer ul,footer p{margin:2rem 0 4rem}footer p.lead{font-size:1.25rem;max-width:67%;line-height:1.33;margin:-2.5rem 0 0;color:#0a455a}footer h4{margin:3rem 0 0;font-size:1.25rem;font-weight:bold;color:#ef946c}footer li{line-height:2;list-style:none;font-size:1.125rem}footer img{max-height:3rem;margin-top:0}footer.is-shallow{min-height:6.5rem}footer.is-shallow img{max-height:2.5rem}footer .footer-nav{border-top:1px solid #d9dbe8}footer .footer-nav .navbar{padding:0;background:rgba(0,0,0,0)}footer .footer-nav .navbar .navbar-item{padding:0 4rem 0 0;font-size:1rem;line-height:1.33;color:#bea7e5}footer .footer-nav .navbar .navbar-item a{color:#b1b5d0;transition:all .3s ease-in-out}footer .footer-nav .navbar .navbar-item a:hover{color:#585f91}footer .footer-nav .navbar .navbar-item:last-of-type{padding-right:0}footer .footer-nav p{margin:0}@media(prefers-color-scheme: dark){html{background:#f7f4f8;color:#0d203f}}@media(prefers-color-scheme: dark){html{background:#0d203f;color:#fff}}html.dark-theme>body{background:#0d203f;color:#fff}html.dark-theme>body h1,html.dark-theme>body h2,html.dark-theme>body h3,html.dark-theme>body h4,html.dark-theme>body h5,html.dark-theme>body p,html.dark-theme>body li{color:#fff}html.dark-theme>body #topbar.navbar{background:#0d203f;border-color:#0a455a}html.dark-theme>body #topbar.navbar .logo svg,html.dark-theme>body #topbar.navbar .logo path{fill:#fff !important}html.dark-theme>body #topbar.navbar .logo-project a{color:#34e8bd}html.dark-theme>body #topbar.navbar .logo-project a .tag{background-color:#213762;color:#bea7e5 !important}html.dark-theme>body #topbar.navbar .navbar-burger{color:#bea7e5;height:5.75rem}html.dark-theme>body #topbar.navbar .navbar-menu a{color:#34e8bd}html.dark-theme>body #topbar.navbar .navbar-menu .button{border:3px solid #34e8bd}html.dark-theme>body #topbar.navbar .navbar-menu .button:hover{background:#34e8bd !important;color:#0d203f}html.dark-theme>body #topbar.navbar .dark-mode svg{fill:#34e8bd;transform:rotate(180deg);transition:all .3s ease-in-out}html.dark-theme>body .menu-wrap{background:#0d203f}html.dark-theme>body aside.menu:hover{border-right:2px solid #321a59}html.dark-theme>body aside.menu a{color:#fff}html.dark-theme>body aside.menu a:hover{color:#34e8bd;background-color:#213762}html.dark-theme>body aside.menu a.button svg,html.dark-theme>body aside.menu a.button path{fill:#fff !important}html.dark-theme>body pre{background:linear-gradient(0, #173564 15%, #233e68 100%)}html.dark-theme>body .card{background:linear-gradient(0, #112b54, #0D203F 100%);box-shadow:0 .5em 1em -0.125em rgba(10,10,10,.5),0 0 0 1px rgba(10,10,10,.52);outline:1px solid rgba(255,255,255,.2);color:#fff}html.dark-theme>body .card figure.image{border-bottom:1px solid rgba(255,255,255,.333)}html.dark-theme>body .card p{color:#fff}html.dark-theme>body .content .box{background-color:#213762;color:#fff}html.dark-theme>body .content h1 code,html.dark-theme>body .content h2 code,html.dark-theme>body .content h3 code,html.dark-theme>body .content h4 code,html.dark-theme>body .content h5 code,html.dark-theme>body .content p code,html.dark-theme>body .content li code,html.dark-theme>body .content th code,html.dark-theme>body .content td code,html.dark-theme>body .content dd code{background-color:#213762;color:#ece5ee}html.dark-theme>body .content section table{background-color:#213762}html.dark-theme>body .content blockquote{background-color:rgba(0,0,0,0)}html.dark-theme>body .content blockquote p{background-color:#1b2c4f;border-color:#243c6c;color:#fff}html.dark-theme>body .content blockquote>blockquote p,html.dark-theme>body .content aside p{background-color:#243c6c;border-color:#2b477f;color:#fff}html.dark-theme>body .content a:hover{background:#1b2c4f !important}html.dark-theme>body footer{background:#0d203f;border-color:#0a455a;color:#fff}html.dark-theme>body footer h4{color:#fff}html.dark-theme>body footer .footer-nav{border-color:#06101f}html.dark-theme>body footer p,html.dark-theme>body footer li,html.dark-theme>body footer a{color:#34e8bd}body{font-family:Sen,Europa,Avenir,system,-apple-system,".SFNSText-Regular","San Francisco","Segoe UI","Helvetica Neue","Lucida Grande",sans-serif;font-size:16pt;color:#0d203f}.content h1,.content h2,.content h3{font-weight:bold;display:block}.content ul,.content ol,.content dl,.content p,.content blockquote{margin:1.67rem 0;font-size:1rem;max-width:800px}.content.size-16 ul,.content.size-16 ol,.content.size-16 dl,.content.size-16 p,.content.size-16 blockquote{font-size:1rem}.content.size-18 ul,.content.size-18 ol,.content.size-18 dl,.content.size-18 p,.content.size-18 blockquote{font-size:1.125rem}.content.size-20 ul,.content.size-20 ol,.content.size-20 dl,.content.size-20 p,.content.size-20 blockquote{font-size:1.25rem}.content ul li{list-style:disc;list-style-position:outside;line-height:1.636;margin:0 .5rem 0 1.25rem;padding-left:.5rem}.content ul.pagination-list{margin:0}.content ul.pagination-list li{list-style:none;margin:0}.content ul.is-disc li{list-style:disc;list-style-position:outside}.content ol li{list-style-position:outside;line-height:1.636;margin:0 .5rem 0 1.25rem;padding-left:.5rem}.content blockquote>blockquote,.content aside{margin-top:3rem;margin-bottom:3rem}.content blockquote>blockquote p,.content aside p{line-height:1.8;border:1px solid #d9dbe8;font-size:1.2rem;background:#f9f7ee;padding:1.25rem 1.5rem !important;margin:2.5em auto 5rem !important;text-align:left;border-radius:.667rem;box-shadow:0 3px 6px rgba(30,30,30,.125);color:#0d203f}.content blockquote>blockquote a,.content aside a{color:#0e8fdd}.content blockquote{padding:0rem 0 !important;margin:0 !important;border-left:none}.content blockquote p{color:#081f24;color:#345995;font-size:1.1rem !important;line-height:2;padding-right:0 !important;border-left:4px solid #d9dbe8;background:#f4f0f5;padding:.65rem 5% .65rem 2rem !important;margin:1rem auto 1rem !important;text-align:left}.content blockquote a{color:#0e8fdd}.content pre,.content code{margin-bottom:2rem !important}.content pre code{margin-bottom:0 !important}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code{font-weight:bold;font-size:1em !important}.content pre,.content code{margin-bottom:2rem !important}.content pre code{margin-bottom:0 !important}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code{font-weight:bold;font-size:1em !important}.content strong{color:#0d203f}.content a{color:#0a68a1;border-radius:.333em;position:relative}.content a:after{position:absolute;text-align:center;background:#0e8fdd;height:.125rem;content:" ";display:inline-block;opacity:0;bottom:-0.2rem;left:33%;right:33%;transition:all .3s ease-in-out}.content a:hover{background:rgba(255,255,255,.67);color:#0e8fdd}.content a:hover:after{opacity:1;left:5%;right:5%}.content a:hover img+:after{display:none !important;margin-top:-4rem}.content hr.page-break{text-align:left;height:4rem;background:rgba(0,0,0,0)}.content hr.page-break:after{position:relative;width:12.5%;margin:1.5rem 0 2.5rem;height:.33rem}.content .copy{padding:.5rem 1rem;position:relative;border-radius:1rem;margin-left:-1.5rem;margin-right:-1.5rem}.content .copy img{width:1em}.content .copy .button{position:absolute;padding:0;line-height:1;top:.01rem;right:.67rem;border:none;opacity:0;background:rgba(0,0,0,0)}.content .copy:hover{background:rgba(100,100,100,.17)}.content .copy:hover .button{opacity:1}.content .copy-button{transition:all .3s ease-in-out;cursor:pointer}.content .copy-button:after{content:"Copied";transition:all .3s ease-in-out;display:inline-block;position:absolute;top:0rem;right:25%;top:75%;transform:perspective(1px) translateY(-50%);z-index:860;background:rgba(100,100,100,.75);padding:.5rem 1rem;border-radius:2rem;font-size:1rem;font-weight:bold;opacity:0;color:#fff}.content .copy-button:active{opacity:.8}.content .copy-button:active:after{top:50%;opacity:1}.content .card p{margin:0;line-height:1.25;color:#0d203f}.content .card p.title{margin-bottom:.5rem}.content .card p em{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-style:normal;opacity:.333;display:inline-block;padding:0 .2rem 0 0}.content .card.card-color{border-radius:.33rem;overflow:hidden}.content .card.card-color figure.image{border:5px solid rgba(0,0,0,0);transition:all .3s ease-in-out}.content .card.card-color figure.image:hover{border-color:#fff}.content .card.card-color .card-content{padding:.5rem .5rem 1rem}.content .card.card-color .card-content p{margin:0 0 -0.333rem;letter-spacing:-0.02em}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code,.content p code,.content li code,.content td code,.content th code,.content dd code{border-radius:.33rem !important;background:#e9e1eb;color:#345995}.content pre,.content code{margin-left:0;border-radius:.67rem;background-color:#0d203f;background-image:linear-gradient(135deg, #0D203F 0%, #10274d 100%);color:#fff;font-size:.925rem;color:#bea7e5;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.content pre a,.content code a{color:#0e8fdd}.content pre code.hljs,.content code code.hljs{padding:0 !important}.content pre code.hljs .hljs-meta,.content code code.hljs .hljs-meta{color:#34e8bd}.content pre{margin:1.333rem 0;max-width:100%;position:relative}.content code{border-radius:0 !important}.content .hljs{background-color:rgba(0,0,0,0) !important}.content pre code.hljs{display:block;overflow-x:auto;padding:1em}.content code.hljs{padding:3px 5px}.content .hljs{color:#abb2bf;background:#282c34}.content .hljs-comment,.content .hljs-quote{color:#5c6370;font-style:italic}.content .hljs-doctag,.content .hljs-formula,.content .hljs-keyword{color:#c678dd}.content .hljs-deletion,.content .hljs-name,.content .hljs-section,.content .hljs-selector-tag,.content .hljs-subst{color:#e06c75}.content .hljs-literal{color:#56b6c2}.content .hljs-addition,.content .hljs-attribute,.content .hljs-meta .hljs-string,.content .hljs-regexp,.content .hljs-string{color:#98c379}.content .hljs-attr,.content .hljs-number,.content .hljs-selector-attr,.content .hljs-selector-class,.content .hljs-selector-pseudo,.content .hljs-template-variable,.content .hljs-type,.content .hljs-variable{color:#d19a66}.content .hljs-bullet,.content .hljs-link,.content .hljs-meta,.content .hljs-selector-id,.content .hljs-symbol,.content .hljs-title{color:#61aeee}.content .hljs-built_in,.content .hljs-class .hljs-title,.content .hljs-title.class_{color:#e6c07b}.content .hljs-emphasis{font-style:italic}.content .hljs-strong{font-weight:700}.content .hljs-link{text-decoration:underline}html.dark-theme>body{background:#0d203f;color:#fff}html.dark-theme>body h1,html.dark-theme>body h2,html.dark-theme>body h3,html.dark-theme>body h4,html.dark-theme>body p,html.dark-theme>body li{color:#fff}html.dark-theme>body .content a,html.dark-theme>body article a{color:#34e8bd}html.dark-theme>body .content strong,html.dark-theme>body article strong{color:#ece5ee}@media screen and (max-width: 1023px){#topbar.navbar .logo{width:3rem;height:3rem;background:url(../image/avatar.png) no-repeat 0 0;background-size:contain}#topbar.navbar .logo svg,#topbar.navbar .logo span{display:none !important}#topbar.navbar .logo-project{margin-left:.5rem}#topbar.navbar .navbar-menu.is-pulled-right{text-align:right}#topbar.navbar .navbar-menu.is-pulled-right a{float:right}.menu-wrap{z-index:1400;width:100vw;display:none}.menu-wrap.is-active{display:block !important;top:0;left:0;right:0;bottom:0;position:fixed}.menu-wrap aside.menu{width:100vw;padding-left:5vw;padding-right:5vw;padding-top:8rem}article.content section,footer{overflow-x:hidden !important;max-width:100vw !important}main.is-fullwidth{max-width:90vw !important;padding-left:5vw !important;padding-right:5vw !important}.menu-wrap+article.content{padding-left:0;max-width:85vw !important}footer.is-shallow .footer-nav{max-width:90vw;padding-left:5vw;padding-right:5vw;border-color:rgba(0,0,0,0) !important}footer.is-shallow .footer-nav .navbar-item{display:inline-block}}.documentation .content{padding-top:8.5rem}.documentation .content h1{margin-top:2rem;position:relative;padding-bottom:2.67rem}.documentation .content.content-docs-wide p{line-height:1.725}.documentation .content details{font-size:1rem;width:100%;background:#f4f0f5;border-left:4px solid #d9dbe8;position:relative;max-width:800px}.documentation .content details .summary-title{-webkit-user-select:none;-moz-user-select:none;user-select:none}.documentation .content details:hover{cursor:pointer}.documentation .content details .summary-content{border-top:1px solid #e2e8f0;cursor:default;padding:1em;font-weight:300;line-height:1.5}.documentation .content details summary{list-style:none;padding:1em}.documentation .content details summary:focus{outline:none}.documentation .content details summary:hover .summary-chevron-up svg{opacity:1}.documentation .content details .summary-chevron-up svg{opacity:.5}.documentation .content details .summary-chevron-up,.documentation .content details .summary-chevron-down{pointer-events:none;position:absolute;top:.75em;right:1em;background:#f4f0f5}.documentation .content details .summary-chevron-up svg,.documentation .content details .summary-chevron-down svg{display:block}.documentation .content details summary::-webkit-details-marker{display:none}.documentation .copy-code-button{position:absolute;top:.7rem;right:.7rem;border-radius:.67rem;padding:.2rem;cursor:pointer;background-color:rgba(237,237,237,.1450980392);border:2px solid;border-color:rgba(237,237,237,.2078431373)}.documentation .copy-code-button>svg{fill:rgba(237,237,237,.6)}.documentation .copy-code-button:hover{border-color:rgba(237,237,237,.6)}.documentation .copy-code-button.is-success{border-color:#18d1a5}.documentation .logo-project a{position:relative}.documentation .logo-project a.is-active::after{content:"";display:block;position:absolute;left:0;right:0;bottom:-0.5rem;width:90%;margin:auto;height:3px;background:#0e8fdd}.documentation .content a.anchor-link{padding:.3rem;text-decoration:none;opacity:0;fill:#363636;background-color:rgba(0,0,0,0)}.documentation h1:hover>a.anchor-link{opacity:1}.documentation h2:hover>a.anchor-link{opacity:1}.documentation h3:hover>a.anchor-link{opacity:1}.documentation h4:hover>a.anchor-link{opacity:1}.documentation a.anchor-link:after{content:none}.documentation aside.menu{padding-bottom:7.5rem}html.dark-theme body .content details{background:#1b2c4f;border-left:4px solid #243c6c}html.dark-theme body .content details .summary-content{border-top:1px solid #243c6c}html.dark-theme body .content details .summary-chevron-up,html.dark-theme body .content details .summary-chevron-down{background:#1b2c4f}html.dark-theme body .content a.anchor-link:hover{background:rgba(0,0,0,0) !important}html.dark-theme body .content a.anchor-link{fill:#fff}@media screen and (max-width: 1023px){.documentation .content h1{font-size:6.333vw}.documentation .content h2{font-size:5vw}.documentation .content h3{font-size:3.33vw}}.content pre{max-width:800px} \ No newline at end of file diff --git a/static/sass/styles.scss b/static/sass/styles.scss index 3fa6fe42c..53cc416ea 100644 --- a/static/sass/styles.scss +++ b/static/sass/styles.scss @@ -263,4 +263,304 @@ html.dark-theme { .content pre { max-width: 800px; +} + +.search-button-container { + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.search-button { + border-radius: 0.667rem; + border: 1px solid #a8a8a8; + color: #345995; + padding: 0.8rem; + background-color: transparent; + z-index: 9; + cursor: grab; + display: flex; + justify-content: space-between; + align-items: center; +} + +.search-icon { + color: #a8a8a8; + font-size: 0.7rem; +} + +.search-placeholder { + padding: 0 1rem 0 1rem; + font-weight: 600; + font-size: 0.8rem; +} + +.search-command { + background-color: #e9e1eb; + color: #345995; + padding: .25em .5em .25em; + font-size: 0.7rem; + border-radius: 0.667rem; +} + +html.dark-theme { + .search-button { + border: 1px solid #a8a8a8; + color: white; + } + + .search-command { + background-color: #213762; + color: #ece5ee; + } + + .modal-wrapper { + background-color: #00000040; + } + + .modal-box { + background: #0d203f; + } + + input[type="text"].modal-search-bar { + background-color: #213762; + color: white; + + &::placeholder { + color: #989898; + } + } + + .result-block { + background-color: #213762; + + a { + color: #fff; + } + + code { + background-color: #0d203f; + } + } + + .result-subitem { + background-color: #0d203f; + } + + .result-subheading-container { + a { + color: #34e8bd; + } + } + + .result-section-container { + .result-filters { + + code { + color: #da1039; + background-color: #99919b; + } + + code.active { + background-color: #e9e1eb; + } + } + + .suggested-project { + background-color: #213762; + + .project-title { + color: #fff; + } + + .suggested-project-link { + background-color: #0d203f; + color: #34e8bd; + } + } + } + +} + +.search-modal-container { + box-sizing: border-box; + margin: 0; + width: 100%; + height: 100%; + z-index: 1000; + position: fixed; + left: 0; + top: 0; + display: none; +} + +.modal-wrapper { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(6px); + background-color: #00000080; +} + +.modal-box { + width: 80%; + height: 80%; + max-width: 600px; + max-height: 700px; + padding: 1rem; + display: flex; + flex-direction: column; + align-items: center; + background-color: #e9e1eb; + border-radius: 0.667rem; +} + +.modal-search-bar { + box-sizing: border-box; + line-height: 1.5rem; + width: 100%; + padding: 0.8rem; + font-size: 1.2rem; + border-radius: 0.667rem; + border: 0px; + margin-bottom: 1rem; + + &:focus { + outline: none; + } +} + +.result-section-container { + width: 100%; + flex-grow: 1; + display: flex; + overflow-y: auto; + flex-direction: column; + + .suggested-project { + justify-content: center; + align-items: center; + padding: 0.6rem; + border-radius: 0.667rem; + margin: 0.2rem; + background-color: #f3f3f3; + color: black; + display: flex; + flex-direction: column; + + .project-title { + padding: 0.5em; + font-weight: 600; + } + + .recommended-navs { + width: 100%; + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: space-evenly; + } + + .suggested-project-link { + width: 45%; + background-color: white; + font-size: 1rem; + display: flex; + justify-content: center; + align-items: center; + overflow-y: auto; + border-radius: 0.667rem; + padding: 1rem; + margin-bottom: 0.4rem; + font-weight: 400; + color: #345995; + } + } + + .result-section { + width: 100%; + flex-grow: 1; + overflow-y: auto; + border-radius: 0.667rem; + + &::-webkit-scrollbar { + width: 0px; + } + } + + .result-filters { + display: flex; + justify-content: space-between; + padding: 0 0.4rem 0.4rem 0.4rem; + align-items: center; + cursor: grab; + + .filter-categories { + max-width: 80%; + } + + .reset-filter { + font-size: 0.8rem; + } + + code { + background-color: #4d407f90; + color: whitesmoke; + font-size: 0.8rem; + margin-left: 0.5rem; + border-radius: 0.667rem; + } + + code.active { + background-color: #0d203f; + color: white; + } + } +} + +.result-block { + padding: 0.6rem; + border-radius: 0.667rem; + margin: 0.2rem; + background-color: #f3f3f3; + color: black; + display: flex; + flex-direction: column; + + a { + color: #363636; + } + + code { + background-color: #e9e1eb; + font-size: 0.8rem; + margin-left: 0.5rem; + border-radius: 0.667rem; + } +} + +.result-subheading-container { + padding: 1rem; + + a { + color: #345995; + } +} + +.result-subitem { + background-color: white; + font-size: 1rem; + display: flex; + align-items: center; + overflow-y: auto; + border-radius: 0.667rem; + margin-bottom: 0.4rem; +} + +.result-item-icon { + font-size: 1.5rem; + padding: 0.4rem; } \ No newline at end of file diff --git a/templates/content_bottom.hbs b/templates/content_bottom.hbs index 51f63486c..9395238ea 100644 --- a/templates/content_bottom.hbs +++ b/templates/content_bottom.hbs @@ -19,7 +19,11 @@ - +
- + + + \ No newline at end of file diff --git a/templates/content_navbar.hbs b/templates/content_navbar.hbs index e79ca38eb..038b5ea22 100644 --- a/templates/content_navbar.hbs +++ b/templates/content_navbar.hbs @@ -91,5 +91,6 @@ fermyon.com +
\ No newline at end of file