diff --git a/.eleventy.js b/.eleventy.js index 610980a..fb9750d 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,13 +1,14 @@ +const cheerio = require("cheerio"); +const site = require("./_data/site.json"); + module.exports = function (eleventyConfig) { // copy site data - eleventyConfig.addPassthroughCopy('htaccess.txt'); eleventyConfig.addPassthroughCopy('.htaccess'); // copy directories to the output eleventyConfig.addPassthroughCopy('css'); eleventyConfig.addPassthroughCopy('js'); eleventyConfig.addPassthroughCopy('img'); // copy favicons - eleventyConfig.addPassthroughCopy('site.webmanifest'); eleventyConfig.addPassthroughCopy('*.ico'); eleventyConfig.addPassthroughCopy('*.png'); @@ -15,7 +16,62 @@ module.exports = function (eleventyConfig) { eleventyConfig.addWatchTarget('css'); eleventyConfig.addWatchTarget('js'); eleventyConfig.addWatchTarget('img'); - eleventyConfig.addWatchTarget('cards'); - eleventyConfig.addWatchTarget('site.webmanifest'); + + // shortcodes + eleventyConfig.addShortcode("currentYear", () => `${new Date().getFullYear()}`); + + // page transforms and filters + // FILTER: split a string by a separator + eleventyConfig.addFilter("split", function(str, separator) { + if (!str) return []; + return str.split(separator); + }); + + // FILTER: Generate canonical URL + eleventyConfig.addFilter("canonicalUrl", function(pageUrl) { + // Remove trailing slash from site.url (if present, though it shouldn't be) + const base = site.url.replace(/\/$/, ""); + + // check if it's the homepage; if so, just return the base URL + if (!pageUrl || pageUrl === "/" || pageUrl === "/index.html") { + return base; + } + + // otherwise, ensure pageUrl starts with a slash + const rel = pageUrl.startsWith("/") ? pageUrl : `/${pageUrl}`; + return base + rel; + }); + + // TRANSFORM: create accessibility table of contents + eleventyConfig.addTransform("injectSrToc", function(content, outputPath) { + if (outputPath && outputPath.endsWith(".html")) { + const $ = cheerio.load(content); + + // Build TOC from sections + const sections = []; + $("section[id]").each((i, elem) => { + const id = $(elem).attr("id"); + const title = id + " section"; + sections.push({ id, title }); + }); + + // Only inject if there are sections + if (sections.length) { + const tocHtml = ` + + `; + // Insert TOC at the start of on the page + $("body").prepend(tocHtml); + return $.html(); + } + } + return content; + }); }; \ No newline at end of file diff --git a/.eleventyignore b/.eleventyignore new file mode 100644 index 0000000..27f55c0 --- /dev/null +++ b/.eleventyignore @@ -0,0 +1,2 @@ +template/ +scripts/ \ No newline at end of file diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml new file mode 100644 index 0000000..2c26667 --- /dev/null +++ b/.github/workflows/dev.yml @@ -0,0 +1,33 @@ +on: + push: + branches: + - dev +name: Build and deploy website (dev) +jobs: + deploy_job: + name: Deploy + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '23' + + - name: Install dependencies + run: npm install + + - name: Build site + run: npx eleventy + + - name: Deploy file(s) + uses: wlixcc/SFTP-Deploy-Action@v1.2.4 + with: + server: ${{ secrets.sftp_server }} + username: ${{ secrets.sftp_username }} + password: ${{ secrets.sftp_password }} + port: 22 + local_path: './_site/*' + remote_path: ${{ secrets.sftp_remote_path_dev }} \ No newline at end of file diff --git a/.github/workflows/update-template.yml b/.github/workflows/update-template.yml new file mode 100644 index 0000000..da8b2f4 --- /dev/null +++ b/.github/workflows/update-template.yml @@ -0,0 +1,44 @@ +name: Sync Template on Template Release + +on: + repository_dispatch: + types: [template-release] # Triggered remotely from template repo + workflow_dispatch: + +jobs: + update-template: + runs-on: ubuntu-latest + steps: + - name: Determine target branch + id: branch-check + run: | + if git ls-remote --heads origin dev | grep dev; then + echo "branch=dev" >> $GITHUB_OUTPUT + else + echo "branch=main" >> $GITHUB_OUTPUT + fi + + - name: Checkout target branch + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ steps.branch-check.outputs.branch }} + + - name: Configure Git + run: | + git config --global user.name "Terrabyte Bot" + git config --global user.email "bot@terrabyte.eco" + + - name: Pull latest template release + run: | + git subtree pull \ + --prefix=template \ + https://github.com/terrabyte-tech/terrabyte-11ty-template.git \ + ${{ github.event.client_payload.tag }} \ + --squash + + - name: Commit & Push changes + run: | + git add template + git commit -m "chore: sync template to release ${{ github.event.client_payload.tag }} ${{ github.event.client_payload.commit_message_suffix }}" || echo "No changes to commit" + git push origin ${{ steps.branch-check.outputs.branch }} diff --git a/.htaccess b/.htaccess index 60a4186..6f01167 100644 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,25 @@ ErrorDocument 400 /error.php ErrorDocument 401 /error.php ErrorDocument 403 /error.php -ErrorDocument 404 /error.php \ No newline at end of file +ErrorDocument 404 /error.php + +# Performance: Caching headers + + ExpiresActive On + ExpiresByType font/woff2 "access plus 1 year" + ExpiresByType image/webp "access plus 30 days" + ExpiresByType text/css "access plus 7 days" + ExpiresByType application/javascript "access plus 7 days" + + + + + Header set Cache-Control "public, max-age=31536000" + + + Header set Cache-Control "public, max-age=2592000" + + + Header set Cache-Control "public, max-age=604800" + + \ No newline at end of file diff --git a/_data/site.json b/_data/site.json index fa6bc8e..7c48d35 100644 --- a/_data/site.json +++ b/_data/site.json @@ -1,7 +1,15 @@ { + "templateVersion": "1.4.0", + "project": "Canapi", "title": "Canapi", - "url": "https://canapi.io", + "url": "https://www.canapi.io", "author": "Terrabyte", + "brand": "Terrabyte", "language": "en-US", - "description": "Canapi is a marketplace and API suite that allows businesses and organizations to make automated environmental contributions." + "description": "Canapi is a marketplace and API suite that allows businesses and organizations to make automated environmental contributions.", + "accentColor": "#", + "backgroundColor": "#ffffff", + "foregroundColor": "#333333", + "schemaType": "Thing", + "fontsRel": "https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Manrope:wght@400;800&display=swap" } \ No newline at end of file diff --git a/_includes/banners.njk b/_includes/banners.njk new file mode 100644 index 0000000..c9d94e4 --- /dev/null +++ b/_includes/banners.njk @@ -0,0 +1,26 @@ +{% from 'macros/banner.njk' import banner %} + + \ No newline at end of file diff --git a/_includes/inspector-splash.njk b/_includes/inspector-splash.njk new file mode 100644 index 0000000..f332d03 --- /dev/null +++ b/_includes/inspector-splash.njk @@ -0,0 +1,6 @@ + + + + + + diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 1f752b3..f642ad6 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -2,24 +2,39 @@ +{% include "partials/inspector-splash.njk" %} + - + + + + + {# add variable to nunjucks templates that shouldn't be indexed in frontmatter; noIndex: true #} {% if noIndex %} {% endif %} + + {{ site.title }}{% if subtitle %}: {{ subtitle }}{% endif %} - + + {# if applicable/desired (default: TB green) #} + + + {# Open Graph meta tags for social media sharing #} + {# Open Graph meta tags #} @@ -27,13 +42,12 @@ - {# Favicon links #} + {# favicons #} - @@ -41,66 +55,119 @@ - {# #} + - {# #} + {% if site.iconsRel %} + + {% endif %} - - + + - + {# #} + + + + + + {% if site.styleType == "pixel" %} + + {% endif %} - - {# #} + + {% if site.project == "Canapi" %} + + {% endif %} - - + - {# conditional styles #} - {% if testPage %} - - {% else %} + {# other conditional styles #} + {# {% if testPage %} #} + {# #} + {# {% else %} #} {# #} - {% endif %} + {# {% endif %} #} + + + - + {# #} + - + - + + + + {% if site.canapiKey %} + + {% endif %} + + - + + +{# ########## #} +{# dependencies #} +{# ########## #} + {# svg container component #} - {% include "svgs.njk" %} + {% include "partials/svgs.njk" %} - {# accessibility/screen reader TOC component #} - {% include "sr-toc.njk" %} +{# ########## #} +{# sys ui #} +{# ########## #} + + {# modals (not supported atm...) #} + {# {% include "modals.njk" %} #} + + {# accessibility/screen reader TOC #} + {# handled as .eleventy.js transform #} {# noscript banner component #} - {% include "noscript-banner.njk" %} + {% include "partials/banners.njk" %} + +{# ########## #} +{# page begins #} +{# ########## #}
{% include "header.njk" %} - {{ content | safe }} +
+ {{ content | safe }} +
- {% include "footer.njk" %} + + {% include "partials/footer.njk" %} {# decorative elements #}
@@ -109,6 +176,6 @@

<div data-canapi-click-trigger data-key="XX-XXXX-XXXX">

- + \ No newline at end of file diff --git a/_includes/layouts/blank-redirect.njk b/_includes/layouts/blank-redirect.njk new file mode 100644 index 0000000..8d37655 --- /dev/null +++ b/_includes/layouts/blank-redirect.njk @@ -0,0 +1,78 @@ + + + + +{% include "partials/inspector-splash.njk" %} + + + + + + + + + + + {# redirect URL should be included in page frontmatter #} + {# rework this to include a /?rel= value from the referring URL #} + + + + + + + {{ site.title }}{% if subtitle %}: {{ subtitle }}{% endif %} + + + + + + {# if applicable/desired (default: TB green) #} + + + {# Open Graph meta tags for social media sharing #} + + {# Open Graph meta tags #} + + + + + + + {# favicons #} + + + + + + + {# ????? what is this ????? #} + + + + + + + + + + + + + + + + + + {% if site.canapiKey %} + + {% endif %} + + + + + + + \ No newline at end of file diff --git a/_includes/macros/banner.njk b/_includes/macros/banner.njk new file mode 100644 index 0000000..61a2ab6 --- /dev/null +++ b/_includes/macros/banner.njk @@ -0,0 +1,14 @@ +{% macro banner(content, id, dismissible=true, timeout=false, position="top", type="info") %} + +{% endmacro %} \ No newline at end of file diff --git a/_includes/macros/button.njk b/_includes/macros/button.njk new file mode 100644 index 0000000..1d77da2 --- /dev/null +++ b/_includes/macros/button.njk @@ -0,0 +1,13 @@ +{# not implemented, but would like to refactor sites to use this standardized button component! #} +{% macro button(text, href="#", className="primary", ariaLabel="", target="", rel="", role="button") %} + + {{ text }} + +{% endmacro %} diff --git a/_includes/noscript-banner.njk b/_includes/noscript-banner.njk deleted file mode 100644 index 6bc99f3..0000000 --- a/_includes/noscript-banner.njk +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/_includes/partials/banners.njk b/_includes/partials/banners.njk new file mode 100644 index 0000000..c9d94e4 --- /dev/null +++ b/_includes/partials/banners.njk @@ -0,0 +1,26 @@ +{% from 'macros/banner.njk' import banner %} + + \ No newline at end of file diff --git a/_includes/partials/footer.njk b/_includes/partials/footer.njk new file mode 100644 index 0000000..ff03b15 --- /dev/null +++ b/_includes/partials/footer.njk @@ -0,0 +1,7 @@ +{# duplicate the Terrabyte footer here #} + +{# pulled from pixel footer #} +{# #} \ No newline at end of file diff --git a/_includes/partials/inspector-splash.njk b/_includes/partials/inspector-splash.njk new file mode 100644 index 0000000..361e072 --- /dev/null +++ b/_includes/partials/inspector-splash.njk @@ -0,0 +1,6 @@ + + + + + + diff --git a/_includes/partials/pixel-footer.njk b/_includes/partials/pixel-footer.njk new file mode 100644 index 0000000..d603ea2 --- /dev/null +++ b/_includes/partials/pixel-footer.njk @@ -0,0 +1,39 @@ + \ No newline at end of file diff --git a/_includes/partials/ppt-header.njk b/_includes/partials/ppt-header.njk new file mode 100644 index 0000000..e69de29 diff --git a/_includes/partials/svgs.njk b/_includes/partials/svgs.njk new file mode 100644 index 0000000..fc0f8b0 --- /dev/null +++ b/_includes/partials/svgs.njk @@ -0,0 +1,57 @@ + + + {# template for icons #} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_includes/sr-toc.njk b/_includes/sr-toc.njk deleted file mode 100644 index 66f454d..0000000 --- a/_includes/sr-toc.njk +++ /dev/null @@ -1,15 +0,0 @@ -{# component for building the table of contents for each page (used by screen readers) #} - -{# psuedo-code: #} -{# 1. take the sections of the page #} -{# 2. make list item for each section #} - - \ No newline at end of file diff --git a/_includes/svgs.njk b/_includes/svgs.njk index 078ccbc..fc0f8b0 100644 --- a/_includes/svgs.njk +++ b/_includes/svgs.njk @@ -3,9 +3,55 @@ {# template for icons #} + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/css/global-tb-styles.css b/css/global-tb-styles.css new file mode 100644 index 0000000..198b385 --- /dev/null +++ b/css/global-tb-styles.css @@ -0,0 +1,85 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* styles that are shared across org/between projects and sites */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +/* css variable initialization */ +:root{ + /* refactor to pull in site.json */ + --white: #ffffff; + /* --HCbackground: #ffffff; */ + --dark: #333333; + --black: #000000; + --tbgreen: #0A8C61; + --errorred: #db2a2a; + --infoblue: #1e90ff; + --warningyellow: #ffcc00; + --accent: #0A8C61; + /* --HCaccent: #096242; */ + /* iconography/branding */ + --projectLogo: url("/img/project-logo.png"); + /* fonts */ + --primary-font: Helvetica, sans-serif; + --secondary-font: monospace; + /* anims */ + --ux-speed: .35s; + --ux-hover-speed: var(--ux-speed); + --ux-active-speed: .15s; +} +/* variables for dark/light mode */ +[data-theme~="dark"]{ + --background: var(--dark); + --foreground: var(--white); +} +[data-theme~="light"]{ + --background: var(--white); + --foreground: var(--dark); +} +/* if system mode is enabled, and set to Dark */ +@media (prefers-color-scheme: dark) { + [data-theme~="system"]{ + --foreground: var(--light); + --background: var(--dark); + } +} +/* variables for high contrast */ +[data-theme~="dark"][data-theme~="hc"]{ + --background: var(--black); + --foreground: var(--white); +} +[data-theme~="light"][data-theme~="hc"]{ + --background: var(--white); + --foreground: var(--black); +} +/* ------------- */ + +/* implementing shared variables (body) */ +body{ + background-color: var(--background); + color: var(--foreground); + font-family: var(--secondary-font); + min-height:100vh; +} +h1, h2, h3, h4, h5, h6, button, .button, input[type='submit']{ + font-family: var(--primary-font); +} +.project-logo{ + /* DEPRECATE, use image elem! */ + background-image:var(--projectLogo); +} +hr{ + border:none; + border-top:2px solid var(--accent); +} +/* ------------- */ + +/* implementing shared variables (user interface) */ +*::selection{ + color:var(--background); + background-color:var(--foreground); +} +*::-moz-selection{ + color:var(--background); + background-color:var(--foreground); +} + +/* +++++++++++++++++++++++++++++++++++++++++++ */ \ No newline at end of file diff --git a/css/global-tb-ui-styles.css b/css/global-tb-ui-styles.css new file mode 100644 index 0000000..1bbc3f7 --- /dev/null +++ b/css/global-tb-ui-styles.css @@ -0,0 +1,201 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* global Terrabyte UI styles */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +/* inputs */ +input{ + font-family: inherit; + font-size:inherit; + color:inherit; + background-color:transparent; + border:none; + outline:none; +} +/* ------------- */ + +/* links */ +a{ + color:currentColor; + text-decoration:none; + cursor:pointer; + user-select: none; + transform:scale(1); + opacity:1; + display:inline-block; +} +a.text-link{} +/* hover state */ +@media (hover: hover) and (pointer: fine) { + a:hover{ + transform:scale(1.05); + } +} +/* active state */ +a:active{ + transition:var(--ux-active-speed); + transform:scale(0.95); + opacity:.6; +} +/* ------------- */ + +/* buttons */ +/* primary buttons */ +button, +.button, +input[type='submit']{ + display:inline-block; + color:var(--white); + border:2px solid var(--accent); + border-radius:2px; + background-color:var(--accent); + padding:10px; + cursor:pointer; + transition:var(--ux-speed); + user-select: none; + line-height:20px; + font-size:14px; + transform:scale(1); + opacity:1; +} +/* secondary button */ +button.secondary, +.button.secondary, +input[type='submit'].secondary{ + color:var(--background); + border:2px solid var(--foreground); + background-color: var(--foreground); +} +/* tertiary/shadow button */ +button.shadow, +.button.shadow, +input[type='submit'].shadow{ + color:inherit; + border:2px solid currentColor; + background-color:transparent; +} +/* hover state */ +@media (hover: hover) and (pointer: fine) { + button:hover, + .button:hover, + input[type='submit']:hover{ + transform:scale(1.05); + } +} +/* active state */ +button:active, +.button:active, +input[type='submit']:active{ + transition:var(--ux-active-speed); + transform:scale(0.95); +} +/* ------------- */ + +/* banners */ +.banner{ + position: fixed; + left: 0; + z-index: 900; + width: 100%; + padding: 15px 20px; + font-size: 12px; + color:white; + background-color:var(--tbgreen); +} +.banner.top{ + top: 0; +} +.banner.info{ + background-color: var(--infoblue); +} +.banner.warning{ + background-color: var(--warningyellow); + color:dark; +} +.banner.error{ + background-color: var(--errorred); +} +/* ------------- */ + +/* accessibility table of contents */ +.sr-only.sr-toc{ + background-color:var(--background); + border: 1px solid var(--foreground); + display:block; + position:fixed; + left:-200px; + top:0px; + width:1px; + height:1px; + overflow:hidden; + transition:width .5s, left .5s; + z-index:1000; + font-size:25px; + padding:0px; + font-family:inherit; +} +.sr-only.sr-toc:focus-within{ + left:0; + width:100%; + max-width:500px; + height:auto; + padding:20px; + clip:unset; +} +.sr-toc h2{ + margin-bottom:20px; +} +.sr-toc ul{ + list-style-type:none; + padding:0px; + margin:0px; +} +.sr-toc a.text-link{ + color:inherit; + display:block; + margin-bottom:10px; + text-transform:capitalize; +} +/* ------------- */ + +/* loading elements */ +.loading-container{ + position:relative; +} +.loading-overlay{ + background-color: #333333dd; + backdrop-filter: blur(5px); + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + opacity:1; + transition:opacity 1s; +} +.loading-spinner{ + width:30px; + height:30px; + margin-bottom:15px; + position:relative; +} +.loading-spinner:before{ + content:""; + width:100%; + height:100%; + position:absolute; + border:2px solid currentColor; + border-right-color:transparent; + border-radius:50%; + animation:spinning ease-in-out 1s infinite; + transform:rotate(10deg); +} +@keyframes spinning { + from{ + transform:rotate(10deg); + } + to{ + transform:rotate(360deg); + } +} + +/* +++++++++++++++++++++++++++++++++++++++++++ */ \ No newline at end of file diff --git a/css/shared-canapi-styles.css b/css/shared-canapi-styles.css new file mode 100644 index 0000000..6b87c4f --- /dev/null +++ b/css/shared-canapi-styles.css @@ -0,0 +1,272 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* Canapi styles that should be shared across project websites. */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +*{ + font-size:inherit; + outline:none; + -webkit-tap-highlight-color:transparent; + -webkit-touch-callout:none; +} + + +/* +++++++++++++++++++++++++++++++++++++++++++ */ + + +/* css variables */ +:root{ + /* default avatar (before load) */ + --avatarPath: linear-gradient(135deg, var(--accent), var(--accent)); + /* --light: #ffffff; */ + /* replace with --white */ + --dark: #333841; + --dark-trans: #33384150; + --dark-light-trans: #33384118; + --grey: #e3e3e3; + --grey-light-trans:#e3e3e318; + --accent:#46af71; + --accent-lime:#80ce4d; + --accent-green-semi-dark-trans:#46af7185; + --accent-green-dark-trans:#46af7178; + /* --accent-lime-dark-trans:#80ce4d78; */ + --accent-green-trans:#46af7150; + /* --accent-lime-trans:#80ce4d60; */ + --accent-green-light-trans:#46af7118; + /* --accent-lime-light-trans:#80ce4d60; */ + + /* shared theme management */ + --shadow:0px 8px 17px -8px rgb(0 0 0 / 10%); + + /* error colors */ + /* --error-red:#e04141; */ + /* replace with... */ + --errorred:#e04141; + /* --error-red-light-trans:#e0414120; */ + /* replace with... */ + --errorred-light-trans:#e0414120; + /* fonts */ + --primary-font: 'Manrope', sans-serif; + --secondary-font: 'Manrope', sans-serif; +} +/* dark mode */ +body.dark, +[data-theme~="dark"]{ + background-color:#30353d; + /* --foreground: var(--light); */ + /* --background: var(--dark); */ + --shadow:0px 8px 17px -8px rgb(0 0 0 / 20%); +} + + +/* +++++++++++++++++++++++++++++++++++++++++++ */ + + +/* html elements */ +body{ + /* put gradient on main page content? */ + /* background:linear-gradient(135deg, #C1F0A3,#A0E1BA); */ + /* background-color:var(--background); */ + /* color:var(--foreground); */ + font-size:14px; + /* min-height:100vh; */ + /* overflow:hidden; */ + /* height:100vh; */ + /* height: calc(var(--vh, 1vh) * 100); */ +} + +/* style scrollbars */ +body::-webkit-scrollbar-track{ + background-color:transparent; + transition:.15s; +} +*::-webkit-scrollbar{ + width: 10px; + height: 10px; + background-color:transparent; + transition:.15s; +} +*::-webkit-scrollbar-thumb{ + background-color:var(--accent); + border-radius:10px; + transition:.15s; +} +/* .page-container{} */ + +a{ + color:var(--accent); + font-weight:bold; + position: relative; + z-index:1; + transition:.25s; + /* transition: transform .25s, color .25s, background-color .25s, opacity .25s; */ +} +a:hover{ + color:var(--accent-green-semi-dark-trans); +} +a.icon-link{ + font-size:1.2em; +} + +.button-container > *{ + margin-right:12px; +} +.button-container > *:last-child{ + margin-right:0; +} +button, +.button{ + border:1px solid var(--accent-green-light-trans); + border-radius:4px; + /* background-color:var(--background); */ + background-color:transparent; + /* padding:8px 10px;?????????? */ + color:var(--foreground); + position: relative; + transition:.25s; + /* transition: transform .25s, color .25s, background-color .25s, opacity .25s, border .25s; */ + font-weight:inherit; +} +button:hover, +.button:hover, +button:focus, +.button:focus{ + /* background-color:#CDF3DC; */ + border-color: var(--accent-green-trans); + /* color: var(--accent-green-semi-dark-trans); */ + background-color:var(--accent-green-light-trans); +} +button:active, +.button:active{ + /* background-color:#A2E1BB; */ + background-color:var(--accent-green-trans); + transform:scale(.95); +} +/* primary buttons */ +button.primary, +.button.primary{ + background-color:var(--accent); + color:var(--white); +} +button.primary:hover, +.button.primary:hover, +button.primary:focus, +.button.primary:focus{ + /* color:var(--grey); */ + background-color:var(--accent-green-semi-dark-trans); +} +button.primary:active, +.button.primary:active{ + color:var(--white); + background-color:var(--accent); +} +p{ + margin-bottom:10px; +} +p:last-child{ + margin-bottom:0; +} +.section-header{ + margin-bottom:20px; +} +h1, h2, h3, h4, h5, h6{ + font-weight:bold; + line-height:1em; + letter-spacing: -1px; +} +h1{ + font-size:3em; +} +h2{ + font-size:2.2em; +} +h3{ + font-size:1.6em; +} +h4{ + font-size:1.1em; +} +h6{ + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0; +} +table{ + width:100%; +} +th{ + text-align:left; + margin-bottom:10px; +} +td{ + text-align:left; +} + + +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* custom selectors, shared elements */ +.max-width{ + max-width:1000px; + margin:0 auto; +} + +/* page layouts */ +.page-container{ + position:relative; + overflow:hidden; + /* overflow-x:hidden; */ + z-index:1; +} + +/* page pieces */ +/* tooltips */ +[data-tooltip]{ + position:relative; + cursor: pointer; + z-index:1; + /* white-space:nowrap; */ + /* min-width:0; */ +} +[data-tooltip]:after, +.tooltip{ + /* container */ + z-index:100; + pointer-events:none; + background-color:var(--background); + border-radius: 4px; + white-space: nowrap; + min-width:0; + /* width:300px; */ + /* max-width:300px; */ + border:1px solid var(--grey); + color:var(--foreground); + padding:12px 15px; + box-shadow:var(--shadow); + position:absolute; + left:0; + /* transition */ + transition:.35s; + opacity:0; + top:70%; + /* content */ + content:attr(data-tooltip); + text-transform: none; + font-size:14px; + font-weight:normal; + letter-spacing: normal; + text-align:left; +} +[data-tooltip]:hover:after, +[data-tooltip]:hover .tooltip{ + opacity:1; + top:150%; +} +.large[data-tooltip]:after{ + min-width:auto; + width:300px; + white-space: initial; +} +[data-tooltip-force-right]:after, +[data-tooltip-force-right] .tooltip{ + left:unset; + right:0; +} \ No newline at end of file diff --git a/css/shared-styles.css b/css/shared-styles.css index 090664e..424b9eb 100644 --- a/css/shared-styles.css +++ b/css/shared-styles.css @@ -1,20 +1,12 @@ +/* DEPRECATED for template/css/shared-canapi-styles.css */ /* styles that are shared between all Canapi sites */ *{ - margin:0; - padding:0; font-size:inherit; font-family:inherit; outline:none; -webkit-tap-highlight-color:transparent; -webkit-touch-callout:none; - /* -webkit-user-select:none; */ - /* -khtml-user-select:none; */ - /* -moz-user-select:none; */ - /* transition:.25s; */ - background-position: center; - background-size:contain; - background-repeat: no-repeat; } @@ -70,9 +62,6 @@ body.dark{ /* html elements */ -html { - scroll-behavior: smooth; -} body{ /* put gradient on main page content? */ /* background:linear-gradient(135deg, #C1F0A3,#A0E1BA); */ diff --git a/css/site-styles.css b/css/site-styles.css index cdd66cf..439a6f2 100644 --- a/css/site-styles.css +++ b/css/site-styles.css @@ -1,31 +1,24 @@ -/*when javascript isn't enabled, toast message*/ -/* shared tb style */ -/* .toast-message{ - z-index:900; - position:absolute; - top:10px; - left:50%; - transform:translateX(-50%); - background-color:#db2a2a; - color:white; - padding:10px 20px 12px 20px; - border-radius:4px; -} */ - -/* move to shared */ -.sr-only{ - display:none; -} +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* site-specific styles */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* */ +/* Careful in template sync, this should be site specific */ +/* */ -/* layout */ +/* overwrite shared */ +.code-text{ + font-family: 'Roboto Mono', Courier, monospace; +} body{ /* overflow-y: scroll; */ background: linear-gradient(135deg, transparent,var(--accent-green-light-trans)); } -.page-container{ - overflow:hidden; -} +/* moved to shared */ +/* .page-container{ + overflow-x:hidden; +} */ +/* shared? */ .padded-section{ padding:30px; } @@ -65,7 +58,7 @@ header .canapi-logo{ background-color:var(--accent-green-trans); } .canapi-logo{ - background-image: url('../img/canapi-logo.png'); + background-image: url('/img/canapi-logo.png'); max-width: 100%; width:350px; height: 150px; @@ -90,7 +83,7 @@ main p{ .canapi-brackets{ user-select: none; pointer-events: none; - background-image: url('https://app.canapi.io/img/canapi-favicon.png'); + background-image: url("/android-chrome-512x512.png"); width:500px; height:800px; opacity:20%; @@ -98,16 +91,13 @@ main p{ top:100px; left:-200px; } -.code-text{ - font-family: 'Roboto Mono', Courier, monospace; -} .canapi-code{ font-size:18px; pointer-events: none; user-select: none; transform:rotate(90deg); transform-origin: top left; - color:var(--accent-green); + color:var(--accent); opacity:20%; position:absolute; width:400px; diff --git a/error.php.njk b/error.php.njk new file mode 100644 index 0000000..b341c85 --- /dev/null +++ b/error.php.njk @@ -0,0 +1,50 @@ +--- +permalink: error.php +eleventyExcludeFromCollections: true +--- + + + +
+
+
+
+

That's an Error ()

+
+
+

Looks like we found a bad byte and some dead pixels. Check the URL above and try again.

+ +

You can also head to the homepage () to try to find what you were looking for there.

+

Or, head to the Terrabyte website to start your digital eco-journey over from the top.

+
+
+
+
\ No newline at end of file diff --git a/img/meta/logo.png b/img/meta/logo.png new file mode 100644 index 0000000..25d10ba Binary files /dev/null and b/img/meta/logo.png differ diff --git a/index.njk b/index.njk index 3efaacc..5ca641c 100644 --- a/index.njk +++ b/index.njk @@ -1,14 +1,37 @@ --- subtitle: Make It Green, Automatically layout: layouts/base.njk -keywords: canapi, terrabyte, automatic, api, software, b2b, green, tech, technology, omaha, nebraska, startup, midwest, business, project, environmental, environmental contributions, tree planting, coral planting, ocean plastic, removal, habitat, restoration, climate, climate change +keywords: canapi, terrabyte, automatic, api, software, b2b, green, tech, technology, omaha, nebraska, startup, midwest, business, project, environmental, environmental contributions, tree planting, coral planting, ocean plastic, removal, habitat, restoration, climate, climate change, litter, sustainability, automation, saas, software as a service --- -
+

make it green, automatically

-
\ No newline at end of file + + +
+
+
+ {#

Plant a tree, pickup litter, fund animal research for every product sold, every newsletter sign-up - anything you can imagine.

#} +

B2B software to help even small operations go green without the hassle.

+
+
+

Canapi is a software as a service (SaaS) product that acts as the middleman between companies and environmental organizations. You decide what triggers environmental contributions, we funnel funds to the organizations that matter most to you.

+
+
+
+
+
+
+

Join Our Newsletter

+
+
+

Stay updated with the latest news, updates, and insights from Canapi. Subscribe to our newsletter and be part of our journey towards a greener future.

+ {# newsletter sign up here #} +
+
+
\ No newline at end of file diff --git a/js/global-tb-scripts.js b/js/global-tb-scripts.js new file mode 100644 index 0000000..ceb8c71 --- /dev/null +++ b/js/global-tb-scripts.js @@ -0,0 +1,26 @@ +window.addEventListener("load", function(){ + + console.log(`[${window.siteData.project}] global-tb-scripts.js loaded`); + + // could revisit this and create within 11ty?? + + // change copyright date + var currentDate = new Date(); + var currentYear = currentDate.getFullYear(); + + var copyrightSpan = document.getElementById("current-year-text"); + // for older implementations + var oldCopyrightSpan = document.getElementsByClassName("copyright-date")[0]; + + if(copyrightSpan){ + copyrightSpan.appendChild(document.createTextNode(currentYear)); + } + // for older implementations + else if(oldCopyrightSpan){ + oldCopyrightSpan.appendChild(document.createTextNode(currentYear)); + } + else{ + // element doesn't exist + } + +}, false); \ No newline at end of file diff --git a/js/scripts.js b/js/scripts.js deleted file mode 100644 index 44813ef..0000000 --- a/js/scripts.js +++ /dev/null @@ -1,7 +0,0 @@ -window.addEventListener("load", function(){ - - console.log("Canapi scripts.js loaded"); - -/////////////// - -}, false); \ No newline at end of file diff --git a/js/site-scripts.js b/js/site-scripts.js new file mode 100644 index 0000000..f2daf1f --- /dev/null +++ b/js/site-scripts.js @@ -0,0 +1,13 @@ +// Careful in template sync, should be site specific + +window.addEventListener("load", function(){ + + console.log(`[${window.siteData.project}] site-scripts.js loaded`); + console.log(`[${window.siteData.project}] Using Template v${window.siteData.templateVersion}`); + + // Add a class to the body element to indicate that the page has loaded + document.body.classList.add("loaded"); + + // custom script here + +}, false); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0580e38..56ca0a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "canapi-website", "version": "1.0.0", "license": "ISC", + "dependencies": { + "cheerio": "^1.1.2" + }, "devDependencies": { "@11ty/eleventy": "^3.1.1" } @@ -409,6 +412,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -433,6 +442,177 @@ "node": ">=8" } }, + "node_modules/cheerio": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz", + "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.12.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -475,6 +655,89 @@ "dev": true, "license": "MIT" }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/css-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/css-select/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/css-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -542,7 +805,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -599,11 +861,23 @@ "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, "node_modules/entities": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -914,6 +1188,18 @@ "node": ">= 0.8" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1288,6 +1574,18 @@ "node": ">=0.10.0" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/nunjucks": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", @@ -1344,6 +1642,58 @@ "dev": true, "license": "MIT" }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1483,6 +1833,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", @@ -1654,6 +2010,15 @@ "dev": true, "license": "MIT" }, + "node_modules/undici": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", + "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1671,6 +2036,27 @@ "dev": true, "license": "MIT" }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/ws": { "version": "8.18.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", diff --git a/package.json b/package.json index ae0cdb9..240309c 100644 --- a/package.json +++ b/package.json @@ -12,5 +12,8 @@ "description": "", "devDependencies": { "@11ty/eleventy": "^3.1.1" + }, + "dependencies": { + "cheerio": "^1.1.2" } -} +} \ No newline at end of file diff --git a/robots.txt.njk b/robots.txt.njk new file mode 100644 index 0000000..49150a6 --- /dev/null +++ b/robots.txt.njk @@ -0,0 +1,7 @@ +--- +permalink: robots.txt +eleventyExcludeFromCollections: true +--- +User-agent: * +Disallow: +Sitemap: {{ site.url }}/sitemap.xml \ No newline at end of file diff --git a/site.manifest.njk b/site.manifest.njk new file mode 100644 index 0000000..b657929 --- /dev/null +++ b/site.manifest.njk @@ -0,0 +1,25 @@ +--- +permalink: site.webmanifest +eleventyExcludeFromCollections: true +--- +{ + "name": "{{ site.title }}", + "short_name": "{{ site.title }}", + "start_url": "/", + "display": "browser", + "background_color": "{{ site.backgroundColor or '#333333' }}", + "theme_color": "{{ site.accentColor or '#ffffff' }}", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "description": "{{ site.description | safe }}" +} diff --git a/site.webmanifest b/site.webmanifest deleted file mode 100644 index 45dc8a2..0000000 --- a/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/sitemap.xml.njk b/sitemap.xml.njk new file mode 100644 index 0000000..8fd1982 --- /dev/null +++ b/sitemap.xml.njk @@ -0,0 +1,21 @@ +--- +permalink: sitemap.xml +eleventyExcludeFromCollections: true +--- + + + {% for page in collections.all %} + {% if page.url and not page.data.draft and not page.data.private %} + + {{ page.url | canonicalUrl }} + {# Calculate depth #} + {% if page.url == '/' %}{% set depth = 0 %} + {% else %}{% set depth = page.url | trim('/') | split('/') | length %}{% endif %} + {# Calculate priority #} + {% set priority = 1.0 - (depth * 0.1) %} + {% if priority > 0.1 %}{{ priority | round(1, 'floor') }} + {% else %}0.1{% endif %} + + {% endif %} + {% endfor %} + \ No newline at end of file diff --git a/template/.eleventy.js b/template/.eleventy.js new file mode 100644 index 0000000..fb9750d --- /dev/null +++ b/template/.eleventy.js @@ -0,0 +1,77 @@ +const cheerio = require("cheerio"); +const site = require("./_data/site.json"); + +module.exports = function (eleventyConfig) { + // copy site data + eleventyConfig.addPassthroughCopy('.htaccess'); + // copy directories to the output + eleventyConfig.addPassthroughCopy('css'); + eleventyConfig.addPassthroughCopy('js'); + eleventyConfig.addPassthroughCopy('img'); + // copy favicons + eleventyConfig.addPassthroughCopy('*.ico'); + eleventyConfig.addPassthroughCopy('*.png'); + + // watch directories for changes + eleventyConfig.addWatchTarget('css'); + eleventyConfig.addWatchTarget('js'); + eleventyConfig.addWatchTarget('img'); + + // shortcodes + eleventyConfig.addShortcode("currentYear", () => `${new Date().getFullYear()}`); + + // page transforms and filters + // FILTER: split a string by a separator + eleventyConfig.addFilter("split", function(str, separator) { + if (!str) return []; + return str.split(separator); + }); + + // FILTER: Generate canonical URL + eleventyConfig.addFilter("canonicalUrl", function(pageUrl) { + // Remove trailing slash from site.url (if present, though it shouldn't be) + const base = site.url.replace(/\/$/, ""); + + // check if it's the homepage; if so, just return the base URL + if (!pageUrl || pageUrl === "/" || pageUrl === "/index.html") { + return base; + } + + // otherwise, ensure pageUrl starts with a slash + const rel = pageUrl.startsWith("/") ? pageUrl : `/${pageUrl}`; + return base + rel; + }); + + // TRANSFORM: create accessibility table of contents + eleventyConfig.addTransform("injectSrToc", function(content, outputPath) { + if (outputPath && outputPath.endsWith(".html")) { + const $ = cheerio.load(content); + + // Build TOC from sections + const sections = []; + $("section[id]").each((i, elem) => { + const id = $(elem).attr("id"); + const title = id + " section"; + sections.push({ id, title }); + }); + + // Only inject if there are sections + if (sections.length) { + const tocHtml = ` + + `; + // Insert TOC at the start of on the page + $("body").prepend(tocHtml); + return $.html(); + } + } + return content; + }); + +}; \ No newline at end of file diff --git a/template/.eleventyignore b/template/.eleventyignore new file mode 100644 index 0000000..27f55c0 --- /dev/null +++ b/template/.eleventyignore @@ -0,0 +1,2 @@ +template/ +scripts/ \ No newline at end of file diff --git a/template/.github/workflows/README.md b/template/.github/workflows/README.md new file mode 100644 index 0000000..7e2a3fa --- /dev/null +++ b/template/.github/workflows/README.md @@ -0,0 +1,57 @@ +# Terrabyte Cross-Project Template Sync System + +**Purpose:** Automatically sync updates from the `terrabyte-11ty-template` repo to downstream Terrabyte sites using a GitHub App and secure automation. + +## Overview + +This system uses: +- A **GitHub App** for secure, scalable authentication +- A **release-based trigger** in the template repo +- A **repository_dispatch** event to notify downstream repos +- A **subtree strategy** to keep `/template` folders up to date with the latest Template release + +No personal access tokens. No manual syncing. No CI/CD chaos (hopefully). + +## Components + +### GitHub App: `terrabyte-template-sync` +- Install on downstream repos (e.g., Terrabyte websites that utilize this template) +- Authenticates via JWT -> access token -> dispatch event + +### Template Repo: [`terrabyte-11ty-template`](./README.md) +- Contains `notify-downstream.yml` workflow +- Triggers on release -> sends dispatch to downstream repos + +### Downstream Repos +- Contain `update-template.yml` workflow +- Listen for `template-release` dispatch -> pull latest template via subtree + +## Setup + +### Template Repo + +The private key and `notify-downstream.yml` file are already in place. The only thing you need to do is create a new release using semantic versioning (v1.1.0, v1.1.1, etc.). Release titles can be descriptive or playful — versioning lives in the tag. + +### Downstream Repo +1. Install GitHub App on the repo +2. Add `.github/workflows/update-template.yml`: + - Listens for `repository_dispatch` + - Pulls latest template into `/template` folder + - Targets `dev` branch first, falls back to `main` + - Uses `[skip ci]` to avoid triggering deploy workflows + +## Caveats & Gotchas + +- JWTs expire after 10 minutes — automation handles this, but manual testing must be quick +- App must be installed on each downstream repo — otherwise dispatch will fail silently +- Do not install the app on the template repo — it only sends, not receives +- Avoid copying `.github/workflows/notify-downstream.yml` into downstream repos — it’ll create a loop +- Subtree merges must be squashed — use `--squash` to avoid polluting history + +## Scaling to more projects + +To add a new Terrabyte site to this automation: +1. Install the GitHub App on the repo +2. Add /template to the repo through the subtree process (we specifically need the `update-template.yml` file) +3. Add the repo name to the `repos=` list in `notify-downstream.yml` Template file +4. Boom — it’ll sync on the next release of the Terrabyte Template. \ No newline at end of file diff --git a/template/.github/workflows/notify-downstream.yml b/template/.github/workflows/notify-downstream.yml new file mode 100644 index 0000000..45607fe --- /dev/null +++ b/template/.github/workflows/notify-downstream.yml @@ -0,0 +1,60 @@ +name: Notify Downstream Repos + +on: + release: + types: [published] + +jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Generate JWT + id: generate-jwt + run: | + npm install jsonwebtoken + node < jwt.txt + const fs = require('fs'); + const jwt = require('jsonwebtoken'); + const APP_ID = '1920979'; + const PRIVATE_KEY = \`${{ secrets.APP_PRIVATE_KEY }}\`; + const now = Math.floor(Date.now() / 1000); + const payload = { + iat: now, + exp: now + (10 * 60), + iss: APP_ID + }; + const token = jwt.sign(payload, PRIVATE_KEY, { algorithm: 'RS256' }); + console.log(token); + EOF + echo "jwt=$(cat jwt.txt)" >> $GITHUB_OUTPUT + + - name: Get Installation Access Token + id: get-token + run: | + TOKEN=$(curl -s -X POST \ + -H "Authorization: Bearer ${{ steps.generate-jwt.outputs.jwt }}" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/app/installations/84964465/access_tokens | jq -r .token) + echo "token=$TOKEN" >> $GITHUB_OUTPUT + + - name: Set downstream repos + id: set-repos + run: | + echo "repos=terrabyte-tech/pixel-pegasus-website" >> $GITHUB_OUTPUT + echo "repos=terrabyte-tech/canapi-website" >> $GITHUB_OUTPUT + echo "repos=terrabyte-tech/terrabyte-11ty-starter" >> $GITHUB_OUTPUT + + - name: Trigger downstream updates + run: | + repos="${{ steps.set-repos.outputs.repos }}" + for repo in $repos; do + echo "Triggering update for $repo..." + curl -X POST \ + -H "Authorization: token ${{ steps.get-token.outputs.token }}" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/repos/$repo/dispatches \ + -d '{"event_type":"template-release","client_payload":{"tag":"${{ github.ref_name }}","commit_message_suffix":"[skip ci]"}}' + done diff --git a/template/.github/workflows/update-template.yml b/template/.github/workflows/update-template.yml new file mode 100644 index 0000000..da8b2f4 --- /dev/null +++ b/template/.github/workflows/update-template.yml @@ -0,0 +1,44 @@ +name: Sync Template on Template Release + +on: + repository_dispatch: + types: [template-release] # Triggered remotely from template repo + workflow_dispatch: + +jobs: + update-template: + runs-on: ubuntu-latest + steps: + - name: Determine target branch + id: branch-check + run: | + if git ls-remote --heads origin dev | grep dev; then + echo "branch=dev" >> $GITHUB_OUTPUT + else + echo "branch=main" >> $GITHUB_OUTPUT + fi + + - name: Checkout target branch + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ steps.branch-check.outputs.branch }} + + - name: Configure Git + run: | + git config --global user.name "Terrabyte Bot" + git config --global user.email "bot@terrabyte.eco" + + - name: Pull latest template release + run: | + git subtree pull \ + --prefix=template \ + https://github.com/terrabyte-tech/terrabyte-11ty-template.git \ + ${{ github.event.client_payload.tag }} \ + --squash + + - name: Commit & Push changes + run: | + git add template + git commit -m "chore: sync template to release ${{ github.event.client_payload.tag }} ${{ github.event.client_payload.commit_message_suffix }}" || echo "No changes to commit" + git push origin ${{ steps.branch-check.outputs.branch }} diff --git a/template/.gitignore b/template/.gitignore new file mode 100644 index 0000000..5a87346 --- /dev/null +++ b/template/.gitignore @@ -0,0 +1,2 @@ +node_modules +_site \ No newline at end of file diff --git a/template/.htaccess b/template/.htaccess new file mode 100644 index 0000000..6f01167 --- /dev/null +++ b/template/.htaccess @@ -0,0 +1,25 @@ +ErrorDocument 400 /error.php +ErrorDocument 401 /error.php +ErrorDocument 403 /error.php +ErrorDocument 404 /error.php + +# Performance: Caching headers + + ExpiresActive On + ExpiresByType font/woff2 "access plus 1 year" + ExpiresByType image/webp "access plus 30 days" + ExpiresByType text/css "access plus 7 days" + ExpiresByType application/javascript "access plus 7 days" + + + + + Header set Cache-Control "public, max-age=31536000" + + + Header set Cache-Control "public, max-age=2592000" + + + Header set Cache-Control "public, max-age=604800" + + \ No newline at end of file diff --git a/template/README.md b/template/README.md new file mode 100644 index 0000000..b28c6fa --- /dev/null +++ b/template/README.md @@ -0,0 +1,155 @@ +# Terrabyte 11ty Template + +The purpose of this project is to standardize the Terrabyte website development and maintenance workflow. [11ty](https://www.11ty.dev/) is a static-site generator that makes the website build process more efficient by leveraging components, site data variables, and other web dev tools. For more information on using 11ty, please read [their documentation](https://www.11ty.dev/docs/). + +Below, you will find a set of instructions for getting started with 11ty, as well as how to best utilize this template in Terrabyte projects (downstream projects). + +**NOTE:** Creating a website with 11ty requires Node.js and npm on your machine. + +## Table of Contents + +- [Initializing a downstream project](#project-initialization) +- [Changing downstream project content](#project-content) + - [Creating a subtree](#1-create-subtree) + - [Incorporating template](#2-incorporate-template) + - [Dependencies](#3-install-dependencies) + - [Adding downstream project content](#4-adding-project-content) +- [Managing updates to template](#managing-updates) + +## Project Initialization + +DigitalOcean has a great [guide](https://www.digitalocean.com/community/tutorials/how-to-create-and-deploy-your-first-eleventy-website#step-2-choosing-a-templating-language) on building your first 11ty website. This guide will use their steps while adapting it to this template. + +### 1. Create repo & checkout + +Create a project repository in GitHub as per-norm. Initialize within GitHub by adding a README, and check it out to your local device through the GitHub CLI (or using terminal commands if you're a nerd ;). + +### 2. Initialize project + +Within the repo's root folder, run the following commands to create a new Node.js project... + +``` +npm init -y +``` + +...and install 11ty as a dependency. + +``` +npm install -D @11ty/eleventy +``` + +### 3. (Optional) package.json + +Optionally, you can add the following scripts to the newly-created `package.json` file to make development easier. Replace the existing `scripts{}` object with the following `scripts{}` object: + +``` +... + "scripts": { + "build": "eleventy", + "start": "eleventy --serve" + }, +... +``` + +After saving the `package.json` file, run the following command to build the project for the first time. + +``` +npm run build +``` + +## Project Content + +Now that the 11ty project bones are in place, it's time to implement the `terrabyte-11ty-starter` (boilerplate) and the `terrabyte-11ty-template` (this template). The two can be distinguished by thinking of the boilerplate as a launch point, and the template as shared UI/Component pieces. There may be some shared elements between the two as the file is required no matter if the template is implemented or not. + +### 1. Implement Boilerplate + +The starter repo is perfect for dropping in the files and components used to build a Terrabyte website. Fetching this content can either be done by simply copy/pasting the repo content, or by creating a subtree. For more information on this starter package, you can view the `terrabyte-11ty-starter` repo on [GitHub](https://github.com/terrabyte-tech/terrabyte-11ty-starter). + +### 2. Create Template Subtree + +By adding this template to a project folder, you are able to bring template updates into your project without disturbing your code additions later (as long as you diff right). We recommend putting the subtree in a root folder, `/template`. + +First, make sure all changes are committed to your branch. Then, create the subtree: + +``` +// define remote repo +git remote add template-remote https://github.com/terrabyte-tech/terrabyte-11ty-template.git +git fetch template-remote + +// ...then add the subtree from remote +git subtree add --prefix=template template-remote main +``` + +### 3. Incorporate Template + +If you are starting a new project, you can simply copy all of the content from the `/template` folder into the root. + +Caveats that _should not_ be copied include: + +- `.git`: This is THIS project's git history - you'll make your own in your new project. +- `.github/workflows/notify-downstream.yml`: This is automation for triggering the update process for projects that use this template. So, let's not create a blackhole by looping through automations that trigger themselves... +- `_site`: This is the web-ready content rendered by the 11ty build process. It will be rendered in your new project as well. +- `node_modules`: This is a folder containing node-specific files. These won't be committed in GitHub nor should they be copied from project to project (use npm for this). +- `package.json` and `package-lock.json`: You just changed the `package.json` file, no need to overwrite it! +- `README.md`: Your new project requires it's own README :) + +### 4. Install dependencies + +Before building the project again, you will need to install dependencies referenced in the template project. This includes: + +#### Cheerio + +Cheerio is used to create accessibility table of contents per-page (via the `.eleventy.js` file). To install the dependency, run the following command. + +``` +npm install cheerio +``` + +### 5. Adding project content + +At this point, you should be ready to build your website as you intend. This can include building components, pages, and other files. + + +#### `site.json` + +This data file should be leveraged for changing site details, information, and other metadata. For a detailed set of data that can be in this file, see [/_data/site.bak.jsonc](./_data/site.bak.jsonc). + +## Managing Updates + +### General + +Whether you are dropping in content from an old project (converting to 11ty) or starting fresh, don't forget to: + +Run the build process after making changes to `.eleventy.js` or other build files. + +``` +npm run build +``` + +And run the local server in order to preview changes as you make them to site files. + +``` +npm run start +``` + +### Updating Template + +As long as this repo is added to the template's `notify-downstream.yml` file, the template within the `/template` folder should _always_ be synced with the latest release of the template. For setup instructions, caveats, and maintenance tips, see the [workflow documentation](.github/workflows/README.md). Otherwise, you can manually update the subtree in the `/template` folder by running the following commands: + +``` +// fetch the remote +git fetch template-remote + +// pull remote into /template +git subtree pull --prefix=template template-remote main +``` + +#### Version History + +As the template changes, so does the documented version. In order to manage what version you are on and what the latest is, template version is stored in the `package.json` file here, as well as in `site.json` for projects that leverage it. To get the most out of this template, we suggest keeping an updated subtree. For more detailed information on releases, please see the Git activity. + +- v1.0.0: Initial release +- v1.1.x: Added styleType logic, fontFamily support +- v1.2.x: Added downstream automation, component utilization, implementation documentation +- v1.3.x: Added global styles, pixel styles, and Canapi styles +- v1.4.x: Split repo into Template and Starter (boilerplate) \ No newline at end of file diff --git a/template/_data/site.bak.jsonc b/template/_data/site.bak.jsonc new file mode 100644 index 0000000..58b59bd --- /dev/null +++ b/template/_data/site.bak.jsonc @@ -0,0 +1,23 @@ +{ + "templateVersion": "1.3.6", + "project": "Project Name", + "title": "Website Title", + "url": "https://www.terrabyte.eco", + "author": "Terrabyte", + "brand": "Terrabyte", + "language": "en-US", + "description": "Terrabyte is green tech company based in Omaha, NE.", + "accentColor": "#0A8C61", + "backgroundColor": "#333333", + "foregroundColor": "#ffffff", + // remove if no particular style set + "styleType": "pixel", + "schemaType": "Thing", + "schemaType": "Organization", + "fontsRel": "https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Manrope:wght@400;800&display=swap", + "fontsRel": "https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap", + // remove if no particular icons set + "iconsRel": "", + // remove if no Canapi integration + "canapiKey": "" +} \ No newline at end of file diff --git a/template/_data/site.json b/template/_data/site.json new file mode 100644 index 0000000..4a80fce --- /dev/null +++ b/template/_data/site.json @@ -0,0 +1,15 @@ +{ + "templateVersion": "1.4.0", + "project": "Project Name", + "title": "Website Title", + "url": "https://www.terrabyte.eco", + "author": "Terrabyte", + "brand": "Terrabyte", + "language": "en-US", + "description": "Terrabyte is green tech company based in Omaha, NE.", + "accentColor": "#0A8C61", + "backgroundColor": "#333333", + "foregroundColor": "#ffffff", + "schemaType": "Thing", + "fontsRel": "https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Manrope:wght@400;800&display=swap" +} \ No newline at end of file diff --git a/template/_includes/layouts/base.njk b/template/_includes/layouts/base.njk new file mode 100644 index 0000000..e64d50d --- /dev/null +++ b/template/_includes/layouts/base.njk @@ -0,0 +1,178 @@ + + + + +{% include "partials/inspector-splash.njk" %} + + + + + + + + + + {# add variable to nunjucks templates that shouldn't be indexed in frontmatter; noIndex: true #} + {% if noIndex %} + + {% endif %} + + + + + + + {{ site.title }}{% if subtitle %}: {{ subtitle }}{% endif %} + + + + + + {# if applicable/desired (default: TB green) #} + + + {# Open Graph meta tags for social media sharing #} + + {# Open Graph meta tags #} + + + + + + + {# favicons #} + + + + + + + + + + + + + + + + {% if site.iconsRel %} + + {% endif %} + + + + + + {# #} + + + + + + {% if site.styleType == "pixel" %} + + {% endif %} + + + {% if site.project == "Canapi" %} + + {% endif %} + + + + + {# other conditional styles #} + {# {% if testPage %} #} + {# #} + {# {% else %} #} + {# #} + {# {% endif %} #} + + + + + + + + + + {# #} + + + + + + + + + + + + + + {% if site.canapiKey %} + + {% endif %} + + + + + +{# ########## #} +{# dependencies #} +{# ########## #} + + {# svg container component #} + {% include "partials/svgs.njk" %} + +{# ########## #} +{# sys ui #} +{# ########## #} + + {# modals (not supported atm...) #} + {# {% include "modals.njk" %} #} + + {# accessibility/screen reader TOC #} + {# handled as .eleventy.js transform #} + + {# noscript banner component #} + {% include "partials/banners.njk" %} + +{# ########## #} +{# page begins #} +{# ########## #} + + + {% if site.project == "Pixel Planet Today" %} + {% include "partials/ppt-header.njk" %} + {% else %} + {% include "header.njk" %} + {% endif %} + +
+ {{ content | safe }} +
+ + + {% if site.styleType == "pixel" %} + {% include "partials/pixel-footer.njk" %} + {% else %} + {% include "partials/footer.njk" %} + {% endif %} + + \ No newline at end of file diff --git a/template/_includes/layouts/blank-redirect.njk b/template/_includes/layouts/blank-redirect.njk new file mode 100644 index 0000000..8d37655 --- /dev/null +++ b/template/_includes/layouts/blank-redirect.njk @@ -0,0 +1,78 @@ + + + + +{% include "partials/inspector-splash.njk" %} + + + + + + + + + + + {# redirect URL should be included in page frontmatter #} + {# rework this to include a /?rel= value from the referring URL #} + + + + + + + {{ site.title }}{% if subtitle %}: {{ subtitle }}{% endif %} + + + + + + {# if applicable/desired (default: TB green) #} + + + {# Open Graph meta tags for social media sharing #} + + {# Open Graph meta tags #} + + + + + + + {# favicons #} + + + + + + + {# ????? what is this ????? #} + + + + + + + + + + + + + + + + + + {% if site.canapiKey %} + + {% endif %} + + + + + + + \ No newline at end of file diff --git a/template/_includes/macros/banner.njk b/template/_includes/macros/banner.njk new file mode 100644 index 0000000..61a2ab6 --- /dev/null +++ b/template/_includes/macros/banner.njk @@ -0,0 +1,14 @@ +{% macro banner(content, id, dismissible=true, timeout=false, position="top", type="info") %} + +{% endmacro %} \ No newline at end of file diff --git a/template/_includes/macros/button.njk b/template/_includes/macros/button.njk new file mode 100644 index 0000000..1d77da2 --- /dev/null +++ b/template/_includes/macros/button.njk @@ -0,0 +1,13 @@ +{# not implemented, but would like to refactor sites to use this standardized button component! #} +{% macro button(text, href="#", className="primary", ariaLabel="", target="", rel="", role="button") %} + + {{ text }} + +{% endmacro %} diff --git a/template/_includes/partials/banners.njk b/template/_includes/partials/banners.njk new file mode 100644 index 0000000..c9d94e4 --- /dev/null +++ b/template/_includes/partials/banners.njk @@ -0,0 +1,26 @@ +{% from 'macros/banner.njk' import banner %} + + \ No newline at end of file diff --git a/template/_includes/partials/footer.njk b/template/_includes/partials/footer.njk new file mode 100644 index 0000000..ff03b15 --- /dev/null +++ b/template/_includes/partials/footer.njk @@ -0,0 +1,7 @@ +{# duplicate the Terrabyte footer here #} + +{# pulled from pixel footer #} +{# #} \ No newline at end of file diff --git a/template/_includes/partials/inspector-splash.njk b/template/_includes/partials/inspector-splash.njk new file mode 100644 index 0000000..361e072 --- /dev/null +++ b/template/_includes/partials/inspector-splash.njk @@ -0,0 +1,6 @@ + + + + + + diff --git a/template/_includes/partials/pixel-footer.njk b/template/_includes/partials/pixel-footer.njk new file mode 100644 index 0000000..d603ea2 --- /dev/null +++ b/template/_includes/partials/pixel-footer.njk @@ -0,0 +1,39 @@ + \ No newline at end of file diff --git a/template/_includes/partials/ppt-header.njk b/template/_includes/partials/ppt-header.njk new file mode 100644 index 0000000..e69de29 diff --git a/template/_includes/partials/svgs.njk b/template/_includes/partials/svgs.njk new file mode 100644 index 0000000..fc0f8b0 --- /dev/null +++ b/template/_includes/partials/svgs.njk @@ -0,0 +1,57 @@ + + + {# template for icons #} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/template/css/global-tb-styles.css b/template/css/global-tb-styles.css new file mode 100644 index 0000000..198b385 --- /dev/null +++ b/template/css/global-tb-styles.css @@ -0,0 +1,85 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* styles that are shared across org/between projects and sites */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +/* css variable initialization */ +:root{ + /* refactor to pull in site.json */ + --white: #ffffff; + /* --HCbackground: #ffffff; */ + --dark: #333333; + --black: #000000; + --tbgreen: #0A8C61; + --errorred: #db2a2a; + --infoblue: #1e90ff; + --warningyellow: #ffcc00; + --accent: #0A8C61; + /* --HCaccent: #096242; */ + /* iconography/branding */ + --projectLogo: url("/img/project-logo.png"); + /* fonts */ + --primary-font: Helvetica, sans-serif; + --secondary-font: monospace; + /* anims */ + --ux-speed: .35s; + --ux-hover-speed: var(--ux-speed); + --ux-active-speed: .15s; +} +/* variables for dark/light mode */ +[data-theme~="dark"]{ + --background: var(--dark); + --foreground: var(--white); +} +[data-theme~="light"]{ + --background: var(--white); + --foreground: var(--dark); +} +/* if system mode is enabled, and set to Dark */ +@media (prefers-color-scheme: dark) { + [data-theme~="system"]{ + --foreground: var(--light); + --background: var(--dark); + } +} +/* variables for high contrast */ +[data-theme~="dark"][data-theme~="hc"]{ + --background: var(--black); + --foreground: var(--white); +} +[data-theme~="light"][data-theme~="hc"]{ + --background: var(--white); + --foreground: var(--black); +} +/* ------------- */ + +/* implementing shared variables (body) */ +body{ + background-color: var(--background); + color: var(--foreground); + font-family: var(--secondary-font); + min-height:100vh; +} +h1, h2, h3, h4, h5, h6, button, .button, input[type='submit']{ + font-family: var(--primary-font); +} +.project-logo{ + /* DEPRECATE, use image elem! */ + background-image:var(--projectLogo); +} +hr{ + border:none; + border-top:2px solid var(--accent); +} +/* ------------- */ + +/* implementing shared variables (user interface) */ +*::selection{ + color:var(--background); + background-color:var(--foreground); +} +*::-moz-selection{ + color:var(--background); + background-color:var(--foreground); +} + +/* +++++++++++++++++++++++++++++++++++++++++++ */ \ No newline at end of file diff --git a/template/css/global-tb-ui-styles.css b/template/css/global-tb-ui-styles.css new file mode 100644 index 0000000..1bbc3f7 --- /dev/null +++ b/template/css/global-tb-ui-styles.css @@ -0,0 +1,201 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* global Terrabyte UI styles */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +/* inputs */ +input{ + font-family: inherit; + font-size:inherit; + color:inherit; + background-color:transparent; + border:none; + outline:none; +} +/* ------------- */ + +/* links */ +a{ + color:currentColor; + text-decoration:none; + cursor:pointer; + user-select: none; + transform:scale(1); + opacity:1; + display:inline-block; +} +a.text-link{} +/* hover state */ +@media (hover: hover) and (pointer: fine) { + a:hover{ + transform:scale(1.05); + } +} +/* active state */ +a:active{ + transition:var(--ux-active-speed); + transform:scale(0.95); + opacity:.6; +} +/* ------------- */ + +/* buttons */ +/* primary buttons */ +button, +.button, +input[type='submit']{ + display:inline-block; + color:var(--white); + border:2px solid var(--accent); + border-radius:2px; + background-color:var(--accent); + padding:10px; + cursor:pointer; + transition:var(--ux-speed); + user-select: none; + line-height:20px; + font-size:14px; + transform:scale(1); + opacity:1; +} +/* secondary button */ +button.secondary, +.button.secondary, +input[type='submit'].secondary{ + color:var(--background); + border:2px solid var(--foreground); + background-color: var(--foreground); +} +/* tertiary/shadow button */ +button.shadow, +.button.shadow, +input[type='submit'].shadow{ + color:inherit; + border:2px solid currentColor; + background-color:transparent; +} +/* hover state */ +@media (hover: hover) and (pointer: fine) { + button:hover, + .button:hover, + input[type='submit']:hover{ + transform:scale(1.05); + } +} +/* active state */ +button:active, +.button:active, +input[type='submit']:active{ + transition:var(--ux-active-speed); + transform:scale(0.95); +} +/* ------------- */ + +/* banners */ +.banner{ + position: fixed; + left: 0; + z-index: 900; + width: 100%; + padding: 15px 20px; + font-size: 12px; + color:white; + background-color:var(--tbgreen); +} +.banner.top{ + top: 0; +} +.banner.info{ + background-color: var(--infoblue); +} +.banner.warning{ + background-color: var(--warningyellow); + color:dark; +} +.banner.error{ + background-color: var(--errorred); +} +/* ------------- */ + +/* accessibility table of contents */ +.sr-only.sr-toc{ + background-color:var(--background); + border: 1px solid var(--foreground); + display:block; + position:fixed; + left:-200px; + top:0px; + width:1px; + height:1px; + overflow:hidden; + transition:width .5s, left .5s; + z-index:1000; + font-size:25px; + padding:0px; + font-family:inherit; +} +.sr-only.sr-toc:focus-within{ + left:0; + width:100%; + max-width:500px; + height:auto; + padding:20px; + clip:unset; +} +.sr-toc h2{ + margin-bottom:20px; +} +.sr-toc ul{ + list-style-type:none; + padding:0px; + margin:0px; +} +.sr-toc a.text-link{ + color:inherit; + display:block; + margin-bottom:10px; + text-transform:capitalize; +} +/* ------------- */ + +/* loading elements */ +.loading-container{ + position:relative; +} +.loading-overlay{ + background-color: #333333dd; + backdrop-filter: blur(5px); + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + opacity:1; + transition:opacity 1s; +} +.loading-spinner{ + width:30px; + height:30px; + margin-bottom:15px; + position:relative; +} +.loading-spinner:before{ + content:""; + width:100%; + height:100%; + position:absolute; + border:2px solid currentColor; + border-right-color:transparent; + border-radius:50%; + animation:spinning ease-in-out 1s infinite; + transform:rotate(10deg); +} +@keyframes spinning { + from{ + transform:rotate(10deg); + } + to{ + transform:rotate(360deg); + } +} + +/* +++++++++++++++++++++++++++++++++++++++++++ */ \ No newline at end of file diff --git a/template/css/shared-canapi-styles.css b/template/css/shared-canapi-styles.css new file mode 100644 index 0000000..6b87c4f --- /dev/null +++ b/template/css/shared-canapi-styles.css @@ -0,0 +1,272 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* Canapi styles that should be shared across project websites. */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +*{ + font-size:inherit; + outline:none; + -webkit-tap-highlight-color:transparent; + -webkit-touch-callout:none; +} + + +/* +++++++++++++++++++++++++++++++++++++++++++ */ + + +/* css variables */ +:root{ + /* default avatar (before load) */ + --avatarPath: linear-gradient(135deg, var(--accent), var(--accent)); + /* --light: #ffffff; */ + /* replace with --white */ + --dark: #333841; + --dark-trans: #33384150; + --dark-light-trans: #33384118; + --grey: #e3e3e3; + --grey-light-trans:#e3e3e318; + --accent:#46af71; + --accent-lime:#80ce4d; + --accent-green-semi-dark-trans:#46af7185; + --accent-green-dark-trans:#46af7178; + /* --accent-lime-dark-trans:#80ce4d78; */ + --accent-green-trans:#46af7150; + /* --accent-lime-trans:#80ce4d60; */ + --accent-green-light-trans:#46af7118; + /* --accent-lime-light-trans:#80ce4d60; */ + + /* shared theme management */ + --shadow:0px 8px 17px -8px rgb(0 0 0 / 10%); + + /* error colors */ + /* --error-red:#e04141; */ + /* replace with... */ + --errorred:#e04141; + /* --error-red-light-trans:#e0414120; */ + /* replace with... */ + --errorred-light-trans:#e0414120; + /* fonts */ + --primary-font: 'Manrope', sans-serif; + --secondary-font: 'Manrope', sans-serif; +} +/* dark mode */ +body.dark, +[data-theme~="dark"]{ + background-color:#30353d; + /* --foreground: var(--light); */ + /* --background: var(--dark); */ + --shadow:0px 8px 17px -8px rgb(0 0 0 / 20%); +} + + +/* +++++++++++++++++++++++++++++++++++++++++++ */ + + +/* html elements */ +body{ + /* put gradient on main page content? */ + /* background:linear-gradient(135deg, #C1F0A3,#A0E1BA); */ + /* background-color:var(--background); */ + /* color:var(--foreground); */ + font-size:14px; + /* min-height:100vh; */ + /* overflow:hidden; */ + /* height:100vh; */ + /* height: calc(var(--vh, 1vh) * 100); */ +} + +/* style scrollbars */ +body::-webkit-scrollbar-track{ + background-color:transparent; + transition:.15s; +} +*::-webkit-scrollbar{ + width: 10px; + height: 10px; + background-color:transparent; + transition:.15s; +} +*::-webkit-scrollbar-thumb{ + background-color:var(--accent); + border-radius:10px; + transition:.15s; +} +/* .page-container{} */ + +a{ + color:var(--accent); + font-weight:bold; + position: relative; + z-index:1; + transition:.25s; + /* transition: transform .25s, color .25s, background-color .25s, opacity .25s; */ +} +a:hover{ + color:var(--accent-green-semi-dark-trans); +} +a.icon-link{ + font-size:1.2em; +} + +.button-container > *{ + margin-right:12px; +} +.button-container > *:last-child{ + margin-right:0; +} +button, +.button{ + border:1px solid var(--accent-green-light-trans); + border-radius:4px; + /* background-color:var(--background); */ + background-color:transparent; + /* padding:8px 10px;?????????? */ + color:var(--foreground); + position: relative; + transition:.25s; + /* transition: transform .25s, color .25s, background-color .25s, opacity .25s, border .25s; */ + font-weight:inherit; +} +button:hover, +.button:hover, +button:focus, +.button:focus{ + /* background-color:#CDF3DC; */ + border-color: var(--accent-green-trans); + /* color: var(--accent-green-semi-dark-trans); */ + background-color:var(--accent-green-light-trans); +} +button:active, +.button:active{ + /* background-color:#A2E1BB; */ + background-color:var(--accent-green-trans); + transform:scale(.95); +} +/* primary buttons */ +button.primary, +.button.primary{ + background-color:var(--accent); + color:var(--white); +} +button.primary:hover, +.button.primary:hover, +button.primary:focus, +.button.primary:focus{ + /* color:var(--grey); */ + background-color:var(--accent-green-semi-dark-trans); +} +button.primary:active, +.button.primary:active{ + color:var(--white); + background-color:var(--accent); +} +p{ + margin-bottom:10px; +} +p:last-child{ + margin-bottom:0; +} +.section-header{ + margin-bottom:20px; +} +h1, h2, h3, h4, h5, h6{ + font-weight:bold; + line-height:1em; + letter-spacing: -1px; +} +h1{ + font-size:3em; +} +h2{ + font-size:2.2em; +} +h3{ + font-size:1.6em; +} +h4{ + font-size:1.1em; +} +h6{ + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0; +} +table{ + width:100%; +} +th{ + text-align:left; + margin-bottom:10px; +} +td{ + text-align:left; +} + + +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* custom selectors, shared elements */ +.max-width{ + max-width:1000px; + margin:0 auto; +} + +/* page layouts */ +.page-container{ + position:relative; + overflow:hidden; + /* overflow-x:hidden; */ + z-index:1; +} + +/* page pieces */ +/* tooltips */ +[data-tooltip]{ + position:relative; + cursor: pointer; + z-index:1; + /* white-space:nowrap; */ + /* min-width:0; */ +} +[data-tooltip]:after, +.tooltip{ + /* container */ + z-index:100; + pointer-events:none; + background-color:var(--background); + border-radius: 4px; + white-space: nowrap; + min-width:0; + /* width:300px; */ + /* max-width:300px; */ + border:1px solid var(--grey); + color:var(--foreground); + padding:12px 15px; + box-shadow:var(--shadow); + position:absolute; + left:0; + /* transition */ + transition:.35s; + opacity:0; + top:70%; + /* content */ + content:attr(data-tooltip); + text-transform: none; + font-size:14px; + font-weight:normal; + letter-spacing: normal; + text-align:left; +} +[data-tooltip]:hover:after, +[data-tooltip]:hover .tooltip{ + opacity:1; + top:150%; +} +.large[data-tooltip]:after{ + min-width:auto; + width:300px; + white-space: initial; +} +[data-tooltip-force-right]:after, +[data-tooltip-force-right] .tooltip{ + left:unset; + right:0; +} \ No newline at end of file diff --git a/template/css/shared-pixel-styles.css b/template/css/shared-pixel-styles.css new file mode 100644 index 0000000..86954c0 --- /dev/null +++ b/template/css/shared-pixel-styles.css @@ -0,0 +1,490 @@ +/* +++++++++++++++++++++++++++++++++++++++++++ */ +/* pixel art styles that should be shared across pixel-themed websites. */ +/* +++++++++++++++++++++++++++++++++++++++++++ */ + +/* overwrite high-level variables */ +:root{ + /* fonts */ + --primary-font: 'Press Start 2P', sans-serif; + --secondary-font: 'VT323', monospace; + --ux-speed:0s; + + /* new black */ + --black: #222222; +} +/* ------------- */ + +/* overwrite high-level styles */ +*{ + image-rendering: pixelated; +} +body{ + font-size:22px; + line-height:1.3em; + letter-spacing:1px; + transition:opacity 1s; + width:100vw; + overflow-x:hidden; + /* cursor: url("../img/ui/arrow-pointer-cursor.png"), default; */ + cursor: url("/img/pixel-assets/ui/mini-default-cursor.png"), default; +} +/* to hide images that overflow from 100vw */ +.scroll-manager{ + width:100vw; + overflow-x:hidden; +} +/* ------------- */ + + + +/* FOR SHARED? MORE GLOBAL?? */ +/* could replace this mechanic with a .show-at-700 or .hide-at-800 or even .show-500-1000 */ +/* STRUCTURE */ +/* adaptive views */ +.show-for-desktop, +.show-for-tablet, +.show-for-mobile{ + display:none; +} +/* desktop */ +@media only screen and (min-width:1220px){ + .show-for-desktop{ + display:block; + } + .show-for-desktop.flex-container{ + display:flex; + } +} +/*tablet*/ +@media only screen and (min-width:615px) and (max-width:1220px){ + .show-for-tablet{ + display:block; + } + .show-for-tablet.flex-container{ + display:flex; + } +} +/*mobile*/ +@media only screen and (max-width:615px){ + .show-for-mobile{ + display:block; + } + .show-for-mobile.flex-container{ + display:flex; + } +} +/* ------------- */ + +/* SHARED TOO??? */ +section{ + position:relative; + min-height:100vh; + /* overflow:hidden; */ +} +.section-content{ + max-width:1200px; + margin:0 auto; + padding:50px; +} +@media only screen and (max-width:615px){ + .section-content{ + padding:40px; + } +} +@media only screen and (max-height:500px){ + section{ + min-height:800px; + } +} +/* ------------- */ + + +/* ELEMENTS */ +/* header/nav */ +/* unique to PPT... */ +/* ------------- */ + + +/* TYPOGRAPHY */ +/*section large headers*/ +h1, h2, h3{ + text-transform:uppercase; +} +h1{ + font-size:30px; + margin-bottom:50px; + line-height:1.5em; + letter-spacing:2px; +} +/*hero question, how to support the project*/ +h2{ + font-size:18px; + margin-bottom:20px; + letter-spacing:1px; +} +/*hero options*/ +h3{ + font-size:14px; + line-height:1em; + letter-spacing:1px; +} +/* paragraph */ +p{ + margin-bottom:20px; +} +p:last-child{ + margin-bottom:0; +} +/* images */ +img{ + user-select: none; +} +/* links */ +a{ + /* cursor: url("../img/ui/finger-pointer-cursor.png"), pointer; */ + cursor: url("/img/pixel-assets/ui/mini-pointer-cursor.png"), pointer; +} +a.text-link{ + position:relative; + display:inline-block; + transition:.25s; +} +a.text-link:after{ + content:""; + opacity:1; + position:absolute; + left:0; + top:calc(100% - 2px); + width:100%; + height:3px; + background-color:currentColor; + pointer-events: none; +} +a.text-link:hover:after{ + animation:hoverLink .55s; +} +@keyframes hoverLink{ + /* fade out */ + 0%, 24%{ + width:0px; + } + 25%, 29%{ + width:10%; + } + 30%, 54%{ + width:15%; + } + 55%, 79%{ + width:60%; + } + 80%, 100%{ + width:100%; + } +} +@media only screen and (max-width:615px){ + h1{ + font-size:25px; + margin-bottom:30px; + } +} + +.button-container{ + position: relative; +} +button, +.button, +input[type="submit"]{ + text-transform:uppercase; + color:inherit; + background-color:transparent; + border:3px solid currentColor; + padding:10px; + font-size:15px; + /* cursor: url("../img/ui/finger-pointer-cursor.png"), pointer; */ + cursor: url("/img/pixel-assets/ui/mini-pointer-cursor.png"), pointer; +} + +button:hover, +.button:hover, +input[type="submit"]:hover, +button.selected, +.button.selected{ + background-color:rgba(255,255,255,.5); +} +button:active, +.button:active, +input[type="submit"]:active{ + background-color:var(--foreground); + color:#e3e3e3; +} +button.primary, +.button.primary{ + background-color:rgba(0,0,0,.35); +} +button.primary:hover, +.button.primary:hover{ + background-color:rgba(0,0,0,.55); +} +button.primary:active, +.button.primary:active{ + background-color:rgba(0,0,0,.15); +} + + +/* pixel icons */ +.pixel-social-icon{ + background-image:url("/img/pixel-assets/icons/social-spritesheet.png"); + /* same as generic link */ + background-position:-198px -158px; + background-size: 600%; + background-repeat: no-repeat; + width:40px; + height:40px; + display:inline-block; + vertical-align:middle; + margin:0 3px; +} +/* icons from spritesheet */ +#instagram-icon, +.instagram-icon{ + background-position:-2px 0px; +} +#facebook-icon, +.facebook-icon{ + background-position:-198px 0px; +} +#wdht-icon, +.wdht-icon{ + background-position:-41px -79px; +} + +#twitter-icon, +.twitter-icon{ + background-position:-41px -158px; +} +#tiktok-icon, +.tiktok-icon{ + background-position:-2px -158px; +} +#etsy-icon, +.etsy-icon{ + background-position:-2px -237px; +} + +#giphy-icon, +.giphy-icon{ + background-position:-2px -79px; +} +#tumblr-icon, +.tumblr-icon{ + background-position:-159px 0px; +} +#shop-icon, +.shop-icon{ + background-position:-80px 0px; +} +#website-icon, +.website-icon{ + background-position:-119px -79px; +} +#newsletter-icon, +.newsletter-icon{ + background-position:-159px -79px; +} +#survey-icon, +.survey-icon{ + background-position:-198px -79px; +} +#blog-icon, +.blog-icon{ + background-position:-80px -79px; +} +#terrabyte-icon, +.terrabyte-icon{ + background-position:-119px -158px; +} +#pinekeepers-icon, +.pinekeepers-icon{ + background-position:-159px -158px; +} + +/* icon hover states */ +#instagram-icon:hover, +.instagram-icon:hover{ + background-position:-2px -42px; +} +#facebook-icon:hover, +.facebook-icon:hover{ + background-position:-198px -42px; +} +#wdht-icon:hover, +.wdht-icon:hover{ + background-position:-41px -121px; +} +#twitter-icon:hover, +.twitter-icon:hover{ + background-position:-41px -200px; +} +#tiktok-icon:hover, +.tiktok-icon:hover{ + background-position:-2px -200px; +} +#etsy-icon:hover, +.etsy-icon:hover{ + background-position:-2px -279px; +} + +#giphy-icon:hover, +.giphy-icon:hover{ + background-position:-2px -121px; +} +#tumblr-icon:hover, +.tumblr-icon:hover{ + background-position:-159px -42px; +} +#shop-icon:hover, +.shop-icon:hover{ + background-position:-80px -42px; +} +#blog-icon:hover, +.blog-icon:hover{ + background-position:-80px -121px; +} + + +/* footer */ +footer{ + background-color:var(--black); + font-size:18px; +} +footer a.text-link:after{ + height:2px; +} +footer section{ + height:auto; + min-height:auto; +} +footer .section-content{ + max-width:1200px; + padding:40px 50px; +} + +/*eco footer*/ +#cookie-disclaimer{ + background-color:#388841cc; + color:var(--white); +} + +/* footer logos */ +.footer-logos-container{ + /* margin-bottom:20px; */ +} +.footer-logos-container > *{ + margin-right:20px; + margin-bottom:0; +} + +.footer-logo{ + height:35px; +} +/* custom sizing for odd-sized logos */ +.footer-logo.ppt-logo{ + background-image:url('/img/pixel-assets/pixel-planet-today-white-lettering.png'); + width:150px; +} +.footer-logo.tb-logo{ + background-image:url('/img/pixel-assets/terrabyte-white-pixel-logo.png'); + width:200px; +} + + +/* company links/additional links */ +.company-links-container{ + margin:50px 0 30px 0; +} + +#footer-copyright-container{ + margin-right:30px; +} + +/* website carbon */ +#wcb{ + font-size:22px!important; + color:var(--white)!important; + font-weight:normal!important; +} +#wcb #wcb_2, #wcb #wcb_a, #wcb #wcb_g{ + font-family:inherit!important; +} +#wcb #wcb_g{ + border-radius:0!important; + background-color:transparent!important; + border-color:var(--foreground)!important; +} +#wcb #wcb_a{ + font-weight:normal!important; + color:var(--background)!important; + background-color:var(--foreground)!important; + border-color:var(--foreground)!important; + border-radius:0!important; +} +/* */ + +/* responsive styles */ +@media only screen and (max-width:800px){ + #logos-social-footer{ + flex-wrap:wrap; + } + #footer-social-container{ + justify-content:flex-start; + margin-top:20px; + } + + #copyright-social-footer{ + flex-wrap:wrap; + } + #footer-copyright-container{ + margin-top:30px; + order:2; + } +} + +/* mobile */ +@media only screen and (max-width:615px){ + footer .section-content{ + padding: 40px; + } + + .footer-logo{ + height:35px; + } + .footer-logo.ppt-logo{ + width:108px; + } + .footer-logo.tb-logo{ + width:175px; + } + #wcb{ + font-size:inherit!important; + } +} +/* extra small custom mobile */ +@media only screen and (max-width:400px){ + #copyright-social-footer{ + padding:0; + } + #footer-copyright-container{ + /* padding:40px 40px 0 40px; */ + margin-right:0; + } + #footer-social-container{ + justify-content:center; + padding-bottom:40px; + } + .footer-logos-container > *{ + display:none; + } + .footer-logos-container > .footer-logo.ppt-logo{ + display:block; + } +} \ No newline at end of file diff --git a/template/error.php.njk b/template/error.php.njk new file mode 100644 index 0000000..b341c85 --- /dev/null +++ b/template/error.php.njk @@ -0,0 +1,50 @@ +--- +permalink: error.php +eleventyExcludeFromCollections: true +--- + + + +
+
+
+
+

That's an Error ()

+
+
+

Looks like we found a bad byte and some dead pixels. Check the URL above and try again.

+ +

You can also head to the homepage () to try to find what you were looking for there.

+

Or, head to the Terrabyte website to start your digital eco-journey over from the top.

+
+
+
+
\ No newline at end of file diff --git a/template/img/pixel-assets/icons/plastic-icon-almost-black.png b/template/img/pixel-assets/icons/plastic-icon-almost-black.png new file mode 100644 index 0000000..e3e62a8 Binary files /dev/null and b/template/img/pixel-assets/icons/plastic-icon-almost-black.png differ diff --git a/template/img/pixel-assets/icons/recycling-square-icon-almost-black.png b/template/img/pixel-assets/icons/recycling-square-icon-almost-black.png new file mode 100644 index 0000000..60ca389 Binary files /dev/null and b/template/img/pixel-assets/icons/recycling-square-icon-almost-black.png differ diff --git a/template/img/pixel-assets/icons/social-spritesheet.png b/template/img/pixel-assets/icons/social-spritesheet.png new file mode 100644 index 0000000..a63a519 Binary files /dev/null and b/template/img/pixel-assets/icons/social-spritesheet.png differ diff --git a/template/img/pixel-assets/icons/tree-icon-almost-black.png b/template/img/pixel-assets/icons/tree-icon-almost-black.png new file mode 100644 index 0000000..00dafe8 Binary files /dev/null and b/template/img/pixel-assets/icons/tree-icon-almost-black.png differ diff --git a/template/img/pixel-assets/pixel-planet-today-white-lettering.png b/template/img/pixel-assets/pixel-planet-today-white-lettering.png new file mode 100644 index 0000000..2d6eb45 Binary files /dev/null and b/template/img/pixel-assets/pixel-planet-today-white-lettering.png differ diff --git a/template/img/pixel-assets/terrabyte-white-pixel-logo.png b/template/img/pixel-assets/terrabyte-white-pixel-logo.png new file mode 100644 index 0000000..8c9dda0 Binary files /dev/null and b/template/img/pixel-assets/terrabyte-white-pixel-logo.png differ diff --git a/template/img/pixel-assets/ui/arrow-pointer-cursor.png b/template/img/pixel-assets/ui/arrow-pointer-cursor.png new file mode 100644 index 0000000..87f6a1f Binary files /dev/null and b/template/img/pixel-assets/ui/arrow-pointer-cursor.png differ diff --git a/template/img/pixel-assets/ui/cart-icon-white.png b/template/img/pixel-assets/ui/cart-icon-white.png new file mode 100644 index 0000000..b98f4ee Binary files /dev/null and b/template/img/pixel-assets/ui/cart-icon-white.png differ diff --git a/template/img/pixel-assets/ui/close-x-icon.png b/template/img/pixel-assets/ui/close-x-icon.png new file mode 100644 index 0000000..ec30386 Binary files /dev/null and b/template/img/pixel-assets/ui/close-x-icon.png differ diff --git a/template/img/pixel-assets/ui/finger-pointer-cursor.png b/template/img/pixel-assets/ui/finger-pointer-cursor.png new file mode 100644 index 0000000..70262d1 Binary files /dev/null and b/template/img/pixel-assets/ui/finger-pointer-cursor.png differ diff --git a/template/img/pixel-assets/ui/hamburger-menu-icon.png b/template/img/pixel-assets/ui/hamburger-menu-icon.png new file mode 100644 index 0000000..040cbbb Binary files /dev/null and b/template/img/pixel-assets/ui/hamburger-menu-icon.png differ diff --git a/template/img/pixel-assets/ui/left-arrow-anim.gif b/template/img/pixel-assets/ui/left-arrow-anim.gif new file mode 100644 index 0000000..c0baf70 Binary files /dev/null and b/template/img/pixel-assets/ui/left-arrow-anim.gif differ diff --git a/template/img/pixel-assets/ui/left-arrow-icon-almost-black.png b/template/img/pixel-assets/ui/left-arrow-icon-almost-black.png new file mode 100644 index 0000000..4e06313 Binary files /dev/null and b/template/img/pixel-assets/ui/left-arrow-icon-almost-black.png differ diff --git a/template/img/pixel-assets/ui/left-arrow-icon-white.png b/template/img/pixel-assets/ui/left-arrow-icon-white.png new file mode 100644 index 0000000..7b86ddc Binary files /dev/null and b/template/img/pixel-assets/ui/left-arrow-icon-white.png differ diff --git a/template/img/pixel-assets/ui/left-arrow-icon.png b/template/img/pixel-assets/ui/left-arrow-icon.png new file mode 100644 index 0000000..86c6e6a Binary files /dev/null and b/template/img/pixel-assets/ui/left-arrow-icon.png differ diff --git a/template/img/pixel-assets/ui/mini-default-cursor.png b/template/img/pixel-assets/ui/mini-default-cursor.png new file mode 100644 index 0000000..8f1ee89 Binary files /dev/null and b/template/img/pixel-assets/ui/mini-default-cursor.png differ diff --git a/template/img/pixel-assets/ui/mini-pointer-cursor.png b/template/img/pixel-assets/ui/mini-pointer-cursor.png new file mode 100644 index 0000000..753fe64 Binary files /dev/null and b/template/img/pixel-assets/ui/mini-pointer-cursor.png differ diff --git a/template/img/pixel-assets/ui/mini-text-cursor.png b/template/img/pixel-assets/ui/mini-text-cursor.png new file mode 100644 index 0000000..131db75 Binary files /dev/null and b/template/img/pixel-assets/ui/mini-text-cursor.png differ diff --git a/template/img/pixel-assets/ui/right-arrow-anim.gif b/template/img/pixel-assets/ui/right-arrow-anim.gif new file mode 100644 index 0000000..52d9a0d Binary files /dev/null and b/template/img/pixel-assets/ui/right-arrow-anim.gif differ diff --git a/template/img/pixel-assets/ui/right-arrow-icon-almost-black.png b/template/img/pixel-assets/ui/right-arrow-icon-almost-black.png new file mode 100644 index 0000000..c1f533d Binary files /dev/null and b/template/img/pixel-assets/ui/right-arrow-icon-almost-black.png differ diff --git a/template/img/pixel-assets/ui/right-arrow-icon-white.png b/template/img/pixel-assets/ui/right-arrow-icon-white.png new file mode 100644 index 0000000..a458e69 Binary files /dev/null and b/template/img/pixel-assets/ui/right-arrow-icon-white.png differ diff --git a/template/img/pixel-assets/ui/right-arrow-icon.png b/template/img/pixel-assets/ui/right-arrow-icon.png new file mode 100644 index 0000000..ecea177 Binary files /dev/null and b/template/img/pixel-assets/ui/right-arrow-icon.png differ diff --git a/template/img/pixel-assets/ui/search-magnifying-glass-icon-almost-black.png b/template/img/pixel-assets/ui/search-magnifying-glass-icon-almost-black.png new file mode 100644 index 0000000..4416820 Binary files /dev/null and b/template/img/pixel-assets/ui/search-magnifying-glass-icon-almost-black.png differ diff --git a/template/img/pixel-assets/ui/search-magnifying-glass-icon-white.png b/template/img/pixel-assets/ui/search-magnifying-glass-icon-white.png new file mode 100644 index 0000000..741ffbe Binary files /dev/null and b/template/img/pixel-assets/ui/search-magnifying-glass-icon-white.png differ diff --git a/template/img/pixel-assets/ui/simple-close-x-icon.png b/template/img/pixel-assets/ui/simple-close-x-icon.png new file mode 100644 index 0000000..75e80d4 Binary files /dev/null and b/template/img/pixel-assets/ui/simple-close-x-icon.png differ diff --git a/template/js/global-tb-scripts.js b/template/js/global-tb-scripts.js new file mode 100644 index 0000000..ceb8c71 --- /dev/null +++ b/template/js/global-tb-scripts.js @@ -0,0 +1,26 @@ +window.addEventListener("load", function(){ + + console.log(`[${window.siteData.project}] global-tb-scripts.js loaded`); + + // could revisit this and create within 11ty?? + + // change copyright date + var currentDate = new Date(); + var currentYear = currentDate.getFullYear(); + + var copyrightSpan = document.getElementById("current-year-text"); + // for older implementations + var oldCopyrightSpan = document.getElementsByClassName("copyright-date")[0]; + + if(copyrightSpan){ + copyrightSpan.appendChild(document.createTextNode(currentYear)); + } + // for older implementations + else if(oldCopyrightSpan){ + oldCopyrightSpan.appendChild(document.createTextNode(currentYear)); + } + else{ + // element doesn't exist + } + +}, false); \ No newline at end of file diff --git a/template/package-lock.json b/template/package-lock.json new file mode 100644 index 0000000..9f6186a --- /dev/null +++ b/template/package-lock.json @@ -0,0 +1,2083 @@ +{ + "name": "terrabyte-11ty-template", + "version": "1.4.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "terrabyte-11ty-template", + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "cheerio": "^1.1.0" + }, + "devDependencies": { + "@11ty/eleventy": "^3.1.1" + } + }, + "node_modules/@11ty/dependency-tree": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.0.tgz", + "integrity": "sha512-PTOnwM8Xt+GdJmwRKg4pZ8EKAgGoK7pedZBfNSOChXu8MYk2FdEsxdJYecX4t62owpGw3xK60q9TQv/5JI59jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1" + } + }, + "node_modules/@11ty/dependency-tree-esm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree-esm/-/dependency-tree-esm-2.0.0.tgz", + "integrity": "sha512-+4ySOON4aEAiyAGuH6XQJtxpGSpo6nibfG01krgix00sqjhman2+UaDUopq6Ksv8/jBB3hqkhsHe3fDE4z8rbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1", + "acorn": "^8.14.0", + "dependency-graph": "^1.0.0", + "normalize-path": "^3.0.0" + } + }, + "node_modules/@11ty/eleventy": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.1.1.tgz", + "integrity": "sha512-nsMCW44WSYzpi6JSQ1ar/wlotj/2cxuP4AABX5Dxqwol3IQ3SkEMgcAugP1t1mthv5I0kIB9lql1Jv/lhUHIkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/dependency-tree": "^4.0.0", + "@11ty/dependency-tree-esm": "^2.0.0", + "@11ty/eleventy-dev-server": "^2.0.8", + "@11ty/eleventy-plugin-bundle": "^3.0.6", + "@11ty/eleventy-utils": "^2.0.7", + "@11ty/lodash-custom": "^4.17.21", + "@11ty/posthtml-urls": "^1.0.1", + "@11ty/recursive-copy": "^4.0.1", + "@sindresorhus/slugify": "^2.2.1", + "bcp-47-normalize": "^2.3.0", + "chokidar": "^3.6.0", + "debug": "^4.4.1", + "dependency-graph": "^1.0.0", + "entities": "^6.0.0", + "filesize": "^10.1.6", + "gray-matter": "^4.0.3", + "iso-639-1": "^3.1.5", + "js-yaml": "^4.1.0", + "kleur": "^4.1.5", + "liquidjs": "^10.21.1", + "luxon": "^3.6.1", + "markdown-it": "^14.1.0", + "minimist": "^1.2.8", + "moo": "^0.5.2", + "node-retrieve-globals": "^6.0.1", + "nunjucks": "^3.2.4", + "picomatch": "^4.0.2", + "please-upgrade-node": "^3.2.0", + "posthtml": "^0.16.6", + "posthtml-match-helper": "^2.0.3", + "semver": "^7.7.2", + "slugify": "^1.6.6", + "tinyglobby": "^0.2.14" + }, + "bin": { + "eleventy": "cmd.cjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-dev-server": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-2.0.8.tgz", + "integrity": "sha512-15oC5M1DQlCaOMUq4limKRYmWiGecDaGwryr7fTE/oM9Ix8siqMvWi+I8VjsfrGr+iViDvWcH/TVI6D12d93mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1", + "chokidar": "^3.6.0", + "debug": "^4.4.0", + "finalhandler": "^1.3.1", + "mime": "^3.0.0", + "minimist": "^1.2.8", + "morphdom": "^2.7.4", + "please-upgrade-node": "^3.2.0", + "send": "^1.1.0", + "ssri": "^11.0.0", + "urlpattern-polyfill": "^10.0.0", + "ws": "^8.18.1" + }, + "bin": { + "eleventy-dev-server": "cmd.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-plugin-bundle": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.6.tgz", + "integrity": "sha512-wlEIMa1SEe6HE6ZyREEnPQiTw72337a2MPkyn0D1IzrqHrKU9euB17mv27LnnnyKvMJamCCqtU0985F5yyDL8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.2", + "debug": "^4.4.0", + "posthtml-match-helper": "^2.0.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-utils": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-2.0.7.tgz", + "integrity": "sha512-6QE+duqSQ0GY9rENXYb4iPR4AYGdrFpqnmi59tFp9VrleOl0QSh8VlBr2yd6dlhkdtj7904poZW5PvGr9cMiJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/lodash-custom": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@11ty/lodash-custom/-/lodash-custom-4.17.21.tgz", + "integrity": "sha512-Mqt6im1xpb1Ykn3nbcCovWXK3ggywRJa+IXIdoz4wIIK+cvozADH63lexcuPpGS/gJ6/m2JxyyXDyupkMr5DHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/posthtml-urls": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@11ty/posthtml-urls/-/posthtml-urls-1.0.1.tgz", + "integrity": "sha512-6EFN/yYSxC/OzYXpq4gXDyDMlX/W+2MgCvvoxf11X1z76bqkqFJ8eep5RiBWfGT5j0323a1pwpelcJJdR46MCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "evaluate-value": "^2.0.0", + "http-equiv-refresh": "^2.0.1", + "list-to-array": "^1.1.0", + "parse-srcset": "^1.0.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@11ty/recursive-copy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.1.tgz", + "integrity": "sha512-Zsg1xgfdVTMKNPj9o4FZeYa73dFZRX856CL4LsmqPMvDr0TuIK4cH9CVWJyf0OkNmM8GmlibGX18fF0B75Rn1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "errno": "^1.0.0", + "junk": "^3.1.0", + "maximatch": "^0.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sindresorhus/slugify": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", + "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/transliterate": "^1.0.0", + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sindresorhus/transliterate": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", + "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-normalize": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz", + "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bcp-47": "^2.0.0", + "bcp-47-match": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cheerio": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.0.tgz", + "integrity": "sha512-+0hMx9eYhJvWbgpKV9hN7jg0JcwydpopZE4hgi+KvQtByZXPp04NiCWU0LzcAbP63abZckIHkTQaXVF52mX3xQ==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.10.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/css-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/css-select/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/css-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz", + "integrity": "sha512-3zV5mFS1E8/1bPxt/B0xxzI1snsg3uSCIh6Zo1qKg6iMw93hzPANk9oBFzSFBFrwuVoQuE3rLoouAUfwOAj1wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm-import-transformer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.3.tgz", + "integrity": "sha512-Wj9kBIA9vKZRYAQzhe229M7wmWb2f3vTu86CkszZUy2/iiVCYljXm/EkwJtWKc0vup30WHhxbm3rpkysBKczxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.2" + } + }, + "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, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/evaluate-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/evaluate-value/-/evaluate-value-2.0.0.tgz", + "integrity": "sha512-VonfiuDJc0z4sOO7W0Pd130VLsXN6vmBWZlrog1mCb/o7o/Nl5Lr25+Kj/nkCCAhG+zqeeGjxhkK9oHpkgTHhQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/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, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-equiv-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-2.0.1.tgz", + "integrity": "sha512-XJpDL/MLkV3dKwLzHwr2dY05dYNfBNlyPu4STQ8WvKCFdc6vC5tPXuq28of663+gHVg03C+16pHHs/+FmmDjcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "ISC" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/iso-639-1": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz", + "integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/liquidjs": { + "version": "10.21.1", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.21.1.tgz", + "integrity": "sha512-NZXmCwv3RG5nire3fmIn9HsOyJX3vo+ptp0yaXUHAMzSNBhx74Hm+dAGJvscUA6lNqbLuYfXgNavRQ9UbUJhQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^10.0.0" + }, + "bin": { + "liquid": "bin/liquid.js", + "liquidjs": "bin/liquid.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/liquidjs" + } + }, + "node_modules/list-to-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/list-to-array/-/list-to-array-1.1.0.tgz", + "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==", + "dev": true, + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz", + "integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/maximatch": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz", + "integrity": "sha512-9ORVtDUFk4u/NFfo0vG/ND/z7UQCVZBL539YW0+U1I7H1BkZwizcPx5foFv7LCPcBnm2U6RjFnQOsIvN4/Vm2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/morphdom": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.5.tgz", + "integrity": "sha512-z6bfWFMra7kBqDjQGHud1LSXtq5JJC060viEkQFMBX6baIecpkNr2Ywrn2OQfWP3rXiNFQRPoFjD8/TvJcWcDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-retrieve-globals": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz", + "integrity": "sha512-j0DeFuZ/Wg3VlklfbxUgZF/mdHMTEiEipBb3q0SpMMbHaV3AVfoUQF8UGxh1s/yjqO0TgRZd4Pi/x2yRqoQ4Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "acorn-walk": "^8.3.4", + "esm-import-transformer": "^3.0.3" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/posthtml": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz", + "integrity": "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "posthtml-parser": "^0.11.0", + "posthtml-render": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/posthtml-match-helper": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-2.0.3.tgz", + "integrity": "sha512-p9oJgTdMF2dyd7WE54QI1LvpBIkNkbSiiECKezNnDVYhGhD1AaOnAkw0Uh0y5TW+OHO8iBdSqnd8Wkpb6iUqmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "posthtml": "^0.16.6" + } + }, + "node_modules/posthtml-parser": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", + "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^7.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/posthtml-render": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", + "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-json": "^2.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.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, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz", + "integrity": "sha512-aZpUoMN/Jj2MqA4vMCeiKGnc/8SuSyHbGSBdgFbZxP8OJGF/lFkIuElzPxsN0q8TQQ+prw3P4EDfB3TBHHgfXw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.10.0.tgz", + "integrity": "sha512-u5otvFBOBZvmdjWLVW+5DAc9Nkq8f24g0O9oY7qw2JVIF1VocIFoyz9JFkuVOS2j41AufeO0xnlweJ2RLT8nGw==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/template/package.json b/template/package.json new file mode 100644 index 0000000..6e33b03 --- /dev/null +++ b/template/package.json @@ -0,0 +1,20 @@ +{ + "name": "terrabyte-11ty-template", + "version": "1.4.0", + "main": "index.js", + "scripts": { + "sync-version": "node scripts/sync-version.js", + "build": "eleventy", + "start": "eleventy --serve" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "devDependencies": { + "@11ty/eleventy": "^3.1.1" + }, + "dependencies": { + "cheerio": "^1.1.0" + } +} diff --git a/template/robots.txt.njk b/template/robots.txt.njk new file mode 100644 index 0000000..49150a6 --- /dev/null +++ b/template/robots.txt.njk @@ -0,0 +1,7 @@ +--- +permalink: robots.txt +eleventyExcludeFromCollections: true +--- +User-agent: * +Disallow: +Sitemap: {{ site.url }}/sitemap.xml \ No newline at end of file diff --git a/template/scripts/README.md b/template/scripts/README.md new file mode 100644 index 0000000..bfcb4cb --- /dev/null +++ b/template/scripts/README.md @@ -0,0 +1,9 @@ +# Terrabyte Template Version Tracking System + +**Purpose:** Automatically track Template version number in `package.json` and `site.json` to manage what version of the template downstream projects are using. + +## How to use + +To bump the project version, run either `release-patch.sh`, `release-minor.sh`, or `release-major.sh`. This will increment the respective value in versioning within the Template's `package.json`, but will also sync to `site.json`. The value within site.json is not used in the template itself, but is meant to help manage versions in downstream projects. Downstream projects can diff files and see that the project currently uses `v1.1.1`, while the template in the `/template` folder (the most up-to-date template version, as long as it is setup correctly) has a version of `v1.2.0`. + +**NOTE:** `sync-version.js` should only need to be ran on its own in outlying circumstances. Each of the shell scripts runs this file as part of its sync version process. \ No newline at end of file diff --git a/template/scripts/release-major.sh b/template/scripts/release-major.sh new file mode 100644 index 0000000..27ce505 --- /dev/null +++ b/template/scripts/release-major.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Bump version +npm version major --no-git-tag-version + +# Sync version to site.json +npm run sync-version + +# Stage and commit updated site.json +git add package.json package-lock.json _data/site.json +VERSION=$(node -p "require('./package.json').version") +git commit -m "chore(release): v$VERSION - sync site.json with package version" + +# Tag the commit with the new version from package.json +git tag -a "v$VERSION" -m "Release $VERSION" + +# Push commit and tag to origin +git push origin main +git push origin --tags + +echo "✅ Version bumped to v$VERSION" +echo "📦 site.json synced" +echo "🏷️ Annotated tag created and pushed" +echo "🚀 Template ready to release!" +echo "-----------------------------------" \ No newline at end of file diff --git a/template/scripts/release-minor.sh b/template/scripts/release-minor.sh new file mode 100644 index 0000000..4b1f8d7 --- /dev/null +++ b/template/scripts/release-minor.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Bump version +npm version minor --no-git-tag-version + +# Sync version to site.json +npm run sync-version + +# Stage and commit updated site.json +git add package.json package-lock.json _data/site.json +VERSION=$(node -p "require('./package.json').version") +git commit -m "chore(release): v$VERSION - sync site.json with package version" + +# Tag the commit with the new version from package.json +git tag -a "v$VERSION" -m "Release $VERSION" + +# Push commit and tag to origin +git push origin main +git push origin --tags + +echo "✅ Version bumped to v$VERSION" +echo "📦 site.json synced" +echo "🏷️ Annotated tag created and pushed" +echo "🚀 Template ready to release!" +echo "-----------------------------------" \ No newline at end of file diff --git a/template/scripts/release-patch.sh b/template/scripts/release-patch.sh new file mode 100644 index 0000000..085a02c --- /dev/null +++ b/template/scripts/release-patch.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Bump version +npm version patch --no-git-tag-version + +# Sync version to site.json +npm run sync-version + +# Stage and commit updated site.json +git add package.json package-lock.json _data/site.json +VERSION=$(node -p "require('./package.json').version") +git commit -m "chore(release): v$VERSION - sync site.json with package version" + +# Tag the commit with the new version from package.json +git tag -a "v$VERSION" -m "Release $VERSION" + +# Push commit and tag to origin +git push origin main +git push origin --tags + +echo "✅ Version bumped to v$VERSION" +echo "📦 site.json synced" +echo "🏷️ Annotated tag created and pushed" +echo "🚀 Template ready to release!" +echo "-----------------------------------" \ No newline at end of file diff --git a/template/scripts/sync-version.js b/template/scripts/sync-version.js new file mode 100644 index 0000000..e5e59c0 --- /dev/null +++ b/template/scripts/sync-version.js @@ -0,0 +1,23 @@ +const fs = require('fs'); +const path = require('path'); + +// Paths to files +const packagePath = path.resolve(__dirname, '../package.json'); +const sitePath = path.resolve(__dirname, '../_data/site.json'); + +// Read package.json +const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8')); +const version = pkg.version; +console.log(`Package version: ${version}`); + + +// Read site.json +const site = JSON.parse(fs.readFileSync(sitePath, 'utf8')); + +// Update templateVersion +site.templateVersion = version; + +// Write back to site.json +fs.writeFileSync(sitePath, JSON.stringify(site, null, 2)); + +console.log(`Changed templateVersion to ${version} in site.json`); diff --git a/template/site.manifest.njk b/template/site.manifest.njk new file mode 100644 index 0000000..b657929 --- /dev/null +++ b/template/site.manifest.njk @@ -0,0 +1,25 @@ +--- +permalink: site.webmanifest +eleventyExcludeFromCollections: true +--- +{ + "name": "{{ site.title }}", + "short_name": "{{ site.title }}", + "start_url": "/", + "display": "browser", + "background_color": "{{ site.backgroundColor or '#333333' }}", + "theme_color": "{{ site.accentColor or '#ffffff' }}", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "description": "{{ site.description | safe }}" +} diff --git a/template/sitemap.xml.njk b/template/sitemap.xml.njk new file mode 100644 index 0000000..8fd1982 --- /dev/null +++ b/template/sitemap.xml.njk @@ -0,0 +1,21 @@ +--- +permalink: sitemap.xml +eleventyExcludeFromCollections: true +--- + + + {% for page in collections.all %} + {% if page.url and not page.data.draft and not page.data.private %} + + {{ page.url | canonicalUrl }} + {# Calculate depth #} + {% if page.url == '/' %}{% set depth = 0 %} + {% else %}{% set depth = page.url | trim('/') | split('/') | length %}{% endif %} + {# Calculate priority #} + {% set priority = 1.0 - (depth * 0.1) %} + {% if priority > 0.1 %}{{ priority | round(1, 'floor') }} + {% else %}0.1{% endif %} + + {% endif %} + {% endfor %} + \ No newline at end of file