diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..4a6ee7aa --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules/ + +server/test/ +client/ +!client/dist/ + +.* +README.md +LICENSE +nano-staged.json +simple-git-hooks.json +Dockerfile diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..8ac1a531 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.svg] +insert_final_newline = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..849ddff3 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +dist/ diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..318fa10b --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "@logux/eslint-config/esm" +} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 152f44c9..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "root": true, - "plugins": [ - "eslint-plugin-github" - ], - "env": { - "es6": true, - "node": true - }, - "extends": [ - "plugin:github/recommended", - "plugin:github/es6" - ], - "rules": { - "eslint-comments/no-use": "off" - } -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..0ee30b10 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,165 @@ +name: CI +on: + push: + branches: + - main + pull_request: +env: + FORCE_COLOR: 2 +jobs: + + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Install asdf tools + if: steps.asdf-cache.outputs.cache-hit != 'true' + uses: asdf-vm/actions/install@v1 + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + - name: Build regions + run: pnpm -r build:regions + - name: Run tests + run: pnpm test + + deploy: + name: Deploy + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Notify about new deployment + uses: bobheadxi/deployments@v1 + id: deployment + with: + step: start + token: ${{ secrets.GITHUB_TOKEN }} + env: production + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install production dependencies + run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Build regions + run: pnpm -r build:regions + - name: Build static files + run: pnpm build + - name: Auth Google Cloud + uses: google-github-actions/auth@v0 + with: + credentials_json: ${{ secrets.GCLOUD_AUTH }} + - name: Install Google Cloud + uses: google-github-actions/setup-gcloud@v0 + - name: Deploy files + id: deploy + run: ./node_modules/.bin/ssdeploy deploy --verbose + env: + GCLOUD_APP: ${{ secrets.GCLOUD_APP }} + GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} + - name: Update deployment status + uses: bobheadxi/deployments@v1 + if: always() + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ job.status }} + env: ${{ steps.deployment.outputs.env }} + env_url: ${{ steps.deploy.outputs.url }} + deployment_id: ${{ steps.deployment.outputs.deployment_id }} + + preview: + name: Preview + runs-on: ubuntu-latest + if: github.ref != 'refs/heads/main' + steps: + - name: Notify about new deployment + uses: bobheadxi/deployments@v1 + id: deployment + with: + step: start + token: ${{ secrets.GITHUB_TOKEN }} + ref: ${{ github.head_ref }} + env: preview-${{ github.event.number }} + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Install asdf tools + if: steps.asdf-cache.outputs.cache-hit != 'true' + uses: asdf-vm/actions/install@v1 + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install production dependencies + run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Build regions + run: pnpm -r build:regions + - name: Build static files + run: pnpm build + - name: Auth Google Cloud + uses: google-github-actions/auth@v0 + with: + credentials_json: ${{ secrets.GCLOUD_AUTH }} + - name: Install Google Cloud + uses: google-github-actions/setup-gcloud@v0 + - name: Deploy files + id: deploy + run: ./node_modules/.bin/ssdeploy preview $PR --verbose + env: + PR: ${{ github.event.number }} + GCLOUD_APP: ${{ secrets.GCLOUD_APP }} + GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} + - name: Update deployment status + uses: bobheadxi/deployments@v1 + if: always() + with: + step: finish + token: ${{ secrets.GITHUB_TOKEN }} + status: ${{ job.status }} + env: ${{ steps.deployment.outputs.env }} + env_url: ${{ steps.deploy.outputs.url }} + deployment_id: ${{ steps.deployment.outputs.deployment_id }} diff --git a/.github/workflows/close.yml b/.github/workflows/close.yml new file mode 100644 index 00000000..3c303695 --- /dev/null +++ b/.github/workflows/close.yml @@ -0,0 +1,50 @@ +name: Clean Preview +on: + pull_request: + types: [ closed ] +jobs: + close: + runs-on: ubuntu-latest + steps: + - name: Clean from GitHub + uses: bobheadxi/deployments@v1 + with: + step: delete-env + token: ${{ secrets.GITHUB_TOKEN }} + env: preview-${{ github.event.number }} + - name: Checkout the repository + uses: actions/checkout@v3 + - name: Install asdf + uses: asdf-vm/actions/setup@v1 + - name: Cache asdf + id: asdf-cache + uses: actions/cache@v3 + with: + path: ~/.asdf + key: asdf-${{ hashFiles('**/.tool-versions') }} + - name: Install asdf tools + if: steps.asdf-cache.outputs.cache-hit != 'true' + uses: asdf-vm/actions/install@v1 + - name: Cache pnpm modules + uses: actions/cache@v3 + env: + cache-name: cache-pnpm-modules + with: + path: ~/.local/share/pnpm/ + key: pnpm-production-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install dependencies + run: pnpm install --prod --frozen-lockfile --ignore-scripts + - name: Auth Google Cloud + uses: google-github-actions/auth@v0 + with: + credentials_json: ${{ secrets.GCLOUD_AUTH }} + - name: Install Google Cloud + uses: google-github-actions/setup-gcloud@v0 + - name: Clean from Google Cloud + run: ./node_modules/.bin/ssdeploy close $PR --verbose + env: + PR: ${{ github.event.number }} + GCLOUD_APP: ${{ secrets.GCLOUD_APP }} + GCLOUD_PROJECT: ${{ secrets.GCLOUD_PROJECT }} + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 1d717808..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Tests -on: [push, pull_request] -env: - CI: true - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v1 - - - name: Set up Node.js - uses: actions/setup-node@v1 - with: - node-version: "10" - - - run: node --version - - run: npm --version - - - name: Install npm dependencies - run: npm install - - - name: Run tests - run: npm test diff --git a/.gitignore b/.gitignore index 1f53980a..b9470778 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,2 @@ -node_modules -*.log -.DS_Store -package-lock.json - -.vercel +node_modules/ +dist/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..82ad122b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "arrowParens": "avoid", + "jsxSingleQuote": false, + "quoteProps": "consistent", + "semi": false, + "singleQuote": true, + "trailingComma": "none" +} diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 00000000..2a65dd33 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,11 @@ +{ + "extends": "@logux/stylelint-config", + "ignoreFiles": ["dist/**/*"], + "rules": { + "function-disallowed-list": ["rgb", "rgba", "hsl", "hsla"], + "alpha-value-notation": "percentage", + "color-named": "never", + "declaration-block-no-redundant-longhand-properties": null, + "font-family-no-duplicate-names": [true, { "ignoreFontFamilyNames":"monospace"}] + } +} diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..86e236dc --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +nodejs 18.7.0 +pnpm 7.9.1 diff --git a/CNAME b/CNAME deleted file mode 100644 index 7480dbbf..00000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -browserl.ist \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..16dd14a2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM node:18-alpine + +ENV NODE_ENV production +WORKDIR /var/www +COPY --chown=node:node . /var/www + +RUN corepack enable +RUN corepack prepare pnpm@7.9.1 --activate +COPY ./pnpm-workspace.yaml /var/www/ +COPY ./package.json /var/www/ +COPY ./pnpm-lock.yaml /var/www/ +COPY ./server/ /var/www/server/ +RUN pnpm install --filter ./server --prod --frozen-lockfile --ignore-scripts +COPY ./client/dist/ /var/www/client/dist/ + +CMD "node" "server/index.js" diff --git a/README.md b/README.md index 159268d9..2e903b5c 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,43 @@ -# Browserl.ist [![Build Status](https://github.com/browserslist/browserl.ist/workflows/Tests/badge.svg)](https://github.com/browserslist/browserl.ist/actions?workflow=Tests) +# Browserslist Website -> A website that shows what browsers supported by a browserslist string +This website uses [Browserslist] and [Can I Use] to display +the compatible browsers for a browsers query. + +[browserslist]: https://github.com/browserslist/browserslist +[Can I Use]: https://github.com/Fyrd/caniuse -This website uses [browserslist][] and [caniuse][] to display the compatible browsers for a [browserslist search query](https://github.com/ai/browserslist#queries). ## Development -This website runs on [expressjs](https://expressjs.com/). To run locally, after `npm install` to install the dependencies, `npm start` to run the server. +To run a local copy for development: + +1. Install correct versions of Node.js and pnpm. There are two ways: + - With [`asdf`](https://github.com/asdf-vm/asdf) version manager: + + ```sh + asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs.git + asdf plugin-add pnpm https://github.com/jonathanmorley/asdf-pnpm.git + asdf install + ``` + + - Manually by check versions in `.tool-versions`. + +2. Install dependencies: -## Contributing + ```sh + pnpm install + ``` -I'm open to any pull requests or bug reports. Anything that has to do with the data that is presented should be opened with [browserslist][] or [caniuse][]. +3. Run local server: -## License + - Server with client-side hot-reload + ```sh + pnpm start + ``` -[MIT](./LICENSE) © [Browserslist](https://github.com/browserslist) + - Server production mode + ```sh + pnpm ssdeploy run + ``` -[browserslist]: https://github.com/ai/browserslist -[caniuse]: https://github.com/Fyrd/caniuse +We recommend to install Prettier and EditorConfig plugins to your text editor. diff --git a/api/server.js b/api/server.js deleted file mode 100644 index 0d809f65..00000000 --- a/api/server.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("../app"); diff --git a/app.js b/app.js deleted file mode 100644 index 481ffe59..00000000 --- a/app.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; - -const path = require("path"); -const express = require("express"); -const logger = require("morgan"); -const cookieParser = require("cookie-parser"); -const bodyParser = require("body-parser"); - -const routes = require("./routes/index"); - -const app = express(); - -// view engine setup -app.set("views", path.join(__dirname, "views")); -app.set("view engine", "pug"); - -app.use(logger("dev")); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, "public"))); - -app.use("/", routes); - -// catch 404 and forward to error handler -app.use((req, res, next) => { - const err = new Error("Not Found"); - err.status = 404; - next(err); -}); - -// error handlers - -// development error handler -// will print stacktrace -if (app.get("env") === "development") { - app.use((err, req, res) => { - res.status(err.status || 500); - res.render("error", { - message: err.message, - error: err, - }); - }); -} - -// production error handler -// no stacktraces leaked to user -app.use((err, req, res) => { - res.status(err.status || 500); - res.render("error", { - message: err.message, - error: {}, - }); -}); - -module.exports = app; diff --git a/bin/www b/bin/www deleted file mode 100755 index 20029c57..00000000 --- a/bin/www +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env node - -/* eslint-disable no-console */ - -"use strict"; - -/** - * Module dependencies. - */ - -const app = require("../app"); -const debug = require("debug")("browserlist:server"); -const http = require("http"); - -/** - * Get port from environment and store in Express. - */ - -const PORT = normalizePort(process.env.PORT || "3000"); -app.set("port", PORT); - -/** - * Create HTTP server. - */ - -const server = http.createServer(app); - -/** - * Listen on provided port, on all network interfaces. - */ - -server.listen(PORT); -server.on("error", onError); -server.on("listening", onListening); - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - const port = parseInt(val, 10); - - if (isNaN(port)) { - // named pipe - return val; - } - - if (port >= 0) { - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== "listen") { - throw error; - } - - const bind = typeof PORT === "string" ? `Pipe ${PORT}` : `Port ${PORT}`; - - // handle specific listen errors with friendly messages - switch (error.code) { - case "EACCES": - console.error(`${bind} requires elevated privileges`); - process.exit(1); - break; - case "EADDRINUSE": - console.error(`${bind} is already in use`); - process.exit(1); - break; - default: - throw error; - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -function onListening() { - const addr = server.address(); - const bind = typeof addr === "string" ? `pipe ${addr}` : `port ${addr.port}`; - debug(`Listening on ${bind}`); -} diff --git a/client/.postcssrc b/client/.postcssrc new file mode 100644 index 00000000..2747ebea --- /dev/null +++ b/client/.postcssrc @@ -0,0 +1,13 @@ +{ + "plugins": { + "@csstools/postcss-oklab-function": { + "subFeatures": { + "displayP3": false + } + }, + "postcss-opacity-percentage": {}, + "postcss-nesting": {}, + "postcss-media-minmax": {}, + "autoprefixer": {} + } +} diff --git a/client/.size-limit.json b/client/.size-limit.json new file mode 100644 index 00000000..f0123cc9 --- /dev/null +++ b/client/.size-limit.json @@ -0,0 +1,13 @@ +[ + { + "name": "Files to download", + "path": ["dist/**/*", "!dist/*.ico", "!dist/*.webmanifest", "!dist/*.png"], + "limit": "40 KB" + }, + { + "name": "All scripts to execute", + "path": "dist/*.js", + "gzip": false, + "limit": "15 KB" + } +] diff --git a/client/data/.gitignore b/client/data/.gitignore new file mode 100644 index 00000000..469a7907 --- /dev/null +++ b/client/data/.gitignore @@ -0,0 +1 @@ +regions.json diff --git a/client/data/browsers-logos.js b/client/data/browsers-logos.js new file mode 100644 index 00000000..80283fd7 --- /dev/null +++ b/client/data/browsers-logos.js @@ -0,0 +1,21 @@ +/* eslint-disable camelcase */ +export { default as and_chr } from './browsers-logos/and_chr.svg' +export { default as and_ff } from './browsers-logos/and_ff.svg' +export { default as and_qq } from './browsers-logos/and_qq.svg' +export { default as and_uc } from './browsers-logos/and_uc.svg' +export { default as android } from './browsers-logos/android.svg' +export { default as baidu } from './browsers-logos/baidu.svg' +export { default as bb } from './browsers-logos/bb.svg' +export { default as chrome } from './browsers-logos/chrome.svg' +export { default as edge } from './browsers-logos/edge.svg' +export { default as firefox } from './browsers-logos/firefox.svg' +export { default as ie_mob } from './browsers-logos/ie_mob.svg' +export { default as ie } from './browsers-logos/ie.svg' +export { default as ios_saf } from './browsers-logos/ios_saf.svg' +export { default as kaios } from './browsers-logos/kaios.svg' +export { default as node } from './browsers-logos/node.svg' +export { default as op_mini } from './browsers-logos/op_mini.svg' +export { default as op_mob } from './browsers-logos/op_mob.svg' +export { default as opera } from './browsers-logos/opera.svg' +export { default as safari } from './browsers-logos/safari.svg' +export { default as samsung } from './browsers-logos/samsung.svg' diff --git a/client/data/browsers-logos/and_chr.svg b/client/data/browsers-logos/and_chr.svg new file mode 100644 index 00000000..30675815 --- /dev/null +++ b/client/data/browsers-logos/and_chr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/and_ff.svg b/client/data/browsers-logos/and_ff.svg new file mode 100644 index 00000000..98cca08f --- /dev/null +++ b/client/data/browsers-logos/and_ff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/and_qq.svg b/client/data/browsers-logos/and_qq.svg new file mode 100644 index 00000000..87a23fd9 --- /dev/null +++ b/client/data/browsers-logos/and_qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/and_uc.svg b/client/data/browsers-logos/and_uc.svg new file mode 100644 index 00000000..4cee13f7 --- /dev/null +++ b/client/data/browsers-logos/and_uc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/android.svg b/client/data/browsers-logos/android.svg new file mode 100644 index 00000000..f4e854e7 --- /dev/null +++ b/client/data/browsers-logos/android.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/baidu.svg b/client/data/browsers-logos/baidu.svg new file mode 100644 index 00000000..a8a456d6 --- /dev/null +++ b/client/data/browsers-logos/baidu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/bb.svg b/client/data/browsers-logos/bb.svg new file mode 100644 index 00000000..e784c5fc --- /dev/null +++ b/client/data/browsers-logos/bb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/chrome.svg b/client/data/browsers-logos/chrome.svg new file mode 100644 index 00000000..30675815 --- /dev/null +++ b/client/data/browsers-logos/chrome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/edge.svg b/client/data/browsers-logos/edge.svg new file mode 100644 index 00000000..9292f223 --- /dev/null +++ b/client/data/browsers-logos/edge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/firefox.svg b/client/data/browsers-logos/firefox.svg new file mode 100644 index 00000000..98cca08f --- /dev/null +++ b/client/data/browsers-logos/firefox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/ie.svg b/client/data/browsers-logos/ie.svg new file mode 100644 index 00000000..fb684e68 --- /dev/null +++ b/client/data/browsers-logos/ie.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/ie_mob.svg b/client/data/browsers-logos/ie_mob.svg new file mode 100644 index 00000000..fb684e68 --- /dev/null +++ b/client/data/browsers-logos/ie_mob.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/ios_saf.svg b/client/data/browsers-logos/ios_saf.svg new file mode 100644 index 00000000..e5ece08d --- /dev/null +++ b/client/data/browsers-logos/ios_saf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/kaios.svg b/client/data/browsers-logos/kaios.svg new file mode 100644 index 00000000..9c88539f --- /dev/null +++ b/client/data/browsers-logos/kaios.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/node.svg b/client/data/browsers-logos/node.svg new file mode 100644 index 00000000..47f791ee --- /dev/null +++ b/client/data/browsers-logos/node.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/op_mini.svg b/client/data/browsers-logos/op_mini.svg new file mode 100644 index 00000000..251b6938 --- /dev/null +++ b/client/data/browsers-logos/op_mini.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/op_mob.svg b/client/data/browsers-logos/op_mob.svg new file mode 100644 index 00000000..cf4c44d8 --- /dev/null +++ b/client/data/browsers-logos/op_mob.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/opera.svg b/client/data/browsers-logos/opera.svg new file mode 100644 index 00000000..cf4c44d8 --- /dev/null +++ b/client/data/browsers-logos/opera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/safari.svg b/client/data/browsers-logos/safari.svg new file mode 100644 index 00000000..e5ece08d --- /dev/null +++ b/client/data/browsers-logos/safari.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/browsers-logos/samsung.svg b/client/data/browsers-logos/samsung.svg new file mode 100644 index 00000000..3c3e6276 --- /dev/null +++ b/client/data/browsers-logos/samsung.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/data/regions.js b/client/data/regions.js new file mode 100644 index 00000000..0e881685 --- /dev/null +++ b/client/data/regions.js @@ -0,0 +1,31 @@ +// regions.json is created on `postinstall` step +import { continents, countryCodes } from './regions.json' + +export const DEFAULT_REGION = 'alt-ww' + +export const regionList = [...Object.keys(continents), ...countryCodes] + +export const regionGroups = { + continents: Object.entries(continents).map(([id, name]) => { + return { + id, + name + } + }), + countries: countryCodes.map(id => { + return { + id, + name: getCountryName(id) + } + }) +} + +function getCountryName(id) { + let isIntlDisplayNameSupports = + 'Intl' in window && 'DisplayNames' in window.Intl + + // Show country `id` instead country fullname for old browsers + return isIntlDisplayNameSupports + ? new Intl.DisplayNames('en-US', { type: 'region' }).of(id) + : id +} diff --git a/client/data/wikipedia-links.js b/client/data/wikipedia-links.js new file mode 100644 index 00000000..0b4572e7 --- /dev/null +++ b/client/data/wikipedia-links.js @@ -0,0 +1,30 @@ +const WIKIPEDIA_URL = 'https://en.wikipedia.org/wiki/' + +const WIKIPEDIA_LINKS = { + and_chr: 'Google_Chrome#Android', + and_ff: 'Firefox_for_Android', + and_qq: 'Tencent_QQ', + and_uc: 'UC_Browser', + android: 'List_of_features_in_Android#AndroidBrowser', + baidu: 'Baidu_Browser', + bb: 'BlackBerry#Software', + chrome: 'Google_Chrome', + edge: 'Microsoft_Edge', + firefox: 'Mozilla_Firefox', + ie: 'Internet_Explorer', + ie_mob: 'Internet_Explorer_Mobile', + ios_saf: 'Safari_(web_browser)', + kaios: 'KaiOS', + node: 'Node.js', + op_mini: 'Opera_Mini', + op_mob: 'Opera_Mobile', + opera: 'Opera_(web_browser)', + safari: 'Safari_(web_browser)', + samsung: 'Samsung_Internet' +} + +for (let browser in WIKIPEDIA_LINKS) { + WIKIPEDIA_LINKS[browser] = WIKIPEDIA_URL + WIKIPEDIA_LINKS[browser] +} + +export default WIKIPEDIA_LINKS diff --git a/client/index.css b/client/index.css new file mode 100644 index 00000000..637115ab --- /dev/null +++ b/client/index.css @@ -0,0 +1,2 @@ +@import "./view/base/index.css"; +@import "./view/base/colors.css"; diff --git a/client/index.html b/client/index.html new file mode 100644 index 00000000..31a04223 --- /dev/null +++ b/client/index.html @@ -0,0 +1,465 @@ + + + + + + + Browserslist + + + + + + + + + + + +
+
+

+ + Browserslist +

+ + 10.5k + + + Count of twitter followers 4k + +
+

Shared browser and platform compatibility config for popular JavaScript tools, + including Autoprefixer, Babel, ESLint, PostCSS, and Webpack

+

+ Supported by + + Evil Martians and + + Cube +

+
+ +
+

Display compatible browsers

+
+
+ +

Write the Browserslist config here…
+ For example + defaults, + > 0.2% and not dead +

+

Press Enter + + + + + + to submit +

+

Query should be not empty

+

Unknown query

+

Loading...

+
+
+

Region coverage:

+ +
+
+ +
+
+ +

add the Browserslist config to display compatible browsers

+
+ +
+
    +
    + +
    +

    + Browserslist version: +

    +

    + Data provided by caniuse-db +

    +
    +
    +
    +
    + +
    +

    How to get started

    +

    + defaults - if you're building a web application for + the global audience. +

    +

    + node 18 - if you're building a Node.js application, + e.g., for SSR. +

    +

    Autoprefixer, + Babel or any of the following libraries will find + target browsers automatically, when + you add the following to package.json: +

    +
    +      "browserslist": [
    +        "defaults",
    +        "not IE 11",
    +        "maintained node versions"
    +      ]
    +    
    +
    +

    Query Syntax

    +
    +

    Start with the default configuration

    + +

    You can pick a sound set of versions with the `defaults` query which is a + shortcut for + + > 0.5%, last 2 versions, Firefox ESR, not dead + . It matches recent versions of popular and supported browsers worldwide and includes + Firefox Extended Support Release which is updated roughly annually. +

    + +

    The defaults query was thoroughly designed by the + Browserslist community. + It helps promote best practices and avoid common pitfalls. +

    +
    + +
    +

    Select browser versions with certain usage

    + +

    You can pick versions that have more than or less than a certain size of the + audience worldwide, in a region, or in a country. You can also use the visitor + data of your own website.

    + +

    Examples:

    + + +

    Beware:

    + + +
    +

    Advanced

    +
      +
    • > 5% in my stats - versions with > + 5% + of usage + within your own audience. +
    • +
    • > 5% in circle-ci stats - + versions with > 5% of usage within the audience data from shareable configuration, available as + github.com/circleci/circleci-docs/blob/master/browserslist-stats.json +
    • +
    • cover 99.5% - the smallest set of popular + versions with collective usage over 99.5% of the audience worldwide. +
    • +
    • cover 99.5% in CN - same as above + but in China. +
    • +
    • cover 99.5% in alt-EU - same + as above but in Europe. +
    • +
    +
    +
    + +
    +

    Select recent browser versions

    + +

    You can pick a few recent browser versions.

    + +

    Examples:

    + + +

    Beware:

    + + +
    +

    Advanced

    + +
    +
    + +
    +

    Select specific browser versions

    + +

    You can pick browser versions or a version range of your choice.

    + +

    Examples:

    + + +

    Beware:

    + + +
    +

    Advanced

    +
      +
    • ie 6-8 - an inclusive range of Internet + Explorer + versions. +
    • +
    • Firefox ESR - the latest Firefox Extended + Support Release. +
    • +
    +
    +
    + +
    +

    Select specific Node.js versions

    + +

    You can pick Node.js versions or a version range of your choice. Useful if you + know for sure the runtime configuration of your server-side code.

    + +

    Examples:

    + + +
    +

    Advanced

    + +
    +
    + +
    +

    Select browser versions that support a certain feature

    + +

    You can pick browser versions that fully support features from the Can I Use database. See the + + caniuse-lite repository + + for the full list of features.

    + +

    Examples:

    + + +

    Beware:

    + +
    + +
    +

    Combine multiple queries into one

    + +

    You can combine versions matched by multiple queries with or or ,; you can + intersect them with and. You can also negate any query with not if it's + not the first one in your list.

    + +

    Examples:

    + + +

    Beware:

    + + +
    +

    Advanced

    + +
    +
    + +
    +

    Exclude unmaintained browser versions

    + +

    You can combine your queries with + not dead + to exclude dead browsers, i.e., + browsers without official support or updates for more than 24 months. + Right now these include IE 11, IE Mobile 11, BlackBerry 10, BlackBerry 7, + Samsung 4, Opera Mobile 12.1, and all versions of Baidu.

    + +

    Examples:

    + +
    + +

    Why Browserslist

    +

    Browserslist helps you keep the right balance between browser compatibility and bundle size. + You will cover wider audience and have smaller bundle size.

    + +

    What people say about Browserslist

    +
    +
    + +
    + Ross Kaffenberger avatar + Ross Kaffenberger + @rossta +
    +

    + Use browserslist!

    + + Leveraged through a module bundler like Webpack, you can specify the supported browser range in a + browserslist file to automagically help you avoid the dangers + @dhh describes.

    + + For Rails devs: it's integrated into Webpacker! +

    +
    + +
    + +
    + Gibbs Herbert avatar + Gibbs Herbert + @gha_dev +
    +

    + + browserslist is a package that allows you to define which browsers you are currently supporting. + #100DaysOfCode + #javascript +

    +
    +
    +
    + + + diff --git a/client/index.js b/client/index.js new file mode 100644 index 00000000..08eb58b5 --- /dev/null +++ b/client/index.js @@ -0,0 +1,2 @@ +import './view/Form/form.js' +import './view/QueryLink/queryLink.js' diff --git a/client/package.json b/client/package.json new file mode 100644 index 00000000..14946161 --- /dev/null +++ b/client/package.json @@ -0,0 +1,31 @@ +{ + "name": "browserl.ist-client", + "private": true, + "type": "module", + "scripts": { + "start": "vite build --watch", + "build": "vite build -m production", + "build:regions": "node ./scripts/build-regions.js", + "test": "pnpm build && size-limit", + "postinstall": "pnpm build:regions" + }, + "dependencies": { + "@csstools/postcss-oklab-function": "^1.1.1", + "autoprefixer": "^10.4.8", + "caniuse-lite": "^1.0.30001375", + "jstransformer-markdown-it": "^3.0.0", + "postcss": "^8.4.16", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.1.10", + "postcss-opacity-percentage": "^1.1.2", + "vite": "^3.0.7", + "vite-plugin-pug-transformer": "^1.0.2" + }, + "devDependencies": { + "@size-limit/file": "^8.0.1", + "size-limit": "^8.0.1" + }, + "engines": { + "node": ">=18" + } +} diff --git a/client/public/browserslist.webmanifest b/client/public/browserslist.webmanifest new file mode 100644 index 00000000..5ebb4004 --- /dev/null +++ b/client/public/browserslist.webmanifest @@ -0,0 +1,10 @@ +{ + "name": "Browserslist", + "start_url": "/", + "display": "standalone", + "background_color": "#f6f6f8", + "icons": [ + { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, + { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" } + ] +} diff --git a/client/public/favicon.ico b/client/public/favicon.ico new file mode 100644 index 00000000..a62e3e65 Binary files /dev/null and b/client/public/favicon.ico differ diff --git a/client/public/icon-192.png b/client/public/icon-192.png new file mode 100644 index 00000000..6829b358 Binary files /dev/null and b/client/public/icon-192.png differ diff --git a/client/public/icon-512.png b/client/public/icon-512.png new file mode 100644 index 00000000..07cc9124 Binary files /dev/null and b/client/public/icon-512.png differ diff --git a/client/public/og.png b/client/public/og.png new file mode 100644 index 00000000..be9ccaa7 Binary files /dev/null and b/client/public/og.png differ diff --git a/client/scripts/build-regions.js b/client/scripts/build-regions.js new file mode 100644 index 00000000..4e7e4bff --- /dev/null +++ b/client/scripts/build-regions.js @@ -0,0 +1,34 @@ +import { writeFileSync, readdirSync } from 'node:fs' + +const DATA_REGION_FILE = 'data/regions.json' +const REGIONS_LIST_PATH = './node_modules/caniuse-lite/data/regions' + +const regions = { + continents: { + 'alt-ww': 'Global', + 'alt-af': 'Africa', + 'alt-an': 'Antarctica', + 'alt-as': 'Asia', + 'alt-eu': 'Europe', + 'alt-na': 'North America', + 'alt-oc': 'Oceania', + 'alt-sa': 'South America' + }, + countryCodes: getCaniuseCountries() +} + +writeFileSync(DATA_REGION_FILE, JSON.stringify(regions)) +process.stdout.write( + `A file "client/${DATA_REGION_FILE}" with regions has been created\n` +) + +function getCaniuseCountries() { + let regionCodes = readdirSync(REGIONS_LIST_PATH).map(f => f.split('.js')[0]) + + return regionCodes + .filter(regionCode => { + let isContinentCode = regionCode.includes('alt-') + return !isContinentCode + }) + .sort((a, b) => b - a) +} diff --git a/client/view/Article/Article.css b/client/view/Article/Article.css new file mode 100644 index 00000000..87d63139 --- /dev/null +++ b/client/view/Article/Article.css @@ -0,0 +1,99 @@ +.Article { + box-sizing: border-box; + flex-basis: 0; + flex-grow: 1; + width: 50%; + padding: 24px 32px; +} + +.Article--stats { + position: fixed; + top: 0; + /* Hide scrollbar */ + right: calc(-1 * (100vw - 100%)); + display: flex; + flex-direction: column; + gap: 16px; + width: 50%; + height: 100vh; + max-height: 100vh; + overflow-y: scroll; + background-color: var(--bg-highlited); +} + +.Article--stats h2 { + margin: 0; + font-size: 22px; + line-height: 26px; +} + +.Article > *:last-child { + margin-bottom: 0; +} + +.Article > *:first-child { + margin-top: 0; +} + +.Article__h1 { + display: flex; + gap: 8px; + align-items: center; + margin: 0; +} + +.Article__h2 { + margin-top: 32px; + font-size: 22px; + line-height: 26px; +} + +.Article--intro__about { + margin: 16px 0; + font-size: 25px; + line-height: 32px; + letter-spacing: 0.01em; +} + +.Article--intro__supported { + font-size: 14px; + line-height: 20px; + color: var(--text-secondary); + letter-spacing: 0.02em; +} + +.Article--intro__supported img { + height: 16px; + vertical-align: middle; +} + +.Article--intro__header { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; +} + +@media (max-width: 740px) { + .Article { + width: initial; + } + + .Article--stats { + position: initial; + height: initial; + max-height: initial; + overflow: visible; + } +} + +@media (max-width: 460px) { + .Article { + padding: 16px 24px; + } + + .Article--intro__about { + font-size: 16px; + line-height: 22px; + } +} diff --git a/client/view/Article/browserlist_logo.svg b/client/view/Article/browserlist_logo.svg new file mode 100644 index 00000000..2ff11a55 --- /dev/null +++ b/client/view/Article/browserlist_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/Article/cube_logo.svg b/client/view/Article/cube_logo.svg new file mode 100644 index 00000000..7f2333e3 --- /dev/null +++ b/client/view/Article/cube_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/Article/evil_maritians_logo.svg b/client/view/Article/evil_maritians_logo.svg new file mode 100644 index 00000000..9a7e9f96 --- /dev/null +++ b/client/view/Article/evil_maritians_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/Badge/Badge.css b/client/view/Badge/Badge.css new file mode 100644 index 00000000..8bce01c8 --- /dev/null +++ b/client/view/Badge/Badge.css @@ -0,0 +1,19 @@ +.Badge { + display: flex; + gap: 4px; + align-items: center; + padding: 4px 6px; + font-size: 14px; + font-weight: 800; + color: inherit; + text-decoration: none; + background-color: var(--bg-highlited); + background-image: initial; + border-radius: 4px; +} + +@media (prefers-color-scheme: dark) { + .Badge__githubLogo { + filter: invert(1); + } +} diff --git a/client/view/Badge/github_logo.svg b/client/view/Badge/github_logo.svg new file mode 100644 index 00000000..f281286c --- /dev/null +++ b/client/view/Badge/github_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/Badge/twitter_logo.svg b/client/view/Badge/twitter_logo.svg new file mode 100644 index 00000000..1de65336 --- /dev/null +++ b/client/view/Badge/twitter_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/BrowserStats/BrowsersStat.css b/client/view/BrowserStats/BrowsersStat.css new file mode 100644 index 00000000..42e869cd --- /dev/null +++ b/client/view/BrowserStats/BrowsersStat.css @@ -0,0 +1,183 @@ +.BrowsersStat__regionCoverageBar { + display: flex; + gap: 1px; + justify-content: flex-start; + width: 100%; + padding: 0; + margin: 0 0 24px; + overflow: hidden; + counter-reset: alpha 0; + background-color: var(--main-bg); + border-radius: 6px; +} + +.BrowsersStat__regionCoverageBarItem { + box-sizing: border-box; + width: calc(var(--proportion, 0) * 1%); + overflow: hidden; + line-height: 32px; + text-overflow: ellipsis; + white-space: nowrap; + list-style: none; + counter-increment: alpha -1; + background-color: var(--accent-alternave); + opacity: var(--alpha, 0%); + + /* TODO types for this variables */ + --proportion: 0; + --alpha: 0; +} + +.BrowsersStat__regionCoverageBarItem--texted::after, +.BrowsersStat__regionCoverageBarItem--texted::before { + display: inline-block; + width: 8px; + content: ""; +} + +.BrowsersStat__tableContainer { + columns: 2; + column-fill: balance; +} + +@media (min-width: 740px) and (max-width: 1200px) { + .BrowsersStat__tableContainer { + columns: 1; + } +} + +@media (max-width: 600px) { + .BrowsersStat__tableContainer { + columns: 1; + } +} + +.BrowsersStat__placeholder { + box-sizing: border-box; + display: flex; + flex-direction: column; + gap: 32px; + align-items: center; + justify-content: center; + height: 100%; + color: var(--separator); +} + +@media (max-width: 740px) { + .BrowsersStat__placeholder { + gap: 16px; + padding: 32px 0; + } +} + +.BrowsersStat__placeholderImage { + width: 100%; + object-fit: cover; + max-width: 380px; +} + +@media (max-width: 740px) { + .BrowsersStat__placeholderImage { + width: initial; + max-width: 100%; + max-height: 300px; + } +} + +.BrowsersStat { + flex-grow: 1; +} + +.BrowsersStat__placeholderText { + width: 80%; + margin: 0; + text-align: center; +} + +.BrowsersStat__placeholder--hidden { + display: none; +} + +.BrowsersStat__stat { + display: flex; + flex-direction: column; + min-height: 100%; +} + +.BrowsersStat__stat--hidden { + display: none; +} + +.BrowsersStat__table { + display: block; + border-spacing: 8px 0; +} + +.BrowsersStat__table tr:first-child td:first-child { + width: 20px; +} + +.BrowsersStat__table tr:first-child td:nth-child(2) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.BrowsersStat__table tr:first-child td:nth-child(3) { + width: 7ch; +} + +.BrowsersStat__td { + box-sizing: border-box; + height: 32px; + line-height: 32px; + vertical-align: top; + break-inside: avoid; +} + +.BrowsersStat__td:last-child { + width: 6ch; + text-align: left; +} + +.BrowsersStat__td--coverage { + --coverage: 20%; + + background-image: + linear-gradient( + to right, + var(--accent-alternave) var(--coverage), + transparent var(--coverage), + transparent + ); +} + +.BrowsersStat__table tbody { + display: inline-table; + width: 100%; + margin-bottom: -1px; + table-layout: fixed; + border-top: 1px solid var(--separator); +} + +.BrowsersStat__icon { + display: inline; + height: 20px; + line-height: 32px; + vertical-align: middle; +} + +.BrowsersStat__toolsVersions { + display: flex; + flex-wrap: wrap; + column-gap: 12px; + color: var(--text-secondary); + margin-top: auto; + padding-top: 24px; +} + +.BrowsersStat__toolsVersionsItem { + font-size: 14px; + line-height: 20px; + margin: 0; +} diff --git a/client/view/BrowserStats/browserStats.js b/client/view/BrowserStats/browserStats.js new file mode 100644 index 00000000..f442543b --- /dev/null +++ b/client/view/BrowserStats/browserStats.js @@ -0,0 +1,143 @@ +import wikipediaLinks from '../../data/wikipedia-links.js' +import * as browsersIcons from '../../data/browsers-logos.js' + +export function updateRegionCoverageCounter(coverage) { + let element = document.querySelector('[data-id=region_coverage_counter]') + element.innerHTML = coverage + '%' +} + +export function updateRegionCoverageBar(data) { + let element = document.querySelector('[data-id=region_coverage_bar]') + element.innerHTML = '' + data.forEach(item => { + let itemElem = document.createElement('li') + itemElem.classList.add('BrowsersStat__regionCoverageBarItem') + itemElem.style.setProperty('--proportion', item.coverage) + itemElem.style.setProperty('--alpha', 1 - 1 / item.coverage) + if (item.coverage > 10) { + itemElem.innerHTML = item.name + itemElem.classList.add('BrowsersStat__regionCoverageBarItem--texted') + } + element.appendChild(itemElem) + }) +} + +export function showStats() { + let statsPlaceholder = document.querySelector( + '[data-id=browsers_stats_placeholder]' + ) + let browserStats = document.querySelector('[data-id=browsers_stats]') + + statsPlaceholder.classList.add('BrowsersStat__placeholder--hidden') + browserStats.classList.remove('BrowsersStat__stat--hidden') +} + +function createCoverageCell(coverage) { + let coveragePercentageHtmlString = cov => cov + '%' + let coveragePercentageCssString = cov => { + let result = (Math.log(1 + cov) * 100) / Math.log(1 + 100) + if (result === 0) { + return '0' + } else if (result > 5) { + return result + '%' + } + return '1px' + } + + let coverageCell = document.createElement('td') + coverageCell.classList.add('BrowsersStat__td') + coverageCell.innerHTML = coveragePercentageHtmlString(coverage) + coverageCell.classList.add('BrowsersStat__td--coverage') + + coverageCell.style.setProperty( + '--coverage', + coveragePercentageCssString(coverage) + ) + return coverageCell +} + +function createVersionCell(version) { + let versionCell = document.createElement('td') + versionCell.classList.add('BrowsersStat__td') + versionCell.innerHTML = version + return versionCell +} + +export function updateBrowsersStats(data) { + let element = document.querySelector('[data-id=browsers_stats_results]') + + let table = document.createElement('table') + table.classList.add('BrowsersStat__table') + + data.forEach(({ id, name, versions: versionsInput }) => { + let versions = Object.entries(versionsInput) + .sort(([versionA], [versionB]) => versionB - versionA) + .map(([version, coverage]) => { + return { + version, + coverage + } + }) + + let tBody = document.createElement('tbody') + let tr = document.createElement('tr') + tr.classList.add('BrowsersStat_tr') + + let iconCell = document.createElement('td') + iconCell.classList.add('BrowsersStat__td') + iconCell.setAttribute('rowspan', versions.length) + tr.appendChild(iconCell) + + if (id in browsersIcons) { + let iconElem = document.createElement('img') + iconElem.classList.add('BrowsersStat__icon') + iconElem.src = browsersIcons[id] + iconElem.setAttribute('alt', '') + iconCell.appendChild(iconElem) + } + + let nameCell = document.createElement('td') + nameCell.classList.add('BrowsersStat__td') + let nameLink = document.createElement('a') + nameLink.classList.add('Link') + // TODO Need to take care of the case when we do not have link for some browser. Can I Use sometimes adds browsers + nameLink.href = wikipediaLinks[id] + nameLink.rel = 'noreferrer noopener' + nameLink.target = '_blank' + nameCell.setAttribute('rowspan', versions.length) + nameLink.innerHTML = name + nameCell.appendChild(nameLink) + tr.appendChild(nameCell) + + tr.appendChild(createVersionCell(versions[0].version)) + + tr.appendChild(createCoverageCell(versions[0].coverage)) + + tBody.appendChild(tr) + + versions.slice(1).forEach(item => { + let { version, coverage } = item + let versionTr = document.createElement('tr') + + versionTr.appendChild(createVersionCell(version)) + + versionTr.appendChild(createCoverageCell(coverage)) + + tBody.appendChild(versionTr) + }) + table.appendChild(tBody) + }) + + element.innerHTML = '' + element.appendChild(table) +} + +export function updateToolsVersions({ browserslist, caniuse }) { + let canIUseElement = document.querySelector('[data-id=can_i_use_version]') + canIUseElement.innerHTML = caniuse + + let browsersListElement = document.querySelector( + '[data-id=browsers_list_version]' + ) + browsersListElement.innerHTML = browserslist +} diff --git a/client/view/BrowserStats/hedgehog.svg b/client/view/BrowserStats/hedgehog.svg new file mode 100644 index 00000000..04c1bcec --- /dev/null +++ b/client/view/BrowserStats/hedgehog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/DocSection/DocSection.css b/client/view/DocSection/DocSection.css new file mode 100644 index 00000000..b3840e35 --- /dev/null +++ b/client/view/DocSection/DocSection.css @@ -0,0 +1,61 @@ +.DocSection { + padding: 16px; + background-color: var(--bg-highlited); + border-radius: 8px; +} + +.DocSection + .DocSection { + margin-top: 24px; +} + +.DocSection__header { + margin: 0; + font-size: 18px; + font-weight: 600; + line-height: 24px; +} + +.DocSection p { + font-size: 16px; + line-height: 22px; +} + +.DocSection__subHeader { + margin-top: 24px; + margin-bottom: 10px; + font-size: 12px; + font-weight: 800; + line-height: 16px; + text-transform: uppercase; +} + +summary .DocSection__subHeader { + display: inline-block; + margin-bottom: 0; +} + +.DocSection details summary { + width: fit-content; + cursor: pointer; +} + +.DocSection details[open] summary { + margin-bottom: 8px; +} + +.DocSection__list { + padding: 0; + margin: 0; +} + +.DocSection__list li { + margin: 0; + font-size: 16px; + font-weight: 400; + line-height: 22px; + list-style: none; +} + +.DocSection__list li + li { + margin-top: 10px; +} diff --git a/client/view/Form/Form.css b/client/view/Form/Form.css new file mode 100644 index 00000000..bbd0d90d --- /dev/null +++ b/client/view/Form/Form.css @@ -0,0 +1,163 @@ +.Form { + display: flex; + flex-direction: column; + gap: 24px; +} + +.Form__queryTextAreaContainer { + position: relative; +} + +.Form__queryTextArea { + box-sizing: border-box; + width: 100%; + padding: 12px; + font-family: monospace, monospace; + font-size: inherit; + color: inherit; + background-color: var(--main-bg); + border: none; + border-radius: 8px; +} + +.Form__queryTextArea::placeholder { + opacity: 0%; +} + +.Form__queryTextArea:focus-visible { + outline-color: var(--accent); +} + +.Form__hint, +.Form__loader { + position: absolute; + bottom: 16px; + left: 16px; + max-width: calc(100% - 12px * 2); + margin: 0; + font-size: 14px; + font-weight: 500; + line-height: 1; + color: var(--text-secondary); + overflow-wrap: break-word; + pointer-events: none; + background-color: var(--main-bg); + opacity: 0%; + transition: opacity 0.2s linear; +} + +.Form__hint--hidden { + opacity: 0%; +} + +.Form__enterIcon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + margin: calc((20px - 1em) / -2) 0; + vertical-align: middle; + background-color: var(--bg-highlited); + border-radius: 2px; +} + +.Form__interactivePlaceholder { + position: absolute; + top: 12px; + left: 12px; + margin: 0; + font-family: monospace, monospace; + color: var(--text-secondary); + pointer-events: none; + opacity: 0%; +} + +.Form__hint--required { + color: var(--warning); +} + +.Form__hint--error { + color: var(--error); +} + +.Form__hint--error a { + color: inherit; + pointer-events: initial; +} + +.Form.Form--serverError:not(.Form--loaded) .Form__hint--error { + opacity: 100%; +} + +.Form__queryTextArea:placeholder-shown ~ .Form__interactivePlaceholder { + pointer-events: none; + opacity: 100%; +} + +.Form__queryTextArea:placeholder-shown ~ .Form__interactivePlaceholder a { + pointer-events: initial; +} + +.Form:not(.Form--serverError):not(.Form--loaded) .Form__queryTextArea:invalid:focus-visible ~ .Form__hint--required { + opacity: 100%; +} + +.Form:not(.Form--serverError):not(.Form--justSend):not(.Form--loaded) .Form__queryTextArea:focus-visible:valid ~ .Form__hint--progress { + opacity: 100%; +} + +.Form--loaded .Form__loader { + opacity: 100%; +} + +.Form__loader::after { + display: inline-block; + width: 1em; + height: 1em; + margin-left: 1ch; + content: ""; + background-image: + radial-gradient(var(--main-bg) 60%, transparent 60%), + conic-gradient(transparent, currentcolor); + border-radius: 50%; + animation-name: form-loader; + animation-duration: 1s; + animation-timing-function: cubic-bezier(0.5, 0.2, 0.5, 0.8); + animation-iteration-count: infinite; +} + +@keyframes form-loader { + 0% { + transform: rotate(0); + } + + 100% { + transform: rotate(360deg); + } +} + +.Form__coverage { + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + justify-content: space-between; +} + +.Form__coverage--hidden { + display: none; +} + +.Form__coverageSelect { + width: fit-content; + max-width: 200px; + padding: 2px 8px; + font-size: 16px; + line-height: 20px; + color: var(--accent); + background-color: var(--main-bg); + background-image: none; + border: none; + border-radius: 4px; +} diff --git a/client/view/Form/form.js b/client/view/Form/form.js new file mode 100644 index 00000000..eec7012a --- /dev/null +++ b/client/view/Form/form.js @@ -0,0 +1,196 @@ +import { DEFAULT_REGION, regionList, regionGroups } from '../../data/regions.js' +import { + updateBrowsersStats, + updateRegionCoverageCounter, + updateRegionCoverageBar, + updateToolsVersions, + showStats +} from '../BrowserStats/browserStats.js' + +const form = document.querySelector('[data-id=query_form]') +const textarea = document.querySelector('[data-id=query_text_area]') +const regionCoverage = document.querySelector('[data-id=region_coverage]') +const regionCoverageSelect = document.querySelector( + '[data-id=region_coverage_select]' +) +const errorMessage = document.querySelector('[data-id=error_message]') + +form.addEventListener('submit', handleFormSubmit) + +textarea.addEventListener('keypress', e => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault() + submitForm() + } +}) + +renderRegionSelectOptions() + +regionCoverageSelect.addEventListener('change', () => { + submitForm() +}) + +submitFormWithUrlParams() + +window.addEventListener('popstate', () => { + submitFormWithUrlParams() +}) + +function handleFormSubmit(e) { + e.preventDefault() + if (!form.checkValidity()) { + return + } + + let formData = new FormData(form) + let query = formData.get('query') + let region = formData.get('region') + + changeUrl(query, region) + + e.preventDefault() + form.classList.add('Form--justSend') + textarea.addEventListener( + 'input', + () => { + form.classList.remove('Form--justSend') + }, + { + once: true + } + ) + updateStatsView(query, region) +} + +export function setFormValues({ query, region }) { + if (query) { + textarea.value = query + form.classList.remove('Form--serverError') + } + + let isRegionExists = regionList.includes(region) + + if (region && isRegionExists) { + regionCoverageSelect.value = region + } +} + +export function submitForm() { + form.dispatchEvent(new Event('submit', { cancelable: true })) +} + +function showCoverageControls() { + regionCoverage.classList.remove('Form__coverage--hidden') +} + +function renderRegionSelectOptions() { + let renderOptgroups = ({ continents, countries }) => { + let renderOption = (id, name) => { + let option = document.createElement('option') + option.value = id + option.innerHTML = name + return option + } + + let renderOptgroup = (groupName, regionsGroup) => { + let optgroup = document.createElement('optgroup') + optgroup.label = groupName + for (let { id, name } of regionsGroup) { + let option = renderOption(id, name) + optgroup.appendChild(option) + } + return optgroup + } + + return { + continentsOptgroup: renderOptgroup('Continents', continents), + countriesOptgroup: renderOptgroup('Countries', countries) + } + } + + let { continentsOptgroup, countriesOptgroup } = renderOptgroups(regionGroups) + regionCoverageSelect.appendChild(continentsOptgroup) + regionCoverageSelect.appendChild(countriesOptgroup) +} + +function renderError(message) { + errorMessage.innerHTML = message + form.classList.add('Form--serverError') + textarea.addEventListener( + 'input', + () => { + form.classList.remove('Form--serverError') + }, + { + once: true + } + ) +} + +async function updateStatsView(query, region) { + let response + try { + form.classList.add('Form--loaded') + let urlParams = new URLSearchParams({ q: query, region }) + response = await fetch(`/api/browsers?${urlParams}`) + } catch (error) { + renderError(`Network error. Check that you are online.`) + form.classList.remove('Form--loaded') + return false + } + + let data = await response.json() + + form.classList.remove('Form--loaded') + + if (!response.ok) { + if (data.message === 'Custom usage statistics was not provided') { + renderError(`This website does not support in my stats queries yet. Run Browserslist + locally.`) + return false + } + if (response.status === 500) { + renderError(`Server error. +Report an issue to our repository.`) + return false + } + renderError(data.message) + return false + } + + let { browsers, coverage, versions } = data + + showCoverageControls() + showStats() + updateBrowsersStats(browsers) + updateRegionCoverageCounter(coverage) + updateRegionCoverageBar(browsers) + updateToolsVersions(versions) + + return true +} + +function changeUrl(query, region) { + let urlParams = new URLSearchParams() + if (query) { + urlParams.set('q', query) + } + + if (region && region !== DEFAULT_REGION) { + urlParams.set('region', region) + } + + window.history.pushState({}, query, '?' + urlParams) +} + +function submitFormWithUrlParams() { + let urlParams = new URLSearchParams(window.location.search) + + let query = urlParams.get('q') + let region = urlParams.get('region') + + if (!query) return + + setFormValues({ query, region }) + submitForm() +} diff --git a/client/view/Link/Link.css b/client/view/Link/Link.css new file mode 100644 index 00000000..d55dbfc5 --- /dev/null +++ b/client/view/Link/Link.css @@ -0,0 +1,17 @@ +.Link { + padding-bottom: 0.2em; + margin-bottom: -0.2em; + color: var(--text-primary); + text-decoration-line: underline; + text-decoration-style: solid; + text-decoration-color: var(--text-secondary); + text-underline-offset: 2px; + transition: text-decoration-color 0.3s; +} + +@media (hover) { + .Link:hover { + text-decoration-color: currentcolor; + background-position: 0 1.1em; + } +} diff --git a/client/view/Pre/Pre.css b/client/view/Pre/Pre.css new file mode 100644 index 00000000..4c186940 --- /dev/null +++ b/client/view/Pre/Pre.css @@ -0,0 +1,17 @@ +.Pre { + display: flex; + flex-direction: column; + padding: 12px; + font-size: inherit; + color: var(--accent); + background-color: var(--text-highlited); + border-radius: 8px; + transition: background-color 0.3s; +} + +.Pre code { + overflow: hidden; + font-size: inherit; + white-space: pre-wrap; + background-color: initial; +} diff --git a/client/view/QueryLink/QueryLink.css b/client/view/QueryLink/QueryLink.css new file mode 100644 index 00000000..0583bffb --- /dev/null +++ b/client/view/QueryLink/QueryLink.css @@ -0,0 +1,19 @@ +.QueryLink { + cursor: pointer; +} + +@media (hover) { + .QueryLink:hover > code, + .QueryLink:hover > pre { + background-color: var(--text-highlited-hover); + } +} + +.QueryLink > code { + padding: 0 4px; + line-height: 20px; + color: var(--accent); + background-color: var(--text-highlited); + border-radius: 4px; + transition: background-color 0.3s; +} diff --git a/client/view/QueryLink/queryLink.js b/client/view/QueryLink/queryLink.js new file mode 100644 index 00000000..bcaf056f --- /dev/null +++ b/client/view/QueryLink/queryLink.js @@ -0,0 +1,21 @@ +import { setFormValues, submitForm } from '../Form/form.js' + +const queryContainer = document.querySelector('[data-id=query_container]') +const links = document.querySelectorAll('a.QueryLink') + +links.forEach(item => { + item.addEventListener('click', e => { + e.preventDefault() + let queryAttr = item.getAttribute('data-query') + if (queryAttr) { + setFormValues({ query: queryAttr }) + } else { + setFormValues({ query: item.innerText.trim() }) + } + + submitForm() + + queryContainer.scrollTo({ top: 0 }) + queryContainer.scrollIntoView() + }) +}) diff --git a/client/view/Tweet/Tweet.css b/client/view/Tweet/Tweet.css new file mode 100644 index 00000000..ee8d61b4 --- /dev/null +++ b/client/view/Tweet/Tweet.css @@ -0,0 +1,86 @@ +.Tweet { + position: relative; + z-index: 1; + height: fit-content; + padding: 16px; + overflow: hidden; + pointer-events: none; + border: 1px solid var(--separator); + border-radius: 12px; +} + +.Tweet__link { + position: absolute; + inset: 0; + z-index: -1; + pointer-events: all; + transition: background-color 0.3s; +} + +@media (hover) { + .Tweet__link:hover { + background-color: var(--text-highlited); + } +} + +.Tweet__address { + position: relative; + display: grid; + grid-template-columns: 40px 1fr; + grid-auto-rows: 1fr 1fr; + column-gap: 10px; + margin-bottom: 10px; + font-style: normal; +} + +.Tweet__address::after { + position: absolute; + bottom: -3px; + left: 26px; + width: 16px; + height: 16px; + content: ""; + background-color: var(--twitter); + background-image: url(./twitter_white.svg); + background-repeat: no-repeat; + background-position: center; + border-radius: 50%; +} + +.Tweet__img { + grid-row: span 2; + width: 40px; + height: 40px; + border-radius: 50%; +} + +.Tweet__nickName { + color: var(--text-secondary); + text-decoration: none; +} + +.Tweet__name { + font-weight: 600; +} + +.Tweet__text { + margin: 0; +} + +.Tweet__text a { + color: var(--accent); + text-decoration: none; + pointer-events: initial; +} + +@media (hover) { + .Tweet__text a:hover { + text-decoration: underline; + } +} + +.Tweet__list { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 12px; +} diff --git a/client/view/Tweet/gha_dev.webp b/client/view/Tweet/gha_dev.webp new file mode 100644 index 00000000..ca583c66 Binary files /dev/null and b/client/view/Tweet/gha_dev.webp differ diff --git a/client/view/Tweet/rossta.webp b/client/view/Tweet/rossta.webp new file mode 100644 index 00000000..7b22b779 Binary files /dev/null and b/client/view/Tweet/rossta.webp differ diff --git a/client/view/Tweet/twitter_white.svg b/client/view/Tweet/twitter_white.svg new file mode 100644 index 00000000..8ec83749 --- /dev/null +++ b/client/view/Tweet/twitter_white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/base/apple-touch-icon.png b/client/view/base/apple-touch-icon.png new file mode 100644 index 00000000..0f2c5e28 Binary files /dev/null and b/client/view/base/apple-touch-icon.png differ diff --git a/client/view/base/colors.css b/client/view/base/colors.css new file mode 100644 index 00000000..c2c4dae9 --- /dev/null +++ b/client/view/base/colors.css @@ -0,0 +1,37 @@ +/* TODO types for this variables */ + +@media (prefers-color-scheme: light) { + :root { + --main-bg: oklch(100% 0 0); + --bg-highlited: oklch(97% 0.003 286.35); + --accent: oklch(53.05% 0.192 258.53); + --text-highlited: oklch(53% 0.192 258.53 / 7%); + --text-highlited-hover: oklch(57.37% 0.195 257.86 / 14%); + --text-primary: oklch(11.264% 0.1 139.088); + --text-secondary: oklch(23.5% 0 0 / 40%); + --accent-blue-primary: oklch(43.639% 45.224 280.199); + --accent-alternave: oklch(88.4% 0.41 92.834); + --separator: oklch(23.5% 0 0 / 12%); + --warning: oklch(73% 100 65.45 / 80%); + --error: oklch(66% 0.096 30.71); + --twitter: oklch(70.35% 0.124 234.85); + } +} + +@media (prefers-color-scheme: dark) { + :root { + --main-bg: oklch(23.5% 0 0); + --bg-highlited: oklch(30.72% 0.009 285.86); + --accent: oklch(77.05% 0.12 255); + --text-highlited: oklch(66.37% 0.18 256.56 / 20%); + --text-highlited-hover: oklch(66.37% 0.185 256.56 / 30%); + --text-primary: oklch(100% 0.1 139.088); + --text-secondary: oklch(60% 0.01 257); + --accent-blue-primary: oklch(43.639% 45.224 280.199); + --accent-alternave: oklch(63.02% 0.13 78.82); + --separator: oklch(100% 3.55 106.37 / 12%); + --warning: oklch(47.96% 0.103 65.45); + --error: oklch(66% 0.096 30.71); + --twitter: oklch(70.35% 0.124 234.85); + } +} diff --git a/client/view/base/icon.svg b/client/view/base/icon.svg new file mode 100644 index 00000000..ef709633 --- /dev/null +++ b/client/view/base/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/view/base/index.css b/client/view/base/index.css new file mode 100644 index 00000000..61f8ce9a --- /dev/null +++ b/client/view/base/index.css @@ -0,0 +1,48 @@ +@import "../BrowserStats/BrowsersStat.css"; +@import "../Article/Article.css"; +@import "../Form/Form.css"; +@import "../Badge/Badge.css"; +@import "../QueryLink/QueryLink.css"; +@import "../DocSection/DocSection.css"; +@import "../Link/Link.css"; +@import "../Pre/Pre.css"; +@import "../Tweet/Tweet.css"; + +@media (prefers-reduced-motion: reduce) { + * { + transition: none !important; + } +} + +body { + margin: 0; + font-family: + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Fira Sans", + "Droid Sans", + "Helvetica Neue", + sans-serif; + color: var(--text-primary); + overflow-wrap: break-word; + background-color: var(--main-bg); + accent-color: var(--accent); +} + +p { + font-size: 16px; + line-height: 22px; + letter-spacing: 0.01em; +} + +code { + /* stylelint-disable-next-line font-family-no-duplicate-names */ + font-family: monospace, monospace; + + /* explain: https://github.com/necolas/normalize.css/issues/519#issuecomment-197131966 */ +} diff --git a/client/vite.config.js b/client/vite.config.js new file mode 100644 index 00000000..f128a1f2 --- /dev/null +++ b/client/vite.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite' +import vitePluginPug from 'vite-plugin-pug-transformer' + +export default defineConfig({ + build: { + assetsDir: '.', + assetsInlineLimit: 0 + }, + plugins: [vitePluginPug()] +}) diff --git a/index.html b/index.html deleted file mode 100644 index 4eeb989c..00000000 --- a/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - Help Browserslist - - - -
    -

    Browserslist website is down.
    Help us make a new and better website.

    -

    Short-term solution

    -

    Use CLI tool instead of the website
    npx browserslist "last 1 version, >1%"

    -

    Long-term solution

    - -

    Why Browserslist is important for JS ecosystem?

    -

    Browserslist is used by many popular tools, including Autoprefixer, Babel, Gatsby, Next.js, Create React App, and other 600+ projects. It has 75+ million downloads per month.

    -

    It helps to keep browsers diversity by moving the focus from few well-know Western browsers (like chrome: 60) to general queries (like 1 last version, >1% or supports es6-module and >0.5% in my stats).

    -

    You can learn more about philosophy under Browserslist in our interview with Google’s The State of the Web.

    -
    - xkcd about dependencies problem in modern open source -
    xkcd: Dependency
    -
    -

    How will we use your donations?

    -
      -
    1. We will pay to the designer and make a redesign for the website.
    2. -
    3. We will refactor the website to run it in a new hosting.
    4. -
    5. In the new website design, we will Browserslist config best practices to promote browser diversity.
    6. -
    7. We will refactor the Browserslist data updates system to avoid the security issue similar to the recent ESLint issue.
    8. -
    9. Add Browserslist config linter.
    10. -
    -
    - - \ No newline at end of file diff --git a/nano-staged.json b/nano-staged.json new file mode 100644 index 00000000..fb6147b0 --- /dev/null +++ b/nano-staged.json @@ -0,0 +1,5 @@ +{ + "*.css": "stylelint --fix", + "*.js": "prettier --write", + "*.svg": "svgo" +} diff --git a/package.json b/package.json index 9443f60f..266d8569 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,42 @@ { - "name": "browserlist", - "version": "0.0.0", + "name": "browserl.ist", "private": true, + "homepage": "https://browsersl.ist/", + "type": "module", + "license": "MIT", + "engines": { + "node": ">=18" + }, "scripts": { - "build": "", - "lint": "eslint bin/www .", - "deploy": "script/deploy", - "start": "node ./bin/www", - "test": "npm run lint" + "start": "pnpm -r start", + "build": "pnpm -r build", + "lint": "eslint . && stylelint **/*.css", + "test": "pnpm audit --prod && pnpm lint && pnpm -r test" }, "dependencies": { - "body-parser": "^1.19.0", - "browserslist": "4.8.3", - "caniuse-db": "1.0.30001019", - "cookie-parser": "^1.4.4", - "debug": "^4.1.1", - "express": "^4.17.1", - "morgan": "^1.9.1", - "pug": "^2.0.4" + "ssdeploy": "^0.9.1" }, "devDependencies": { - "eslint": "^6.6.0", - "eslint-plugin-github": "^3.2.1" + "@logux/eslint-config": "^47.2.0", + "@logux/stylelint-config": "^0.10.1", + "@typescript-eslint/eslint-plugin": "^5.33.0", + "@typescript-eslint/parser": "^5.33.0", + "eslint": "^8.21.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.2.4", + "eslint-plugin-prefer-let": "^3.0.1", + "eslint-plugin-promise": "^6.0.0", + "nano-staged": "^0.8.0", + "prettier": "^2.7.1", + "simple-git-hooks": "^2.8.0", + "stylelint": "^14.10.0", + "svgo": "^2.8.0", + "typescript": "^4.7.4" + }, + "pnpm": { + "overrides": { + "markdown-it@<12.3.2": ">=12.3.2" + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..0c7d81ab --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3208 @@ +lockfileVersion: 5.4 + +overrides: + markdown-it@<12.3.2: '>=12.3.2' + +importers: + + .: + specifiers: + '@logux/eslint-config': ^47.2.0 + '@logux/stylelint-config': ^0.10.1 + '@typescript-eslint/eslint-plugin': ^5.33.0 + '@typescript-eslint/parser': ^5.33.0 + eslint: ^8.21.0 + eslint-config-standard: ^17.0.0 + eslint-plugin-import: ^2.26.0 + eslint-plugin-n: ^15.2.4 + eslint-plugin-prefer-let: ^3.0.1 + eslint-plugin-promise: ^6.0.0 + nano-staged: ^0.8.0 + prettier: ^2.7.1 + simple-git-hooks: ^2.8.0 + ssdeploy: ^0.9.1 + stylelint: ^14.10.0 + svgo: ^2.8.0 + typescript: ^4.7.4 + dependencies: + ssdeploy: 0.9.1 + devDependencies: + '@logux/eslint-config': 47.2.0_7hz3xvmviof7onfgk6hpedqcom + '@logux/stylelint-config': 0.10.1_stylelint@14.10.0 + '@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq + '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + eslint: 8.21.0 + eslint-config-standard: 17.0.0_dfwa53o44x4e5xhsfv5mvfhk5a + eslint-plugin-import: 2.26.0_qfqnhzzittf54udqwes54xx65q + eslint-plugin-n: 15.2.4_eslint@8.21.0 + eslint-plugin-prefer-let: 3.0.1 + eslint-plugin-promise: 6.0.0_eslint@8.21.0 + nano-staged: 0.8.0 + prettier: 2.7.1 + simple-git-hooks: 2.8.0 + stylelint: 14.10.0 + svgo: 2.8.0 + typescript: 4.7.4 + + client: + specifiers: + '@csstools/postcss-oklab-function': ^1.1.1 + '@size-limit/file': ^8.0.1 + autoprefixer: ^10.4.8 + caniuse-lite: ^1.0.30001375 + jstransformer-markdown-it: ^3.0.0 + postcss: ^8.4.16 + postcss-media-minmax: ^5.0.0 + postcss-nesting: ^10.1.10 + postcss-opacity-percentage: ^1.1.2 + size-limit: ^8.0.1 + vite: ^3.0.7 + vite-plugin-pug-transformer: ^1.0.2 + dependencies: + '@csstools/postcss-oklab-function': 1.1.1_postcss@8.4.16 + autoprefixer: 10.4.8_postcss@8.4.16 + caniuse-lite: 1.0.30001375 + jstransformer-markdown-it: 3.0.0 + postcss: 8.4.16 + postcss-media-minmax: 5.0.0_postcss@8.4.16 + postcss-nesting: 10.1.10_postcss@8.4.16 + postcss-opacity-percentage: 1.1.2 + vite: 3.0.7 + vite-plugin-pug-transformer: 1.0.2_vite@3.0.7 + devDependencies: + '@size-limit/file': 8.0.1_size-limit@8.0.1 + size-limit: 8.0.1 + + server: + specifiers: + browserslist: ^4.21.3 + caniuse-lite: ^1.0.30001375 + dependencies: + browserslist: 4.21.3 + caniuse-lite: 1.0.30001375 + +packages: + + /@babel/code-frame/7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + dev: true + + /@babel/helper-string-parser/7.18.10: + resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-identifier/7.18.6: + resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} + engines: {node: '>=6.9.0'} + + /@babel/highlight/7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.18.6 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser/7.18.11: + resolution: {integrity: sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.18.10 + dev: false + + /@babel/types/7.18.10: + resolution: {integrity: sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.18.10 + '@babel/helper-validator-identifier': 7.18.6 + to-fast-properties: 2.0.0 + dev: false + + /@csstools/postcss-oklab-function/1.1.1_postcss@8.4.16: + resolution: {integrity: sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==} + engines: {node: ^12 || ^14 || >=16} + peerDependencies: + postcss: ^8.2 + dependencies: + '@csstools/postcss-progressive-custom-properties': 1.3.0_postcss@8.4.16 + postcss: 8.4.16 + postcss-value-parser: 4.2.0 + dev: false + + /@csstools/postcss-progressive-custom-properties/1.3.0_postcss@8.4.16: + resolution: {integrity: sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==} + engines: {node: ^12 || ^14 || >=16} + peerDependencies: + postcss: ^8.3 + dependencies: + postcss: 8.4.16 + postcss-value-parser: 4.2.0 + dev: false + + /@csstools/selector-specificity/2.0.2_pnx64jze6bptzcedy5bidi3zdi: + resolution: {integrity: sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==} + engines: {node: ^12 || ^14 || >=16} + peerDependencies: + postcss: ^8.2 + postcss-selector-parser: ^6.0.10 + dependencies: + postcss: 8.4.16 + postcss-selector-parser: 6.0.10 + + /@esbuild/linux-loong64/0.14.54: + resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@eslint/eslintrc/1.3.0: + resolution: {integrity: sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.3.3 + globals: 13.17.0 + ignore: 5.2.0 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/config-array/0.10.4: + resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/gitignore-to-minimatch/1.0.2: + resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==} + dev: true + + /@humanwhocodes/object-schema/1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@logux/eslint-config/47.2.0_7hz3xvmviof7onfgk6hpedqcom: + resolution: {integrity: sha512-nNPPkw+kfA2bLyhkxaqGzd3MWSN4S2dUf69xo2syskBd5ZfFk2WT9ssO+yDDUd26yNgN3AmweKztEwyUim9wOQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + eslint: ^8.14.0 + eslint-config-standard: ^17.0.0 + eslint-plugin-import: ^2.26.0 + eslint-plugin-n: ^15.1.0 + eslint-plugin-prefer-let: ^3.0.1 + eslint-plugin-promise: ^6.0.0 + dependencies: + eslint: 8.21.0 + eslint-config-standard: 17.0.0_dfwa53o44x4e5xhsfv5mvfhk5a + eslint-plugin-import: 2.26.0_qfqnhzzittf54udqwes54xx65q + eslint-plugin-n: 15.2.4_eslint@8.21.0 + eslint-plugin-prefer-let: 3.0.1 + eslint-plugin-promise: 6.0.0_eslint@8.21.0 + dev: true + + /@logux/stylelint-config/0.10.1_stylelint@14.10.0: + resolution: {integrity: sha512-LdqGWEO/IisgQMhtu2t18ygmFP1c38CD4d2HmFIonTvNPKJAAyGcYexOdi8MkUxdGC3oXR4dwJII3z4apiEhNQ==} + peerDependencies: + stylelint: ^14.2.0 + dependencies: + stylelint: 14.10.0 + stylelint-config-recess-order: 3.0.0_stylelint@14.10.0 + stylelint-config-standard: 25.0.0_stylelint@14.10.0 + stylelint-order: 5.0.0_stylelint@14.10.0 + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: true + + /@size-limit/file/8.0.1_size-limit@8.0.1: + resolution: {integrity: sha512-kwgc5UJQIz5qbRow3atSiW2K7vEIIw4DelT4WLn09cOwcJgWs82Imgz2UqVivHJmCisn/ltPjT4qmxaDfjFflw==} + engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} + peerDependencies: + size-limit: 8.0.1 + dependencies: + semver: 7.3.7 + size-limit: 8.0.1 + dev: true + + /@trysound/sax/0.2.0: + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + dev: true + + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + + /@types/json5/0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/minimist/1.2.2: + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + dev: true + + /@types/normalize-package-data/2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + + /@types/parse-json/4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + dev: true + + /@typescript-eslint/eslint-plugin/5.33.0_njno5y7ry2l2lcmiu4tywxkwnq: + resolution: {integrity: sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/scope-manager': 5.33.0 + '@typescript-eslint/type-utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + debug: 4.3.4 + eslint: 8.21.0 + functional-red-black-tree: 1.0.1 + ignore: 5.2.0 + regexpp: 3.2.0 + semver: 7.3.7 + tsutils: 3.21.0_typescript@4.7.4 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: + resolution: {integrity: sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.33.0 + '@typescript-eslint/types': 5.33.0 + '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 + debug: 4.3.4 + eslint: 8.21.0 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager/5.33.0: + resolution: {integrity: sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.33.0 + '@typescript-eslint/visitor-keys': 5.33.0 + dev: true + + /@typescript-eslint/type-utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: + resolution: {integrity: sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + debug: 4.3.4 + eslint: 8.21.0 + tsutils: 3.21.0_typescript@4.7.4 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types/5.33.0: + resolution: {integrity: sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.33.0_typescript@4.7.4: + resolution: {integrity: sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.33.0 + '@typescript-eslint/visitor-keys': 5.33.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.7 + tsutils: 3.21.0_typescript@4.7.4 + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: + resolution: {integrity: sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@typescript-eslint/scope-manager': 5.33.0 + '@typescript-eslint/types': 5.33.0 + '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 + eslint: 8.21.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.21.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys/5.33.0: + resolution: {integrity: sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.33.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /acorn-jsx/5.3.2_acorn@8.8.0: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.0 + dev: true + + /acorn/7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /acorn/8.8.0: + resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv/8.11.0: + resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse/2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + /array-includes/3.1.5: + resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + get-intrinsic: 1.1.2 + is-string: 1.0.7 + dev: true + + /array-union/2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat/1.3.0: + resolution: {integrity: sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + es-shim-unscopables: 1.0.0 + dev: true + + /arrify/1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + dev: true + + /asap/2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: false + + /assert-never/1.2.1: + resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} + dev: false + + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /autoprefixer/10.4.8_postcss@8.4.16: + resolution: {integrity: sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.3 + caniuse-lite: 1.0.30001375 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.16 + postcss-value-parser: 4.2.0 + dev: false + + /babel-walk/3.0.0-canary-5: + resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/types': 7.18.10 + dev: false + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /balanced-match/2.0.0: + resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /boolbase/1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion/2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browserslist/4.21.3: + resolution: {integrity: sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001375 + electron-to-chromium: 1.4.217 + node-releases: 2.0.6 + update-browserslist-db: 1.0.5_browserslist@4.21.3 + dev: false + + /builtins/5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.3.7 + dev: true + + /bytes-iec/3.1.1: + resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} + engines: {node: '>= 0.8'} + dev: true + + /bytes/3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: false + + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.2 + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-keys/6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: true + + /camelcase/5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /caniuse-lite/1.0.30001375: + resolution: {integrity: sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==} + dev: false + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /character-parser/2.2.0: + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} + dependencies: + is-regex: 1.1.4 + dev: false + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /ci-job-number/1.2.2: + resolution: {integrity: sha512-CLOGsVDrVamzv8sXJGaILUVI6dsuAkouJP/n6t+OxLPeeA4DDby7zn9SB6EUpa1H7oIKoE+rMmkW80zYsFfUjA==} + dev: true + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colord/2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + dev: true + + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /constantinople/4.0.1: + resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} + dependencies: + '@babel/parser': 7.18.11 + '@babel/types': 7.18.10 + dev: false + + /cosmiconfig/7.0.1: + resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /css-functions-list/3.1.0: + resolution: {integrity: sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==} + engines: {node: '>=12.22'} + dev: true + + /css-select/4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + dev: true + + /css-tree/1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + dev: true + + /css-what/6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + /csso/4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + dependencies: + css-tree: 1.1.3 + dev: true + + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /decamelize-keys/1.1.0: + resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} + engines: {node: '>=0.10.0'} + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + dev: true + + /decamelize/1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /deep-is/0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-lazy-prop/2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: false + + /define-properties/1.1.4: + resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /dir-glob/3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine/2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine/3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctypes/1.1.0: + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} + dev: false + + /dom-serializer/1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + dev: true + + /domelementtype/2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domhandler/4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + + /domutils/2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + dev: true + + /dotenv/16.0.1: + resolution: {integrity: sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==} + engines: {node: '>=12'} + dev: false + + /electron-to-chromium/1.4.217: + resolution: {integrity: sha512-iX8GbAMij7cOtJPZo02CClpaPMWjvN5meqXiJXkBgwvraNWTNH0Z7F9tkznI34JRPtWASoPM/xWamq3oNb49GA==} + dev: false + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /entities/2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true + + /entities/3.0.1: + resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} + engines: {node: '>=0.12'} + dev: false + + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract/1.20.1: + resolution: {integrity: sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.1.2 + get-symbol-description: 1.0.0 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-symbols: 1.0.3 + internal-slot: 1.0.3 + is-callable: 1.2.4 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-weakref: 1.0.2 + object-inspect: 1.12.2 + object-keys: 1.1.1 + object.assign: 4.1.3 + regexp.prototype.flags: 1.4.3 + string.prototype.trimend: 1.0.5 + string.prototype.trimstart: 1.0.5 + unbox-primitive: 1.0.2 + dev: true + + /es-shim-unscopables/1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.4 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild-android-64/0.14.54: + resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-android-arm64/0.14.54: + resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-64/0.14.54: + resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-arm64/0.14.54: + resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-64/0.14.54: + resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-arm64/0.14.54: + resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-32/0.14.54: + resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-64/0.14.54: + resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm/0.14.54: + resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm64/0.14.54: + resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-mips64le/0.14.54: + resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-ppc64le/0.14.54: + resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-riscv64/0.14.54: + resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-s390x/0.14.54: + resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-netbsd-64/0.14.54: + resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-openbsd-64/0.14.54: + resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-sunos-64/0.14.54: + resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-32/0.14.54: + resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-64/0.14.54: + resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-arm64/0.14.54: + resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild/0.14.54: + resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/linux-loong64': 0.14.54 + esbuild-android-64: 0.14.54 + esbuild-android-arm64: 0.14.54 + esbuild-darwin-64: 0.14.54 + esbuild-darwin-arm64: 0.14.54 + esbuild-freebsd-64: 0.14.54 + esbuild-freebsd-arm64: 0.14.54 + esbuild-linux-32: 0.14.54 + esbuild-linux-64: 0.14.54 + esbuild-linux-arm: 0.14.54 + esbuild-linux-arm64: 0.14.54 + esbuild-linux-mips64le: 0.14.54 + esbuild-linux-ppc64le: 0.14.54 + esbuild-linux-riscv64: 0.14.54 + esbuild-linux-s390x: 0.14.54 + esbuild-netbsd-64: 0.14.54 + esbuild-openbsd-64: 0.14.54 + esbuild-sunos-64: 0.14.54 + esbuild-windows-32: 0.14.54 + esbuild-windows-64: 0.14.54 + esbuild-windows-arm64: 0.14.54 + dev: false + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: false + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-standard/17.0.0_dfwa53o44x4e5xhsfv5mvfhk5a: + resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==} + peerDependencies: + eslint: ^8.0.1 + eslint-plugin-import: ^2.25.2 + eslint-plugin-n: ^15.0.0 + eslint-plugin-promise: ^6.0.0 + dependencies: + eslint: 8.21.0 + eslint-plugin-import: 2.26.0_qfqnhzzittf54udqwes54xx65q + eslint-plugin-n: 15.2.4_eslint@8.21.0 + eslint-plugin-promise: 6.0.0_eslint@8.21.0 + dev: true + + /eslint-import-resolver-node/0.3.6: + resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} + dependencies: + debug: 3.2.7 + resolve: 1.22.1 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils/2.7.4_xtzkthmenmjo2h753u2dv735yy: + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + debug: 3.2.7 + eslint: 8.21.0 + eslint-import-resolver-node: 0.3.6 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-es/4.1.0_eslint@8.21.0: + resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.21.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-import/2.26.0_qfqnhzzittf54udqwes54xx65q: + resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + array-includes: 3.1.5 + array.prototype.flat: 1.3.0 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.21.0 + eslint-import-resolver-node: 0.3.6 + eslint-module-utils: 2.7.4_xtzkthmenmjo2h753u2dv735yy + has: 1.0.3 + is-core-module: 2.10.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.5 + resolve: 1.22.1 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-n/15.2.4_eslint@8.21.0: + resolution: {integrity: sha512-tjnVMv2fiXYMnuiIFI8QMtyUFI42SckEEWvi8h68SWGWshfqO6SSCASy24dGMGAiy7NUk6DZt90DM0iNUsmQ5w==} + engines: {node: '>=12.22.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + builtins: 5.0.1 + eslint: 8.21.0 + eslint-plugin-es: 4.1.0_eslint@8.21.0 + eslint-utils: 3.0.0_eslint@8.21.0 + ignore: 5.2.0 + is-core-module: 2.10.0 + minimatch: 3.1.2 + resolve: 1.22.1 + semver: 7.3.7 + dev: true + + /eslint-plugin-prefer-let/3.0.1: + resolution: {integrity: sha512-vbznkkBSXB63d4o1o0NIm5C2ey3V5wKr/25dAvPdydQXdowAcnr69cbLgxd2YAG81IV5eddCO55Lp6gL7wSE4w==} + engines: {node: '>=0.10.0'} + dependencies: + requireindex: 1.2.0 + dev: true + + /eslint-plugin-promise/6.0.0_eslint@8.21.0: + resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.21.0 + dev: true + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope/7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils/2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-utils/3.0.0_eslint@8.21.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.21.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys/1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys/2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint/8.21.0: + resolution: {integrity: sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 1.3.0 + '@humanwhocodes/config-array': 0.10.4 + '@humanwhocodes/gitignore-to-minimatch': 1.0.2 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.21.0 + eslint-visitor-keys: 3.3.0 + espree: 9.3.3 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + functional-red-black-tree: 1.0.1 + glob-parent: 6.0.2 + globals: 13.17.0 + globby: 11.1.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.0 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree/9.3.3: + resolution: {integrity: sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.0 + acorn-jsx: 5.3.2_acorn@8.8.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /esquery/1.4.0: + resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob/3.2.11: + resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein/2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastest-levenshtein/1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + dev: true + + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache/6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up/4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up/5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache/3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.6 + rimraf: 3.0.2 + dev: true + + /flatted/3.2.6: + resolution: {integrity: sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==} + dev: true + + /folder-hash/4.0.2: + resolution: {integrity: sha512-Iw9GCqdA+zHfDVvk90TSAV66jq0IwiZaPvPgUiW+DHRwnaPOeZomzlgutx9QclinsQGz/XcVIGlDEJbFhCV5wA==} + engines: {node: '>=10.10.0'} + hasBin: true + dependencies: + debug: 4.3.4 + graceful-fs: 4.2.10 + minimatch: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /fraction.js/4.2.0: + resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + dev: false + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + /function.prototype.name/1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + functions-have-names: 1.2.3 + dev: true + + /functional-red-black-tree/1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + dev: true + + /functions-have-names/1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /get-intrinsic/1.1.2: + resolution: {integrity: sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + + /get-symbol-description/1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.2 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /global-modules/2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + dependencies: + global-prefix: 3.0.0 + dev: true + + /global-prefix/3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + dev: true + + /globals/13.17.0: + resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globby/11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.2.11 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /globjoin/0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: false + + /grapheme-splitter/1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /hard-rejection/2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + dev: true + + /has-bigints/1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag/3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors/1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.1.2 + dev: true + + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + + /hasha/5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + dev: false + + /hosted-git-info/2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /hosted-git-info/4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + dependencies: + lru-cache: 6.0.0 + dev: true + + /html-tags/3.2.0: + resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==} + engines: {node: '>=8'} + dev: true + + /ignore/5.2.0: + resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-lazy/4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + dev: true + + /imurmurhash/0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string/4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /ini/1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /internal-slot/1.0.3: + resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.2 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /is-arrayish/0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint/1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object/1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable/1.2.4: + resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module/2.10.0: + resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} + dependencies: + has: 1.0.3 + + /is-date-object/1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: false + + /is-expression/4.0.0: + resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} + dependencies: + acorn: 7.4.1 + object-assign: 4.1.1 + dev: false + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-negative-zero/2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object/1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-plain-obj/1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-object/5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + dev: true + + /is-promise/2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: false + + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + + /is-shared-array-buffer/1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + + /is-string/1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-weakref/1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-wsl/2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: false + + /isexe/2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /js-stringify/1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + dev: false + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse/1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-stable-stringify-without-jsonify/1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.6 + dev: true + + /jstransformer-markdown-it/3.0.0: + resolution: {integrity: sha512-/2fNT0ir/D0NYI5roBTVRwDV2YBjMfU3f/wSeraKLfOMNxcrIJatjJQy4zPmwQBxqKxUojXBN8hmfQBMTLZ3KA==} + engines: {node: '>=7'} + dependencies: + markdown-it: 13.0.1 + dev: false + + /jstransformer/1.0.0: + resolution: {integrity: sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=} + dependencies: + is-promise: 2.2.2 + promise: 7.3.1 + dev: false + + /kind-of/6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /known-css-properties/0.25.0: + resolution: {integrity: sha512-b0/9J1O9Jcyik1GC6KC42hJ41jKwdO/Mq8Mdo5sYN+IuRTXs2YFHZC3kZSx6ueusqa95x3wLYe/ytKjbAfGixA==} + dev: true + + /levn/0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig/2.0.6: + resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns/1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /linkify-it/4.0.1: + resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} + dependencies: + uc.micro: 1.0.6 + dev: false + + /locate-path/5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path/6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.truncate/4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /map-obj/1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-obj/4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: true + + /markdown-it/13.0.1: + resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 3.0.1 + linkify-it: 4.0.1 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: false + + /mathml-tag-names/2.1.3: + resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + dev: true + + /mdn-data/2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + dev: true + + /mdurl/1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + dev: false + + /meow/9.0.0: + resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==} + engines: {node: '>=10'} + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 6.2.2 + decamelize: 1.2.0 + decamelize-keys: 1.1.0 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /min-indent/1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch/5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /minimist-options/4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + dev: true + + /minimist/1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + dev: true + + /mkdirp/1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /ms/2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms/2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /nano-staged/0.8.0: + resolution: {integrity: sha512-QSEqPGTCJbkHU2yLvfY6huqYPjdBrOaTMKatO1F8nCSrkQGXeKwtCiCnsdxnuMhbg3DTVywKaeWLGCE5oJpq0g==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + picocolors: 1.0.0 + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /nanospinner/1.1.0: + resolution: {integrity: sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==} + dependencies: + picocolors: 1.0.0 + dev: true + + /natural-compare/1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-releases/2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + dev: false + + /normalize-package-data/2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.1 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-package-data/3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.10.0 + semver: 7.3.7 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-range/0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: false + + /nth-check/2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + + /object-inspect/1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign/4.1.3: + resolution: {integrity: sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.values/1.1.5: + resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /open/8.4.0: + resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: false + + /optionator/0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /p-limit/2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit/3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate/4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate/5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try/2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-json/5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /postcss-media-minmax/5.0.0_postcss@8.4.16: + resolution: {integrity: sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.16 + dev: false + + /postcss-media-query-parser/0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + dev: true + + /postcss-nesting/10.1.10_postcss@8.4.16: + resolution: {integrity: sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w==} + engines: {node: ^12 || ^14 || >=16} + peerDependencies: + postcss: ^8.2 + dependencies: + '@csstools/selector-specificity': 2.0.2_pnx64jze6bptzcedy5bidi3zdi + postcss: 8.4.16 + postcss-selector-parser: 6.0.10 + dev: false + + /postcss-opacity-percentage/1.1.2: + resolution: {integrity: sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==} + engines: {node: ^12 || ^14 || >=16} + dev: false + + /postcss-resolve-nested-selector/0.1.1: + resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} + dev: true + + /postcss-safe-parser/6.0.0_postcss@8.4.16: + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + dependencies: + postcss: 8.4.16 + dev: true + + /postcss-selector-parser/6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + /postcss-sorting/7.0.1_postcss@8.4.16: + resolution: {integrity: sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==} + peerDependencies: + postcss: ^8.3.9 + dependencies: + postcss: 8.4.16 + dev: true + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + /postcss/8.4.16: + resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + + /prelude-ls/1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier/2.7.1: + resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /promise/7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + dependencies: + asap: 2.0.6 + dev: false + + /pug-attrs/3.0.0: + resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} + dependencies: + constantinople: 4.0.1 + js-stringify: 1.0.2 + pug-runtime: 3.0.1 + dev: false + + /pug-code-gen/3.0.2: + resolution: {integrity: sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==} + dependencies: + constantinople: 4.0.1 + doctypes: 1.1.0 + js-stringify: 1.0.2 + pug-attrs: 3.0.0 + pug-error: 2.0.0 + pug-runtime: 3.0.1 + void-elements: 3.1.0 + with: 7.0.2 + dev: false + + /pug-error/2.0.0: + resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} + dev: false + + /pug-filters/4.0.0: + resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} + dependencies: + constantinople: 4.0.1 + jstransformer: 1.0.0 + pug-error: 2.0.0 + pug-walk: 2.0.0 + resolve: 1.22.1 + dev: false + + /pug-lexer/5.0.1: + resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} + dependencies: + character-parser: 2.2.0 + is-expression: 4.0.0 + pug-error: 2.0.0 + dev: false + + /pug-linker/4.0.0: + resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} + dependencies: + pug-error: 2.0.0 + pug-walk: 2.0.0 + dev: false + + /pug-load/3.0.0: + resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} + dependencies: + object-assign: 4.1.1 + pug-walk: 2.0.0 + dev: false + + /pug-parser/6.0.0: + resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} + dependencies: + pug-error: 2.0.0 + token-stream: 1.0.0 + dev: false + + /pug-runtime/3.0.1: + resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} + dev: false + + /pug-strip-comments/2.0.0: + resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} + dependencies: + pug-error: 2.0.0 + dev: false + + /pug-walk/2.0.0: + resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} + dev: false + + /pug/3.0.2: + resolution: {integrity: sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==} + dependencies: + pug-code-gen: 3.0.2 + pug-filters: 4.0.0 + pug-lexer: 5.0.1 + pug-linker: 4.0.0 + pug-load: 3.0.0 + pug-parser: 6.0.0 + pug-runtime: 3.0.1 + pug-strip-comments: 2.0.0 + dev: false + + /punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru/4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: true + + /read-pkg-up/7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg/5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /redent/3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /regexp.prototype.flags/1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + functions-have-names: 1.2.3 + dev: true + + /regexpp/3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /require-from-string/2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /requireindex/1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from/5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.10.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup/2.77.3: + resolution: {integrity: sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: false + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /semver/5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + + /semver/7.3.7: + resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.2 + object-inspect: 1.12.2 + dev: true + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /simple-git-hooks/2.8.0: + resolution: {integrity: sha512-ocmZQORwa6x9mxg+gVIAp5o4wXiWOHGXyrDBA0+UxGKIEKOyFtL4LWNKkP/2ornQPdlnlDGDteVeYP5FjhIoWA==} + hasBin: true + requiresBuild: true + dev: true + + /size-limit/8.0.1: + resolution: {integrity: sha512-VHrozqkQTYfcv1OlZIRIL0x6f+xhZ3TT+RTXC5AvKn/yA+3PIWERrKWqHMJPD7G/Vi0SuBtWAn3IvCGx2/UB1g==} + engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0} + hasBin: true + dependencies: + bytes-iec: 3.1.1 + chokidar: 3.5.3 + ci-job-number: 1.2.2 + globby: 11.1.0 + lilconfig: 2.0.6 + mkdirp: 1.0.4 + nanospinner: 1.1.0 + picocolors: 1.0.0 + dev: true + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spdx-correct/3.1.1: + resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.11 + dev: true + + /spdx-exceptions/2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse/3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.11 + dev: true + + /spdx-license-ids/3.0.11: + resolution: {integrity: sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==} + dev: true + + /ssdeploy/0.9.1: + resolution: {integrity: sha512-4jfgSGlpKGBLQcva72Vo33CSW9VlHmEaAZ4WV8hgTEL8mnOsdxOYYZlxq2+hwtHrmPVdML4A0cOHAy6bmhGI9w==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + bytes: 3.1.2 + dotenv: 16.0.1 + folder-hash: 4.0.2 + hasha: 5.2.2 + open: 8.4.0 + picocolors: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /stable/0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.trimend/1.0.5: + resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + dev: true + + /string.prototype.trimstart/1.0.5: + resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.1 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom/3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-indent/3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments/3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /style-search/0.1.0: + resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + dev: true + + /stylelint-config-recess-order/3.0.0_stylelint@14.10.0: + resolution: {integrity: sha512-uNXrlDz570Q7HJlrq8mNjgfO/xlKIh2hKVKEFMTG1/ih/6tDLcTbuvO1Zoo2dnQay990OAkWLDpTDOorB+hmBw==} + peerDependencies: + stylelint: '>=14' + dependencies: + stylelint: 14.10.0 + stylelint-order: 5.0.0_stylelint@14.10.0 + dev: true + + /stylelint-config-recommended/7.0.0_stylelint@14.10.0: + resolution: {integrity: sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==} + peerDependencies: + stylelint: ^14.4.0 + dependencies: + stylelint: 14.10.0 + dev: true + + /stylelint-config-standard/25.0.0_stylelint@14.10.0: + resolution: {integrity: sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==} + peerDependencies: + stylelint: ^14.4.0 + dependencies: + stylelint: 14.10.0 + stylelint-config-recommended: 7.0.0_stylelint@14.10.0 + dev: true + + /stylelint-order/5.0.0_stylelint@14.10.0: + resolution: {integrity: sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==} + peerDependencies: + stylelint: ^14.0.0 + dependencies: + postcss: 8.4.16 + postcss-sorting: 7.0.1_postcss@8.4.16 + stylelint: 14.10.0 + dev: true + + /stylelint/14.10.0: + resolution: {integrity: sha512-VAmyKrEK+wNFh9R8mNqoxEFzaa4gsHGhcT4xgkQDuOA5cjF6CaNS8loYV7gpi4tIZBPUyXesotPXzJAMN8VLOQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + '@csstools/selector-specificity': 2.0.2_pnx64jze6bptzcedy5bidi3zdi + balanced-match: 2.0.0 + colord: 2.9.3 + cosmiconfig: 7.0.1 + css-functions-list: 3.1.0 + debug: 4.3.4 + fast-glob: 3.2.11 + fastest-levenshtein: 1.0.16 + file-entry-cache: 6.0.1 + global-modules: 2.0.0 + globby: 11.1.0 + globjoin: 0.1.4 + html-tags: 3.2.0 + ignore: 5.2.0 + import-lazy: 4.0.0 + imurmurhash: 0.1.4 + is-plain-object: 5.0.0 + known-css-properties: 0.25.0 + mathml-tag-names: 2.1.3 + meow: 9.0.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.16 + postcss-media-query-parser: 0.2.3 + postcss-resolve-nested-selector: 0.1.1 + postcss-safe-parser: 6.0.0_postcss@8.4.16 + postcss-selector-parser: 6.0.10 + postcss-value-parser: 4.2.0 + resolve-from: 5.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + style-search: 0.1.0 + supports-hyperlinks: 2.2.0 + svg-tags: 1.0.0 + table: 6.8.0 + v8-compile-cache: 2.3.0 + write-file-atomic: 4.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-hyperlinks/2.2.0: + resolution: {integrity: sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + /svg-tags/1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + dev: true + + /svgo/2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.0.0 + stable: 0.1.8 + dev: true + + /table/6.8.0: + resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.11.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /text-table/0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: false + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /token-stream/1.0.0: + resolution: {integrity: sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=} + dev: false + + /trim-newlines/3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + dev: true + + /tsconfig-paths/3.14.1: + resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.1 + minimist: 1.2.6 + strip-bom: 3.0.0 + dev: true + + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tsutils/3.21.0_typescript@4.7.4: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.7.4 + dev: true + + /type-check/0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest/0.18.1: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest/0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + /typescript/4.7.4: + resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /uc.micro/1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + dev: false + + /unbox-primitive/1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /update-browserslist-db/1.0.5_browserslist@4.21.3: + resolution: {integrity: sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.3 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: false + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /v8-compile-cache/2.3.0: + resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} + dev: true + + /validate-npm-package-license/3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.1.1 + spdx-expression-parse: 3.0.1 + dev: true + + /vite-plugin-pug-transformer/1.0.2_vite@3.0.7: + resolution: {integrity: sha512-RtXEYaEgQoy5ttNjuuNMWRzZwfJz+cjePSdQzmNJTteIzUamVb8xvAlwNouMt189V2mk6HxyfTGfAGKUQ6KGig==} + engines: {node: '>=12.22.0'} + peerDependencies: + vite: ^2.5.10 || ^3.0.0 + dependencies: + picocolors: 1.0.0 + pug: 3.0.2 + vite: 3.0.7 + dev: false + + /vite/3.0.7: + resolution: {integrity: sha512-dILhvKba1mbP1wCezVQx/qhEK7/+jVn9ciadEcyKMMhZpsuAi/eWZfJRMkmYlkSFG7Qq9NvJbgFq4XOBxugJsA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + terser: ^5.4.0 + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.14.54 + postcss: 8.4.16 + resolve: 1.22.1 + rollup: 2.77.3 + optionalDependencies: + fsevents: 2.3.2 + dev: false + + /void-elements/3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: false + + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which/1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /with/7.0.2: + resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/parser': 7.18.11 + '@babel/types': 7.18.10 + assert-never: 1.2.1 + babel-walk: 3.0.0-canary-5 + dev: false + + /word-wrap/1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic/4.0.1: + resolution: {integrity: sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yargs-parser/20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + + /yocto-queue/0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..b2eff6c8 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - client + - server diff --git a/public/images/and_chr.png b/public/images/and_chr.png deleted file mode 120000 index da47ce43..00000000 --- a/public/images/and_chr.png +++ /dev/null @@ -1 +0,0 @@ -chrome.png \ No newline at end of file diff --git a/public/images/and_ff.png b/public/images/and_ff.png deleted file mode 120000 index 93c4678c..00000000 --- a/public/images/and_ff.png +++ /dev/null @@ -1 +0,0 @@ -firefox.png \ No newline at end of file diff --git a/public/images/and_qq.png b/public/images/and_qq.png deleted file mode 100644 index 6094b5ec..00000000 Binary files a/public/images/and_qq.png and /dev/null differ diff --git a/public/images/and_uc.png b/public/images/and_uc.png deleted file mode 120000 index e21e353b..00000000 --- a/public/images/and_uc.png +++ /dev/null @@ -1 +0,0 @@ -uc.png \ No newline at end of file diff --git a/public/images/android-webview-beta.png b/public/images/android-webview-beta.png deleted file mode 100755 index f751068f..00000000 Binary files a/public/images/android-webview-beta.png and /dev/null differ diff --git a/public/images/android.png b/public/images/android.png deleted file mode 100755 index 6808a366..00000000 Binary files a/public/images/android.png and /dev/null differ diff --git a/public/images/baidu.png b/public/images/baidu.png deleted file mode 100644 index 0919dd0d..00000000 Binary files a/public/images/baidu.png and /dev/null differ diff --git a/public/images/bb.png b/public/images/bb.png deleted file mode 100755 index 80dfae0a..00000000 Binary files a/public/images/bb.png and /dev/null differ diff --git a/public/images/chrome-beta.png b/public/images/chrome-beta.png deleted file mode 100755 index 5cbdff63..00000000 Binary files a/public/images/chrome-beta.png and /dev/null differ diff --git a/public/images/chrome-canary.png b/public/images/chrome-canary.png deleted file mode 100755 index 8a9d415f..00000000 Binary files a/public/images/chrome-canary.png and /dev/null differ diff --git a/public/images/chrome-dev.png b/public/images/chrome-dev.png deleted file mode 100755 index e3330331..00000000 Binary files a/public/images/chrome-dev.png and /dev/null differ diff --git a/public/images/chrome.png b/public/images/chrome.png deleted file mode 100755 index eaaddc6e..00000000 Binary files a/public/images/chrome.png and /dev/null differ diff --git a/public/images/edge-tile.png b/public/images/edge-tile.png deleted file mode 100755 index 28aeece1..00000000 Binary files a/public/images/edge-tile.png and /dev/null differ diff --git a/public/images/edge.png b/public/images/edge.png deleted file mode 100755 index 87cfb29e..00000000 Binary files a/public/images/edge.png and /dev/null differ diff --git a/public/images/favicon.png b/public/images/favicon.png deleted file mode 100644 index 1dea7736..00000000 Binary files a/public/images/favicon.png and /dev/null differ diff --git a/public/images/firefox-beta.png b/public/images/firefox-beta.png deleted file mode 100755 index e824f09c..00000000 Binary files a/public/images/firefox-beta.png and /dev/null differ diff --git a/public/images/firefox-developer-edition.png b/public/images/firefox-developer-edition.png deleted file mode 100755 index e38fe35a..00000000 Binary files a/public/images/firefox-developer-edition.png and /dev/null differ diff --git a/public/images/firefox-nightly.png b/public/images/firefox-nightly.png deleted file mode 100755 index e4de3fb8..00000000 Binary files a/public/images/firefox-nightly.png and /dev/null differ diff --git a/public/images/firefox.png b/public/images/firefox.png deleted file mode 100755 index e9d7facd..00000000 Binary files a/public/images/firefox.png and /dev/null differ diff --git a/public/images/ie.png b/public/images/ie.png deleted file mode 120000 index 07642c1f..00000000 --- a/public/images/ie.png +++ /dev/null @@ -1 +0,0 @@ -internet-explorer.png \ No newline at end of file diff --git a/public/images/ie_mob.png b/public/images/ie_mob.png deleted file mode 120000 index e0e452ba..00000000 --- a/public/images/ie_mob.png +++ /dev/null @@ -1 +0,0 @@ -internet-explorer-tile.png \ No newline at end of file diff --git a/public/images/internet-explorer-tile.png b/public/images/internet-explorer-tile.png deleted file mode 100755 index d5ab8a3e..00000000 Binary files a/public/images/internet-explorer-tile.png and /dev/null differ diff --git a/public/images/internet-explorer.png b/public/images/internet-explorer.png deleted file mode 100755 index 51b26d2b..00000000 Binary files a/public/images/internet-explorer.png and /dev/null differ diff --git a/public/images/ios_saf.png b/public/images/ios_saf.png deleted file mode 120000 index 198bfab3..00000000 --- a/public/images/ios_saf.png +++ /dev/null @@ -1 +0,0 @@ -safari-ios.png \ No newline at end of file diff --git a/public/images/kaios.png b/public/images/kaios.png deleted file mode 100644 index 908ce92f..00000000 Binary files a/public/images/kaios.png and /dev/null differ diff --git a/public/images/node.png b/public/images/node.png deleted file mode 100644 index 0d2013dc..00000000 Binary files a/public/images/node.png and /dev/null differ diff --git a/public/images/op_mini.png b/public/images/op_mini.png deleted file mode 120000 index 01e8a63a..00000000 --- a/public/images/op_mini.png +++ /dev/null @@ -1 +0,0 @@ -opera-mini.png \ No newline at end of file diff --git a/public/images/op_mob.png b/public/images/op_mob.png deleted file mode 120000 index 01e8a63a..00000000 --- a/public/images/op_mob.png +++ /dev/null @@ -1 +0,0 @@ -opera-mini.png \ No newline at end of file diff --git a/public/images/opera-beta.png b/public/images/opera-beta.png deleted file mode 100755 index 03e0b891..00000000 Binary files a/public/images/opera-beta.png and /dev/null differ diff --git a/public/images/opera-developer.png b/public/images/opera-developer.png deleted file mode 100755 index 09e69c8e..00000000 Binary files a/public/images/opera-developer.png and /dev/null differ diff --git a/public/images/opera-mini-beta.png b/public/images/opera-mini-beta.png deleted file mode 100755 index 54c7b7f1..00000000 Binary files a/public/images/opera-mini-beta.png and /dev/null differ diff --git a/public/images/opera-mini.png b/public/images/opera-mini.png deleted file mode 100755 index 85afada4..00000000 Binary files a/public/images/opera-mini.png and /dev/null differ diff --git a/public/images/opera.png b/public/images/opera.png deleted file mode 100755 index 78f71717..00000000 Binary files a/public/images/opera.png and /dev/null differ diff --git a/public/images/safari-ios.png b/public/images/safari-ios.png deleted file mode 100755 index 8f6ab13d..00000000 Binary files a/public/images/safari-ios.png and /dev/null differ diff --git a/public/images/safari-technology-preview.png b/public/images/safari-technology-preview.png deleted file mode 100755 index 5f512fb2..00000000 Binary files a/public/images/safari-technology-preview.png and /dev/null differ diff --git a/public/images/safari.png b/public/images/safari.png deleted file mode 100755 index 96373e24..00000000 Binary files a/public/images/safari.png and /dev/null differ diff --git a/public/images/samsung-internet.png b/public/images/samsung-internet.png deleted file mode 100755 index b2efaccc..00000000 Binary files a/public/images/samsung-internet.png and /dev/null differ diff --git a/public/images/samsung.png b/public/images/samsung.png deleted file mode 120000 index 169b71b3..00000000 --- a/public/images/samsung.png +++ /dev/null @@ -1 +0,0 @@ -samsung-internet.png \ No newline at end of file diff --git a/public/images/uc.png b/public/images/uc.png deleted file mode 100755 index 0091d6c8..00000000 Binary files a/public/images/uc.png and /dev/null differ diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css deleted file mode 100644 index 4acb8040..00000000 --- a/public/stylesheets/style.css +++ /dev/null @@ -1,25 +0,0 @@ -body { - color: #111; - background-color: #fff; -} - -a { - font-weight: bold; - text-decoration: none; - color: #490245; -} - -a:hover { - text-decoration: underline; -} - -.neon-carrot { color: #fda34f; } -.plum { color: #490245; } -.bg-neon-carrot { background-color: #fda34f; } -.bg-plum { background-color: #490245; } -.dt-ns ::selection { background: #ffcc00; } -.lh-copy ::selection { background: #ffcc00; } - -.bg-plum--hover:hover { - background-color: #260024; -} diff --git a/public/stylesheets/tachyons.min.css b/public/stylesheets/tachyons.min.css deleted file mode 100644 index ed7da41f..00000000 --- a/public/stylesheets/tachyons.min.css +++ /dev/null @@ -1,2 +0,0 @@ -/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}[hidden],template{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:700}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.border-box,article,body,code,dd,div,dl,dt,fieldset,footer,form,header,html,input[type=email],input[type=number],input[type=password],input[type=tel],input[type=text],input[type=url],li,main,ol,p,pre,section,textarea,ul{box-sizing:border-box}.cover{background-size:cover}.contain{background-size:contain}.ba{border-style:solid;border-width:1px}.bt{border-top-style:solid;border-top-width:1px}.br{border-right-style:solid;border-right-width:1px}.bb{border-bottom-style:solid;border-bottom-width:1px}.bl{border-left-style:solid;border-left-width:1px}.bn{border-style:none;border-width:0}.b--black{border-color:#000}.b--near-black{border-color:#111}.b--dark-gray{border-color:#333}.b--mid-gray{border-color:#555}.b--gray{border-color:#777}.b--silver{border-color:#999}.b--light-silver{border-color:#aaa}.b--light-gray{border-color:#eee}.b--near-white{border-color:#f4f4f4}.b--white{border-color:#fff}.b--white-90{border-color:hsla(0,0%,100%,.9)}.b--white-80{border-color:hsla(0,0%,100%,.8)}.b--white-70{border-color:hsla(0,0%,100%,.7)}.b--white-60{border-color:hsla(0,0%,100%,.6)}.b--white-50{border-color:hsla(0,0%,100%,.5)}.b--white-40{border-color:hsla(0,0%,100%,.4)}.b--white-30{border-color:hsla(0,0%,100%,.3)}.b--white-20{border-color:hsla(0,0%,100%,.2)}.b--white-10{border-color:hsla(0,0%,100%,.1)}.b--white-05{border-color:hsla(0,0%,100%,.05)}.b--white-025{border-color:hsla(0,0%,100%,.025)}.b--white-0125{border-color:hsla(0,0%,100%,.0125)}.b--black-90{border-color:rgba(0,0,0,.9)}.b--black-80{border-color:rgba(0,0,0,.8)}.b--black-70{border-color:rgba(0,0,0,.7)}.b--black-60{border-color:rgba(0,0,0,.6)}.b--black-50{border-color:rgba(0,0,0,.5)}.b--black-40{border-color:rgba(0,0,0,.4)}.b--black-30{border-color:rgba(0,0,0,.3)}.b--black-20{border-color:rgba(0,0,0,.2)}.b--black-10{border-color:rgba(0,0,0,.1)}.b--black-05{border-color:rgba(0,0,0,.05)}.b--black-025{border-color:rgba(0,0,0,.025)}.b--black-0125{border-color:rgba(0,0,0,.0125)}.b--dark-red{border-color:#f00008}.b--red{border-color:#ff3223}.b--orange{border-color:#f3a801}.b--gold{border-color:#f2c800}.b--yellow{border-color:#ffde37}.b--purple{border-color:#7d5da9}.b--light-purple{border-color:#8d4f92}.b--hot-pink{border-color:#d62288}.b--dark-pink{border-color:#c64774}.b--pink{border-color:#f49cc8}.b--dark-green{border-color:#006c71}.b--green{border-color:#41d69f}.b--navy{border-color:#001b44}.b--dark-blue{border-color:#00449e}.b--blue{border-color:#357edd}.b--light-blue{border-color:#96ccff}.b--lightest-blue{border-color:#cdecff}.b--washed-blue{border-color:#f6fffe}.b--washed-green{border-color:#e8fdf5}.b--washed-yellow{border-color:#fff8d5}.b--light-pink{border-color:#efa4b8}.b--light-yellow{border-color:#f3dd70}.b--light-red{border-color:#ffd3c0}.b--transparent{border-color:transparent}.br0{border-radius:0}.br1{border-radius:.125rem}.br2{border-radius:.25rem}.br3{border-radius:.5rem}.br4{border-radius:1rem}.br-100{border-radius:100%}.br--bottom{border-top-left-radius:0;border-top-right-radius:0}.br--top{border-bottom-right-radius:0}.br--right,.br--top{border-bottom-left-radius:0}.br--right{border-top-left-radius:0}.br--left{border-top-right-radius:0;border-bottom-right-radius:0}.b--dotted{border-style:dotted}.b--dashed{border-style:dashed}.b--solid{border-style:solid}.b--none{border-style:none}.bw0{border-width:0}.bw1{border-width:.125rem}.bw2{border-width:.25rem}.bw3{border-width:.5rem}.bw4{border-width:1rem}.bw5{border-width:2rem}.bt-0{border-top-width:0}.br-0{border-right-width:0}.bb-0{border-bottom-width:0}.bl-0{border-left-width:0}.shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}.pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-1{top:1rem}.right-1{right:1rem}.bottom-1{bottom:1rem}.left-1{left:1rem}.top-2{top:2rem}.right-2{right:2rem}.bottom-2{bottom:2rem}.left-2{left:2rem}.top--1{top:-1rem}.right--1{right:-1rem}.bottom--1{bottom:-1rem}.left--1{left:-1rem}.top--2{top:-2rem}.right--2{right:-2rem}.bottom--2{bottom:-2rem}.left--2{left:-2rem}.absolute--fill{top:0;right:0;bottom:0;left:0}.cf:after,.cf:before{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.cl{clear:left}.cr{clear:right}.cb{clear:both}.cn{clear:none}.dn{display:none}.di{display:inline}.db{display:block}.dib{display:inline-block}.dit{display:inline-table}.dt{display:table}.dtc{display:table-cell}.dt-row{display:table-row}.dt-row-group{display:table-row-group}.dt-column{display:table-column}.dt-column-group{display:table-column-group}.dt--fixed{table-layout:fixed;width:100%}.flex{display:flex}.flex-auto{flex:1 1 auto;min-width:0;min-height:0}.flex-none{flex:none}.flex-column{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.self-start{align-self:flex-start}.self-end{align-self:flex-end}.self-center{align-self:center}.self-baseline{align-self:baseline}.self-stretch{align-self:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.content-start{align-content:flex-start}.content-end{align-content:flex-end}.content-center{align-content:center}.content-between{align-content:space-between}.content-around{align-content:space-around}.content-stretch{align-content:stretch}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-last{order:99999}.fl{float:left}.fl,.fr{_display:inline}.fr{float:right}.fn{float:none}.sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica,helvetica neue,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.serif{font-family:georgia,times,serif}.system-sans-serif{font-family:sans-serif}.system-serif{font-family:serif}.code,code{font-family:Consolas,monaco,monospace}.helvetica{font-family:helvetica neue,helvetica,sans-serif}.avenir{font-family:avenir next,avenir,sans-serif}.georgia{font-family:georgia,serif}.times{font-family:times,serif}.bodoni{font-family:Bodoni MT,serif}.calisto{font-family:Calisto MT,serif}.baskerville,.garamond{font-family:garamond,serif}.i{font-style:italic}.fs-normal{font-style:normal}.normal{font-weight:400}.b{font-weight:700}.fw1{font-weight:100}.fw2{font-weight:200}.fw3{font-weight:300}.fw4{font-weight:400}.fw5{font-weight:500}.fw6{font-weight:600}.fw7{font-weight:700}.fw8{font-weight:800}.fw9{font-weight:900}.input-reset{-webkit-appearance:none;-moz-appearance:none}.h1{height:1rem}.h2{height:2rem}.h3{height:4rem}.h4{height:8rem}.h5{height:16rem}.h-25{height:25%}.h-50{height:50%}.h-75{height:75%}.h-100{height:100%}.h-auto{height:auto}.h-inherit{height:inherit}.tracked{letter-spacing:.16em}.tracked-tight{letter-spacing:-.05em}.tracked-mega{letter-spacing:.32em}.lh-solid{line-height:1}.lh-title{line-height:1.3}.lh-copy{line-height:1.6}.link{text-decoration:none}.link,.link:active,.link:focus,.link:hover,.link:link,.link:visited{transition:color .15s ease-in}.list{list-style-type:none}.mw-100{max-width:100%}.mw1{max-width:1rem}.mw2{max-width:2rem}.mw3{max-width:4rem}.mw4{max-width:8rem}.mw5{max-width:16rem}.mw6{max-width:32rem}.mw7{max-width:48rem}.mw8{max-width:64rem}.mw9{max-width:96rem}.mw-none{max-width:none}.w1{width:1rem}.w2{width:2rem}.w3{width:4rem}.w4{width:8rem}.w5{width:16rem}.w-10{width:10%}.w-20{width:20%}.w-25{width:25%}.w-33{width:33%}.w-34{width:34%}.w-40{width:40%}.w-50{width:50%}.w-60{width:60%}.w-75{width:75%}.w-80{width:80%}.w-100{width:100%}.w-auto{width:auto}.overflow-visible{overflow:visible}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.overflow-x-visible{overflow-x:visible}.overflow-x-hidden{overflow-x:hidden}.overflow-x-scroll{overflow-x:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-visible{overflow-y:visible}.overflow-y-hidden{overflow-y:hidden}.overflow-y-scroll{overflow-y:scroll}.overflow-y-auto{overflow-y:auto}.static{position:static}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.o-100{opacity:1}.o-90{opacity:.9}.o-80{opacity:.8}.o-70{opacity:.7}.o-60{opacity:.6}.o-50{opacity:.5}.o-40{opacity:.4}.o-30{opacity:.3}.o-20{opacity:.2}.o-10{opacity:.1}.o-05{opacity:.05}.o-025{opacity:.025}.o-0{opacity:0}.black-90{color:rgba(0,0,0,.9)}.black-80{color:rgba(0,0,0,.8)}.black-70{color:rgba(0,0,0,.7)}.black-60{color:rgba(0,0,0,.6)}.black-50{color:rgba(0,0,0,.5)}.black-40{color:rgba(0,0,0,.4)}.black-30{color:rgba(0,0,0,.3)}.black-20{color:rgba(0,0,0,.2)}.black-10{color:rgba(0,0,0,.1)}.black-05{color:rgba(0,0,0,.05)}.white-90{color:hsla(0,0%,100%,.9)}.white-80{color:hsla(0,0%,100%,.8)}.white-70{color:hsla(0,0%,100%,.7)}.white-60{color:hsla(0,0%,100%,.6)}.white-50{color:hsla(0,0%,100%,.5)}.white-40{color:hsla(0,0%,100%,.4)}.white-30{color:hsla(0,0%,100%,.3)}.white-20{color:hsla(0,0%,100%,.2)}.white-10{color:hsla(0,0%,100%,.1)}.black{color:#000}.near-black{color:#111}.dark-gray{color:#333}.mid-gray{color:#555}.gray{color:#777}.silver{color:#999}.light-silver{color:#aaa}.moon-gray{color:#ccc}.light-gray{color:#eee}.near-white{color:#f4f4f4}.white{color:#fff}.dark-red{color:#f00008}.red{color:#ff3223}.orange{color:#f3a801}.gold{color:#f2c800}.yellow{color:#ffde37}.purple{color:#7d5da9}.light-purple{color:#8d4f92}.hot-pink{color:#d62288}.dark-pink{color:#c64774}.pink{color:#f49cc8}.dark-green{color:#006c71}.green{color:#41d69f}.navy{color:#001b44}.dark-blue{color:#00449e}.blue{color:#357edd}.light-blue{color:#96ccff}.lightest-blue{color:#cdecff}.washed-blue{color:#f6fffe}.washed-green{color:#e8fdf5}.washed-yellow{color:#fff8d5}.light-pink{color:#efa4b8}.light-yellow{color:#f3dd70}.light-red{color:#ffd3c0}.bg-black-90{background-color:rgba(0,0,0,.9)}.bg-black-80{background-color:rgba(0,0,0,.8)}.bg-black-70{background-color:rgba(0,0,0,.7)}.bg-black-60{background-color:rgba(0,0,0,.6)}.bg-black-50{background-color:rgba(0,0,0,.5)}.bg-black-40{background-color:rgba(0,0,0,.4)}.bg-black-30{background-color:rgba(0,0,0,.3)}.bg-black-20{background-color:rgba(0,0,0,.2)}.bg-black-10{background-color:rgba(0,0,0,.1)}.bg-black-05{background-color:rgba(0,0,0,.05)}.bg-white-90{background-color:hsla(0,0%,100%,.9)}.bg-white-80{background-color:hsla(0,0%,100%,.8)}.bg-white-70{background-color:hsla(0,0%,100%,.7)}.bg-white-60{background-color:hsla(0,0%,100%,.6)}.bg-white-50{background-color:hsla(0,0%,100%,.5)}.bg-white-40{background-color:hsla(0,0%,100%,.4)}.bg-white-30{background-color:hsla(0,0%,100%,.3)}.bg-white-20{background-color:hsla(0,0%,100%,.2)}.bg-white-10{background-color:hsla(0,0%,100%,.1)}.bg-black{background-color:#000}.bg-near-black{background-color:#111}.bg-dark-gray{background-color:#333}.bg-mid-gray{background-color:#555}.bg-gray{background-color:#777}.bg-silver{background-color:#999}.bg-light-silver{background-color:#aaa}.bg-moon-gray{background-color:#ccc}.bg-light-gray{background-color:#eee}.bg-near-white{background-color:#f4f4f4}.bg-white{background-color:#fff}.bg-transparent{background-color:transparent}.bg-dark-red{background-color:#f00008}.bg-red{background-color:#ff3223}.bg-orange{background-color:#f3a801}.bg-gold{background-color:#f2c800}.bg-yellow{background-color:#ffde37}.bg-purple{background-color:#7d5da9}.bg-light-purple{background-color:#8d4f92}.bg-hot-pink{background-color:#d62288}.bg-dark-pink{background-color:#c64774}.bg-pink{background-color:#f49cc8}.bg-dark-green{background-color:#006c71}.bg-green{background-color:#41d69f}.bg-navy{background-color:#001b44}.bg-dark-blue{background-color:#00449e}.bg-blue{background-color:#357edd}.bg-light-blue{background-color:#96ccff}.bg-lightest-blue{background-color:#cdecff}.bg-washed-blue{background-color:#f6fffe}.bg-washed-green{background-color:#e8fdf5}.bg-washed-yellow{background-color:#fff8d5}.bg-light-pink{background-color:#efa4b8}.bg-light-yellow{background-color:#f3dd70}.bg-light-red{background-color:#ffd3c0}.hover-black:hover{color:#000}.hover-near-black:hover{color:#111}.hover-dark-gray:hover{color:#333}.hover-mid-gray:hover{color:#555}.hover-gray:hover{color:#777}.hover-silver:hover{color:#999}.hover-light-silver:hover{color:#aaa}.hover-moon-gray:hover{color:#ccc}.hover-light-gray:hover{color:#eee}.hover-near-white:hover{color:#f4f4f4}.hover-white:hover{color:#fff}.hover-bg-black:hover{background-color:#000}.hover-bg-near-black:hover{background-color:#111}.hover-bg-dark-gray:hover{background-color:#333}.hover-bg-mid-gray:hover{background-color:#555}.hover-bg-gray:hover{background-color:#777}.hover-bg-silver:hover{background-color:#999}.hover-bg-light-silver:hover{background-color:#aaa}.hover-bg-moon-gray:hover{background-color:#ccc}.hover-bg-light-gray:hover{background-color:#eee}.hover-bg-near-white:hover{background-color:#f4f4f4}.hover-bg-white:hover{background-color:#fff}.hover-bg-transparent:hover{background-color:transparent}.hover-bg-dark-red:hover{background-color:#f00008}.hover-bg-red:hover{background-color:#ff3223}.hover-bg-orange:hover{background-color:#f3a801}.hover-bg-gold:hover{background-color:#f2c800}.hover-bg-yellow:hover{background-color:#ffde37}.hover-bg-purple:hover{background-color:#7d5da9}.hover-bg-light-purple:hover{background-color:#8d4f92}.hover-bg-hot-pink:hover{background-color:#d62288}.hover-bg-dark-pink:hover{background-color:#c64774}.hover-bg-pink:hover{background-color:#f49cc8}.hover-bg-dark-green:hover{background-color:#006c71}.hover-bg-green:hover{background-color:#41d69f}.hover-bg-navy:hover{background-color:#001b44}.hover-bg-dark-blue:hover{background-color:#00449e}.hover-bg-blue:hover{background-color:#357edd}.hover-bg-light-blue:hover{background-color:#96ccff}.hover-bg-lightest-blue:hover{background-color:#cdecff}.hover-bg-washed-blue:hover{background-color:#f6fffe}.hover-bg-washed-green:hover{background-color:#e8fdf5}.hover-bg-washed-yellow:hover{background-color:#fff8d5}.hover-bg-light-pink:hover{background-color:#efa4b8}.hover-bg-light-yellow:hover{background-color:#f3dd70}.hover-bg-light-red:hover{background-color:#ffd3c0}.pa0{padding:0}.pa1{padding:.25rem}.pa2{padding:.5rem}.pa3{padding:1rem}.pa4{padding:2rem}.pa5{padding:4rem}.pa6{padding:8rem}.pa7{padding:16rem}.pl0{padding-left:0}.pl1{padding-left:.25rem}.pl2{padding-left:.5rem}.pl3{padding-left:1rem}.pl4{padding-left:2rem}.pl5{padding-left:4rem}.pl6{padding-left:8rem}.pl7{padding-left:16rem}.pr0{padding-right:0}.pr1{padding-right:.25rem}.pr2{padding-right:.5rem}.pr3{padding-right:1rem}.pr4{padding-right:2rem}.pr5{padding-right:4rem}.pr6{padding-right:8rem}.pr7{padding-right:16rem}.pb0{padding-bottom:0}.pb1{padding-bottom:.25rem}.pb2{padding-bottom:.5rem}.pb3{padding-bottom:1rem}.pb4{padding-bottom:2rem}.pb5{padding-bottom:4rem}.pb6{padding-bottom:8rem}.pb7{padding-bottom:16rem}.pt0{padding-top:0}.pt1{padding-top:.25rem}.pt2{padding-top:.5rem}.pt3{padding-top:1rem}.pt4{padding-top:2rem}.pt5{padding-top:4rem}.pt6{padding-top:8rem}.pt7{padding-top:16rem}.pv0{padding-top:0;padding-bottom:0}.pv1{padding-top:.25rem;padding-bottom:.25rem}.pv2{padding-top:.5rem;padding-bottom:.5rem}.pv3{padding-top:1rem;padding-bottom:1rem}.pv4{padding-top:2rem;padding-bottom:2rem}.pv5{padding-top:4rem;padding-bottom:4rem}.pv6{padding-top:8rem;padding-bottom:8rem}.pv7{padding-top:16rem;padding-bottom:16rem}.ph0{padding-left:0;padding-right:0}.ph1{padding-left:.25rem;padding-right:.25rem}.ph2{padding-left:.5rem;padding-right:.5rem}.ph3{padding-left:1rem;padding-right:1rem}.ph4{padding-left:2rem;padding-right:2rem}.ph5{padding-left:4rem;padding-right:4rem}.ph6{padding-left:8rem;padding-right:8rem}.ph7{padding-left:16rem;padding-right:16rem}.ma0{margin:0}.ma1{margin:.25rem}.ma2{margin:.5rem}.ma3{margin:1rem}.ma4{margin:2rem}.ma5{margin:4rem}.ma6{margin:8rem}.ma7{margin:16rem}.ml0{margin-left:0}.ml1{margin-left:.25rem}.ml2{margin-left:.5rem}.ml3{margin-left:1rem}.ml4{margin-left:2rem}.ml5{margin-left:4rem}.ml6{margin-left:8rem}.ml7{margin-left:16rem}.mr0{margin-right:0}.mr1{margin-right:.25rem}.mr2{margin-right:.5rem}.mr3{margin-right:1rem}.mr4{margin-right:2rem}.mr5{margin-right:4rem}.mr6{margin-right:8rem}.mr7{margin-right:16rem}.mb0{margin-bottom:0}.mb1{margin-bottom:.25rem}.mb2{margin-bottom:.5rem}.mb3{margin-bottom:1rem}.mb4{margin-bottom:2rem}.mb5{margin-bottom:4rem}.mb6{margin-bottom:8rem}.mb7{margin-bottom:16rem}.mt0{margin-top:0}.mt1{margin-top:.25rem}.mt2{margin-top:.5rem}.mt3{margin-top:1rem}.mt4{margin-top:2rem}.mt5{margin-top:4rem}.mt6{margin-top:8rem}.mt7{margin-top:16rem}.mv0{margin-top:0;margin-bottom:0}.mv1{margin-top:.25rem;margin-bottom:.25rem}.mv2{margin-top:.5rem;margin-bottom:.5rem}.mv3{margin-top:1rem;margin-bottom:1rem}.mv4{margin-top:2rem;margin-bottom:2rem}.mv5{margin-top:4rem;margin-bottom:4rem}.mv6{margin-top:8rem;margin-bottom:8rem}.mv7{margin-top:16rem;margin-bottom:16rem}.mh0{margin-left:0;margin-right:0}.mh1{margin-left:.25rem;margin-right:.25rem}.mh2{margin-left:.5rem;margin-right:.5rem}.mh3{margin-left:1rem;margin-right:1rem}.mh4{margin-left:2rem;margin-right:2rem}.mh5{margin-left:4rem;margin-right:4rem}.mh6{margin-left:8rem;margin-right:8rem}.mh7{margin-left:16rem;margin-right:16rem}.collapse{border-collapse:collapse;border-spacing:0}.striped--moon-gray:nth-child(odd){background-color:#aaa;background-color:#ccc}.striped--light-gray:nth-child(odd){background-color:#eee}.striped--near-white:nth-child(odd){background-color:#f4f4f4}.strike{text-decoration:line-through}.underline{text-decoration:underline}.no-underline{text-decoration:none}.tl{text-align:left}.tr{text-align:right}.tc{text-align:center}.ttc{text-transform:capitalize}.ttl{text-transform:lowercase}.ttu{text-transform:uppercase}.ttn{text-transform:none}.f-6,.f-headline{font-size:6rem}.f-5,.f-subheadline{font-size:5rem}.f1{font-size:3rem}.f2{font-size:2.25rem}.f3{font-size:1.5rem}.f4{font-size:1.25rem}.f5{font-size:1rem}.f6{font-size:.875rem}.measure{max-width:30em}.measure-wide{max-width:34em}.measure-narrow{max-width:20em}.indent{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps{font-variant:small-caps}.truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.aspect-ratio{height:0;position:relative}.aspect-ratio--16x9{padding-bottom:56.25%}.aspect-ratio--4x3{padding-bottom:75%}.aspect-ratio--8x5{padding-bottom:62.5%}.aspect-ratio--object{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:1}.overflow-container{overflow-y:scroll}.center{margin-right:auto;margin-left:auto}.clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal{white-space:normal}.nowrap{white-space:nowrap}.pre{white-space:pre}.v-base{vertical-align:baseline}.v-mid{vertical-align:middle}.v-top{vertical-align:top}.v-btm{vertical-align:bottom}.dim{opacity:1}.dim,.dim:focus,.dim:hover{transition:opacity .15s ease-in}.dim:focus,.dim:hover{opacity:.5}.dim:active{opacity:.8;transition:opacity .15s ease-out}.hide-child .child{opacity:0;transition:opacity .15s ease-in}.hide-child:active .child,.hide-child:focus .child,.hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.underline-hover:focus,.underline-hover:hover{text-decoration:underline}.grow{transition:transform .2s}.grow:hover{transform:scale(1.05)}.grow-large{transition:transform .2s}.grow-large:hover{transform:scale(1.2)}.pointer:hover{cursor:pointer}.debug *{outline:1px solid gold}@media screen and (min-width:30em){.cover-ns{background-size:cover}.contain-ns{background-size:contain}.ba-ns{border-style:solid;border-width:1px}.bt-ns{border-top-style:solid;border-top-width:1px}.br-ns{border-right-style:solid;border-right-width:1px}.bb-ns{border-bottom-style:solid;border-bottom-width:1px}.bl-ns{border-left-style:solid;border-left-width:1px}.bn-ns{border-style:none;border-width:0}.br0-ns{border-radius:0}.br1-ns{border-radius:.125rem}.br2-ns{border-radius:.25rem}.br3-ns{border-radius:.5rem}.br4-ns{border-radius:1rem}.br-100-ns{border-radius:100%}.br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.br--top-ns{border-bottom-right-radius:0}.br--right-ns,.br--top-ns{border-bottom-left-radius:0}.br--right-ns{border-top-left-radius:0}.br--left-ns{border-top-right-radius:0;border-bottom-right-radius:0}.b--dotted-ns{border-style:dotted}.b--dashed-ns{border-style:dashed}.b--solid-ns{border-style:solid}.b--none-ns{border-style:none}.bw0-ns{border-width:0}.bw1-ns{border-width:.125rem}.bw2-ns{border-width:.25rem}.bw3-ns{border-width:.5rem}.bw4-ns{border-width:1rem}.bw5-ns{border-width:2rem}.bt-0-ns{border-top-width:0}.br-0-ns{border-right-width:0}.bb-0-ns{border-bottom-width:0}.bl-0-ns{border-left-width:0}.shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-ns{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-ns{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}.top-0-ns{top:0}.left-0-ns{left:0}.right-0-ns{right:0}.bottom-0-ns{bottom:0}.top-1-ns{top:1rem}.left-1-ns{left:1rem}.right-1-ns{right:1rem}.bottom-1-ns{bottom:1rem}.top-2-ns{top:2rem}.left-2-ns{left:2rem}.right-2-ns{right:2rem}.bottom-2-ns{bottom:2rem}.top--1-ns{top:-1rem}.right--1-ns{right:-1rem}.bottom--1-ns{bottom:-1rem}.left--1-ns{left:-1rem}.top--2-ns{top:-2rem}.right--2-ns{right:-2rem}.bottom--2-ns{bottom:-2rem}.left--2-ns{left:-2rem}.absolute--fill-ns{top:0;right:0;bottom:0;left:0}.cl-ns{clear:left}.cr-ns{clear:right}.cb-ns{clear:both}.cn-ns{clear:none}.dn-ns{display:none}.di-ns{display:inline}.db-ns{display:block}.dib-ns{display:inline-block}.dit-ns{display:inline-table}.dt-ns{display:table}.dtc-ns{display:table-cell}.dt-row-ns{display:table-row}.dt-row-group-ns{display:table-row-group}.dt-column-ns{display:table-column}.dt-column-group-ns{display:table-column-group}.dt--fixed-ns{table-layout:fixed;width:100%}.flex-ns{display:flex}.flex-auto-ns{flex:1 1 auto;min-width:0;min-height:0}.flex-none-ns{flex:none}.flex-column-ns{flex-direction:column}.flex-wrap-ns{flex-wrap:wrap}.items-start-ns{align-items:flex-start}.items-end-ns{align-items:flex-end}.items-center-ns{align-items:center}.items-baseline-ns{align-items:baseline}.items-stretch-ns{align-items:stretch}.self-start-ns{align-self:flex-start}.self-end-ns{align-self:flex-end}.self-center-ns{align-self:center}.self-baseline-ns{align-self:baseline}.self-stretch-ns{align-self:stretch}.justify-start-ns{justify-content:flex-start}.justify-end-ns{justify-content:flex-end}.justify-center-ns{justify-content:center}.justify-between-ns{justify-content:space-between}.justify-around-ns{justify-content:space-around}.content-start-ns{align-content:flex-start}.content-end-ns{align-content:flex-end}.content-center-ns{align-content:center}.content-between-ns{align-content:space-between}.content-around-ns{align-content:space-around}.content-stretch-ns{align-content:stretch}.order-0-ns{order:0}.order-1-ns{order:1}.order-2-ns{order:2}.order-3-ns{order:3}.order-4-ns{order:4}.order-5-ns{order:5}.order-6-ns{order:6}.order-7-ns{order:7}.order-8-ns{order:8}.order-last-ns{order:99999}.fl-ns{float:left}.fl-ns,.fr-ns{display:inline}.fr-ns{float:right}.fn-ns{float:none}.i-ns{font-style:italic}.fs-normal-ns{font-style:normal}.normal-ns{font-weight:400}.b-ns{font-weight:700}.fw1-ns{font-weight:100}.fw2-ns{font-weight:200}.fw3-ns{font-weight:300}.fw4-ns{font-weight:400}.fw5-ns{font-weight:500}.fw6-ns{font-weight:600}.fw7-ns{font-weight:700}.fw8-ns{font-weight:800}.fw9-ns{font-weight:900}.h1-ns{height:1rem}.h2-ns{height:2rem}.h3-ns{height:4rem}.h4-ns{height:8rem}.h5-ns{height:16rem}.h-25-ns{height:25%}.h-50-ns{height:50%}.h-75-ns{height:75%}.h-100-ns{height:100%}.h-auto-ns{height:auto}.h-inherit-ns{height:inherit}.tracked-ns{letter-spacing:.16em}.tracked-tight-ns{letter-spacing:-.05em}.tracked-mega-ns{letter-spacing:.32em}.lh-solid-ns{line-height:1}.lh-title-ns{line-height:1.3}.lh-copy-ns{line-height:1.6}.mw-100-ns{max-width:100%}.mw1-ns{max-width:1rem}.mw2-ns{max-width:2rem}.mw3-ns{max-width:4rem}.mw4-ns{max-width:8rem}.mw5-ns{max-width:16rem}.mw6-ns{max-width:32rem}.mw7-ns{max-width:48rem}.mw8-ns{max-width:64rem}.mw9-ns{max-width:96rem}.mw-none-ns{max-width:none}.w1-ns{width:1rem}.w2-ns{width:2rem}.w3-ns{width:4rem}.w4-ns{width:8rem}.w5-ns{width:16rem}.w-10-ns{width:10%}.w-20-ns{width:20%}.w-25-ns{width:25%}.w-33-ns{width:33%}.w-34-ns{width:34%}.w-40-ns{width:40%}.w-50-ns{width:50%}.w-60-ns{width:60%}.w-75-ns{width:75%}.w-80-ns{width:80%}.w-100-ns{width:100%}.w-auto-ns{width:auto}.overflow-visible-ns{overflow:visible}.overflow-hidden-ns{overflow:hidden}.overflow-scroll-ns{overflow:scroll}.overflow-auto-ns{overflow:auto}.overflow-x-visible-ns{overflow-x:visible}.overflow-x-hidden-ns{overflow-x:hidden}.overflow-x-scroll-ns{overflow-x:scroll}.overflow-x-auto-ns{overflow-x:auto}.overflow-y-visible-ns{overflow-y:visible}.overflow-y-hidden-ns{overflow-y:hidden}.overflow-y-scroll-ns{overflow-y:scroll}.overflow-y-auto-ns{overflow-y:auto}.static-ns{position:static}.relative-ns{position:relative}.absolute-ns{position:absolute}.fixed-ns{position:fixed}.pa0-ns{padding:0}.pa1-ns{padding:.25rem}.pa2-ns{padding:.5rem}.pa3-ns{padding:1rem}.pa4-ns{padding:2rem}.pa5-ns{padding:4rem}.pa6-ns{padding:8rem}.pa7-ns{padding:16rem}.pl0-ns{padding-left:0}.pl1-ns{padding-left:.25rem}.pl2-ns{padding-left:.5rem}.pl3-ns{padding-left:1rem}.pl4-ns{padding-left:2rem}.pl5-ns{padding-left:4rem}.pl6-ns{padding-left:8rem}.pl7-ns{padding-left:16rem}.pr0-ns{padding-right:0}.pr1-ns{padding-right:.25rem}.pr2-ns{padding-right:.5rem}.pr3-ns{padding-right:1rem}.pr4-ns{padding-right:2rem}.pr5-ns{padding-right:4rem}.pr6-ns{padding-right:8rem}.pr7-ns{padding-right:16rem}.pb0-ns{padding-bottom:0}.pb1-ns{padding-bottom:.25rem}.pb2-ns{padding-bottom:.5rem}.pb3-ns{padding-bottom:1rem}.pb4-ns{padding-bottom:2rem}.pb5-ns{padding-bottom:4rem}.pb6-ns{padding-bottom:8rem}.pb7-ns{padding-bottom:16rem}.pt0-ns{padding-top:0}.pt1-ns{padding-top:.25rem}.pt2-ns{padding-top:.5rem}.pt3-ns{padding-top:1rem}.pt4-ns{padding-top:2rem}.pt5-ns{padding-top:4rem}.pt6-ns{padding-top:8rem}.pt7-ns{padding-top:16rem}.pv0-ns{padding-top:0;padding-bottom:0}.pv1-ns{padding-top:.25rem;padding-bottom:.25rem}.pv2-ns{padding-top:.5rem;padding-bottom:.5rem}.pv3-ns{padding-top:1rem;padding-bottom:1rem}.pv4-ns{padding-top:2rem;padding-bottom:2rem}.pv5-ns{padding-top:4rem;padding-bottom:4rem}.pv6-ns{padding-top:8rem;padding-bottom:8rem}.pv7-ns{padding-top:16rem;padding-bottom:16rem}.ph0-ns{padding-left:0;padding-right:0}.ph1-ns{padding-left:.25rem;padding-right:.25rem}.ph2-ns{padding-left:.5rem;padding-right:.5rem}.ph3-ns{padding-left:1rem;padding-right:1rem}.ph4-ns{padding-left:2rem;padding-right:2rem}.ph5-ns{padding-left:4rem;padding-right:4rem}.ph6-ns{padding-left:8rem;padding-right:8rem}.ph7-ns{padding-left:16rem;padding-right:16rem}.ma0-ns{margin:0}.ma1-ns{margin:.25rem}.ma2-ns{margin:.5rem}.ma3-ns{margin:1rem}.ma4-ns{margin:2rem}.ma5-ns{margin:4rem}.ma6-ns{margin:8rem}.ma7-ns{margin:16rem}.ml0-ns{margin-left:0}.ml1-ns{margin-left:.25rem}.ml2-ns{margin-left:.5rem}.ml3-ns{margin-left:1rem}.ml4-ns{margin-left:2rem}.ml5-ns{margin-left:4rem}.ml6-ns{margin-left:8rem}.ml7-ns{margin-left:16rem}.mr0-ns{margin-right:0}.mr1-ns{margin-right:.25rem}.mr2-ns{margin-right:.5rem}.mr3-ns{margin-right:1rem}.mr4-ns{margin-right:2rem}.mr5-ns{margin-right:4rem}.mr6-ns{margin-right:8rem}.mr7-ns{margin-right:16rem}.mb0-ns{margin-bottom:0}.mb1-ns{margin-bottom:.25rem}.mb2-ns{margin-bottom:.5rem}.mb3-ns{margin-bottom:1rem}.mb4-ns{margin-bottom:2rem}.mb5-ns{margin-bottom:4rem}.mb6-ns{margin-bottom:8rem}.mb7-ns{margin-bottom:16rem}.mt0-ns{margin-top:0}.mt1-ns{margin-top:.25rem}.mt2-ns{margin-top:.5rem}.mt3-ns{margin-top:1rem}.mt4-ns{margin-top:2rem}.mt5-ns{margin-top:4rem}.mt6-ns{margin-top:8rem}.mt7-ns{margin-top:16rem}.mv0-ns{margin-top:0;margin-bottom:0}.mv1-ns{margin-top:.25rem;margin-bottom:.25rem}.mv2-ns{margin-top:.5rem;margin-bottom:.5rem}.mv3-ns{margin-top:1rem;margin-bottom:1rem}.mv4-ns{margin-top:2rem;margin-bottom:2rem}.mv5-ns{margin-top:4rem;margin-bottom:4rem}.mv6-ns{margin-top:8rem;margin-bottom:8rem}.mv7-ns{margin-top:16rem;margin-bottom:16rem}.mh0-ns{margin-left:0;margin-right:0}.mh1-ns{margin-left:.25rem;margin-right:.25rem}.mh2-ns{margin-left:.5rem;margin-right:.5rem}.mh3-ns{margin-left:1rem;margin-right:1rem}.mh4-ns{margin-left:2rem;margin-right:2rem}.mh5-ns{margin-left:4rem;margin-right:4rem}.mh6-ns{margin-left:8rem;margin-right:8rem}.mh7-ns{margin-left:16rem;margin-right:16rem}.strike-ns{text-decoration:line-through}.underline-ns{text-decoration:underline}.no-underline-ns{text-decoration:none}.tl-ns{text-align:left}.tr-ns{text-align:right}.tc-ns{text-align:center}.ttc-ns{text-transform:capitalize}.ttl-ns{text-transform:lowercase}.ttu-ns{text-transform:uppercase}.ttn-ns{text-transform:none}.f-6-ns,.f-headline-ns{font-size:6rem}.f-5-ns,.f-subheadline-ns{font-size:5rem}.f1-ns{font-size:3rem}.f2-ns{font-size:2.25rem}.f3-ns{font-size:1.5rem}.f4-ns{font-size:1.25rem}.f5-ns{font-size:1rem}.f6-ns{font-size:.875rem}.measure-ns{max-width:30em}.measure-wide-ns{max-width:34em}.measure-narrow-ns{max-width:20em}.indent-ns{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-ns{font-variant:small-caps}.truncate-ns{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.clip-ns{position:fixed!important;position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal-ns{white-space:normal}.nowrap-ns{white-space:nowrap}.pre-ns{white-space:pre}.v-base-ns{vertical-align:baseline}.v-mid-ns{vertical-align:middle}.v-top-ns{vertical-align:top}.v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.cover-m{background-size:cover}.contain-m{background-size:contain}.ba-m{border-style:solid;border-width:1px}.bt-m{border-top-style:solid;border-top-width:1px}.br-m{border-right-style:solid;border-right-width:1px}.bb-m{border-bottom-style:solid;border-bottom-width:1px}.bl-m{border-left-style:solid;border-left-width:1px}.bn-m{border-style:none;border-width:0}.br0-m{border-radius:0}.br1-m{border-radius:.125rem}.br2-m{border-radius:.25rem}.br3-m{border-radius:.5rem}.br4-m{border-radius:1rem}.br-100-m{border-radius:100%}.br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.br--top-m{border-bottom-right-radius:0}.br--right-m,.br--top-m{border-bottom-left-radius:0}.br--right-m{border-top-left-radius:0}.br--left-m{border-top-right-radius:0;border-bottom-right-radius:0}.b--dotted-m{border-style:dotted}.b--dashed-m{border-style:dashed}.b--solid-m{border-style:solid}.b--none-m{border-style:none}.bw0-m{border-width:0}.bw1-m{border-width:.125rem}.bw2-m{border-width:.25rem}.bw3-m{border-width:.5rem}.bw4-m{border-width:1rem}.bw5-m{border-width:2rem}.bt-0-m{border-top-width:0}.br-0-m{border-right-width:0}.bb-0-m{border-bottom-width:0}.bl-0-m{border-left-width:0}.shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-m{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-m{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}.top-0-m{top:0}.left-0-m{left:0}.right-0-m{right:0}.bottom-0-m{bottom:0}.top-1-m{top:1rem}.left-1-m{left:1rem}.right-1-m{right:1rem}.bottom-1-m{bottom:1rem}.top-2-m{top:2rem}.left-2-m{left:2rem}.right-2-m{right:2rem}.bottom-2-m{bottom:2rem}.top--1-m{top:-1rem}.right--1-m{right:-1rem}.bottom--1-m{bottom:-1rem}.left--1-m{left:-1rem}.top--2-m{top:-2rem}.right--2-m{right:-2rem}.bottom--2-m{bottom:-2rem}.left--2-m{left:-2rem}.absolute--fill-m{top:0;right:0;bottom:0;left:0}.cl-m{clear:left}.cr-m{clear:right}.cb-m{clear:both}.cn-m{clear:none}.dn-m{display:none}.di-m{display:inline}.db-m{display:block}.dib-m{display:inline-block}.dit-m{display:inline-table}.dt-m{display:table}.dtc-m{display:table-cell}.dt-row-m{display:table-row}.dt-row-group-m{display:table-row-group}.dt-column-m{display:table-column}.dt-column-group-m{display:table-column-group}.dt--fixed-m{table-layout:fixed;width:100%}.flex-m{display:flex}.flex-auto-m{flex:1 1 auto;min-width:0;min-height:0}.flex-none-m{flex:none}.flex-column-m{flex-direction:column}.flex-wrap-m{flex-wrap:wrap}.items-start-m{align-items:flex-start}.items-end-m{align-items:flex-end}.items-center-m{align-items:center}.items-baseline-m{align-items:baseline}.items-stretch-m{align-items:stretch}.self-start-m{align-self:flex-start}.self-end-m{align-self:flex-end}.self-center-m{align-self:center}.self-baseline-m{align-self:baseline}.self-stretch-m{align-self:stretch}.justify-start-m{justify-content:flex-start}.justify-end-m{justify-content:flex-end}.justify-center-m{justify-content:center}.justify-between-m{justify-content:space-between}.justify-around-m{justify-content:space-around}.content-start-m{align-content:flex-start}.content-end-m{align-content:flex-end}.content-center-m{align-content:center}.content-between-m{align-content:space-between}.content-around-m{align-content:space-around}.content-stretch-m{align-content:stretch}.order-0-m{order:0}.order-1-m{order:1}.order-2-m{order:2}.order-3-m{order:3}.order-4-m{order:4}.order-5-m{order:5}.order-6-m{order:6}.order-7-m{order:7}.order-8-m{order:8}.order-last-m{order:99999}.fl-m{float:left}.fl-m,.fr-m{display:inline}.fr-m{float:right}.fn-m{float:none}.i-m{font-style:italic}.fs-normal-m{font-style:normal}.normal-m{font-weight:400}.b-m{font-weight:700}.fw1-m{font-weight:100}.fw2-m{font-weight:200}.fw3-m{font-weight:300}.fw4-m{font-weight:400}.fw5-m{font-weight:500}.fw6-m{font-weight:600}.fw7-m{font-weight:700}.fw8-m{font-weight:800}.fw9-m{font-weight:900}.h1-m{height:1rem}.h2-m{height:2rem}.h3-m{height:4rem}.h4-m{height:8rem}.h5-m{height:16rem}.h-25-m{height:25%}.h-50-m{height:50%}.h-75-m{height:75%}.h-100-m{height:100%}.h-auto-m{height:auto}.h-inherit-m{height:inherit}.tracked-m{letter-spacing:.16em}.tracked-tight-m{letter-spacing:-.05em}.tracked-mega-m{letter-spacing:.32em}.lh-solid-m{line-height:1}.lh-title-m{line-height:1.3}.lh-copy-m{line-height:1.6}.mw-100-m{max-width:100%}.mw1-m{max-width:1rem}.mw2-m{max-width:2rem}.mw3-m{max-width:4rem}.mw4-m{max-width:8rem}.mw5-m{max-width:16rem}.mw6-m{max-width:32rem}.mw7-m{max-width:48rem}.mw8-m{max-width:64rem}.mw9-m{max-width:96rem}.mw-none-m{max-width:none}.w1-m{width:1rem}.w2-m{width:2rem}.w3-m{width:4rem}.w4-m{width:8rem}.w5-m{width:16rem}.w-10-m{width:10%}.w-20-m{width:20%}.w-25-m{width:25%}.w-33-m{width:33%}.w-34-m{width:34%}.w-40-m{width:40%}.w-50-m{width:50%}.w-60-m{width:60%}.w-75-m{width:75%}.w-80-m{width:80%}.w-100-m{width:100%}.w-auto-m{width:auto}.overflow-visible-m{overflow:visible}.overflow-hidden-m{overflow:hidden}.overflow-scroll-m{overflow:scroll}.overflow-auto-m{overflow:auto}.overflow-x-visible-m{overflow-x:visible}.overflow-x-hidden-m{overflow-x:hidden}.overflow-x-scroll-m{overflow-x:scroll}.overflow-x-auto-m{overflow-x:auto}.overflow-y-visible-m{overflow-y:visible}.overflow-y-hidden-m{overflow-y:hidden}.overflow-y-scroll-m{overflow-y:scroll}.overflow-y-auto-m{overflow-y:auto}.static-m{position:static}.relative-m{position:relative}.absolute-m{position:absolute}.fixed-m{position:fixed}.pa0-m{padding:0}.pa1-m{padding:.25rem}.pa2-m{padding:.5rem}.pa3-m{padding:1rem}.pa4-m{padding:2rem}.pa5-m{padding:4rem}.pa6-m{padding:8rem}.pa7-m{padding:16rem}.pl0-m{padding-left:0}.pl1-m{padding-left:.25rem}.pl2-m{padding-left:.5rem}.pl3-m{padding-left:1rem}.pl4-m{padding-left:2rem}.pl5-m{padding-left:4rem}.pl6-m{padding-left:8rem}.pl7-m{padding-left:16rem}.pr0-m{padding-right:0}.pr1-m{padding-right:.25rem}.pr2-m{padding-right:.5rem}.pr3-m{padding-right:1rem}.pr4-m{padding-right:2rem}.pr5-m{padding-right:4rem}.pr6-m{padding-right:8rem}.pr7-m{padding-right:16rem}.pb0-m{padding-bottom:0}.pb1-m{padding-bottom:.25rem}.pb2-m{padding-bottom:.5rem}.pb3-m{padding-bottom:1rem}.pb4-m{padding-bottom:2rem}.pb5-m{padding-bottom:4rem}.pb6-m{padding-bottom:8rem}.pb7-m{padding-bottom:16rem}.pt0-m{padding-top:0}.pt1-m{padding-top:.25rem}.pt2-m{padding-top:.5rem}.pt3-m{padding-top:1rem}.pt4-m{padding-top:2rem}.pt5-m{padding-top:4rem}.pt6-m{padding-top:8rem}.pt7-m{padding-top:16rem}.pv0-m{padding-top:0;padding-bottom:0}.pv1-m{padding-top:.25rem;padding-bottom:.25rem}.pv2-m{padding-top:.5rem;padding-bottom:.5rem}.pv3-m{padding-top:1rem;padding-bottom:1rem}.pv4-m{padding-top:2rem;padding-bottom:2rem}.pv5-m{padding-top:4rem;padding-bottom:4rem}.pv6-m{padding-top:8rem;padding-bottom:8rem}.pv7-m{padding-top:16rem;padding-bottom:16rem}.ph0-m{padding-left:0;padding-right:0}.ph1-m{padding-left:.25rem;padding-right:.25rem}.ph2-m{padding-left:.5rem;padding-right:.5rem}.ph3-m{padding-left:1rem;padding-right:1rem}.ph4-m{padding-left:2rem;padding-right:2rem}.ph5-m{padding-left:4rem;padding-right:4rem}.ph6-m{padding-left:8rem;padding-right:8rem}.ph7-m{padding-left:16rem;padding-right:16rem}.ma0-m{margin:0}.ma1-m{margin:.25rem}.ma2-m{margin:.5rem}.ma3-m{margin:1rem}.ma4-m{margin:2rem}.ma5-m{margin:4rem}.ma6-m{margin:8rem}.ma7-m{margin:16rem}.ml0-m{margin-left:0}.ml1-m{margin-left:.25rem}.ml2-m{margin-left:.5rem}.ml3-m{margin-left:1rem}.ml4-m{margin-left:2rem}.ml5-m{margin-left:4rem}.ml6-m{margin-left:8rem}.ml7-m{margin-left:16rem}.mr0-m{margin-right:0}.mr1-m{margin-right:.25rem}.mr2-m{margin-right:.5rem}.mr3-m{margin-right:1rem}.mr4-m{margin-right:2rem}.mr5-m{margin-right:4rem}.mr6-m{margin-right:8rem}.mr7-m{margin-right:16rem}.mb0-m{margin-bottom:0}.mb1-m{margin-bottom:.25rem}.mb2-m{margin-bottom:.5rem}.mb3-m{margin-bottom:1rem}.mb4-m{margin-bottom:2rem}.mb5-m{margin-bottom:4rem}.mb6-m{margin-bottom:8rem}.mb7-m{margin-bottom:16rem}.mt0-m{margin-top:0}.mt1-m{margin-top:.25rem}.mt2-m{margin-top:.5rem}.mt3-m{margin-top:1rem}.mt4-m{margin-top:2rem}.mt5-m{margin-top:4rem}.mt6-m{margin-top:8rem}.mt7-m{margin-top:16rem}.mv0-m{margin-top:0;margin-bottom:0}.mv1-m{margin-top:.25rem;margin-bottom:.25rem}.mv2-m{margin-top:.5rem;margin-bottom:.5rem}.mv3-m{margin-top:1rem;margin-bottom:1rem}.mv4-m{margin-top:2rem;margin-bottom:2rem}.mv5-m{margin-top:4rem;margin-bottom:4rem}.mv6-m{margin-top:8rem;margin-bottom:8rem}.mv7-m{margin-top:16rem;margin-bottom:16rem}.mh0-m{margin-left:0;margin-right:0}.mh1-m{margin-left:.25rem;margin-right:.25rem}.mh2-m{margin-left:.5rem;margin-right:.5rem}.mh3-m{margin-left:1rem;margin-right:1rem}.mh4-m{margin-left:2rem;margin-right:2rem}.mh5-m{margin-left:4rem;margin-right:4rem}.mh6-m{margin-left:8rem;margin-right:8rem}.mh7-m{margin-left:16rem;margin-right:16rem}.strike-m{text-decoration:line-through}.underline-m{text-decoration:underline}.no-underline-m{text-decoration:none}.tl-m{text-align:left}.tr-m{text-align:right}.tc-m{text-align:center}.ttc-m{text-transform:capitalize}.ttl-m{text-transform:lowercase}.ttu-m{text-transform:uppercase}.ttn-m{text-transform:none}.f-6-m,.f-headline-m{font-size:6rem}.f-5-m,.f-subheadline-m{font-size:5rem}.f1-m{font-size:3rem}.f2-m{font-size:2.25rem}.f3-m{font-size:1.5rem}.f4-m{font-size:1.25rem}.f5-m{font-size:1rem}.f6-m{font-size:.875rem}.measure-m{max-width:30em}.measure-wide-m{max-width:34em}.measure-narrow-m{max-width:20em}.indent-m{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-m{font-variant:small-caps}.truncate-m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.clip-m{position:fixed!important;position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal-m{white-space:normal}.nowrap-m{white-space:nowrap}.pre-m{white-space:pre}.v-base-m{vertical-align:baseline}.v-mid-m{vertical-align:middle}.v-top-m{vertical-align:top}.v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.cover-l{background-size:cover}.contain-l{background-size:contain}.ba-l{border-style:solid;border-width:1px}.bt-l{border-top-style:solid;border-top-width:1px}.br-l{border-right-style:solid;border-right-width:1px}.bb-l{border-bottom-style:solid;border-bottom-width:1px}.bl-l{border-left-style:solid;border-left-width:1px}.bn-l{border-style:none;border-width:0}.br0-l{border-radius:0}.br1-l{border-radius:.125rem}.br2-l{border-radius:.25rem}.br3-l{border-radius:.5rem}.br4-l{border-radius:1rem}.br-100-l{border-radius:100%}.br--bottom-l{border-radius-top-left:0;border-radius-top-right:0}.br--top-l{border-bottom-right-radius:0}.br--right-l,.br--top-l{border-bottom-left-radius:0}.br--right-l{border-top-left-radius:0}.br--left-l{border-top-right-radius:0;border-bottom-right-radius:0}.b--dotted-l{border-style:dotted}.b--dashed-l{border-style:dashed}.b--solid-l{border-style:solid}.b--none-l{border-style:none}.bw0-l{border-width:0}.bw1-l{border-width:.125rem}.bw2-l{border-width:.25rem}.bw3-l{border-width:.5rem}.bw4-l{border-width:1rem}.bw5-l{border-width:2rem}.bt-0-l{border-top-width:0}.br-0-l{border-right-width:0}.bb-0-l{border-bottom-width:0}.bl-0-l{border-left-width:0}.shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-l{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-l{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}.top-0-l{top:0}.left-0-l{left:0}.right-0-l{right:0}.bottom-0-l{bottom:0}.top-1-l{top:1rem}.left-1-l{left:1rem}.right-1-l{right:1rem}.bottom-1-l{bottom:1rem}.top-2-l{top:2rem}.left-2-l{left:2rem}.right-2-l{right:2rem}.bottom-2-l{bottom:2rem}.top--1-l{top:-1rem}.right--1-l{right:-1rem}.bottom--1-l{bottom:-1rem}.left--1-l{left:-1rem}.top--2-l{top:-2rem}.right--2-l{right:-2rem}.bottom--2-l{bottom:-2rem}.left--2-l{left:-2rem}.absolute--fill-l{top:0;right:0;bottom:0;left:0}.cl-l{clear:left}.cr-l{clear:right}.cb-l{clear:both}.cn-l{clear:none}.dn-l{display:none}.di-l{display:inline}.db-l{display:block}.dib-l{display:inline-block}.dit-l{display:inline-table}.dt-l{display:table}.dtc-l{display:table-cell}.dt-row-l{display:table-row}.dt-row-group-l{display:table-row-group}.dt-column-l{display:table-column}.dt-column-group-l{display:table-column-group}.dt--fixed-l{table-layout:fixed;width:100%}.flex-l{display:flex}.flex-auto-l{flex:1 1 auto;min-width:0;min-height:0}.flex-none-l{flex:none}.flex-column-l{flex-direction:column}.flex-wrap-l{flex-wrap:wrap}.items-start-l{align-items:flex-start}.items-end-l{align-items:flex-end}.items-center-l{align-items:center}.items-baseline-l{align-items:baseline}.items-stretch-l{align-items:stretch}.self-start-l{align-self:flex-start}.self-end-l{align-self:flex-end}.self-center-l{align-self:center}.self-baseline-l{align-self:baseline}.self-stretch-l{align-self:stretch}.justify-start-l{justify-content:flex-start}.justify-end-l{justify-content:flex-end}.justify-center-l{justify-content:center}.justify-between-l{justify-content:space-between}.justify-around-l{justify-content:space-around}.content-start-l{align-content:flex-start}.content-end-l{align-content:flex-end}.content-center-l{align-content:center}.content-between-l{align-content:space-between}.content-around-l{align-content:space-around}.content-stretch-l{align-content:stretch}.order-0-l{order:0}.order-1-l{order:1}.order-2-l{order:2}.order-3-l{order:3}.order-4-l{order:4}.order-5-l{order:5}.order-6-l{order:6}.order-7-l{order:7}.order-8-l{order:8}.order-last-l{order:99999}.fl-l{float:left}.fl-l,.fr-l{display:inline}.fr-l{float:right}.fn-l{float:none}.i-l{font-style:italic}.fs-normal-l{font-style:normal}.normal-l{font-weight:400}.b-l{font-weight:700}.fw1-l{font-weight:100}.fw2-l{font-weight:200}.fw3-l{font-weight:300}.fw4-l{font-weight:400}.fw5-l{font-weight:500}.fw6-l{font-weight:600}.fw7-l{font-weight:700}.fw8-l{font-weight:800}.fw9-l{font-weight:900}.h1-l{height:1rem}.h2-l{height:2rem}.h3-l{height:4rem}.h4-l{height:8rem}.h5-l{height:16rem}.h-25-l{height:25%}.h-50-l{height:50%}.h-75-l{height:75%}.h-100-l{height:100%}.h-auto-l{height:auto}.h-inherit-l{height:inherit}.tracked-l{letter-spacing:.16em}.tracked-tight-l{letter-spacing:-.05em}.tracked-mega-l{letter-spacing:.32em}.lh-solid-l{line-height:1}.lh-title-l{line-height:1.3}.lh-copy-l{line-height:1.6}.mw-100-l{max-width:100%}.mw1-l{max-width:1rem}.mw2-l{max-width:2rem}.mw3-l{max-width:4rem}.mw4-l{max-width:8rem}.mw5-l{max-width:16rem}.mw6-l{max-width:32rem}.mw7-l{max-width:48rem}.mw8-l{max-width:64rem}.mw9-l{max-width:96rem}.mw-none-l{max-width:none}.w1-l{width:1rem}.w2-l{width:2rem}.w3-l{width:4rem}.w4-l{width:8rem}.w5-l{width:16rem}.w-10-l{width:10%}.w-20-l{width:20%}.w-25-l{width:25%}.w-33-l{width:33%}.w-34-l{width:34%}.w-40-l{width:40%}.w-50-l{width:50%}.w-60-l{width:60%}.w-75-l{width:75%}.w-80-l{width:80%}.w-100-l{width:100%}.w-auto-l{width:auto}.overflow-visible-l{overflow:visible}.overflow-hidden-l{overflow:hidden}.overflow-scroll-l{overflow:scroll}.overflow-auto-l{overflow:auto}.overflow-x-visible-l{overflow-x:visible}.overflow-x-hidden-l{overflow-x:hidden}.overflow-x-scroll-l{overflow-x:scroll}.overflow-x-auto-l{overflow-x:auto}.overflow-y-visible-l{overflow-y:visible}.overflow-y-hidden-l{overflow-y:hidden}.overflow-y-scroll-l{overflow-y:scroll}.overflow-y-auto-l{overflow-y:auto}.static-l{position:static}.relative-l{position:relative}.absolute-l{position:absolute}.fixed-l{position:fixed}.pa0-l{padding:0}.pa1-l{padding:.25rem}.pa2-l{padding:.5rem}.pa3-l{padding:1rem}.pa4-l{padding:2rem}.pa5-l{padding:4rem}.pa6-l{padding:8rem}.pa7-l{padding:16rem}.pl0-l{padding-left:0}.pl1-l{padding-left:.25rem}.pl2-l{padding-left:.5rem}.pl3-l{padding-left:1rem}.pl4-l{padding-left:2rem}.pl5-l{padding-left:4rem}.pl6-l{padding-left:8rem}.pl7-l{padding-left:16rem}.pr0-l{padding-right:0}.pr1-l{padding-right:.25rem}.pr2-l{padding-right:.5rem}.pr3-l{padding-right:1rem}.pr4-l{padding-right:2rem}.pr5-l{padding-right:4rem}.pr6-l{padding-right:8rem}.pr7-l{padding-right:16rem}.pb0-l{padding-bottom:0}.pb1-l{padding-bottom:.25rem}.pb2-l{padding-bottom:.5rem}.pb3-l{padding-bottom:1rem}.pb4-l{padding-bottom:2rem}.pb5-l{padding-bottom:4rem}.pb6-l{padding-bottom:8rem}.pb7-l{padding-bottom:16rem}.pt0-l{padding-top:0}.pt1-l{padding-top:.25rem}.pt2-l{padding-top:.5rem}.pt3-l{padding-top:1rem}.pt4-l{padding-top:2rem}.pt5-l{padding-top:4rem}.pt6-l{padding-top:8rem}.pt7-l{padding-top:16rem}.pv0-l{padding-top:0;padding-bottom:0}.pv1-l{padding-top:.25rem;padding-bottom:.25rem}.pv2-l{padding-top:.5rem;padding-bottom:.5rem}.pv3-l{padding-top:1rem;padding-bottom:1rem}.pv4-l{padding-top:2rem;padding-bottom:2rem}.pv5-l{padding-top:4rem;padding-bottom:4rem}.pv6-l{padding-top:8rem;padding-bottom:8rem}.pv7-l{padding-top:16rem;padding-bottom:16rem}.ph0-l{padding-left:0;padding-right:0}.ph1-l{padding-left:.25rem;padding-right:.25rem}.ph2-l{padding-left:.5rem;padding-right:.5rem}.ph3-l{padding-left:1rem;padding-right:1rem}.ph4-l{padding-left:2rem;padding-right:2rem}.ph5-l{padding-left:4rem;padding-right:4rem}.ph6-l{padding-left:8rem;padding-right:8rem}.ph7-l{padding-left:16rem;padding-right:16rem}.ma0-l{margin:0}.ma1-l{margin:.25rem}.ma2-l{margin:.5rem}.ma3-l{margin:1rem}.ma4-l{margin:2rem}.ma5-l{margin:4rem}.ma6-l{margin:8rem}.ma7-l{margin:16rem}.ml0-l{margin-left:0}.ml1-l{margin-left:.25rem}.ml2-l{margin-left:.5rem}.ml3-l{margin-left:1rem}.ml4-l{margin-left:2rem}.ml5-l{margin-left:4rem}.ml6-l{margin-left:8rem}.ml7-l{margin-left:16rem}.mr0-l{margin-right:0}.mr1-l{margin-right:.25rem}.mr2-l{margin-right:.5rem}.mr3-l{margin-right:1rem}.mr4-l{margin-right:2rem}.mr5-l{margin-right:4rem}.mr6-l{margin-right:8rem}.mr7-l{margin-right:16rem}.mb0-l{margin-bottom:0}.mb1-l{margin-bottom:.25rem}.mb2-l{margin-bottom:.5rem}.mb3-l{margin-bottom:1rem}.mb4-l{margin-bottom:2rem}.mb5-l{margin-bottom:4rem}.mb6-l{margin-bottom:8rem}.mb7-l{margin-bottom:16rem}.mt0-l{margin-top:0}.mt1-l{margin-top:.25rem}.mt2-l{margin-top:.5rem}.mt3-l{margin-top:1rem}.mt4-l{margin-top:2rem}.mt5-l{margin-top:4rem}.mt6-l{margin-top:8rem}.mt7-l{margin-top:16rem}.mv0-l{margin-top:0;margin-bottom:0}.mv1-l{margin-top:.25rem;margin-bottom:.25rem}.mv2-l{margin-top:.5rem;margin-bottom:.5rem}.mv3-l{margin-top:1rem;margin-bottom:1rem}.mv4-l{margin-top:2rem;margin-bottom:2rem}.mv5-l{margin-top:4rem;margin-bottom:4rem}.mv6-l{margin-top:8rem;margin-bottom:8rem}.mv7-l{margin-top:16rem;margin-bottom:16rem}.mh0-l{margin-left:0;margin-right:0}.mh1-l{margin-left:.25rem;margin-right:.25rem}.mh2-l{margin-left:.5rem;margin-right:.5rem}.mh3-l{margin-left:1rem;margin-right:1rem}.mh4-l{margin-left:2rem;margin-right:2rem}.mh5-l{margin-left:4rem;margin-right:4rem}.mh6-l{margin-left:8rem;margin-right:8rem}.mh7-l{margin-left:16rem;margin-right:16rem}.strike-l{text-decoration:line-through}.underline-l{text-decoration:underline}.no-underline-l{text-decoration:none}.tl-l{text-align:left}.tr-l{text-align:right}.tc-l{text-align:center}.ttc-l{text-transform:capitalize}.ttl-l{text-transform:lowercase}.ttu-l{text-transform:uppercase}.ttn-l{text-transform:none}.f-6-l,.f-headline-l{font-size:6rem}.f-5-l,.f-subheadline-l{font-size:5rem}.f1-l{font-size:3rem}.f2-l{font-size:2.25rem}.f3-l{font-size:1.5rem}.f4-l{font-size:1.25rem}.f5-l{font-size:1rem}.f6-l{font-size:.875rem}.measure-l{max-width:30em}.measure-wide-l{max-width:34em}.measure-narrow-l{max-width:20em}.indent-l{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-l{font-variant:small-caps}.truncate-l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.clip-l{position:fixed!important;position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal-l{white-space:normal}.nowrap-l{white-space:nowrap}.pre-l{white-space:pre}.v-base-l{vertical-align:baseline}.v-mid-l{vertical-align:middle}.v-top-l{vertical-align:top}.v-btm-l{vertical-align:bottom}} - diff --git a/routes/index.js b/routes/index.js deleted file mode 100644 index 42af1dfb..00000000 --- a/routes/index.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -const express = require("express"); -const router = express.Router(); -const browserslist = require("browserslist"); -const bv = require("browserslist/package.json").version; -const cv = require("caniuse-db/package.json").version; -const caniuse = require("caniuse-db/data.json").agents; - -let caniuseRegion; - -function getCoverage(data, version) { - const lastVersion = Object.keys(data).sort((a, b) => { - return parseInt(b) - parseInt(a); - })[0]; - // If specific version coverage is missing, fall back to "version zero" - return data[version] !== undefined ? data[version] : data[lastVersion]; -} - -function getRegionCoverage(region, id, version) { - if (!caniuseRegion) { - caniuseRegion = require(`caniuse-db/region-usage-json/${region}.json`); - } - - return getCoverage(caniuseRegion.data[id], version); -} - -/* GET home page. */ -router.get("/", (req, res) => { - const query = req.query.q || "defaults"; - const queryHasIn = query.match(/ in ((?:alt-)?[A-Za-z]{2})(?:,|$)/); - - const region = queryHasIn ? queryHasIn[1] : undefined; - - let bl = null; - try { - // Remove quotes to allow users to copy multiline strings, - // e.g., from their package.json file. - const queryWithoutQuotes = query.replace(/"/g, ""); - bl = browserslist(queryWithoutQuotes); - } catch (e) { - // Error - return res.render("index", { - compatible: null, - query, - description: - "A page to display compatible browsers from a browserslist string.", - error: e, - }); - } - - const compatible = {}; - - if (bl) { - bl.map((b) => { - b = b.split(" "); - - const id = b[0]; - const version = b[1]; - - let coverage; - let type; - let name; - - // "Can I use" doesn't have stats for Node - if (id === "node") { - type = "server"; - name = "Node"; - } else { - const db = caniuse[id]; - - coverage = region - ? getRegionCoverage(region, id, version) - : getCoverage(db.usage_global, version); - type = db.type; - name = db.browser; - } - - if (!compatible[type]) { - compatible[type] = []; - } - - compatible[type].push({ - version, - id, - name, - coverage, - logo: `/images/${id}.png`, - }); - }); - } - - res.render("index", { - compatible, - query, - bv, - cv, - coverage: browserslist.coverage(bl, region), - description: - "A page to display compatible browsers from a browserslist string.", - region: region || "Global", - }); -}); - -module.exports = router; diff --git a/script/deploy b/script/deploy deleted file mode 100755 index ecca4cb2..00000000 --- a/script/deploy +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -e -now rm -y browserlist -now --public -now alias browserl.ist -now alias browsersl.ist diff --git a/server/handlers/api-browsers.js b/server/handlers/api-browsers.js new file mode 100644 index 00000000..6ceeecf1 --- /dev/null +++ b/server/handlers/api-browsers.js @@ -0,0 +1,22 @@ +import { URL } from 'node:url' + +import getBrowsers, { + QUERY_DEFAULTS, + REGION_GLOBAL +} from '../lib/get-browsers.js' +import { sendResponseAPI } from '../lib/send-response.js' + +export default async function handleAPIBrowsers(req, res) { + let { searchParams: params } = new URL(req.url, `http://${req.headers.host}/`) + + let query = params.get('q') || QUERY_DEFAULTS + let queryWithoutQuotes = query.replace(/'/g, '') + + let region = params.get('region') || REGION_GLOBAL + + try { + sendResponseAPI(res, 200, await getBrowsers(queryWithoutQuotes, region)) + } catch (error) { + sendResponseAPI(res, 400, { message: error.message }) + } +} diff --git a/server/handlers/main.js b/server/handlers/main.js new file mode 100644 index 00000000..6c7e64a5 --- /dev/null +++ b/server/handlers/main.js @@ -0,0 +1,24 @@ +import { URL } from 'node:url' + +import getFileData from '../lib/get-file-data.js' +import { sendResponse, sendResponseError } from '../lib/send-response.js' + +const responseHeaders = { + 'Content-Type': 'text/html', + 'Cache-Control': 'public, max-age=300, must-revalidate' +} + +export default async function handleMain(req, res) { + let filePath = new URL('../../client/dist/index.html', import.meta.url) + + try { + let { data } = await getFileData(filePath, true) + sendResponse(res, 200, responseHeaders, data) + } catch (error) { + if (error.httpStatus) { + sendResponseError(res, error.httpStatus, error.message) + } else { + sendResponseError(res, 500, 'Internal Server Error') + } + } +} diff --git a/server/handlers/static.js b/server/handlers/static.js new file mode 100644 index 00000000..9e5fbd89 --- /dev/null +++ b/server/handlers/static.js @@ -0,0 +1,50 @@ +import { URL } from 'node:url' + +import { sendResponse, sendResponseError } from '../lib/send-response.js' +import getFileData from '../lib/get-file-data.js' + +const CLIENT_DIR = '../../client' +const DIST_DIR = '/dist' +const MIME_TYPES = { + '.html': 'text/html', + '.js': 'text/javascript', + '.css': 'text/css', + '.json': 'application/json', + '.webmanifest': 'application/manifest+json', + '.png': 'image/png', + '.jpg': 'image/jpg', + '.svg': 'image/svg+xml', + '.ico': 'image/x-icon' +} + +export default async function handleStatic(req, res) { + let filePath = new URL(`${CLIENT_DIR}${DIST_DIR}${req.url}`, import.meta.url) + + try { + let shouldBeCached = req.url === '/favicon.ico' + let { name, ext, size, data } = await getFileData(filePath, shouldBeCached) + let resHeaders = { + 'Cache-Control': getCacheControl(name), + 'Content-Type': getContentType(ext), + 'Content-Length': size + } + sendResponse(res, 200, resHeaders, data) + } catch (error) { + if (error.httpStatus) { + sendResponseError(res, error.httpStatus, error.message) + } else { + sendResponseError(res, 500, 'Internal Server Error') + } + } +} + +function getContentType(ext) { + return MIME_TYPES[ext] || 'application/octet-stream' +} + +function getCacheControl(name) { + let hasFileCacheBuster = /\.(\w{8})$/.test(name) + return hasFileCacheBuster + ? 'public, max-age=31536000, immutable' + : 'max-age=3600' +} diff --git a/server/index.js b/server/index.js new file mode 100644 index 00000000..5894145b --- /dev/null +++ b/server/index.js @@ -0,0 +1,32 @@ +import http from 'node:http' +import { URL } from 'node:url' + +import handleMain from './handlers/main.js' +import handleAPIBrowsers from './handlers/api-browsers.js' +import handleStatic from './handlers/static.js' + +const PORT = process.env.PORT || 5000 + +const App = http.createServer(async (req, res) => { + let { pathname } = new URL(req.url, `http://${req.headers.host}/`) + + switch (pathname) { + case '/': + handleMain(req, res) + break + + case '/api/browsers': + handleAPIBrowsers(req, res) + break + + default: + handleStatic(req, res) + break + } +}) + +App.listen(PORT, () => { + process.stdout.write(`Server listening on a port http://localhost:${PORT}/\n`) +}) + +export default App diff --git a/server/lib/get-browsers.js b/server/lib/get-browsers.js new file mode 100644 index 00000000..27d53cb5 --- /dev/null +++ b/server/lib/get-browsers.js @@ -0,0 +1,139 @@ +import { agents as caniuseAgents, region as caniuseRegion } from 'caniuse-lite' +import { readFileSync } from 'node:fs' +import browserslist from 'browserslist' +import { URL } from 'node:url' + +let { version: bv } = importJSON('../node_modules/browserslist/package.json') +let { version: cv } = importJSON('../node_modules/caniuse-lite/package.json') + +export const QUERY_DEFAULTS = 'defaults' +export const REGION_GLOBAL = 'Global' + +export default async function getBrowsers(query, region) { + let loadBrowsersData = async (resolve, reject) => { + let browsersByQuery = [] + + try { + browsersByQuery = browserslist(query) + } catch (error) { + reject( + error.browserslist + ? error + : new Error(`Unknown browser query \`${query}\`.`) + ) + return + } + + let browsersGroups = {} + let browsersGroupsKeys = [] + + for (let browser of browsersByQuery) { + if (browsersGroupsKeys.includes(browser)) { + return + } + + browsersGroupsKeys.push(browser) + let [id, version] = browser.split(' ') + let versionCoverage = null + + if (id !== 'node') { + try { + versionCoverage = + region === REGION_GLOBAL + ? getGlobalCoverage(id, version) + : await getRegionCoverage(id, version, region) + } catch (error) { + reject(error) + } + } + + let versionData = { [`${version}`]: roundNumber(versionCoverage) } + + if (!browsersGroups[id]) { + browsersGroups[id] = { versions: versionData } + } else { + Object.assign(browsersGroups[id].versions, versionData) + } + } + + let browsers = Object.entries(browsersGroups) + .map(([id, { versions }]) => { + let name + let coverage + + // The Node.js is not in the Can I Use db + if (id === 'node') { + name = 'Node' + coverage = null + } else { + name = caniuseAgents[id].browser + coverage = roundNumber( + Object.values(versions).reduce((a, b) => a + b, 0) + ) + } + + return { + id, + name, + coverage, + versions + } + }) + .sort((a, b) => b.coverage - a.coverage) + + let coverage + + try { + coverage = roundNumber(browserslist.coverage(browsersByQuery, region)) + } catch (error) { + reject(error) + } + + resolve({ + query, + region, + coverage, + versions: { + browserslist: bv, + caniuse: cv + }, + browsers + }) + } + + return new Promise(loadBrowsersData) +} + +function getGlobalCoverage(id, version) { + return getCoverage(caniuseAgents[id].usage_global, version) +} + +async function getRegionCoverage(id, version, region) { + try { + if (region.includes('/')) { + throw new Error(`Invalid symbols in region name \`${region}\`.`) + } + + let { default: regionData } = await import( + `caniuse-lite/data/regions/${region}.js` + ) + return getCoverage(caniuseRegion(regionData)[id], version) + } catch (e) { + throw new Error(`Unknown region name \`${region}\`.`) + } +} + +function getCoverage(data, version) { + let [lastVersion] = Object.keys(data).sort((a, b) => Number(b) - Number(a)) + + // If specific version coverage is missing, fall back to 'version zero' + return data[version] !== undefined ? data[version] : data[lastVersion] +} + +function roundNumber(value) { + return Math.round(value * 100) / 100 +} + +function importJSON(path) { + return JSON.parse(readFileSync(new URL(path, import.meta.url))) +} diff --git a/server/lib/get-file-data.js b/server/lib/get-file-data.js new file mode 100644 index 00000000..d9460433 --- /dev/null +++ b/server/lib/get-file-data.js @@ -0,0 +1,37 @@ +import { readFile, stat } from 'node:fs/promises' +import { existsSync } from 'node:fs' +import { parse } from 'node:path' + +const IS_PRODUCTION = process.env.NODE_ENV === 'production' +const CACHE = {} + +export default async function getFileData(filePath, shouldBeCached = false) { + shouldBeCached = shouldBeCached && IS_PRODUCTION + + if (shouldBeCached && filePath in CACHE) { + return CACHE[filePath] + } + + if (!existsSync(filePath)) { + let error = new Error('Not Found') + error.httpStatus = 404 + throw error + } + + let { name, ext } = parse(filePath.pathname) + let { size } = await stat(filePath) + let data = await readFile(filePath) + + let fileData = { + name, + ext, + size, + data + } + + if (shouldBeCached) { + CACHE[filePath] = fileData + } + + return fileData +} diff --git a/server/lib/send-response.js b/server/lib/send-response.js new file mode 100644 index 00000000..25d73207 --- /dev/null +++ b/server/lib/send-response.js @@ -0,0 +1,24 @@ +export function sendResponse(res, status, headers, data) { + res.writeHead(status, headers) + res.write(data) + res.end() +} + +export function sendResponseAPI(res, status, data) { + let JSONData = JSON.stringify(data) + + res.writeHead(status, { + 'Access-Control-Allow-Origin': '*', + 'Content-Type': 'text/json', + 'Content-Length': JSONData.length + }) + res.write(JSONData) + res.end() +} + +export function sendResponseError(res, status, message) { + res.writeHead(status, { + 'Content-Type': 'text/plain' + }) + res.end(message) +} diff --git a/server/package.json b/server/package.json new file mode 100644 index 00000000..3e46a7b9 --- /dev/null +++ b/server/package.json @@ -0,0 +1,13 @@ +{ + "name": "browserl.ist-server", + "private": true, + "type": "module", + "scripts": { + "start": "node index.js", + "test": "pnpm -r build && node --test test/*.test.js" + }, + "dependencies": { + "browserslist": "^4.21.3", + "caniuse-lite": "^1.0.30001375" + } +} diff --git a/server/test/browsers.test.js b/server/test/browsers.test.js new file mode 100644 index 00000000..a0525d87 --- /dev/null +++ b/server/test/browsers.test.js @@ -0,0 +1,50 @@ +import test from 'node:test' +import { equal, notEqual, ok, match } from 'node:assert' + +import getBrowsers from '../lib/get-browsers.js' + +test('Throws error for wrong browserslist `query`', async () => { + let error + try { + await getBrowsers('wrong', 'Global') + } catch (e) { + error = e + } + ok(error instanceof Error) + match(error.message, /Unknown browser query/) +}) + +test('Throws error for wrong Can I Use `region`', async () => { + let error + try { + await getBrowsers('>0%', 'XX') + } catch (e) { + error = e + } + ok(error instanceof Error) + match(error.message, /Unknown region name/) +}) + +test('Returns Node.js versions without coverage`', async () => { + let data = await getBrowsers('Node > 0', 'Global') + + equal(data.browsers[0].name, 'Node') + equal(data.browsers[0].coverage, null) +}) + +test('Сoverage of all browsers should differ in different regions', async () => { + let continentData = await getBrowsers('>1%', 'Global') + let countryData = await getBrowsers('>1%', 'IT') + + notEqual(continentData.coverage, countryData.coverage) +}) + +test('Сoverage for browser should differ in different regions', async () => { + let continentData = await getBrowsers('last 2 Chrome versions', 'alt-eu') + let countryData = await getBrowsers('last 2 Chrome versions', 'NP') + + let continentBrowser = continentData.browsers[0] + let countryBrowser = countryData.browsers[0] + + notEqual(continentBrowser.coverage, countryBrowser.coverage) +}) diff --git a/server/test/index.test.js b/server/test/index.test.js new file mode 100644 index 00000000..9c726706 --- /dev/null +++ b/server/test/index.test.js @@ -0,0 +1,83 @@ +import { equal, match } from 'node:assert' +import { URL } from 'node:url' +import test from 'node:test' + +import App from '../index.js' + +const base = `http://localhost:${App.address().port}/` + +test('Integration tests', async t => { + await t.test( + 'responses `defaults` query for `/browsers` route without `q` param', + async () => { + let url = new URL(`api/browsers`, base) + let response = await fetch(url) + let data = await response.json() + equal(data.query, 'defaults') + } + ) + + await t.test( + 'responses `Global` region for `/browsers` route without `region` param', + async () => { + let url = new URL(`api/browsers`, base) + let response = await fetch(url) + let data = await response.json() + equal(data.region, 'Global') + } + ) + + await t.test('responses status 200 for `/browsers` route', async () => { + let url = new URL(`api/browsers`, base) + let response = await fetch(url) + equal(response.status, 200) + }) + + await t.test( + 'responses 400 for `/browsers` route with wrong `q` param', + async () => { + let url = new URL(`api/browsers?q=wrong-query`, base) + let response = await fetch(url) + let error = await response.json() + equal(response.status, 400) + match(error.message, /Unknown/) + } + ) + + await t.test('responses 404 for unknown route', async () => { + let url = new URL(`wrong-route`, base) + let response = await fetch(url) + let text = await response.text() + equal(response.status, 404) + match(text, /Not Found/) + }) + + await t.test('opens the file index.html by the URL `/`', async () => { + let url = new URL('', base) + let response = await fetch(url) + let html = await response.text() + equal(response.status, 200) + match(html, /Browserslist/) + match(html, / { + let url = new URL('/favicon.ico', base) + let response = await fetch(url) + equal(response.status, 200) + equal(response.headers.get('Content-Type'), 'image/x-icon') + } + ) + + await t.test('loads static `/favicon.ico` with 1 hour cache', async () => { + let url = new URL('/favicon.ico', base) + let response = await fetch(url) + equal(response.status, 200) + equal(response.headers.get('Cache-Control'), 'max-age=3600') + }) + + App.closeAllConnections() + App.close() +}) diff --git a/simple-git-hooks.json b/simple-git-hooks.json new file mode 100644 index 00000000..f7b0c2ff --- /dev/null +++ b/simple-git-hooks.json @@ -0,0 +1,3 @@ +{ + "pre-commit": "./node_modules/.bin/nano-staged --config ./nano-staged.json" +} diff --git a/vercel.json b/vercel.json deleted file mode 100644 index 60121507..00000000 --- a/vercel.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "version": 2, - "rewrites": [{ "source": "/(.*)", "destination": "/api/server" }] -} diff --git a/views/error.pug b/views/error.pug deleted file mode 100644 index 51ec12c6..00000000 --- a/views/error.pug +++ /dev/null @@ -1,6 +0,0 @@ -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/views/index.pug b/views/index.pug deleted file mode 100644 index 6ffafa26..00000000 --- a/views/index.pug +++ /dev/null @@ -1,42 +0,0 @@ -extends layout - -block content - div(class="tc bg-neon-carrot plum bb b--black-10 pa4 pa5-ns") - h1(class="f2 f-headline-l f1-ns fw6 mid-gray ma0") - a(href="/") browsersl.ist - p(class="ma0 mt2 mb4 mb5-ns") #{description} - form(method="get" action="/" class="cf dt-ns w-100 my4 f5 f4-l") - div(class="fl dtc-ns w-100 w-80-ns mb2 mb0-ns pr2-ns") - input(class="pa2 ba b--black-30 code br1 border-box w-100 lh-title" name="q" value= query) - div(class="fl dtc-ns w-100 w-20-ns") - button(type=submit class="bg-plum neon-carrot b bg-plum--hover pa2 ba b--black-30 br1 db w-100 lh-title border-box pointer") Show #[span(class="dn-m") Browsers] - div(class="dt-ns w-100 mw8 center") - if compatible - - const columns = Object.keys(compatible).length - each browsers, platform in compatible - div(class=`dtc-l pa2 ${columns === 3 ? 'w-third' : 'w-50-l'} border-box`) - h2(class="f4 f3-ns ma0 mt4 mb4 tc ttc") - if platform === 'server' - | Node.js #{platform}s - else - | #{platform} browsers - ul(class="ma0 list pa3") - each browser in browsers - li(class="ma0 mb3 lh-copy") - img(src=browser.logo class="v-mid mr2" alt="" height="34" width="34") - span(class="mr1 v-mid") #{browser.name} - span(class="mr1 v-mid") #{browser.version} - span(class="v-mid fr") - small - if isFinite(browser.coverage) - | #{Math.round(browser.coverage * 100) / 100}% - else - | Unknown coverage - else if error != null - h2(class="f4 f3-ns ma0 mv5 tc ttc") #{error} - div(class="tc bg-neon-carrot plum bb b--black-10 pa2 pa3-ns mt4") - if compatible - | #{region} coverage: - strong(class="ml1") #{Math.round(coverage * 100) / 100}% - else - | Unknown coverage diff --git a/views/layout.pug b/views/layout.pug deleted file mode 100644 index 8c0b63fc..00000000 --- a/views/layout.pug +++ /dev/null @@ -1,19 +0,0 @@ -doctype html -html(lang='en') - head - meta(charset="utf-8") - title browserl.ist: #{description} - meta(name="description" content=description) - meta(http-equiv="X-UA-Compatible" content="IE=Edge") - meta(name="author" content="@browserslist") - meta(name="viewport" content="width=device-width, initial-scale=1") - link(rel='shortcut icon', href='/images/favicon.png', type='image/png') - link(rel='stylesheet', href='/stylesheets/tachyons.min.css') - link(rel='stylesheet', href='/stylesheets/style.css') - body(class="sans-serif f4") - block content - div(class="pa5 f6 lh-copy") - span(class="mr4 db di-ns mb2 mb0-ns") Made by #[a(href="https://twitter.com/browserslist") browserslist] - span(class="mr4 db di-ns mb2 mb0-ns") Code on #[a(href="https://github.com/browserslist/browserl.ist") GitHub] - span(class="mr4 db di-ns mb2 mb0-ns") Functionality provided by #[a(href="https://github.com/browserslist/browserslist") browserslist] #{bv} - span(class="mr4 db di-ns mb2 mb0-ns") Data provided by #[a(href="https://github.com/Fyrd/caniuse") caniuse-db] #{cv}