From 9050f93074759cd4175a9ccbaae61400ebbc624b Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Thu, 11 Jan 2024 18:37:55 +0200 Subject: [PATCH 01/91] Apply initial setup for updates for distribution builds --- .gitignore | 8 +- LICENSE | 2 +- README.md | 28 +- css/blog.scss | 2 + js/comments.js | 2 +- package-lock.json | 4778 +++++++++++++++++++++++++++++++++++++++++++-- package.json | 25 +- 7 files changed, 4644 insertions(+), 201 deletions(-) diff --git a/.gitignore b/.gitignore index 473ec04..886a7ca 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,13 @@ # node modules /node_modules/ +# distribution bundles directories +/dist/ + # bootstrap source may be required for autocomplite, # but they aren't part of current repository content -/css/bootstrap-*.* -/css/bootstrap.* -/js/bootstrap.* +bootstrap-*.* +bootstrap.* # emacs caches and backup files \#*\# diff --git a/LICENSE b/LICENSE index f4deba5..dea0135 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Python training course authors and contributors +Copyright (c) 2024 Python training course authors and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 30be62d..f1ca477 100644 --- a/README.md +++ b/README.md @@ -4,33 +4,15 @@ DJANGO BLOG - BOOTSTRAP TEMPLATES This repo contains Bootstrap5 templates for the main training project, and itself is a supporting subproject. -[Live preview](https://edu-python-course.github.io/blog-bootstrap/) +Getting started +--------------- + +[//]: # (TODO: GH-30) Contents -------- -- [index.html](./index.html) - This is the main blog page. It contains a list of blog posts. - Each entity is a link to detailed blog post page. -- [detail.html](./detail.html) - This is a detailed blog post page. It contains the full blog post's - content. Comments related to a single blog post are also present here. -- [form.html](./form_article.html) - Blog post form (Creation and update). -- [profile.html](./profile.html) - User's personal page. This page is supposed to be public for all. - In case current user visiting their own profile page, this page will - include forms to change user data or set a new password. All blog posts - authored by a certain user is listed here in the form, similar to main - page view. -- [form_login.html](./form_login.html) - User login form. -- [form_registration.html](./form_registration.html) - New user registration form. -- [profile.html](./profile.html) - User profile page. -- [about.html](./about.html) - About page (static content). +[//]: # (TODO: GH-30) References ---------- diff --git a/css/blog.scss b/css/blog.scss index 24f912f..15c47cd 100644 --- a/css/blog.scss +++ b/css/blog.scss @@ -2,6 +2,8 @@ * Django Blog Main Stylesheet */ +// TODO: split into individual stylesheets to focus on components GH-40 + // external resources @import url("https://fonts.googleapis.com/css?family=Pacifico"); diff --git a/js/comments.js b/js/comments.js index ded68fb..a118fa2 100644 --- a/js/comments.js +++ b/js/comments.js @@ -1,5 +1,5 @@ // article comment creation - +// TODO: Slit into individual packages to handle UI, API etc. GH-41 /** * Create author block for new comment diff --git a/package-lock.json b/package-lock.json index f86a062..6087ab2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,654 @@ { "name": "blog-bootstrap", - "version": "1.0.0", + "version": "2.0-development", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "blog-bootstrap", - "version": "1.0.0", + "version": "2.0-development", "license": "MIT", + "dependencies": { + "@popperjs/core": "^2.11.8", + "bootstrap": "^5.3.2" + }, "devDependencies": { + "autoprefixer": "^10.4.16", + "css-loader": "^6.9.0", "csso-cli": "^4.0.2", - "sass": "^1.63.4", - "uglify-js": "^3.17.4" + "html-webpack-plugin": "^5.6.0", + "mini-css-extract-plugin": "^2.7.7", + "postcss-loader": "^7.3.4", + "sass": "^1.69.7", + "sass-loader": "^13.3.3", + "style-loader": "^3.3.4", + "uglify-js": "^3.17.4", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", + "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" } }, "node_modules/ansi-colors": { @@ -23,285 +660,4086 @@ "node": ">=6" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001576", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", + "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clap": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/clap/-/clap-3.1.1.tgz", + "integrity": "sha512-vp42956Ax06WwaaheYEqEOgXZ3VKJxgccZ0gJL0HpyiupkIS9RVJFo5eDU1BPeQAOqz+cclndZg4DCqG1sJReQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.0.tgz", + "integrity": "sha512-3I5Nu4ytWlHvOP6zItjiHlefBNtrH+oehq8tnQa2kO305qpVyx9XNIT1CXIj5bgCJs7qICBCkgCYxQLKPANoLA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.31", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.1.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso-cli": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/csso-cli/-/csso-cli-4.0.2.tgz", + "integrity": "sha512-p/VipA45w8EmS8Lv6wGtE+UdsbFlqUBGhL9FCTGKxd5dC07mtg3BbZaMzMh0X+oIl2JUGR/mPx5YzuNnTM2a3w==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.3", + "clap": "^3.1.1", + "csso": "^5.0.4", + "source-map-js": "^1.0.2" + }, + "bin": { + "csso": "bin/csso" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.628", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.628.tgz", + "integrity": "sha512-2k7t5PHvLsufpP6Zwk0nof62yLOsCf032wZx7/q0mv8gwlXjhcxI3lz6f0jBr0GrnWKcm3burXzI3t5IrcdUxw==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "dev": true, + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.7", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.7.tgz", + "integrity": "sha512-+0n11YGyRavUR3IlaOzJ0/4Il1avMvJ1VJfhWfCn24ITQXhRr1gghbhhrda6tgtNcpZaWKdSuwKq20Jb7fnlyw==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.33", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", + "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "dev": true, + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.0.tgz", + "integrity": "sha512-SaIbK8XW+MZbd0xHPf7kdfA/3eOt7vxJ72IRecn3EzuZVLr1r0orzf0MX/pN8m+NMDoo6X/SQd8oeKqGZd8PXg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.69.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz", + "integrity": "sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-loader": { + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", + "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/style-loader": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, "engines": { - "node": ">= 8" + "node": ">= 0.6" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, "engines": { - "node": ">=8" + "node": ">=0.8.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" }, - "engines": { - "node": ">= 8.10.0" + "bin": { + "update-browserslist-db": "cli.js" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/clap": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/clap/-/clap-3.1.1.tgz", - "integrity": "sha512-vp42956Ax06WwaaheYEqEOgXZ3VKJxgccZ0gJL0HpyiupkIS9RVJFo5eDU1BPeQAOqz+cclndZg4DCqG1sJReQ==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" - }, + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, "engines": { - "node": "^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">= 0.4.0" } }, - "node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=10.13.0" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "dependencies": { - "css-tree": "~2.2.0" + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/csso-cli": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/csso-cli/-/csso-cli-4.0.2.tgz", - "integrity": "sha512-p/VipA45w8EmS8Lv6wGtE+UdsbFlqUBGhL9FCTGKxd5dC07mtg3BbZaMzMh0X+oIl2JUGR/mPx5YzuNnTM2a3w==", + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "dependencies": { - "chokidar": "^3.5.3", - "clap": "^3.1.1", - "csso": "^5.0.4", - "source-map-js": "^1.0.2" + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" }, "bin": { - "csso": "bin/csso" + "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=12.20.0" + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">= 6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, - "engines": { - "node": ">=0.12.0" + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, "engines": { - "node": ">=8.6" + "node": ">= 12.13.0" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dev": true, "dependencies": { - "picomatch": "^2.2.1" + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=10.0.0" } }, - "node_modules/sass": { - "version": "1.63.4", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.4.tgz", - "integrity": "sha512-Sx/+weUmK+oiIlI+9sdD0wZHsqpbgQg8wSwSnGBjwb5GwqFhYNwwnI+UWZtLjKvKyFlKkatRK235qQ3mokyPoQ==", + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=0.8.0" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "is-number": "^7.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=8.0" + "node": ">= 8" } }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, "engines": { - "node": ">=0.8.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } } diff --git a/package.json b/package.json index 526b42a..3caa129 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,30 @@ { "name": "blog-bootstrap", - "version": "1.0.2", + "description": "Blog site bootstrap5 templates bundle", + "author": { + "name": "Serhii Horodilov", + "email": "sgorodil@gmail.com" + }, + "version": "2.0-development", "private": true, "license": "MIT", "devDependencies": { + "autoprefixer": "^10.4.16", + "css-loader": "^6.9.0", "csso-cli": "^4.0.2", - "sass": "^1.63.4", - "uglify-js": "^3.17.4" + "html-webpack-plugin": "^5.6.0", + "mini-css-extract-plugin": "^2.7.7", + "postcss-loader": "^7.3.4", + "sass": "^1.69.7", + "sass-loader": "^13.3.3", + "style-loader": "^3.3.4", + "uglify-js": "^3.17.4", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1" + }, + "dependencies": { + "@popperjs/core": "^2.11.8", + "bootstrap": "^5.3.2" } } From 7e7e7a777044632a1ebf5fc59333cc7536996e60 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Thu, 11 Jan 2024 19:30:50 +0200 Subject: [PATCH 02/91] Apply webpack development configuration - fixes GH-35 - fixes GH-39 - GH-38 --- package.json | 5 ++++ src/index.js | 8 +++++++ src/scss/bs-styles.scss | 2 ++ webpack.config.js | 52 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 src/index.js create mode 100644 src/scss/bs-styles.scss create mode 100644 webpack.config.js diff --git a/package.json b/package.json index 3caa129..747e7fa 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,11 @@ "version": "2.0-development", "private": true, "license": "MIT", + "scripts": { + "start": "webpack serve", + "build": "webpack build --mode production", + "build:dev": "webpack build --mode development" + }, "devDependencies": { "autoprefixer": "^10.4.16", "css-loader": "^6.9.0", diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..50142a0 --- /dev/null +++ b/src/index.js @@ -0,0 +1,8 @@ +// IDE: do not report unused imports +// noinspection ES6UnusedImports + +// Bind sources +import "./scss/bs-styles.scss" + +// Import all of Bootstrap's JS +import * as bootstrap from "bootstrap" diff --git a/src/scss/bs-styles.scss b/src/scss/bs-styles.scss new file mode 100644 index 0000000..8f11562 --- /dev/null +++ b/src/scss/bs-styles.scss @@ -0,0 +1,2 @@ +// Import all of Bootstrap's CSS +@import "bootstrap/scss/bootstrap"; diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..70d772f --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,52 @@ +/** + * Webpack configuration + * + * This configuration uses the default entry point for webpack v5 at + * "src/index.js" (omitted inside the config object + * + */ + +"use strict" + +const path = require("path") +const autoprefixer = require("autoprefixer") +const HTMLWebpackPlugin = require("html-webpack-plugin") +const miniCssExportPlugin = require("mini-css-extract-plugin") + +// webpack config object +module.exports = { + mode: "development", + output: { + filename: "main.bundle.js", + path: path.resolve(__dirname, "dist"), + clean: true + }, + devServer: { + static: path.resolve(__dirname, "dist"), + port: 8000, + hot: true + }, + plugins: [ + new miniCssExportPlugin({"filename": "main.min.css"}), + ], + module: { + rules: [ + { + test: /\.scss$/, + use: [ + {loader: miniCssExportPlugin.loader}, + {loader: "css-loader"}, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: [autoprefixer] + } + } + }, + {loader: "sass-loader"} + ] + }, + ] + } +} From 28e2e0b3f2380730b34b60ec9dedab3b14e1de11 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Thu, 11 Jan 2024 20:46:30 +0200 Subject: [PATCH 03/91] Configure webpack to serve images --- about.html | 8 ++++---- detail.html | 8 ++++---- form_article.html | 8 ++++---- form_login.html | 8 ++++---- form_registration.html | 8 ++++---- index.html | 10 +++++----- profile.html | 8 ++++---- {img => src/img}/anonymous.svg | 0 {img => src/img}/favicon.png | Bin {img => src/img}/favicon.svg | 0 {img => src/img}/logo.svg | 0 src/index.js | 5 +++++ webpack.config.js | 7 +++++++ 13 files changed, 41 insertions(+), 29 deletions(-) rename {img => src/img}/anonymous.svg (100%) rename {img => src/img}/favicon.png (100%) rename {img => src/img}/favicon.svg (100%) rename {img => src/img}/logo.svg (100%) diff --git a/about.html b/about.html index d068fd1..38e4cbd 100644 --- a/about.html +++ b/about.html @@ -8,8 +8,8 @@ About | Django Blog - - + + @@ -23,13 +23,13 @@
- +
- +
diff --git a/detail.html b/detail.html index 508cc3f..5fa6f63 100644 --- a/detail.html +++ b/detail.html @@ -8,8 +8,8 @@ Exploring the Evolving Landscape of Web Development in the Age of Technology Trends | Django Blog - - + + @@ -44,13 +44,13 @@
- +
- +
diff --git a/form_article.html b/form_article.html index 049ed8a..5b2920c 100644 --- a/form_article.html +++ b/form_article.html @@ -8,8 +8,8 @@ Articles | Django Blog - - + + @@ -23,13 +23,13 @@
- +
- +
diff --git a/form_login.html b/form_login.html index 3ed549f..225802b 100644 --- a/form_login.html +++ b/form_login.html @@ -7,8 +7,8 @@ Log In | Django Blog - - + + @@ -22,13 +22,13 @@
- +
- +
diff --git a/form_registration.html b/form_registration.html index 5372a4e..3d5f9d1 100644 --- a/form_registration.html +++ b/form_registration.html @@ -7,8 +7,8 @@ Registration | Django Blog - - + + @@ -22,13 +22,13 @@
- +
- +
diff --git a/index.html b/index.html index 1834431..0d6f9f9 100644 --- a/index.html +++ b/index.html @@ -8,8 +8,8 @@ Articles | Django Blog - - + + @@ -23,13 +23,13 @@
- +
- +
@@ -237,7 +237,7 @@

Account

- avatar + avatar
register diff --git a/profile.html b/profile.html index 7d6e1e1..cb9efab 100644 --- a/profile.html +++ b/profile.html @@ -7,8 +7,8 @@ Profile | Django Blog - - + + @@ -108,13 +108,13 @@
- +
- +
diff --git a/img/anonymous.svg b/src/img/anonymous.svg similarity index 100% rename from img/anonymous.svg rename to src/img/anonymous.svg diff --git a/img/favicon.png b/src/img/favicon.png similarity index 100% rename from img/favicon.png rename to src/img/favicon.png diff --git a/img/favicon.svg b/src/img/favicon.svg similarity index 100% rename from img/favicon.svg rename to src/img/favicon.svg diff --git a/img/logo.svg b/src/img/logo.svg similarity index 100% rename from img/logo.svg rename to src/img/logo.svg diff --git a/src/index.js b/src/index.js index 50142a0..067ae99 100644 --- a/src/index.js +++ b/src/index.js @@ -4,5 +4,10 @@ // Bind sources import "./scss/bs-styles.scss" +import "./img/anonymous.svg" +import "./img/favicon.png" +import "./img/favicon.svg" +import "./img/logo.svg" + // Import all of Bootstrap's JS import * as bootstrap from "bootstrap" diff --git a/webpack.config.js b/webpack.config.js index 70d772f..3f0438d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -47,6 +47,13 @@ module.exports = { {loader: "sass-loader"} ] }, + { + test: /\.(png|svg|jpg|jpeg|gif)$/i, + type: "asset/resource", + generator: { + filename: "img/[name][ext]" + } + } ] } } From ae52fda3b6ac16bf1ad59d7c78f05e6ea260a113 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Thu, 11 Jan 2024 20:57:44 +0200 Subject: [PATCH 04/91] Extract SVG files while building via Webpack --- webpack.config.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 3f0438d..da153bc 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -14,6 +14,7 @@ const HTMLWebpackPlugin = require("html-webpack-plugin") const miniCssExportPlugin = require("mini-css-extract-plugin") // webpack config object +// noinspection WebpackConfigHighlighting module.exports = { mode: "development", output: { @@ -22,9 +23,9 @@ module.exports = { clean: true }, devServer: { - static: path.resolve(__dirname, "dist"), - port: 8000, - hot: true + static: path.resolve(__dirname, "dist"), + port: 8000, + hot: true }, plugins: [ new miniCssExportPlugin({"filename": "main.min.css"}), @@ -53,7 +54,15 @@ module.exports = { generator: { filename: "img/[name][ext]" } - } + }, + { + mimetype: "image/svg+xml", + scheme: "data", + type: "asset/resource", + generator: { + filename: "icons/[hash].svg" + } + }, ] } } From 698bed8237c3d0be61a2b1a63198ed5050dc5262 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Thu, 11 Jan 2024 21:06:02 +0200 Subject: [PATCH 05/91] [2.0-development] Set up development environment --- blog/conf.js | 14 +++++ package-lock.json | 119 +++++++++++++++++++++++++++++++++++++ package.json | 1 + src/js/masonry.pkgd.min.js | 9 +++ src/views/index.hbs | 23 +++++++ webpack.config.js | 17 +++++- 6 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 blog/conf.js create mode 100644 src/js/masonry.pkgd.min.js create mode 100644 src/views/index.hbs diff --git a/blog/conf.js b/blog/conf.js new file mode 100644 index 0000000..f05d5c9 --- /dev/null +++ b/blog/conf.js @@ -0,0 +1,14 @@ +/** + * Global source configurations + */ + +const templateParameters = { + favicon_svg: "./img/favicon.svg", + favicon_png: "./img/favicon.png", + anonymous_img: "./img/anonymous.svg", + logo: "./img/logo.svg", +} + +module.exports = { + templateParameters +} diff --git a/package-lock.json b/package-lock.json index 6087ab2..2cc4020 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "autoprefixer": "^10.4.16", "css-loader": "^6.9.0", "csso-cli": "^4.0.2", + "handlebars-loader": "^1.7.3", "html-webpack-plugin": "^5.6.0", "mini-css-extract-plugin": "^2.7.7", "postcss-loader": "^7.3.4", @@ -718,6 +719,12 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, "node_modules/autoprefixer": { "version": "10.4.16", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", @@ -767,6 +774,15 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1516,6 +1532,15 @@ "integrity": "sha512-2k7t5PHvLsufpP6Zwk0nof62yLOsCf032wZx7/q0mv8gwlXjhcxI3lz6f0jBr0GrnWKcm3burXzI3t5IrcdUxw==", "dev": true }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1751,6 +1776,12 @@ "node": ">= 4.9.1" } }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -1990,6 +2021,43 @@ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars-loader": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/handlebars-loader/-/handlebars-loader-1.7.3.tgz", + "integrity": "sha512-dDb+8D51vE3OTSE2wuGPWRAegtsEuw8Mk8hCjtRu/pNcBfN5q+M8ZG3kVJxBuOeBrVElpFStipGmaxSBTRR1mQ==", + "dev": true, + "dependencies": { + "async": "^3.2.2", + "fastparse": "^1.0.0", + "loader-utils": "1.4.x", + "object-assign": "^4.1.0" + }, + "peerDependencies": { + "handlebars": ">= 1.3.0 < 5" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2566,6 +2634,18 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2600,6 +2680,20 @@ "node": ">=6.11.5" } }, + "node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2832,6 +2926,15 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2951,6 +3054,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -4708,6 +4820,13 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "peer": true + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 747e7fa..17decaa 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "autoprefixer": "^10.4.16", "css-loader": "^6.9.0", "csso-cli": "^4.0.2", + "handlebars-loader": "^1.7.3", "html-webpack-plugin": "^5.6.0", "mini-css-extract-plugin": "^2.7.7", "postcss-loader": "^7.3.4", diff --git a/src/js/masonry.pkgd.min.js b/src/js/masonry.pkgd.min.js new file mode 100644 index 0000000..53386ae --- /dev/null +++ b/src/js/masonry.pkgd.min.js @@ -0,0 +1,9 @@ +/*! + * Masonry PACKAGED v4.2.2 + * Cascading grid layout library + * https://masonry.desandro.com + * MIT License + * by David DeSandro + */ + +!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;oe;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;is?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}); \ No newline at end of file diff --git a/src/views/index.hbs b/src/views/index.hbs new file mode 100644 index 0000000..f811077 --- /dev/null +++ b/src/views/index.hbs @@ -0,0 +1,23 @@ + + + + + + + + + + {{title}} | Blog Site + + +
+

Test Webpack builds

+
+ + + diff --git a/webpack.config.js b/webpack.config.js index da153bc..2967f2d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,13 +12,14 @@ const path = require("path") const autoprefixer = require("autoprefixer") const HTMLWebpackPlugin = require("html-webpack-plugin") const miniCssExportPlugin = require("mini-css-extract-plugin") +const conf = require("./blog/conf") // webpack config object // noinspection WebpackConfigHighlighting module.exports = { mode: "development", output: { - filename: "main.bundle.js", + filename: "js/main.bundle.js", path: path.resolve(__dirname, "dist"), clean: true }, @@ -28,7 +29,15 @@ module.exports = { hot: true }, plugins: [ - new miniCssExportPlugin({"filename": "main.min.css"}), + new miniCssExportPlugin({"filename": "css/main.min.css"}), + new HTMLWebpackPlugin({ + template: "./src/views/index.hbs", + filename: "index.html", + templateParameters: { + title: "Test Webpack", + ...conf.templateParameters + } + }) ], module: { rules: [ @@ -63,6 +72,10 @@ module.exports = { filename: "icons/[hash].svg" } }, + { + test: /\.hbs$/, + loader: "handlebars-loader" + } ] } } From d76a7f621d955851cceddff1be923088996f6e56 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Fri, 12 Jan 2024 01:32:21 +0200 Subject: [PATCH 06/91] Remove outdated files --- about.html | 191 ------------------------ css/blog.css | 140 ------------------ css/blog.css.map | 1 - css/blog.min.css | 1 - css/blog.scss | 180 ----------------------- detail.html | 325 ----------------------------------------- form_article.html | 151 ------------------- form_login.html | 93 ------------ form_registration.html | 103 ------------- index.html | 300 ------------------------------------- js/articles.js | 6 - js/articles.min.js | 1 - js/articles.min.js.map | 1 - js/comments.js | 114 --------------- js/comments.min.js | 1 - js/comments.min.js.map | 1 - profile.html | 292 ------------------------------------ 17 files changed, 1901 deletions(-) delete mode 100644 about.html delete mode 100644 css/blog.css delete mode 100644 css/blog.css.map delete mode 100644 css/blog.min.css delete mode 100644 css/blog.scss delete mode 100644 detail.html delete mode 100644 form_article.html delete mode 100644 form_login.html delete mode 100644 form_registration.html delete mode 100644 index.html delete mode 100644 js/articles.js delete mode 100644 js/articles.min.js delete mode 100644 js/articles.min.js.map delete mode 100644 js/comments.js delete mode 100644 js/comments.min.js delete mode 100644 js/comments.min.js.map delete mode 100644 profile.html diff --git a/about.html b/about.html deleted file mode 100644 index 38e4cbd..0000000 --- a/about.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - About | Django Blog - - - - - - - - - - - - -
-
-
-
-
-

About Our Website

-

- Welcome to our website! We are a passionate team of web developers, data scientists, and cybersecurity - experts dedicated to creating exceptional digital experiences. Our goal is to provide you with valuable - insights, secure web solutions, and a seamless user experience. -

-
-
-
-
-

Who We Are:

-

- We are a dynamic team of professionals with expertise in web development, data science, and cybersecurity. - Our diverse backgrounds and skill sets enable us to tackle complex challenges and deliver innovative - solutions tailored to your specific needs. We are committed to staying up-to-date with the latest industry - trends and technologies to ensure that we provide you with cutting-edge solutions. -

-

Our Commitment:

-

- We are committed to providing you with exceptional service and solutions that exceed your expectations. We - believe in building long-term partnerships with our clients, collaborating closely to understand your unique - requirements and deliver customized solutions that address your specific challenges. -

-

- Our team is dedicated to delivering projects on time and within budget, without compromising on quality. We - strive for excellence in every aspect of our work, ensuring that our web solutions are visually appealing, - user-friendly, and aligned with your business objectives. -

-
-
-

What We Do:

-

- At our core, we specialize in web development, creating dynamic and user-friendly websites that captivate - audiences and drive results. Whether you need a simple informative website or a complex web application, we - have the skills and expertise to bring your vision to life. Our focus is on delivering websites that not - only look visually stunning but also provide a seamless and intuitive user experience. -

-

- In addition to web development, we are passionate about data science. We leverage advanced analytics - techniques to extract insights from data, empowering you to make informed decisions and unlock the hidden - potential in your data. From predictive analytics to personalized recommendations, we help you harness the - power of data to drive growth and optimize your business strategies. -

-

- As cybersecurity is a top priority in today's digital landscape, we also prioritize the security of our web - solutions. We implement robust security measures to protect your data and ensure the integrity of your web - applications. From secure authentication to encrypted communication, we employ industry best practices to - safeguard your information and provide a secure browsing experience. -

-
-
-
-
-

Get in Touch:

-

- We would love to hear from you and discuss how we can help you achieve your web development, data science, - or cybersecurity goals. Feel free to reach out to us through the contact information provided on our - website. Our friendly team is here to answer your questions and guide you through the process of creating an - exceptional web presence. -

-

- Thank you for visiting our website. We look forward to partnering with you and helping you - succeed in the digital world. -

-
-
-
-
-
-
-

Account

-
-
- avatar -
- - -
-
- -
-

About

-

- Our goal is to provide you with valuable insights, secure web solutions, and a seamless - user experience. See more... -

-
-
-
-
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - - diff --git a/css/blog.css b/css/blog.css deleted file mode 100644 index c86bef9..0000000 --- a/css/blog.css +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Django Blog Main Stylesheet - */ -@import url("https://fonts.googleapis.com/css?family=Pacifico"); -.disclaimer { - color: var(--bs-danger); -} -.disclaimer:before { - content: "DISCLAIMER: "; -} - -.avatar { - max-height: 15rem; - max-width: 15rem; - width: auto; - margin: 0.25rem 0; -} - -.btn-group { - margin: 1.5rem auto; -} - -.btn { - text-transform: capitalize !important; -} - -header { - border-bottom-color: #e5e5e5 !important; -} -header .logo { - max-height: 2.75rem; - width: auto; -} -header #headerLogoRight { - transform: scaleX(-1); -} -header .site-title { - font-family: "Pacifico", "Times New Roman", serif; - font-size: 3rem; -} -header .site-title:hover { - text-decoration: none; -} - -.pagination { - margin: 1.5rem auto; -} - -.nav-scroller { - position: relative; - z-index: 2; - height: 2.75rem; - overflow-y: hidden; -} -.nav-scroller .nav { - display: flex; - flex-wrap: nowrap; - padding-bottom: 1rem; - margin-top: -1px; - overflow-x: auto; - text-align: center; - white-space: nowrap; - -webkit-overflow-scrolling: touch; -} - -section[aria-label=Sidebar] .position-sticky { - top: 1rem; -} -section[aria-label=Sidebar] h4 { - margin-top: 0.5rem; -} -section[aria-label=Sidebar] .avatar { - max-height: 7.5rem; - max-width: 7.5rem; -} -section[aria-label=Sidebar] .btn-group-vertical { - margin: 0.5rem; - max-width: 10rem; -} - -article h1, article h2, article h3 { - font-size: 1.25rem; -} - -#articleCommentsContainer .avatar { - height: 5rem; - width: 5rem; -} -#articleCommentsContainer .flex-row div:first-child { - width: 7.5rem; -} - -#articleCommentForm { - margin-top: 2.5rem; -} - -.form-auth { - height: 100%; - display: block; - align-items: center; - text-align: center; - max-width: 300px; - padding: 15px; -} -.form-auth input { - border-radius: 0; -} -.form-auth input#title { - border-top-left-radius: 1rem; - border-top-right-radius: 1rem; -} -.form-auth .form-floating:focus-within { - z-index: 2; -} - -.form-auth.form-signin #password { - border-bottom-left-radius: 1rem; - border-bottom-right-radius: 1rem; -} - -.form-auth.form-signup #confirmPassword { - border-bottom-left-radius: 1rem; - border-bottom-right-radius: 1rem; -} - -#articleForm #content { - min-height: 20rem; -} - -footer { - margin-top: 1.5rem; - padding: 2rem; -} -footer .social { - font-size: 2.75rem; - color: var(--bs-body-color); - margin: 0 1rem; -} - -/*# sourceMappingURL=blog.css.map */ diff --git a/css/blog.css.map b/css/blog.css.map deleted file mode 100644 index d04bd5f..0000000 --- a/css/blog.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["blog.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAKQ;AAGR;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIF;EACE;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAEA;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAMF;EACE;;;AAMF;EACE;EACA;;AAIA;EACE;;;AAKN;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AAKF;EACE;EACA;;;AAKF;EACE;EACA;;;AAKF;EACE;;;AAKJ;EACE;EACA;;AAEA;EACE;EACA;EACA","file":"blog.css"} \ No newline at end of file diff --git a/css/blog.min.css b/css/blog.min.css deleted file mode 100644 index fa043b6..0000000 --- a/css/blog.min.css +++ /dev/null @@ -1 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Pacifico);.disclaimer{color:var(--bs-danger)}.disclaimer:before{content:"DISCLAIMER: "}.avatar{max-height:15rem;max-width:15rem;width:auto;margin:.25rem 0}.btn-group{margin:1.5rem auto}.btn{text-transform:capitalize!important}header{border-bottom-color:#e5e5e5!important}header .logo{max-height:2.75rem;width:auto}header #headerLogoRight{transform:scaleX(-1)}header .site-title{font-family:"Pacifico","Times New Roman",serif;font-size:3rem}header .site-title:hover{text-decoration:none}.pagination{margin:1.5rem auto}.nav-scroller{position:relative;z-index:2;height:2.75rem;overflow-y:hidden}.nav-scroller .nav{display:flex;flex-wrap:nowrap;padding-bottom:1rem;margin-top:-1px;overflow-x:auto;text-align:center;white-space:nowrap;-webkit-overflow-scrolling:touch}section[aria-label=Sidebar] .position-sticky{top:1rem}section[aria-label=Sidebar] h4{margin-top:.5rem}section[aria-label=Sidebar] .avatar{max-height:7.5rem;max-width:7.5rem}section[aria-label=Sidebar] .btn-group-vertical{margin:.5rem;max-width:10rem}article h1,article h2,article h3{font-size:1.25rem}#articleCommentsContainer .avatar{height:5rem;width:5rem}#articleCommentsContainer .flex-row div:first-child{width:7.5rem}#articleCommentForm{margin-top:2.5rem}.form-auth{height:100%;display:block;align-items:center;text-align:center;max-width:300px;padding:15px}.form-auth input{border-radius:0}.form-auth input#title{border-top-left-radius:1rem;border-top-right-radius:1rem}.form-auth .form-floating:focus-within{z-index:2}.form-auth.form-signin #password,.form-auth.form-signup #confirmPassword{border-bottom-left-radius:1rem;border-bottom-right-radius:1rem}#articleForm #content{min-height:20rem}footer{margin-top:1.5rem;padding:2rem}footer .social{font-size:2.75rem;color:var(--bs-body-color);margin:0 1rem} \ No newline at end of file diff --git a/css/blog.scss b/css/blog.scss deleted file mode 100644 index 15c47cd..0000000 --- a/css/blog.scss +++ /dev/null @@ -1,180 +0,0 @@ -/** - * Django Blog Main Stylesheet - */ - -// TODO: split into individual stylesheets to focus on components GH-40 - -// external resources -@import url("https://fonts.googleapis.com/css?family=Pacifico"); - -// general styles -.disclaimer { - color: var(--bs-danger); - - &:before { - content: "DISCLAIMER: "; - } -} - -.avatar { - max-height: 15rem; - max-width: 15rem; - width: auto; - margin: 0.25rem 0; -} - -.btn-group { - margin: 1.5rem auto; -} - -.btn { - text-transform: capitalize !important; -} - -// site header -header { - border-bottom-color: #e5e5e5 !important; - - .logo { - max-height: 2.75rem; - width: auto; - } - - #headerLogoRight { - transform: scaleX(-1); // flip the right one logo horizontally - } - - .site-title { - font-family: "Pacifico", "Times New Roman", serif; - font-size: 3rem; - - &:hover { - text-decoration: none; - } - } -} - -// pagination -.pagination { - margin: 1.5rem auto; -} - -// topics navigation -.nav-scroller { - position: relative; - z-index: 2; - height: 2.75rem; - overflow-y: hidden; - - .nav { - display: flex; - flex-wrap: nowrap; - padding-bottom: 1rem; - margin-top: -1px; - overflow-x: auto; - text-align: center; - white-space: nowrap; - -webkit-overflow-scrolling: touch; - } -} - -// blog sidebar -section[aria-label=Sidebar] { - .position-sticky { - top: 1rem; - } - - h4 { - margin-top: 0.5rem; - } - - .avatar { - max-height: 7.5rem; - max-width: 7.5rem; - } - - .btn-group-vertical { - margin: 0.5rem; - max-width: 10rem; - } -} - -// articles -article { - h1, h2, h3 { - font-size: 1.25rem; - } -} - -// comments -#articleCommentsContainer { - .avatar { - height: 5rem; - width: 5rem; - } - - .flex-row { - div:first-child { - width: 7.5rem; - } - } -} - -#articleCommentForm { - margin-top: 2.5rem; -} - -// forms -.form-auth { - height: 100%; - display: block; - align-items: center; - text-align: center; - max-width: 300px; - padding: 15px; - - input { - border-radius: 0; - } - - input#title { - border-top-left-radius: 1rem; - border-top-right-radius: 1rem; - } - - .form-floating:focus-within { - z-index: 2; - } -} - -.form-auth.form-signin { - #password { - border-bottom-left-radius: 1rem; - border-bottom-right-radius: 1rem; - } -} - -.form-auth.form-signup { - #confirmPassword { - border-bottom-left-radius: 1rem; - border-bottom-right-radius: 1rem; - } -} - -#articleForm { - #content { - min-height: 20rem; - } -} - -// site footer -footer { - margin-top: 1.5rem; - padding: 2rem; - - .social { - font-size: 2.75rem; - color: var(--bs-body-color); - margin: 0 1rem; - } -} diff --git a/detail.html b/detail.html deleted file mode 100644 index 5fa6f63..0000000 --- a/detail.html +++ /dev/null @@ -1,325 +0,0 @@ - - - - - - - - Exploring the Evolving Landscape of Web Development in the Age of Technology Trends | Django Blog - - - - - - - - - - - - - -
-
-
-
-
    -
  • Technology Trends
  • -
  • Web Development
  • -
-

- Exploring the Evolving Landscape of Web Development in the Age of Technology Trends -

-
- Published on March 22, 2023 by Amaranth Burrowes -
-
-

Introduction:

-

- In today's rapidly advancing technological landscape, web development has become an indispensable part of - our lives. As the world becomes increasingly interconnected, it is vital for businesses and individuals - alike to stay up-to-date with the latest technology trends in order to thrive in the digital realm. In this - article, we will delve into some of the key technology trends shaping the field of web development, offering - insights into how these advancements are revolutionizing the way websites and applications are built, and - how they are transforming the user experience. -

-

- Progressive Web Apps (PWAs): -

-

- One of the most significant technology trends in web development is the rise of Progressive Web Apps (PWAs). - PWAs combine the best of both worlds, bringing together the responsiveness and versatility of web - applications with the user experience of native mobile apps. With features like offline access, push - notifications, and seamless responsiveness across devices, PWAs offer an immersive and engaging user - experience. As web developers continue to embrace this trend, we can expect to see a surge in the - development of PWAs that provide a more app-like experience to users. -

-

- Artificial Intelligence (AI) and Machine Learning (ML): -

-

- The integration of Artificial Intelligence and Machine Learning into web development has opened up new - possibilities for creating intelligent and personalized user experiences. AI-powered chatbots, - recommendation systems, and content personalization are just a few examples of how AI and ML are - transforming web development. These technologies enable websites and applications to analyze user behavior, - provide relevant recommendations, and adapt their content dynamically, thereby enhancing user engagement and - satisfaction. -

-

- Voice User Interface (VUI): -

-

- The rise of voice assistants and smart speakers has brought about a new paradigm in user interface design. - Voice User Interfaces (VUIs) are gaining traction as an alternative means of interacting with websites and - applications. Web developers are now incorporating voice commands and natural language processing - capabilities to enable users to perform tasks and access information hands-free. VUIs offer a more - convenient and accessible way of interacting with digital systems, leading to improved user experiences and - increased user engagement. -

-

- Single-Page Applications (SPAs): -

-

- Single-Page Applications have gained popularity due to their ability to deliver fast and seamless user - experiences. SPAs load the entire website or application upfront, allowing for quick navigation and - minimizing page reloads. By leveraging JavaScript frameworks like React, Angular, or Vue.js, web developers - can create dynamic and interactive SPAs that provide a fluid browsing experience. As internet speeds - continue to improve, SPAs are expected to become even more prevalent, offering users a smooth and responsive - browsing experience. -

-

- Cybersecurity and Data Privacy: -

-

- As technology advances, ensuring the security and privacy of user data has become a top priority for web - developers. With the increasing frequency and sophistication of cyberattacks, implementing robust security - measures and adhering to data privacy regulations is crucial. Web developers are now adopting secure coding - practices, implementing encryption protocols, and regularly updating software to safeguard user data. - Additionally, advancements in technologies like blockchain are being explored to enhance data security and - transparency in web applications. -

-

- Conclusion: -

-

- In this era of rapid technological evolution, web development is at the forefront of innovation. As we have - explored some of the prominent technology trends shaping the field, it is clear that web developers must - stay updated and adapt to these changes to deliver exceptional user experiences. From Progressive Web Apps - to AI integration, Voice User Interfaces to Single-Page Applications, and cybersecurity to data privacy, the - landscape of web development continues to evolve. By embracing these trends, web developers can unlock new - possibilities and create websites and applications that are not only functional but also captivating and - user-centric. -

-
-
-
-

Comments

-
-
-
-
- avatar -
Wilcome Brownlock
-
-
- January 31, 2023 -

- Great article! I found the insights on Progressive Web Apps and their app-like experience quite - intriguing. It's amazing how web development is evolving to provide more seamless and immersive user - experiences. -

-
-
-
-
- avatar -
Pippin Sackville-Baggins
-
-
- February 12, 2023 -

- The integration of Artificial Intelligence and Machine Learning in web development is truly fascinating. - The ability to analyze user behavior and provide personalized recommendations will definitely enhance - user engagement and satisfaction. Exciting times ahead for web developers! -

-
-
-
-
- avatar -
Bildad Burrows
-
-
- February 13, 2023 -

- Voice User Interfaces are becoming increasingly popular, and it's easy to see why. The convenience of - interacting with websites and applications through voice commands is a game-changer. It will be - interesting to see how web developers leverage this technology to create even more intuitive and - accessible user experiences. -

-
-
-
-
- avatar -
Pippin Sackville-Baggins
-
-
- March 5, 2023 -

- I appreciate the emphasis on cybersecurity and data privacy in web development. With the rising number - of cyber threats, it's crucial for developers to prioritize the security of user data. The mention of - blockchain as a potential solution shows promising advancements in protecting user information. -

-
-
-
-
- avatar -
Wilcome Brownlock
-
-
- March 31, 2023 -

- The article provides a comprehensive overview of the current technology trends in web development. - Single-Page Applications caught my attention as they offer a fast and seamless browsing experience. It's - great to see how web developers are constantly pushing the boundaries to create more dynamic and - interactive websites. -

-
-
-
-
-
- - -
-
- -
-
-
-
-
-
-

Account

- -
- -
-

About

-

- Our goal is to provide you with valuable insights, secure web solutions, and a seamless - user experience. See more... -

-
-
-
-
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - - - diff --git a/form_article.html b/form_article.html deleted file mode 100644 index 5b2920c..0000000 --- a/form_article.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - Articles | Django Blog - - - - - - - - - - - - -
-
-
-
Article Form
-
-
- - -
-
- - -
-
- - -
-
-
-
-
-
-

Account

-
-
- avatar -
- -
- cancel - -
-
-
- -
-

About

-

- Our goal is to provide you with valuable insights, secure web solutions, and a seamless - user experience. See more... -

-
-
-
-
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - - - diff --git a/form_login.html b/form_login.html deleted file mode 100644 index 225802b..0000000 --- a/form_login.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - Log In | Django Blog - - - - - - - - - - - -
-
-
Please sign in
- -
- - -
- -
- - -
- -
-

Have no account?

- Join us now -
- - -
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - diff --git a/form_registration.html b/form_registration.html deleted file mode 100644 index 3d5f9d1..0000000 --- a/form_registration.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - Registration | Django Blog - - - - - - - - - - - -
-
-
Register new account
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
-

Have already an account?

- Sing in here -
- - -
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - diff --git a/index.html b/index.html deleted file mode 100644 index 0d6f9f9..0000000 --- a/index.html +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - - - Articles | Django Blog - - - - - - - - - - - - -
-
-
-
Blog posts
-
-
-
-
-
March 22, 2023
-

- Exploring the Evolving Landscape of Web Development in the Age of Technology Trends -

- -
    -
  • Technology Trends
  • -
  • Web Development
  • -
-

- Introduction: - - In today's rapidly advancing technological landscape, web development has become an indispensable part - of our lives. As the world becomes increasingly interconnected, it is vital for businesses and - individuals alike to stay up-to-date with the latest technology trends in order to thrive in the digital - realm. -

- Continue reading... -
-
-
-
-
-
-
August 14, 2022
-

- The Convergence of Cybersecurity, Cloud Computing, and DevOps: Building Secure and Agile Systems -

- -
    -
  • DevOps
  • -
  • Cloud Computing
  • -
  • Cybersecurity
  • -
-

- Introduction: - - In today's digital landscape, where data breaches and cyber threats are rampant, ensuring the security - of systems and applications is of paramount importance. -

- Continue reading... -
-
-
-
-
-
-
May 1, 2023
-

- Driving Innovation and Efficiency: The Synergy of Agile Methodology and the Internet of Things (IoT) -

- -
    -
  • Agile Methodology
  • -
  • Internet of Things (IoT)
  • -
-

- Introduction: - - In an era of rapid technological advancements, organizations are seeking ways to innovate and stay ahead - of the curve. The combination of Agile methodology and the Internet of Things (IoT) has emerged as a - powerful duo, enabling businesses to drive efficiency, enhance collaboration, and deliver innovative IoT - solutions. In this article, we will explore the convergence of Agile and IoT, highlighting how this - synergy can revolutionize product development, accelerate time to market, and unlock new possibilities - in the connected world. -

- Continue reading... -
-
-
-
-
-
-
February 27, 2023
-

- Navigating the Ever-Evolving World of Web Development: Trends, Technologies, and Best Practices -

- -
    -
  • Web Development
  • -
-

- Introduction: - - Web development has witnessed remarkable growth and transformation over the years, shaping the digital - landscape we interact with every day. -

- Continue reading... -
-
-
-
-
-
-
January 23, 2023
-

- The Intersection of UX/UI Design and Technology Trends: Enhancing User Experiences in the Digital Age -

- -
    -
  • Technology Trends
  • -
  • UX/UI Design
  • -
-

- Introduction: - - In the digital age, delivering exceptional user experiences (UX) has become a key differentiator for - businesses across industries. UX/UI design, the practice of creating intuitive and visually appealing - interfaces, plays a crucial role in shaping how users interact with technology. -

- Continue reading... -
-
-
-
-
-
-
September 27, 2022
-

- Securing the Digital Frontier: Cybersecurity Strategies and Best Practices -

- -
    -
  • Cybersecurity
  • -
-

- Introduction: - - In an increasingly interconnected world, where digital technologies pervade every aspect of our lives, - cybersecurity has become a critical concern. Protecting sensitive data, securing networks, and defending - against cyber threats are paramount for individuals, organizations, and governments. -

- Continue reading... -
-
-
-
-
-
-
March 6, 2023
-

- Synergizing Data Science, Cybersecurity, and Mobile App Development: Unlocking the Power of Secure and - Data-Driven Mobile Experiences -

- -
    -
  • Mobile App Development
  • -
  • Data Science
  • -
  • Cybersecurity
  • -
-

- Introduction: - - The convergence of data science, cybersecurity, and mobile app development has opened up unprecedented - opportunities to create secure, data-driven mobile experiences. -

- Continue reading... -
-
-
-
-
- -
-
-
-
-
-

Account

-
-
- avatar -
-
- register - login -
-
-
- -
-

About

-

- Our goal is to provide you with valuable insights, secure web solutions, and a seamless - user experience. See more... -

-
-
-
-
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - - diff --git a/js/articles.js b/js/articles.js deleted file mode 100644 index e38f14d..0000000 --- a/js/articles.js +++ /dev/null @@ -1,6 +0,0 @@ -// articles actions - -const submitButton = document.getElementById("publishSubmit") -if (submitButton) submitButton.addEventListener("click", () => { - document.getElementById("articleForm").submit() -}) diff --git a/js/articles.min.js b/js/articles.min.js deleted file mode 100644 index cfaed68..0000000 --- a/js/articles.min.js +++ /dev/null @@ -1 +0,0 @@ -const submitButton=document.getElementById("publishSubmit");submitButton&&submitButton.addEventListener("click",()=>{document.getElementById("articleForm").submit()}); \ No newline at end of file diff --git a/js/articles.min.js.map b/js/articles.min.js.map deleted file mode 100644 index fa89d8b..0000000 --- a/js/articles.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["articles.js"],"names":["submitButton","document","getElementById","addEventListener","submit"],"mappings":"AAEA,MAAMA,aAAeC,SAASC,eAAe,eAAe,EACxDF,cAAcA,aAAaG,iBAAiB,QAAS,KACrDF,SAASC,eAAe,aAAa,EAAEE,OAAO,CAClD,CAAC"} \ No newline at end of file diff --git a/js/comments.js b/js/comments.js deleted file mode 100644 index a118fa2..0000000 --- a/js/comments.js +++ /dev/null @@ -1,114 +0,0 @@ -// article comment creation -// TODO: Slit into individual packages to handle UI, API etc. GH-41 - -/** - * Create author block for new comment - * - * @param name author's name - * @param image author's avatar link - * @returns {HTMLDivElement} - */ -const createCommentAuthorBlock = ({name, image}) => { - const container = document.createElement("div") - container.classList.add("col-3", "text-center") - - const authorImage = document.createElement("img") - authorImage.classList.add("avatar", "rounded-circle", "p-2") - authorImage.src = image - container.appendChild(authorImage) - - const authorName = document.createElement("div") - authorName.classList.add("fw-bolder", "fst-italic") - authorName.innerText = name - container.appendChild(authorName) - - return container -} - - -/** - * Create message block for new comment - * - * @param created message creation date - * @param message message text - * @returns {HTMLDivElement} - */ -const createCommentMessageBlock = ({created, message}) => { - const container = document.createElement("div") - container.classList.add("col", "text-start") - - const messageCreated = document.createElement("small") - messageCreated.classList.add("fw-light") - messageCreated.innerText = created - container.appendChild(messageCreated) - - const messageText = document.createElement("p") - messageText.innerText = message - container.appendChild(messageText) - - return container -} - - -/** - * Create article comment - * - * @param author comment's author information - * @param comment comment date (creation date and message text) - * @returns {HTMLDivElement} - */ -const createArticleComment = ({author, comment}) => { - const container = document.createElement("div") - container.classList.add("row", "d-flex", "flex-row") - container.appendChild(createCommentAuthorBlock(author)) - container.appendChild(createCommentMessageBlock(comment)) - - return container -} - - -/** - * Add article comment to page - * - * @param comment comment data to append - */ -const addArticleComment = comment => { - const container = document.getElementById("articleCommentsContainer") - if (container) container.appendChild(comment) -} - - -/** - * Handle comment form submit event - * - * @param event - */ -const handleNewCommentSubmit = (event) => { - event.preventDefault(); - event.stopPropagation(); - - const message = event.target.querySelector("textarea").value.trim() - event.target.reset(); - - if (!message) return; - - // TODO: get payload from backend - const payload = { - author: { - image: "https://i.pravatar.cc/350?u=2054e2c9", - name: "Amaranth Burrowes", - }, - comment: { - message, - created: "Feb 2, 2023", - } - } - - const comment = createArticleComment(payload) - addArticleComment(comment); -} - - -// set event listeners -const commentForm = document.getElementById("articleCommentForm") -if (commentForm) commentForm.addEventListener("submit", handleNewCommentSubmit) diff --git a/js/comments.min.js b/js/comments.min.js deleted file mode 100644 index e4989c3..0000000 --- a/js/comments.min.js +++ /dev/null @@ -1 +0,0 @@ -const createCommentAuthorBlock=({name:e,image:t})=>{var a=document.createElement("div"),m=(a.classList.add("col-3","text-center"),document.createElement("img")),t=(m.classList.add("avatar","rounded-circle","p-2"),m.src=t,a.appendChild(m),document.createElement("div"));return t.classList.add("fw-bolder","fst-italic"),t.innerText=e,a.appendChild(t),a},createCommentMessageBlock=({created:e,message:t})=>{var a=document.createElement("div"),m=(a.classList.add("col","text-start"),document.createElement("small")),e=(m.classList.add("fw-light"),m.innerText=e,a.appendChild(m),document.createElement("p"));return e.innerText=t,a.appendChild(e),a},createArticleComment=({author:e,comment:t})=>{var a=document.createElement("div");return a.classList.add("row","d-flex","flex-row"),a.appendChild(createCommentAuthorBlock(e)),a.appendChild(createCommentMessageBlock(t)),a},addArticleComment=e=>{var t=document.getElementById("articleCommentsContainer");t&&t.appendChild(e)},handleNewCommentSubmit=e=>{e.preventDefault(),e.stopPropagation();var t=e.target.querySelector("textarea").value.trim();e.target.reset(),t&&(e={author:{image:"https://i.pravatar.cc/350?u=2054e2c9",name:"Amaranth Burrowes"},comment:{message:t,created:"Feb 2, 2023"}},t=createArticleComment(e),addArticleComment(t))},commentForm=document.getElementById("articleCommentForm");commentForm&&commentForm.addEventListener("submit",handleNewCommentSubmit); \ No newline at end of file diff --git a/js/comments.min.js.map b/js/comments.min.js.map deleted file mode 100644 index b515eb0..0000000 --- a/js/comments.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["comments.js"],"names":["createCommentAuthorBlock","name","image","container","document","createElement","authorImage","classList","add","authorName","src","appendChild","innerText","createCommentMessageBlock","created","message","messageCreated","messageText","createArticleComment","author","comment","addArticleComment","getElementById","handleNewCommentSubmit","event","preventDefault","stopPropagation","target","querySelector","value","trim","reset","payload","commentForm","addEventListener"],"mappings":"AAUA,MAAMA,yBAA2B,CAAA,CAAEC,KAAAA,EAAMC,MAAAA,CAAM,KAC3C,IAAMC,EAAYC,SAASC,cAAc,KAAK,EAGxCC,GAFNH,EAAUI,UAAUC,IAAI,QAAS,aAAa,EAE1BJ,SAASC,cAAc,KAAK,GAK1CI,GAJNH,EAAYC,UAAUC,IAAI,SAAU,iBAAkB,KAAK,EAC3DF,EAAYI,IAAMR,EAClBC,EAAUQ,YAAYL,CAAW,EAEdF,SAASC,cAAc,KAAK,GAK/C,OAJAI,EAAWF,UAAUC,IAAI,YAAa,YAAY,EAClDC,EAAWG,UAAYX,EACvBE,EAAUQ,YAAYF,CAAU,EAEzBN,CACX,EAUMU,0BAA4B,CAAA,CAAEC,QAAAA,EAASC,QAAAA,CAAQ,KACjD,IAAMZ,EAAYC,SAASC,cAAc,KAAK,EAGxCW,GAFNb,EAAUI,UAAUC,IAAI,MAAO,YAAY,EAEpBJ,SAASC,cAAc,OAAO,GAK/CY,GAJND,EAAeT,UAAUC,IAAI,UAAU,EACvCQ,EAAeJ,UAAYE,EAC3BX,EAAUQ,YAAYK,CAAc,EAEhBZ,SAASC,cAAc,GAAG,GAI9C,OAHAY,EAAYL,UAAYG,EACxBZ,EAAUQ,YAAYM,CAAW,EAE1Bd,CACX,EAUMe,qBAAuB,CAAA,CAAEC,OAAAA,EAAQC,QAAAA,CAAQ,KAC3C,IAAMjB,EAAYC,SAASC,cAAc,KAAK,EAK9C,OAJAF,EAAUI,UAAUC,IAAI,MAAO,SAAU,UAAU,EACnDL,EAAUQ,YAAYX,yBAAyBmB,CAAM,CAAC,EACtDhB,EAAUQ,YAAYE,0BAA0BO,CAAO,CAAC,EAEjDjB,CACX,EAQMkB,kBAAoBD,IACtB,IAAMjB,EAAYC,SAASkB,eAAe,0BAA0B,EAChEnB,GAAWA,EAAUQ,YAAYS,CAAO,CAChD,EAQMG,uBAAyB,IAC3BC,EAAMC,eAAe,EACrBD,EAAME,gBAAgB,EAEtB,IAAMX,EAAUS,EAAMG,OAAOC,cAAc,UAAU,EAAEC,MAAMC,KAAK,EAClEN,EAAMG,OAAOI,MAAM,EAEdhB,IAGCiB,EAAU,CACZb,OAAQ,CACJjB,MAAO,uCACPD,KAAM,mBACV,EACAmB,QAAS,CACLL,QAAAA,EACAD,QAAS,aACb,CACJ,EAEMM,EAAUF,qBAAqBc,CAAO,EAC5CX,kBAAkBD,CAAO,EAC7B,EAIMa,YAAc7B,SAASkB,eAAe,oBAAoB,EAC5DW,aAAaA,YAAYC,iBAAiB,SAAUX,sBAAsB"} \ No newline at end of file diff --git a/profile.html b/profile.html deleted file mode 100644 index cb9efab..0000000 --- a/profile.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - - Profile | Django Blog - - - - - - - - - - - - - - -
-
-
-
-

Amaranth Burrowes

-
-
-
- avatar -
-
- Hello, I'm a passionate web developer, data science enthusiast, and cybersecurity advocate. - With several years of experience in the field, I have dedicated my career to staying at the forefront of - technological advancements in web development and leveraging them to create innovative and user-centric - solutions. - - As a web developer, I have always been fascinated by the power of technology to transform the way we - interact with websites and applications. My journey in web development began with a strong foundation in - programming languages such as HTML, CSS, and JavaScript, which laid the groundwork for my exploration of - more advanced frameworks and technologies. -
-
- create article - - - -
-
-

Articles by this author [2]

-
-
-
-
-
March 22, 2023
-

- Exploring the Evolving Landscape of Web Development in the Age of Technology Trends -

- -
    -
  • Technology Trends
  • -
  • Web Development
  • -
-

- Introduction: - - In today's rapidly advancing technological landscape, web development has become an indispensable part - of our lives. As the world becomes increasingly interconnected, it is vital for businesses and - individuals alike to stay up-to-date with the latest technology trends in order to thrive in the digital - realm. -

- Continue reading... -
-
-
-
-
-
-
May 1, 2023
-

- Driving Innovation and Efficiency: The Synergy of Agile Methodology and the Internet of Things (IoT) -

- -
    -
  • Agile Methodology
  • -
  • Internet of Things (IoT)
  • -
-

- Introduction: - - In an era of rapid technological advancements, organizations are seeking ways to innovate and stay ahead - of the curve. The combination of Agile methodology and the Internet of Things (IoT) has emerged as a - powerful duo, enabling businesses to drive efficiency, enhance collaboration, and deliver innovative IoT - solutions. In this article, we will explore the convergence of Agile and IoT, highlighting how this - synergy can revolutionize product development, accelerate time to market, and unlock new possibilities - in the connected world. -

- Continue reading... -
-
-
-
-
-
-
-
-

Account

-
-
- avatar -
- - -
-
- -
-

About

-

- Our goal is to provide you with valuable insights, secure web solutions, and a seamless - user experience. See more... -

-
-
-
-
-
- -
-
Our social media
-
    -
  • -
  • -
  • -
  • -
  • -
-
- This template is prepared for the training project. All content is generated by - ChatGPT, - a language model developed by OpenAI. -
-
- - - - - From cf767514df35259b9efe62fa294cf8ff5e1ea4f8 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Fri, 12 Jan 2024 05:01:54 +0200 Subject: [PATCH 07/91] Update bootstrap SCSS import --- src/index.js | 2 +- src/scss/bs-styles.scss | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 src/scss/bs-styles.scss diff --git a/src/index.js b/src/index.js index 067ae99..179a6ed 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ // noinspection ES6UnusedImports // Bind sources -import "./scss/bs-styles.scss" +import "bootstrap/scss/bootstrap.scss" import "./img/anonymous.svg" import "./img/favicon.png" diff --git a/src/scss/bs-styles.scss b/src/scss/bs-styles.scss deleted file mode 100644 index 8f11562..0000000 --- a/src/scss/bs-styles.scss +++ /dev/null @@ -1,2 +0,0 @@ -// Import all of Bootstrap's CSS -@import "bootstrap/scss/bootstrap"; From 5bb74d1a06dea6b8a394e4b22937c4fc218c827d Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Fri, 12 Jan 2024 00:13:18 +0200 Subject: [PATCH 08/91] Add base list view template --- src/views/{index.hbs => list_view.hbs} | 2 +- src/views/partials/list_article.hbs | 19 ++++++ src/views/partials/list_articles.hbs | 83 ++++++++++++++++++++++++++ webpack.config.js | 4 +- 4 files changed, 105 insertions(+), 3 deletions(-) rename src/views/{index.hbs => list_view.hbs} (94%) create mode 100644 src/views/partials/list_article.hbs create mode 100644 src/views/partials/list_articles.hbs diff --git a/src/views/index.hbs b/src/views/list_view.hbs similarity index 94% rename from src/views/index.hbs rename to src/views/list_view.hbs index f811077..2812a0a 100644 --- a/src/views/index.hbs +++ b/src/views/list_view.hbs @@ -12,7 +12,7 @@
-

Test Webpack builds

+ {{>partials/list_articles.hbs}}
+ + diff --git a/webpack.config.js b/webpack.config.js index 2ca14f4..66fbaf5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -38,7 +38,16 @@ module.exports = { ...blog.globalTemplateParameters, ...blog.refs } - }) + }), + new HTMLWebpackPlugin({ + template: "./src/views/profile_view.hbs", + filename: "profile.html", + templateParameters: { + title: "User Profile", + ...blog.globalTemplateParameters, + ...blog.refs + } + }), ], module: { rules: [ From 95ad8ce7a7cd48370d4fca452038549fe02a69d9 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Fri, 12 Jan 2024 23:27:36 +0200 Subject: [PATCH 30/91] Adjust articles section content for the profile page template (GH-48) --- src/views/partials/profile_main.hbs | 68 ++++++++--------------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/src/views/partials/profile_main.hbs b/src/views/partials/profile_main.hbs index 465ca5e..ac0448f 100644 --- a/src/views/partials/profile_main.hbs +++ b/src/views/partials/profile_main.hbs @@ -36,55 +36,23 @@

Articles by this author [2]

-
-
-
-
March 22, 2023
-

- Exploring the Evolving Landscape of Web Development in the Age of Technology Trends -

- -
    -
  • Technology Trends
  • -
  • Web Development
  • -
-

- Introduction: - - In today's rapidly advancing technological landscape, web development has become an indispensable part - of our lives. As the world becomes increasingly interconnected, it is vital for businesses and - individuals alike to stay up-to-date with the latest technology trends in order to thrive in the digital - realm. -

- Continue reading... -
-
-
-
-
-
-
May 1, 2023
-

- Driving Innovation and Efficiency: The Synergy of Agile Methodology and the Internet of Things (IoT) -

- -
    -
  • Agile Methodology
  • -
  • Internet of Things (IoT)
  • -
-

- Introduction: - - In an era of rapid technological advancements, organizations are seeking ways to innovate and stay ahead - of the curve. The combination of Agile methodology and the Internet of Things (IoT) has emerged as a - powerful duo, enabling businesses to drive efficiency, enhance collaboration, and deliver innovative IoT - solutions. In this article, we will explore the convergence of Agile and IoT, highlighting how this - synergy can revolutionize product development, accelerate time to market, and unlock new possibilities - in the connected world. -

- Continue reading... -
-
-
+ {{>list_article.hbs + ArticleTitle="Ship-wide, carnivorous crews impressively deserve an extraterrestrial, devastated ferengi" + ArticleAuthor="Pippin Sackville-Baggins" + ArticleContent="Shield at the colony was the turbulence of friendship, attacked to a lunar tribble. + Where is the strange nanomachine? The machine is more ferengi now than processor. united and wildly delighted. + Honor, disconnection, and mind. Mystery at the holodeck was the plasma of paralysis, raised to an intelligent + collective. Tribble of a post-apocalyptic tragedy, handle the alarm! Bare, brave queens cunningly question + a strange, post-apocalyptic crew. kahlesses die with core?" + ArticleTopics=(topics "Fake latin;Science Fiction;Culinary Inspirations") + ArticleDate="July 7, 2024" + }} + {{>list_article.hbs + ArticleTitle="Black, wet seashells calmly pull a gutless, misty whale" + ArticleAuthor="Pippin Sackville-Baggins" + ArticleContent="The lad commands with life, scrape the galley until it falls!" + ArticleTopics=(topics "Pirate Lingo;Esoteric Wisdom;Fake Latin") + ArticleDate="December 9, 2023" + }}
From 36aabe2755561d08121e9698f864eb3754e8989c Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Fri, 12 Jan 2024 23:34:21 +0200 Subject: [PATCH 31/91] Update CSS classes for user data section (fixes GH-48) --- src/views/partials/profile_main.hbs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/partials/profile_main.hbs b/src/views/partials/profile_main.hbs index ac0448f..7fda702 100644 --- a/src/views/partials/profile_main.hbs +++ b/src/views/partials/profile_main.hbs @@ -2,11 +2,11 @@

{{user.first_name}} {{user.last_name}}

-
-
+
+
avatar
-
+
Hello, I'm a passionate web developer, data science enthusiast, and cybersecurity advocate. With several years of experience in the field, I have dedicated my career to staying at the forefront of technological advancements in web development and leveraging them to create innovative and user-centric @@ -33,7 +33,7 @@
{{/if}} -

Articles by this author [2]

+
Articles by this author [2]
{{>list_article.hbs From 36fa8e5e9f35872163e47101976403946e5144c2 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 00:29:46 +0200 Subject: [PATCH 32/91] Adjust profile image align and default avatar sizes --- src/scss/default.scss | 9 ++++++--- src/views/partials/profile_main.hbs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/scss/default.scss b/src/scss/default.scss index ad68285..dfeeab9 100644 --- a/src/scss/default.scss +++ b/src/scss/default.scss @@ -1,7 +1,10 @@ -$avatar-size-default: 24rem; +$avatar-min-size-default: 12rem; +$avatar-max-size-default: 16rem; .avatar { - max-height: $avatar-size-default; - max-width: $avatar-size-default; + min-height: $avatar-min-size-default; + min-width: $avatar-min-size-default; + max-height: $avatar-max-size-default; + max-width: $avatar-max-size-default; margin: 0.25rem 0; } diff --git a/src/views/partials/profile_main.hbs b/src/views/partials/profile_main.hbs index 7fda702..d13a8d6 100644 --- a/src/views/partials/profile_main.hbs +++ b/src/views/partials/profile_main.hbs @@ -3,7 +3,7 @@

{{user.first_name}} {{user.last_name}}

-
+
avatar
From f5cdd3ff33f6b88499e084f8323b3838174a9215 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 00:42:14 +0200 Subject: [PATCH 33/91] Add Jest test runner workflow --- .github/workflows/run_tests.yml | 26 ++++++++++++++++++++++++++ .github/workflows/webpack_builds.yml | 11 +++-------- 2 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/run_tests.yml diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 0000000..2883ba6 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,26 @@ +name: Test project code + +on: + pull_request: + branches: + - master + - devel + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + + - name: Setup NodeJs + uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Test code with Jest + run: npm run test diff --git a/.github/workflows/webpack_builds.yml b/.github/workflows/webpack_builds.yml index f12fcc0..722e808 100644 --- a/.github/workflows/webpack_builds.yml +++ b/.github/workflows/webpack_builds.yml @@ -1,17 +1,12 @@ -name: Build project bundle with Webpack +name: Check project bundle builds on: - push: - branches: - - master - pull_request: branches: - master - devel jobs: - development: runs-on: ubuntu-latest @@ -27,7 +22,7 @@ jobs: - name: Install dependencies run: npm install - - name: build the distribution bundle + - name: Build the distribution bundle run: npm run build:dev production: @@ -45,5 +40,5 @@ jobs: - name: Install dependencies run: npm install - - name: build the distribution bundle + - name: Build the distribution bundle run: npm run build From 5c819bdae1aad05cb73ec8fbc34ee31a662c3ec3 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 01:30:28 +0200 Subject: [PATCH 34/91] Add base sources for auth form views - GH-68 - GH-69 --- src/views/partials/signin_form.hbs | 0 src/views/partials/signup_form.hbs | 0 src/views/signin_view.hbs | 26 ++++++++++++++++++++++++++ src/views/signup_view.hbs | 26 ++++++++++++++++++++++++++ webpack.config.js | 18 ++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 src/views/partials/signin_form.hbs create mode 100644 src/views/partials/signup_form.hbs create mode 100644 src/views/signin_view.hbs create mode 100644 src/views/signup_view.hbs diff --git a/src/views/partials/signin_form.hbs b/src/views/partials/signin_form.hbs new file mode 100644 index 0000000..e69de29 diff --git a/src/views/partials/signup_form.hbs b/src/views/partials/signup_form.hbs new file mode 100644 index 0000000..e69de29 diff --git a/src/views/signin_view.hbs b/src/views/signin_view.hbs new file mode 100644 index 0000000..85d1125 --- /dev/null +++ b/src/views/signin_view.hbs @@ -0,0 +1,26 @@ + + + + + + + + + + {{title}} | Blog Site + + +{{>partials/_header.hbs}} +
+
+ {{>partials/signin_form.hbs}} +
+
+ + + diff --git a/src/views/signup_view.hbs b/src/views/signup_view.hbs new file mode 100644 index 0000000..213c14a --- /dev/null +++ b/src/views/signup_view.hbs @@ -0,0 +1,26 @@ + + + + + + + + + + {{title}} | Blog Site + + +{{>partials/_header.hbs}} +
+
+ {{>partials/signup_form.hbs}} +
+
+ + + diff --git a/webpack.config.js b/webpack.config.js index 66fbaf5..e443014 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -48,6 +48,24 @@ module.exports = { ...blog.refs } }), + new HTMLWebpackPlugin({ + template: "./src/views/signin_view.hbs", + filename: "signin.html", + templateParameters: { + title: "Sign In", + ...blog.globalTemplateParameters, + ...blog.refs + } + }), + new HTMLWebpackPlugin({ + template: "./src/views/signup_view.hbs", + filename: "signup.html", + templateParameters: { + title: "Sign Up", + ...blog.globalTemplateParameters, + ...blog.refs + } + }), ], module: { rules: [ From b3262686a04fa6ed260e902f9de0ab77571fae4d Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 01:51:03 +0200 Subject: [PATCH 35/91] Fix dist filenames - GH-68 - GH-69 --- webpack.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index e443014..e42f4e8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -50,7 +50,7 @@ module.exports = { }), new HTMLWebpackPlugin({ template: "./src/views/signin_view.hbs", - filename: "signin.html", + filename: "sign-in.html", templateParameters: { title: "Sign In", ...blog.globalTemplateParameters, @@ -59,7 +59,7 @@ module.exports = { }), new HTMLWebpackPlugin({ template: "./src/views/signup_view.hbs", - filename: "signup.html", + filename: "sign-up.html", templateParameters: { title: "Sign Up", ...blog.globalTemplateParameters, From d05d0a08308181e1449e18c02262bd3cd690b874 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 01:52:39 +0200 Subject: [PATCH 36/91] Add sign-up form template - GH-69 --- src/views/partials/signup_form.hbs | 32 ++++++++++++++++++++++++++++++ src/views/signup_view.hbs | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/views/partials/signup_form.hbs b/src/views/partials/signup_form.hbs index e69de29..0c17605 100644 --- a/src/views/partials/signup_form.hbs +++ b/src/views/partials/signup_form.hbs @@ -0,0 +1,32 @@ +
+
+
Register new account
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+

Have already an account?

+ Sing in here +
+ + +
+
diff --git a/src/views/signup_view.hbs b/src/views/signup_view.hbs index 213c14a..6bb55a2 100644 --- a/src/views/signup_view.hbs +++ b/src/views/signup_view.hbs @@ -13,7 +13,7 @@ {{>partials/_header.hbs}}
-
+
{{>partials/signup_form.hbs}}
From c89402275f4b4df51bebde74026ebe185a15f9bc Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 02:00:43 +0200 Subject: [PATCH 37/91] Add sign-in form template - GH-68 --- src/views/partials/signin_form.hbs | 22 ++++++++++++++++++++++ src/views/signin_view.hbs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/views/partials/signin_form.hbs b/src/views/partials/signin_form.hbs index e69de29..6f7889b 100644 --- a/src/views/partials/signin_form.hbs +++ b/src/views/partials/signin_form.hbs @@ -0,0 +1,22 @@ +
+
+
Login to your account
+ +
+ + +
+ +
+ + +
+ +
+

Have no account?

+ Join us now +
+ + +
+
diff --git a/src/views/signin_view.hbs b/src/views/signin_view.hbs index 85d1125..44be88f 100644 --- a/src/views/signin_view.hbs +++ b/src/views/signin_view.hbs @@ -13,7 +13,7 @@ {{>partials/_header.hbs}}
-
+
{{>partials/signin_form.hbs}}
From 7a3f07372c96faddf36ad68c9a6735431a99c73d Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 02:03:28 +0200 Subject: [PATCH 38/91] Center forms headers and append block roles - GH-68 - GH-69 --- src/views/partials/signin_form.hbs | 2 +- src/views/partials/signup_form.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/partials/signin_form.hbs b/src/views/partials/signin_form.hbs index 6f7889b..a8bd32b 100644 --- a/src/views/partials/signin_form.hbs +++ b/src/views/partials/signin_form.hbs @@ -1,6 +1,6 @@
-
Login to your account
+
Login to your account
diff --git a/src/views/partials/signup_form.hbs b/src/views/partials/signup_form.hbs index 0c17605..274e529 100644 --- a/src/views/partials/signup_form.hbs +++ b/src/views/partials/signup_form.hbs @@ -1,6 +1,6 @@
-
Register new account
+
Register new account
From c4e855e4299a3ecf7ca8d188aa73fdbf60beffbf Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 02:30:15 +0200 Subject: [PATCH 39/91] Apply general auth forms styling - fixes GH-68 - fixes GH-69 --- src/index.js | 1 + src/scss/auth.scss | 17 +++++++++++++++++ src/scss/default.scss | 6 ++++++ src/views/partials/signin_form.hbs | 6 +++--- src/views/partials/signup_form.hbs | 6 +++--- 5 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/scss/auth.scss diff --git a/src/index.js b/src/index.js index 8262250..4862a1a 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ import "bootstrap/scss/bootstrap.scss" import * as bootstrap from "bootstrap" // Bind sources +import "./scss/auth.scss" import "./scss/default.scss" import "./scss/header.scss" import "./scss/sidebar.scss" diff --git a/src/scss/auth.scss b/src/scss/auth.scss new file mode 100644 index 0000000..242edb9 --- /dev/null +++ b/src/scss/auth.scss @@ -0,0 +1,17 @@ +$input-border-radius: 0.75rem; + +.form-auth { + .form-first-input { + input { + border-top-left-radius: $input-border-radius; + border-top-right-radius: $input-border-radius; + } + } + + .form-last-input { + input { + border-bottom-left-radius: $input-border-radius; + border-bottom-right-radius: $input-border-radius; + } + } +} diff --git a/src/scss/default.scss b/src/scss/default.scss index dfeeab9..0ea0699 100644 --- a/src/scss/default.scss +++ b/src/scss/default.scss @@ -8,3 +8,9 @@ $avatar-max-size-default: 16rem; max-width: $avatar-max-size-default; margin: 0.25rem 0; } + +.form-auth { + input { + border-radius: 0; + } +} diff --git a/src/views/partials/signin_form.hbs b/src/views/partials/signin_form.hbs index a8bd32b..b608da4 100644 --- a/src/views/partials/signin_form.hbs +++ b/src/views/partials/signin_form.hbs @@ -1,13 +1,13 @@
- +
Login to your account
-
+
-
+
diff --git a/src/views/partials/signup_form.hbs b/src/views/partials/signup_form.hbs index 274e529..7581533 100644 --- a/src/views/partials/signup_form.hbs +++ b/src/views/partials/signup_form.hbs @@ -1,8 +1,8 @@
- +
Register new account
-
+
@@ -17,7 +17,7 @@
-
+
From 7dd939487a2576c3469d352aff485cc26a20ffac Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 02:42:10 +0200 Subject: [PATCH 40/91] Apply generic filenames for HTML files --- webpack.config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index e42f4e8..09e23ec 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -32,7 +32,7 @@ module.exports = { new miniCssExportPlugin({"filename": "css/main.min.css"}), new HTMLWebpackPlugin({ template: "./src/views/list_view.hbs", - filename: "index.html", + filename: blog.refs.ListView, templateParameters: { title: "All Articles", ...blog.globalTemplateParameters, @@ -41,7 +41,7 @@ module.exports = { }), new HTMLWebpackPlugin({ template: "./src/views/profile_view.hbs", - filename: "profile.html", + filename: blog.refs.ProfileView, templateParameters: { title: "User Profile", ...blog.globalTemplateParameters, @@ -52,14 +52,14 @@ module.exports = { template: "./src/views/signin_view.hbs", filename: "sign-in.html", templateParameters: { - title: "Sign In", + title: blog.refs.SignInView, ...blog.globalTemplateParameters, ...blog.refs } }), new HTMLWebpackPlugin({ template: "./src/views/signup_view.hbs", - filename: "sign-up.html", + filename: blog.refs.SignUpView, templateParameters: { title: "Sign Up", ...blog.globalTemplateParameters, From b8ef33a229d085daef28a44e39cbfbf957008561 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 13:23:59 +0200 Subject: [PATCH 41/91] Add base detail sources (GH-49) --- src/views/detail_view.hbs | 27 +++++++++++++++++++++++++++ src/views/partials/_sidebar.hbs | 2 +- src/views/partials/detail_main.hbs | 3 +++ webpack.config.js | 9 +++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/views/detail_view.hbs create mode 100644 src/views/partials/detail_main.hbs diff --git a/src/views/detail_view.hbs b/src/views/detail_view.hbs new file mode 100644 index 0000000..3b8c9e4 --- /dev/null +++ b/src/views/detail_view.hbs @@ -0,0 +1,27 @@ + + + + + + + + + + {{title}} | Blog Site + + +{{>partials/_header.hbs}} +
+
+ {{>partials/detail_main.hbs}} + {{>partials/_sidebar.hbs authenticated=user can_edit=true}} +
+
+ + + diff --git a/src/views/partials/_sidebar.hbs b/src/views/partials/_sidebar.hbs index 5cf519c..37bd1e3 100644 --- a/src/views/partials/_sidebar.hbs +++ b/src/views/partials/_sidebar.hbs @@ -19,7 +19,7 @@ {{#if authenticated }}
create article - {{#if is_editable}} + {{#if can_edit}} update article
+
+ {{#each article.comments}} + {{>detail_comment.hbs comment=this}} + {{/each}} +
From 74741492dfa4fecdedef1a5f075957e73071582d Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sat, 13 Jan 2024 22:38:33 +0200 Subject: [PATCH 44/91] Add comment button to detail view template (GH-73) --- src/views/detail_view.hbs | 2 +- src/views/partials/_sidebar.hbs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/views/detail_view.hbs b/src/views/detail_view.hbs index a28f6ff..b791b88 100644 --- a/src/views/detail_view.hbs +++ b/src/views/detail_view.hbs @@ -15,7 +15,7 @@
{{>partials/detail_main.hbs article=article}} - {{>partials/_sidebar.hbs authenticated=user can_edit=true}} + {{>partials/_sidebar.hbs authenticated=user can_edit=true can_comment=true}}
+ + diff --git a/src/views/partials/_sidebar.hbs b/src/views/partials/_sidebar.hbs index 7b0cff1..ab7e5f8 100644 --- a/src/views/partials/_sidebar.hbs +++ b/src/views/partials/_sidebar.hbs @@ -20,13 +20,18 @@
{{#if can_comment}} + data-bs-toggle="modal" data-bs-target="#modalArticleComment">comment + + {{/if}} + + {{#if create_view}} + cancel {{/if}} - create article {{#if can_edit}} update article + data-bs-toggle="modal" data-bs-target="#modalArticleDelete">delete article + {{/if}}
{{else}} diff --git a/src/views/partials/form_main.hbs b/src/views/partials/form_main.hbs new file mode 100644 index 0000000..a5a2eb6 --- /dev/null +++ b/src/views/partials/form_main.hbs @@ -0,0 +1,24 @@ +
+ +
Article Form
+
+
+ + +
+
+ + +
+
+ + +
+ +
diff --git a/webpack.config.js b/webpack.config.js index 159029e..dbb4bd8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -50,6 +50,16 @@ module.exports = { user: globals.user, } }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/form_view.hbs"), + filename: globals.refs.FormView, + templateParameters: { + title: "Article Form", + ...globals.templateParameters, + ...globals.refs, + user: globals.user, + } + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/profile_view.hbs"), filename: globals.refs.ProfileView, @@ -57,7 +67,7 @@ module.exports = { title: "User Profile", ...globals.templateParameters, ...globals.refs, - user:globals.user, + user: globals.user, } }), new HTMLWebpackPlugin({ diff --git a/webpack.dev.config.js b/webpack.dev.config.js index d30ff74..216380f 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -45,6 +45,15 @@ module.exports = { navs: globals.refs.navs, } }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/form_main.hbs"), + filename: "articles/article_form.html", + chunks: [], + templateParameters: { + ...globals.templateParametersDevelopment, + navs: globals.refs.navs, + } + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/signin_form.hbs"), filename: "auth/signin_form.html", From c8de8e539dcdaa06377b4e03cb09741c6e6b591b Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 14:17:19 +0200 Subject: [PATCH 56/91] Add masonry layout to project dependencies (fixes GH-71) --- package-lock.json | 45 +++++++++++++++++++++++++++++++++++++- package.json | 3 ++- src/index.js | 2 ++ src/js/masonry.pkgd.min.js | 9 -------- src/views/detail_view.hbs | 5 ----- src/views/form_view.hbs | 5 ----- src/views/list_view.hbs | 5 ----- src/views/profile_view.hbs | 5 ----- src/views/signin_view.hbs | 5 ----- src/views/signup_view.hbs | 5 ----- 10 files changed, 48 insertions(+), 41 deletions(-) delete mode 100644 src/js/masonry.pkgd.min.js diff --git a/package-lock.json b/package-lock.json index 5026a04..a082843 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "MIT", "dependencies": { "@popperjs/core": "^2.11.8", - "bootstrap": "^5.3.2" + "bootstrap": "^5.3.2", + "masonry-layout": "^4.2.2" }, "devDependencies": { "autoprefixer": "^10.4.16", @@ -3113,6 +3114,11 @@ "node": ">= 0.8" } }, + "node_modules/desandro-matches-selector": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz", + "integrity": "sha512-+1q0nXhdzg1IpIJdMKalUwvvskeKnYyEe3shPRwedNcWtnhEKT3ZxvFjzywHDeGcKViIxTCAoOYQWP1qD7VNyg==" + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -3419,6 +3425,11 @@ "node": ">= 0.6" } }, + "node_modules/ev-emitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ev-emitter/-/ev-emitter-1.1.1.tgz", + "integrity": "sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q==" + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -3615,6 +3626,14 @@ "node": ">=8" } }, + "node_modules/fizzy-ui-utils": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz", + "integrity": "sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg==", + "dependencies": { + "desandro-matches-selector": "^2.0.0" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -3752,6 +3771,11 @@ "node": ">=8.0.0" } }, + "node_modules/get-size": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/get-size/-/get-size-2.0.3.tgz", + "integrity": "sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q==" + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -6198,6 +6222,15 @@ "tmpl": "1.0.5" } }, + "node_modules/masonry-layout": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/masonry-layout/-/masonry-layout-4.2.2.tgz", + "integrity": "sha512-iGtAlrpHNyxaR19CvKC3npnEcAwszXoyJiI8ARV2ePi7fmYhIud25MHK8Zx4P0LCC4d3TNO9+rFa1KoK1OEOaA==", + "dependencies": { + "get-size": "^2.0.2", + "outlayer": "^2.1.0" + } + }, "node_modules/mdn-data": { "version": "2.0.28", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", @@ -6617,6 +6650,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/outlayer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/outlayer/-/outlayer-2.1.1.tgz", + "integrity": "sha512-+GplXsCQ3VrbGujAeHEzP9SXsBmJxzn/YdDSQZL0xqBmAWBmortu2Y9Gwdp9J0bgDQ8/YNIPMoBM13nTwZfAhw==", + "dependencies": { + "ev-emitter": "^1.0.0", + "fizzy-ui-utils": "^2.0.0", + "get-size": "^2.0.2" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", diff --git a/package.json b/package.json index 2196290..5f99acb 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ }, "dependencies": { "@popperjs/core": "^2.11.8", - "bootstrap": "^5.3.2" + "bootstrap": "^5.3.2", + "masonry-layout": "^4.2.2" }, "jest": { "verbose": true diff --git a/src/index.js b/src/index.js index ec48817..39aecf6 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,8 @@ import "bootstrap/scss/bootstrap.scss" import * as bootstrap from "bootstrap" +import * as masonry from "masonry-layout" + import "./js/sidebar" import "./scss/auth.scss" diff --git a/src/js/masonry.pkgd.min.js b/src/js/masonry.pkgd.min.js deleted file mode 100644 index 53386ae..0000000 --- a/src/js/masonry.pkgd.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Masonry PACKAGED v4.2.2 - * Cascading grid layout library - * https://masonry.desandro.com - * MIT License - * by David DeSandro - */ - -!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;oe;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;is?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}); \ No newline at end of file diff --git a/src/views/detail_view.hbs b/src/views/detail_view.hbs index 41639f2..f89a769 100644 --- a/src/views/detail_view.hbs +++ b/src/views/detail_view.hbs @@ -18,10 +18,5 @@ {{>partials/_sidebar authenticated=user can_edit=true can_comment=true}}
- diff --git a/src/views/form_view.hbs b/src/views/form_view.hbs index aa6ce33..d4e70c1 100644 --- a/src/views/form_view.hbs +++ b/src/views/form_view.hbs @@ -18,10 +18,5 @@ {{>partials/_sidebar authenticated=user create_view=true}}
- diff --git a/src/views/list_view.hbs b/src/views/list_view.hbs index 84b277f..7fadc38 100644 --- a/src/views/list_view.hbs +++ b/src/views/list_view.hbs @@ -18,10 +18,5 @@ {{>partials/_sidebar}} - diff --git a/src/views/profile_view.hbs b/src/views/profile_view.hbs index b3fdc12..cf3ebaf 100644 --- a/src/views/profile_view.hbs +++ b/src/views/profile_view.hbs @@ -18,10 +18,5 @@ {{>partials/_sidebar authenticated=user}} - diff --git a/src/views/signin_view.hbs b/src/views/signin_view.hbs index 3b8d36f..fc37bbc 100644 --- a/src/views/signin_view.hbs +++ b/src/views/signin_view.hbs @@ -17,10 +17,5 @@ {{>partials/signin_form}} - diff --git a/src/views/signup_view.hbs b/src/views/signup_view.hbs index 8826c5f..f98ba52 100644 --- a/src/views/signup_view.hbs +++ b/src/views/signup_view.hbs @@ -17,10 +17,5 @@ {{>partials/signup_form}} - From bc44f4027cae9fa9de0688a53eaeab52ca8b39e5 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 14:25:06 +0200 Subject: [PATCH 57/91] Add comment (header) to the webpack entry point --- src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.js b/src/index.js index 39aecf6..5e5a571 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,4 @@ +// webpack default entry point // noinspection ES6UnusedImports: do not report unused imports (IDE) import "bootstrap/scss/bootstrap.scss" From e61bfe6fe89841622285a3d7a8cfa30bef9c2a6c Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 14:31:05 +0200 Subject: [PATCH 58/91] Change package version to "release candidate" --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f99acb..dbf1100 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "url": "git+https://github.com/edu-python-course/blog-bootstrap", "type": "git" }, - "version": "2.0-development", + "version": "2.0-rc1", "private": true, "license": "MIT", "scripts": { From 2084cc1e0a5fe306dc5b0cbfb4d0b4b0da893153 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 14:47:13 +0200 Subject: [PATCH 59/91] Update package lock file --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a082843..dbc0826 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "blog-bootstrap", - "version": "2.0-development", + "version": "2.0-rc1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "blog-bootstrap", - "version": "2.0-development", + "version": "2.0-rc1", "license": "MIT", "dependencies": { "@popperjs/core": "^2.11.8", From 1ae4d50fc97857a13568159aaaa2e8d500c3aed6 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 14:53:27 +0200 Subject: [PATCH 60/91] Add base template to the development bundle --- src/views/_template.hbs | 21 +++++++++++++++++++++ webpack.dev.config.js | 4 ++++ 2 files changed, 25 insertions(+) create mode 100644 src/views/_template.hbs diff --git a/src/views/_template.hbs b/src/views/_template.hbs new file mode 100644 index 0000000..ffb6170 --- /dev/null +++ b/src/views/_template.hbs @@ -0,0 +1,21 @@ + + + + + + + + + + {{title}} | Blog Site + + + +
+
+ +
+
+ + diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 216380f..28ffb88 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -27,6 +27,10 @@ module.exports = { new MiniCSSExtractPlugin({ "filename": "static/css/main.css" }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/_template.hbs"), + filename: "base.html", + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/list_main.hbs"), filename: "articles/article_list.html", From 567a20f8560283c230b986d1d61470465482ad48 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 14:55:11 +0200 Subject: [PATCH 61/91] Rename GitHub workflow configs --- .github/workflows/{run_tests.yml => run_js_tests.yml} | 0 .github/workflows/{webpack_builds.yml => test_webpack_builds.yml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{run_tests.yml => run_js_tests.yml} (100%) rename .github/workflows/{webpack_builds.yml => test_webpack_builds.yml} (100%) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_js_tests.yml similarity index 100% rename from .github/workflows/run_tests.yml rename to .github/workflows/run_js_tests.yml diff --git a/.github/workflows/webpack_builds.yml b/.github/workflows/test_webpack_builds.yml similarity index 100% rename from .github/workflows/webpack_builds.yml rename to .github/workflows/test_webpack_builds.yml From fbd6b6364fdcf28be1f154efb486e66b69bba772 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 15:19:04 +0200 Subject: [PATCH 62/91] Add various sidebars to the development bundle --- webpack.dev.config.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 28ffb88..197938f 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -16,6 +16,11 @@ const autoprefixer = require("autoprefixer"); const baseConfig = require("./webpack.config") const globals = require("./blog/globals") +const sidebar_authenticated = {user:globals.user, authenticated:true} +const sidebar_can_comment = {...sidebar_authenticated, can_comment:true} +const sidebar_can_edit = {...sidebar_authenticated, can_edit:true} +const sidebar_create_view = {...sidebar_authenticated, create_view:true} + module.exports = { ...baseConfig, mode: "development", @@ -31,6 +36,30 @@ module.exports = { template: path.resolve(__dirname, "src/views/_template.hbs"), filename: "base.html", }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), + filename: "_sidebars/non-authenticated.html", + }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), + filename: "_sidebars/authenticated.html", + templateParameters: {...sidebar_authenticated} + }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), + filename: "_sidebars/can_comment.html", + templateParameters: {...sidebar_can_comment} + }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), + filename: "_sidebars/can_edit.html", + templateParameters: {...sidebar_can_edit} + }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), + filename: "_sidebars/create_view.html", + templateParameters: {...sidebar_create_view} + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/list_main.hbs"), filename: "articles/article_list.html", From 4aff24c1d256aaa467964fc9087731508db67dbc Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 15:49:21 +0200 Subject: [PATCH 63/91] [CD] Deploy to GitHub pages workflow --- .github/workflows/deploy_pages.yml | 53 ++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/deploy_pages.yml diff --git a/.github/workflows/deploy_pages.yml b/.github/workflows/deploy_pages.yml new file mode 100644 index 0000000..6e40e4f --- /dev/null +++ b/.github/workflows/deploy_pages.yml @@ -0,0 +1,53 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy static content to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: + - master + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + - name: Setup NodeJs + uses: actions/setup-node@v4 + - name: Install dependencies + run: | + npm install + - name: Build + run: | + npm run build + - name: Setup Pages + uses: actions/configure-pages@v2 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + # Upload entire repository + path: "dist" + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 From ed280450da94f8d2e1c0325f418dd0c5319bbb1a Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 15:51:03 +0200 Subject: [PATCH 64/91] [CD] Add upload release asset workflow --- .github/workflows/upload_to_release.yml | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/upload_to_release.yml diff --git a/.github/workflows/upload_to_release.yml b/.github/workflows/upload_to_release.yml new file mode 100644 index 0000000..e6ada6d --- /dev/null +++ b/.github/workflows/upload_to_release.yml @@ -0,0 +1,35 @@ +name: Build dist for release + +on: + push: + branches: + - master + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup NodeJs + uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Build the distribution + run: npm run build:dev + + - name: Upload release asset + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./dist + asset_name: dist + asset_content_type: application/zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c299ae6b814e0fb361b9ee9c9a65adffe3de1999 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 16:41:41 +0200 Subject: [PATCH 65/91] [CI] Apply base setup for distribution tests (GH-77) --- .github/workflows/run_selenium.yml | 36 ++++++++++++++++++++ requirements.txt | 23 +++++++++++++ tests/list_view_test.py | 54 ++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 .github/workflows/run_selenium.yml create mode 100644 requirements.txt create mode 100644 tests/list_view_test.py diff --git a/.github/workflows/run_selenium.yml b/.github/workflows/run_selenium.yml new file mode 100644 index 0000000..e2ddc71 --- /dev/null +++ b/.github/workflows/run_selenium.yml @@ -0,0 +1,36 @@ +name: Test project code + +on: + pull_request: + branches: + - master + - devel + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + + - name: Setup NodeJs + uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + npm install + pip install -r requirements.txt + + - name: Build the dist + run: npm run build:dev + + - name: Test distribution with Selenium + run: pytest diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4f5e296 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,23 @@ +attrs==23.2.0 +certifi==2023.11.17 +cffi==1.16.0 +chromedriver-autoinstaller==0.6.3 +colorama==0.4.6 +exceptiongroup==1.2.0 +h11==0.14.0 +idna==3.6 +iniconfig==2.0.0 +outcome==1.3.0.post0 +packaging==23.2 +pluggy==1.3.0 +pycparser==2.21 +PySocks==1.7.1 +pytest==7.4.4 +selenium==4.16.0 +sniffio==1.3.0 +sortedcontainers==2.4.0 +tomli==2.0.1 +trio==0.24.0 +trio-websocket==0.11.1 +urllib3==2.1.0 +wsproto==1.2.0 diff --git a/tests/list_view_test.py b/tests/list_view_test.py new file mode 100644 index 0000000..3060cb7 --- /dev/null +++ b/tests/list_view_test.py @@ -0,0 +1,54 @@ +import http.server +import os +import threading +import unittest +from pathlib import Path + +from selenium import webdriver +from selenium.webdriver.common.by import By + +DIST_DIR = Path(__file__).resolve().parent.parent.joinpath("dist") +ARTICLES_DIR = DIST_DIR.joinpath("articles") +HTTPD_PORT = 8000 + + +class TestListView(unittest.TestCase): + browser: webdriver.Chrome + + @staticmethod + def start_httpd(port: int = HTTPD_PORT): + os.chdir(ARTICLES_DIR) + handler = http.server.SimpleHTTPRequestHandler + # noinspection PyTypeChecker + httpd = http.server.HTTPServer(("", port), handler) + httpd.serve_forever() + + @classmethod + def setUpClass(cls): + httpd = threading.Thread(target=cls.start_httpd, daemon=True) + httpd.start() + + options = webdriver.ChromeOptions() + options.add_argument("--headless") + cls.browser = webdriver.Chrome(options=options) + + @classmethod + def tearDownClass(cls): + cls.browser.quit() + + def test_distribution_exists(self): + dist = ARTICLES_DIR / "article_list.html" + self.assertTrue(dist.exists()) + + def setUp(self): + self.browser.get(f"http://localhost:{HTTPD_PORT}/article_list.html") + self.browser.implicitly_wait(0.5) + + def test_title(self): + element = self.browser.find_element(By.CSS_SELECTOR, "div.h4") + self.assertIsNotNone(element) + self.assertEqual(element.text, "Articles") + + +if __name__ == "__main__": + unittest.main() From dfbafe93e26b70812842ece9bdcce8bdd7aa0d59 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 16:48:05 +0200 Subject: [PATCH 66/91] [CI] Apply base setup for distribution tests (fixes GH-77) --- .github/workflows/run_js_tests.yml | 2 +- .github/workflows/run_selenium.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_js_tests.yml b/.github/workflows/run_js_tests.yml index 2883ba6..3ce1150 100644 --- a/.github/workflows/run_js_tests.yml +++ b/.github/workflows/run_js_tests.yml @@ -1,4 +1,4 @@ -name: Test project code +name: Test custom JavaScript on: pull_request: diff --git a/.github/workflows/run_selenium.yml b/.github/workflows/run_selenium.yml index e2ddc71..95587a0 100644 --- a/.github/workflows/run_selenium.yml +++ b/.github/workflows/run_selenium.yml @@ -1,4 +1,4 @@ -name: Test project code +name: Test distribution with Selenium on: pull_request: From bb9ebd7dc9e193bd8374906d1fbc9b50f1eb6703 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 16:51:55 +0200 Subject: [PATCH 67/91] Update gitignore patterns --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index ee3d015..d7cc390 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ /venv/ /env/ +# python byte-compiled +__pycache__ + # distribution bundles directories /dist/ From 3e6ff90d147012e9c5bcca062a9653788a4d6c0b Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 17:20:56 +0200 Subject: [PATCH 68/91] Add list view dist tests - fixes GH-82 - fixes GH-83 - fixes GH-84 --- src/views/partials/list_main.hbs | 2 +- tests/list_view_test.py | 38 +++++++++++++++++++++++++------- webpack.config.js | 2 +- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/views/partials/list_main.hbs b/src/views/partials/list_main.hbs index b329e21..38346c8 100644 --- a/src/views/partials/list_main.hbs +++ b/src/views/partials/list_main.hbs @@ -1,7 +1,7 @@
Articles
+ data-masonry='{"percentPosition": true}'> {{>list_article ArticleTitle="To some, a cow is a tantra for hurting" ArticleAuthor="Wilcome Brownlock" diff --git a/tests/list_view_test.py b/tests/list_view_test.py index 3060cb7..ea46a89 100644 --- a/tests/list_view_test.py +++ b/tests/list_view_test.py @@ -1,4 +1,10 @@ +""" +Test articles list template (development distribution) + +""" + import http.server +import json import os import threading import unittest @@ -7,8 +13,7 @@ from selenium import webdriver from selenium.webdriver.common.by import By -DIST_DIR = Path(__file__).resolve().parent.parent.joinpath("dist") -ARTICLES_DIR = DIST_DIR.joinpath("articles") +DIST_DIR = Path(__file__).resolve().parent.parent.joinpath("dist", "articles") HTTPD_PORT = 8000 @@ -17,7 +22,7 @@ class TestListView(unittest.TestCase): @staticmethod def start_httpd(port: int = HTTPD_PORT): - os.chdir(ARTICLES_DIR) + os.chdir(DIST_DIR) handler = http.server.SimpleHTTPRequestHandler # noinspection PyTypeChecker httpd = http.server.HTTPServer(("", port), handler) @@ -36,19 +41,36 @@ def setUpClass(cls): def tearDownClass(cls): cls.browser.quit() - def test_distribution_exists(self): - dist = ARTICLES_DIR / "article_list.html" - self.assertTrue(dist.exists()) - def setUp(self): self.browser.get(f"http://localhost:{HTTPD_PORT}/article_list.html") self.browser.implicitly_wait(0.5) + def test_distribution_exists(self): + dist = DIST_DIR / "article_list.html" + self.assertTrue(dist.exists()) + def test_title(self): - element = self.browser.find_element(By.CSS_SELECTOR, "div.h4") + selector = "div.h4[role=heading]" + element = self.browser.find_element(By.CSS_SELECTOR, selector) self.assertIsNotNone(element) self.assertEqual(element.text, "Articles") + def test_articles_block(self): + element = self.browser.find_element(By.ID, "articlesContainer") + self.assertIsNotNone(element) + self.assertIn("col", element.get_attribute("class")) + + def test_masonry_applied(self): + element = self.browser.find_element(By.ID, "articlesContainer") + section = element.find_element(By.TAG_NAME, "section") + self.assertIsNotNone(section) + masonry = json.loads(section.get_attribute("data-masonry")) + self.assertDictEqual(masonry, {"percentPosition": True}) + + def test_articles_count(self): + articles = self.browser.find_elements(By.TAG_NAME, "article") + self.assertEqual(len(articles), 8) + if __name__ == "__main__": unittest.main() diff --git a/webpack.config.js b/webpack.config.js index dbb4bd8..e5b10c4 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -25,7 +25,7 @@ module.exports = { }, devServer: { static: path.resolve(__dirname, "dist"), - port: 8000, + port: 3000, hot: true }, plugins: [ From da0b1f3afea1880754ab769ab984ee775e82b2b3 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 17:49:10 +0200 Subject: [PATCH 69/91] Add pagination section to list view (fixes GH-50) --- src/views/partials/list_main.hbs | 15 +++++++++++- tests/list_view_test.py | 39 +++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/views/partials/list_main.hbs b/src/views/partials/list_main.hbs index 38346c8..94ecc49 100644 --- a/src/views/partials/list_main.hbs +++ b/src/views/partials/list_main.hbs @@ -1,6 +1,6 @@
Articles
-
{{>list_article ArticleTitle="To some, a cow is a tantra for hurting" @@ -78,4 +78,17 @@ ArticleDate="August 27, 2023" }}
+
+ +
diff --git a/tests/list_view_test.py b/tests/list_view_test.py index ea46a89..b9c45c8 100644 --- a/tests/list_view_test.py +++ b/tests/list_view_test.py @@ -60,17 +60,44 @@ def test_articles_block(self): self.assertIsNotNone(element) self.assertIn("col", element.get_attribute("class")) + def test_sections(self): + elements = self.browser.find_elements(By.TAG_NAME, "section") + self.assertEqual(len(elements), 2) + articles, pagination = elements + self.assertEqual("ArticlesList", articles.get_attribute("aria-label")) + self.assertIn("row", articles.get_attribute("class")) + self.assertIn("row-cols-1", articles.get_attribute("class")) + self.assertEqual("Pagination", pagination.get_attribute("aria-label")) + self.assertIn("row", pagination.get_attribute("class")) + self.assertIn("row-cols-1", pagination.get_attribute("class")) + def test_masonry_applied(self): - element = self.browser.find_element(By.ID, "articlesContainer") - section = element.find_element(By.TAG_NAME, "section") - self.assertIsNotNone(section) - masonry = json.loads(section.get_attribute("data-masonry")) + selector = "#articlesContainer section:first-of-type" + element = self.browser.find_element(By.CSS_SELECTOR, selector) + masonry = json.loads(element.get_attribute("data-masonry")) self.assertDictEqual(masonry, {"percentPosition": True}) - def test_articles_count(self): - articles = self.browser.find_elements(By.TAG_NAME, "article") + def test_articles(self): + selector = "#articlesContainer section:first-of-type" + container = self.browser.find_element(By.CSS_SELECTOR, selector) + articles = container.find_elements(By.TAG_NAME, "article") self.assertEqual(len(articles), 8) + def test_pagination(self): + selector = "#articlesContainer section:last-of-type" + container = self.browser.find_element(By.CSS_SELECTOR, selector) + + nav = container.find_element(By.TAG_NAME, "nav") + self.assertIn("justify-content-center", nav.get_attribute("class")) + + ul = nav.find_element(By.TAG_NAME, "ul") + self.assertIn("pagination", ul.get_attribute("class")) + + for li in ul.find_elements(By.TAG_NAME, "li"): + self.assertIn("page-item", li.get_attribute("class")) + a = li.find_element(By.TAG_NAME, "a") + self.assertIn("page-link", a.get_attribute("class")) + if __name__ == "__main__": unittest.main() From 54979e7018357da34faf0861c1655f12da05f646 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 18:11:37 +0200 Subject: [PATCH 70/91] Separate distribution content tests --- tests/list_view_test.py | 4 --- tests/test_dist.py | 73 +++++++++++++++++++++++++++++++++++++++++ webpack.dev.config.js | 2 +- 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 tests/test_dist.py diff --git a/tests/list_view_test.py b/tests/list_view_test.py index b9c45c8..4e01c1b 100644 --- a/tests/list_view_test.py +++ b/tests/list_view_test.py @@ -45,10 +45,6 @@ def setUp(self): self.browser.get(f"http://localhost:{HTTPD_PORT}/article_list.html") self.browser.implicitly_wait(0.5) - def test_distribution_exists(self): - dist = DIST_DIR / "article_list.html" - self.assertTrue(dist.exists()) - def test_title(self): selector = "div.h4[role=heading]" element = self.browser.find_element(By.CSS_SELECTOR, selector) diff --git a/tests/test_dist.py b/tests/test_dist.py new file mode 100644 index 0000000..ced2b0e --- /dev/null +++ b/tests/test_dist.py @@ -0,0 +1,73 @@ +""" +Test distribution contents + +""" + +import unittest +from pathlib import Path + + +class TestDistContents(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.dist = Path(__file__).resolve().parent.parent.joinpath("dist") + + def test_images(self): + img_dir = self.dist / "static" / "img" + self.assertTrue(img_dir.joinpath("favicon.svg").exists()) + self.assertTrue(img_dir.joinpath("favicon.svg").is_file()) + self.assertTrue(img_dir.joinpath("favicon.png").exists()) + self.assertTrue(img_dir.joinpath("favicon.png").is_file()) + self.assertTrue(img_dir.joinpath("anonymous.svg").exists()) + self.assertTrue(img_dir.joinpath("anonymous.svg").is_file()) + self.assertTrue(img_dir.joinpath("logo.svg").exists()) + self.assertTrue(img_dir.joinpath("logo.svg").is_file()) + + def test_css(self): + css_dir = self.dist / "static" / "css" + self.assertTrue(css_dir.joinpath("main.css").exists()) + self.assertTrue(css_dir.joinpath("main.css").is_file()) + + def test_js(self): + js_dir = self.dist / "static" / "js" + self.assertTrue(js_dir.joinpath("main.bundle.js").exists()) + self.assertTrue(js_dir.joinpath("main.bundle.js").is_file()) + + def test_articles(self): + templates_dir = self.dist / "articles" + self.assertTrue(templates_dir.joinpath("article_list.html").exists()) + self.assertTrue(templates_dir.joinpath("article_list.html").is_file()) + self.assertTrue(templates_dir.joinpath("article_detail.html").exists()) + self.assertTrue(templates_dir.joinpath("article_detail.html").is_file()) + self.assertTrue(templates_dir.joinpath("article_form.html").exists()) + self.assertTrue(templates_dir.joinpath("article_form.html").is_file()) + + def test_users(self): + templates_dir = self.dist / "users" + self.assertTrue(templates_dir.joinpath("profile.html").exists()) + self.assertTrue(templates_dir.joinpath("profile.html").is_file()) + + def test_auth(self): + templates_dir = self.dist / "auth" + self.assertTrue(templates_dir.joinpath("signin_form.html").exists()) + self.assertTrue(templates_dir.joinpath("signin_form.html").is_file()) + self.assertTrue(templates_dir.joinpath("signup_form.html").exists()) + self.assertTrue(templates_dir.joinpath("signup_form.html").is_file()) + + def test_sidebars(self): + templates_dir = self.dist / "_sidebars" + + self.assertTrue(templates_dir.joinpath("authenticated.html").exists()) + self.assertTrue(templates_dir.joinpath("authenticated.html").is_file()) + self.assertTrue(templates_dir.joinpath("can_comment.html").exists()) + self.assertTrue(templates_dir.joinpath("can_comment.html").is_file()) + self.assertTrue(templates_dir.joinpath("can_edit.html").exists()) + self.assertTrue(templates_dir.joinpath("can_edit.html").is_file()) + self.assertTrue(templates_dir.joinpath("create_view.html").exists()) + self.assertTrue(templates_dir.joinpath("create_view.html").is_file()) + self.assertTrue(templates_dir.joinpath("anonymous.html").exists()) + self.assertTrue(templates_dir.joinpath("anonymous.html").is_file()) + + +if __name__ == "__main__": + unittest.main() diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 197938f..cbc2e6b 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -38,7 +38,7 @@ module.exports = { }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), - filename: "_sidebars/non-authenticated.html", + filename: "_sidebars/anonymous.html", }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), From bfb093470711edfec3e2f1d8442c0e92bee48450 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 18:15:28 +0200 Subject: [PATCH 71/91] Update distribution content tests --- tests/test_dist.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/test_dist.py b/tests/test_dist.py index ced2b0e..ffd9fe4 100644 --- a/tests/test_dist.py +++ b/tests/test_dist.py @@ -33,6 +33,24 @@ def test_js(self): self.assertTrue(js_dir.joinpath("main.bundle.js").exists()) self.assertTrue(js_dir.joinpath("main.bundle.js").is_file()) + def test_base_html(self): + self.assertTrue(self.dist.joinpath("base.html").exists()) + self.assertTrue(self.dist.joinpath("base.html").is_file()) + + def test_sidebars(self): + templates_dir = self.dist / "_sidebars" + + self.assertTrue(templates_dir.joinpath("authenticated.html").exists()) + self.assertTrue(templates_dir.joinpath("authenticated.html").is_file()) + self.assertTrue(templates_dir.joinpath("can_comment.html").exists()) + self.assertTrue(templates_dir.joinpath("can_comment.html").is_file()) + self.assertTrue(templates_dir.joinpath("can_edit.html").exists()) + self.assertTrue(templates_dir.joinpath("can_edit.html").is_file()) + self.assertTrue(templates_dir.joinpath("create_view.html").exists()) + self.assertTrue(templates_dir.joinpath("create_view.html").is_file()) + self.assertTrue(templates_dir.joinpath("anonymous.html").exists()) + self.assertTrue(templates_dir.joinpath("anonymous.html").is_file()) + def test_articles(self): templates_dir = self.dist / "articles" self.assertTrue(templates_dir.joinpath("article_list.html").exists()) @@ -54,20 +72,6 @@ def test_auth(self): self.assertTrue(templates_dir.joinpath("signup_form.html").exists()) self.assertTrue(templates_dir.joinpath("signup_form.html").is_file()) - def test_sidebars(self): - templates_dir = self.dist / "_sidebars" - - self.assertTrue(templates_dir.joinpath("authenticated.html").exists()) - self.assertTrue(templates_dir.joinpath("authenticated.html").is_file()) - self.assertTrue(templates_dir.joinpath("can_comment.html").exists()) - self.assertTrue(templates_dir.joinpath("can_comment.html").is_file()) - self.assertTrue(templates_dir.joinpath("can_edit.html").exists()) - self.assertTrue(templates_dir.joinpath("can_edit.html").is_file()) - self.assertTrue(templates_dir.joinpath("create_view.html").exists()) - self.assertTrue(templates_dir.joinpath("create_view.html").is_file()) - self.assertTrue(templates_dir.joinpath("anonymous.html").exists()) - self.assertTrue(templates_dir.joinpath("anonymous.html").is_file()) - if __name__ == "__main__": unittest.main() From 14f2ddb1ffecbd88ad66c81637eb038a88a9623b Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 19:01:55 +0200 Subject: [PATCH 72/91] Add article detail content tests --- src/views/partials/detail_main.hbs | 4 +- tests/detail_view_test.py | 68 ++++++++++++++++++++++++++++++ webpack.dev.config.js | 1 + 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 tests/detail_view_test.py diff --git a/src/views/partials/detail_main.hbs b/src/views/partials/detail_main.hbs index 62b36ec..df9ecde 100644 --- a/src/views/partials/detail_main.hbs +++ b/src/views/partials/detail_main.hbs @@ -2,12 +2,12 @@

{{article.title}}

-
+
Published on {{article.published}} by
-
    +
      {{#each article.topics }}
    • {{this}}
    • {{/each}} diff --git a/tests/detail_view_test.py b/tests/detail_view_test.py new file mode 100644 index 0000000..414baad --- /dev/null +++ b/tests/detail_view_test.py @@ -0,0 +1,68 @@ +""" +Test articles list template (development distribution) + +""" + +import http.server +import os +import threading +import unittest +from pathlib import Path + +from selenium import webdriver +from selenium.webdriver.common.by import By + +DIST_DIR = Path(__file__).resolve().parent.parent.joinpath("dist", "articles") +HTTPD_PORT = 8000 + + +class TestListView(unittest.TestCase): + browser: webdriver.Chrome + + @staticmethod + def start_httpd(port: int = HTTPD_PORT): + os.chdir(DIST_DIR) + handler = http.server.SimpleHTTPRequestHandler + # noinspection PyTypeChecker + httpd = http.server.HTTPServer(("", port), handler) + httpd.serve_forever() + + @classmethod + def setUpClass(cls): + httpd = threading.Thread(target=cls.start_httpd, daemon=True) + httpd.start() + + options = webdriver.ChromeOptions() + options.add_argument("--headless") + cls.browser = webdriver.Chrome(options=options) + + @classmethod + def tearDownClass(cls): + cls.browser.quit() + + def setUp(self): + self.browser.get(f"http://localhost:{HTTPD_PORT}/article_detail.html") + self.browser.implicitly_wait(0.5) + + def test_title(self): + element = self.browser.find_element(By.TAG_NAME, "h1") + self.assertIn("text-center", element.get_attribute("class")) + title = ("Ship-wide, carnivorous crews impressively deserve " + "an extraterrestrial, devastated ferengi") + self.assertEqual(element.text, title) + + def test_data_section(self): + selector = "section[aria-label=ArticleData]" + element = self.browser.find_element(By.CSS_SELECTOR, selector) + self.assertIn("flex-row", element.get_attribute("class")) + + def test_topics(self): + selector = "ul[aria-label=ArticleTopics" + element = self.browser.find_element(By.CSS_SELECTOR, selector) + self.assertIn("flex-row", element.get_attribute("class")) + topics = element.find_elements(By.TAG_NAME, "li") + self.assertEqual(len(topics), 3) + + +if __name__ == "__main__": + unittest.main() diff --git a/webpack.dev.config.js b/webpack.dev.config.js index cbc2e6b..76099ec 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -76,6 +76,7 @@ module.exports = { templateParameters: { ...globals.templateParametersDevelopment, navs: globals.refs.navs, + article: globals.article, } }), new HTMLWebpackPlugin({ From 2aee1c08966edb2f6cd6a16356e784aa7231199e Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 19:07:31 +0200 Subject: [PATCH 73/91] Add tests helper module to reduce code duplication --- tests/_helpers.py | 36 ++++++++++++++++++++++++++++++++++++ tests/detail_view_test.py | 32 ++------------------------------ tests/list_view_test.py | 32 ++------------------------------ 3 files changed, 40 insertions(+), 60 deletions(-) create mode 100644 tests/_helpers.py diff --git a/tests/_helpers.py b/tests/_helpers.py new file mode 100644 index 0000000..a98aa31 --- /dev/null +++ b/tests/_helpers.py @@ -0,0 +1,36 @@ +import http.server +import os +import threading +import unittest +from pathlib import Path + +from selenium import webdriver + +HTTPD_PORT = 8000 +DIST_DIR = Path(__file__).resolve().parent.parent / "dist" + + +class TestArticlesHelper(unittest.TestCase): + browser: webdriver.Chrome + dist: Path = DIST_DIR / "articles" + + @classmethod + def start_httpd(cls, port: int = HTTPD_PORT): + os.chdir(cls.dist) + handler = http.server.SimpleHTTPRequestHandler + # noinspection PyTypeChecker + httpd = http.server.HTTPServer(("", port), handler) + httpd.serve_forever() + + @classmethod + def setUpClass(cls): + httpd = threading.Thread(target=cls.start_httpd, daemon=True) + httpd.start() + + options = webdriver.ChromeOptions() + options.add_argument("--headless") + cls.browser = webdriver.Chrome(options=options) + + @classmethod + def tearDownClass(cls): + cls.browser.quit() diff --git a/tests/detail_view_test.py b/tests/detail_view_test.py index 414baad..349ea70 100644 --- a/tests/detail_view_test.py +++ b/tests/detail_view_test.py @@ -3,42 +3,14 @@ """ -import http.server -import os -import threading import unittest -from pathlib import Path -from selenium import webdriver from selenium.webdriver.common.by import By -DIST_DIR = Path(__file__).resolve().parent.parent.joinpath("dist", "articles") -HTTPD_PORT = 8000 +from _helpers import HTTPD_PORT, TestArticlesHelper -class TestListView(unittest.TestCase): - browser: webdriver.Chrome - - @staticmethod - def start_httpd(port: int = HTTPD_PORT): - os.chdir(DIST_DIR) - handler = http.server.SimpleHTTPRequestHandler - # noinspection PyTypeChecker - httpd = http.server.HTTPServer(("", port), handler) - httpd.serve_forever() - - @classmethod - def setUpClass(cls): - httpd = threading.Thread(target=cls.start_httpd, daemon=True) - httpd.start() - - options = webdriver.ChromeOptions() - options.add_argument("--headless") - cls.browser = webdriver.Chrome(options=options) - - @classmethod - def tearDownClass(cls): - cls.browser.quit() +class TestListView(TestArticlesHelper): def setUp(self): self.browser.get(f"http://localhost:{HTTPD_PORT}/article_detail.html") diff --git a/tests/list_view_test.py b/tests/list_view_test.py index 4e01c1b..9996191 100644 --- a/tests/list_view_test.py +++ b/tests/list_view_test.py @@ -3,43 +3,15 @@ """ -import http.server import json -import os -import threading import unittest -from pathlib import Path -from selenium import webdriver from selenium.webdriver.common.by import By -DIST_DIR = Path(__file__).resolve().parent.parent.joinpath("dist", "articles") -HTTPD_PORT = 8000 +from _helpers import HTTPD_PORT, TestArticlesHelper -class TestListView(unittest.TestCase): - browser: webdriver.Chrome - - @staticmethod - def start_httpd(port: int = HTTPD_PORT): - os.chdir(DIST_DIR) - handler = http.server.SimpleHTTPRequestHandler - # noinspection PyTypeChecker - httpd = http.server.HTTPServer(("", port), handler) - httpd.serve_forever() - - @classmethod - def setUpClass(cls): - httpd = threading.Thread(target=cls.start_httpd, daemon=True) - httpd.start() - - options = webdriver.ChromeOptions() - options.add_argument("--headless") - cls.browser = webdriver.Chrome(options=options) - - @classmethod - def tearDownClass(cls): - cls.browser.quit() +class TestListView(TestArticlesHelper): def setUp(self): self.browser.get(f"http://localhost:{HTTPD_PORT}/article_list.html") From 32111c642daf41c86ee2ee515e5d97f394b544f3 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 19:13:54 +0200 Subject: [PATCH 74/91] Update detail view test name --- tests/detail_view_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/detail_view_test.py b/tests/detail_view_test.py index 349ea70..0bf2bc9 100644 --- a/tests/detail_view_test.py +++ b/tests/detail_view_test.py @@ -10,7 +10,7 @@ from _helpers import HTTPD_PORT, TestArticlesHelper -class TestListView(TestArticlesHelper): +class TestDetailView(TestArticlesHelper): def setUp(self): self.browser.get(f"http://localhost:{HTTPD_PORT}/article_detail.html") From bbc6a8bbdff831f1589ee50757a7f1dfae525e07 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 19:32:40 +0200 Subject: [PATCH 75/91] [CD] Update asset upload on release workflow (fixes GH-53) --- .github/workflows/upload_to_release.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/upload_to_release.yml b/.github/workflows/upload_to_release.yml index e6ada6d..5e19866 100644 --- a/.github/workflows/upload_to_release.yml +++ b/.github/workflows/upload_to_release.yml @@ -1,9 +1,9 @@ name: Build dist for release on: - push: - branches: - - master + release: + types: + - published jobs: deploy: @@ -24,12 +24,15 @@ jobs: - name: Build the distribution run: npm run build:dev + - name: Create dist archive + run: zip -r dist.zip ./dist + - name: Upload release asset uses: actions/upload-release-asset@v1 with: upload_url: ${{ github.event.release.upload_url }} - asset_path: ./dist - asset_name: dist + asset_path: ./dist.zip + asset_name: dist.zip asset_content_type: application/zip env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 3196e740c8612b5548b0a600a1a79a8a1f56d336 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 19:54:18 +0200 Subject: [PATCH 76/91] [CD] Update deploy to pages workflow configuration --- .github/workflows/deploy_pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy_pages.yml b/.github/workflows/deploy_pages.yml index 6e40e4f..ea7745b 100644 --- a/.github/workflows/deploy_pages.yml +++ b/.github/workflows/deploy_pages.yml @@ -46,7 +46,7 @@ jobs: - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: - # Upload entire repository + # Upload distribution directory path: "dist" - name: Deploy to GitHub Pages id: deployment From f916dfdeda240e38b0d9988073d6cd164ab1edd9 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 22:00:59 +0200 Subject: [PATCH 77/91] Update sidebar template condition name (create_view -> can_create) for consistency reasons --- src/js/sidebar.js | 9 +++++---- src/views/form_view.hbs | 2 +- src/views/partials/_sidebar.hbs | 4 ++-- webpack.dev.config.js | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/js/sidebar.js b/src/js/sidebar.js index 8b74c64..e537b16 100644 --- a/src/js/sidebar.js +++ b/src/js/sidebar.js @@ -2,8 +2,9 @@ const createArticleBtn = document.getElementById("createArticleBtn") const articleForm = document.getElementById("articleForm") if (createArticleBtn && articleForm) { - createArticleBtn.addEventListener("click", () => articleForm.submit()) -} -if (createArticleBtn && !articleForm) { - createArticleBtn.addEventListener("click", () => window.location.href = "/form.html") + createArticleBtn.addEventListener("click", event => { + event.preventDefault() + event.stopPropagation() + articleForm.submit() + }) } diff --git a/src/views/form_view.hbs b/src/views/form_view.hbs index d4e70c1..62862a2 100644 --- a/src/views/form_view.hbs +++ b/src/views/form_view.hbs @@ -15,7 +15,7 @@
      {{>partials/form_main}} - {{>partials/_sidebar authenticated=user create_view=true}} + {{>partials/_sidebar authenticated=user can_create=true}}
      diff --git a/src/views/partials/_sidebar.hbs b/src/views/partials/_sidebar.hbs index ab7e5f8..00e6293 100644 --- a/src/views/partials/_sidebar.hbs +++ b/src/views/partials/_sidebar.hbs @@ -23,8 +23,8 @@ data-bs-toggle="modal" data-bs-target="#modalArticleComment">comment {{/if}} - - {{#if create_view}} + create article + {{#if can_create}} cancel {{/if}} {{#if can_edit}} diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 76099ec..53efa8b 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -19,7 +19,7 @@ const globals = require("./blog/globals") const sidebar_authenticated = {user:globals.user, authenticated:true} const sidebar_can_comment = {...sidebar_authenticated, can_comment:true} const sidebar_can_edit = {...sidebar_authenticated, can_edit:true} -const sidebar_create_view = {...sidebar_authenticated, create_view:true} +const sidebar_can_create = {...sidebar_authenticated, can_create:true} module.exports = { ...baseConfig, @@ -58,7 +58,7 @@ module.exports = { new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), filename: "_sidebars/create_view.html", - templateParameters: {...sidebar_create_view} + templateParameters: {...sidebar_can_create} }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/list_main.hbs"), From fde7ba0ea587afcf0f25078f3a599ab9d2d987b7 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Sun, 14 Jan 2024 22:28:07 +0200 Subject: [PATCH 78/91] Add ids to sidebar buttons elements --- src/views/partials/_sidebar.hbs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/views/partials/_sidebar.hbs b/src/views/partials/_sidebar.hbs index 00e6293..0cf76ae 100644 --- a/src/views/partials/_sidebar.hbs +++ b/src/views/partials/_sidebar.hbs @@ -19,25 +19,25 @@ {{#if authenticated }}
      {{#if can_comment}} - {{/if}} create article {{#if can_create}} - cancel + cancel {{/if}} {{#if can_edit}} - update article - {{/if}}
      {{else}} {{/if}}
From 6c5efd15a74f8310aa85b10c3d8eb24ce4e3cf9a Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Mon, 15 Jan 2024 00:35:56 +0200 Subject: [PATCH 79/91] Update project description (fixes GH-30) --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1ca477..d309938 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,56 @@ DJANGO BLOG - BOOTSTRAP TEMPLATES ================================= +[![](https://github.com/edu-python-course/blog-bootstrap/actions/workflows/deploy_pages.yml/badge.svg)](https://edu-python-course.github.io/blog-bootstrap) +![](https://github.com/edu-python-course/blog-bootstrap/actions/workflows/test_webpack_builds.yml/badge.svg) +![](https://github.com/edu-python-course/blog-bootstrap/actions/workflows/run_selenium.yml/badge.svg) + This repo contains Bootstrap5 templates for the main training project, and itself is a supporting subproject. Getting started --------------- -[//]: # (TODO: GH-30) +For those who want to use the templates provided in this repository - +the shortest way is to check the +[release page](https://github.com/edu-python-course/blog-bootstrap/releases). +Starting from `ver2.0` each release has a **dist.zip** attached to it. +There are partials for individual site parts within the archive. These are +suitable for using with template processors (like Django templates or Jinja2). + +In case you want to adjust the sources before build: + +1. Clone the repo to your local machine +2. Install project dependencies: `npm install` +3. Build templates: `npm run build` + - to build the developer's version: `npm run build:dev` Contents -------- -[//]: # (TODO: GH-30) +### Production vs Development bundles + +Production bundle is aimed to be served via GitHub pages. It's main purpose is +the site demonstration. + +The development bundle is for usage with other projects (Django, Flask etc.). + +Both production and development distributions bundle the JS code into a single +file. The same is for CSS. The only difference is the output distribution +structure. + +### Sources + +All the source are located within **src** directory. + +`index.js` file is the entry point for the `webpack`. All resources required +by webpack are to be imported here. + +`scss` directory contains individual styles used by various templates. + +`js` directory contains custom JavaScript modules used within the project. + +`views` directory contains templates for the HTML pages. References ---------- From 2bcc255709abf8f0232e099253eca02a9fc0828d Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Mon, 15 Jan 2024 00:57:45 +0200 Subject: [PATCH 80/91] Add static content page source (fixes GH-46) --- src/views/about_view.hbs | 91 ++++++++++++++++++++++++++++++++++++++++ webpack.config.js | 9 ++++ webpack.dev.config.js | 12 ++++-- 3 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/views/about_view.hbs diff --git a/src/views/about_view.hbs b/src/views/about_view.hbs new file mode 100644 index 0000000..eaedb16 --- /dev/null +++ b/src/views/about_view.hbs @@ -0,0 +1,91 @@ + + + + + + + + + + {{title}} | Blog Site + + +{{>partials/_header}} +
+
+
+
+
+

About Our Website

+

+ Welcome to our website! We are a passionate team of web developers, data scientists, and cybersecurity + experts dedicated to creating exceptional digital experiences. Our goal is to provide you with valuable + insights, secure web solutions, and a seamless user experience. +

+
+
+
+
+

Who We Are:

+

+ We are a dynamic team of professionals with expertise in web development, data science, and cybersecurity. + Our diverse backgrounds and skill sets enable us to tackle complex challenges and deliver innovative + solutions tailored to your specific needs. We are committed to staying up-to-date with the latest industry + trends and technologies to ensure that we provide you with cutting-edge solutions. +

+

Our Commitment:

+

+ We are committed to providing you with exceptional service and solutions that exceed your expectations. We + believe in building long-term partnerships with our clients, collaborating closely to understand your unique + requirements and deliver customized solutions that address your specific challenges. +

+

+ Our team is dedicated to delivering projects on time and within budget, without compromising on quality. We + strive for excellence in every aspect of our work, ensuring that our web solutions are visually appealing, + user-friendly, and aligned with your business objectives. +

+
+
+

What We Do:

+

+ At our core, we specialize in web development, creating dynamic and user-friendly websites that captivate + audiences and drive results. Whether you need a simple informative website or a complex web application, we + have the skills and expertise to bring your vision to life. Our focus is on delivering websites that not + only look visually stunning but also provide a seamless and intuitive user experience. +

+

+ In addition to web development, we are passionate about data science. We leverage advanced analytics + techniques to extract insights from data, empowering you to make informed decisions and unlock the hidden + potential in your data. From predictive analytics to personalized recommendations, we help you harness the + power of data to drive growth and optimize your business strategies. +

+

+ As cybersecurity is a top priority in today's digital landscape, we also prioritize the security of our web + solutions. We implement robust security measures to protect your data and ensure the integrity of your web + applications. From secure authentication to encrypted communication, we employ industry best practices to + safeguard your information and provide a secure browsing experience. +

+
+
+
+
+

Get in Touch:

+

+ We would love to hear from you and discuss how we can help you achieve your web development, data science, + or cybersecurity goals. Feel free to reach out to us through the contact information provided on our + website. Our friendly team is here to answer your questions and guide you through the process of creating an + exceptional web presence. +

+

+ Thank you for visiting our website. We look forward to partnering with you and helping you + succeed in the digital world. +

+
+
+
+ {{>partials/_sidebar}} +
+
+ + diff --git a/webpack.config.js b/webpack.config.js index e5b10c4..6a53c9b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,6 +30,15 @@ module.exports = { }, plugins: [ new MiniCSSExtractPlugin({"filename": "css/main.min.css"}), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/about_view.hbs"), + filename: "about.html", + templateParameters: { + title: "About", + ...globals.templateParameters, + ...globals.refs, + } + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/list_view.hbs"), filename: globals.refs.ListView, diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 53efa8b..20e968f 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -16,10 +16,10 @@ const autoprefixer = require("autoprefixer"); const baseConfig = require("./webpack.config") const globals = require("./blog/globals") -const sidebar_authenticated = {user:globals.user, authenticated:true} -const sidebar_can_comment = {...sidebar_authenticated, can_comment:true} -const sidebar_can_edit = {...sidebar_authenticated, can_edit:true} -const sidebar_can_create = {...sidebar_authenticated, can_create:true} +const sidebar_authenticated = {user: globals.user, authenticated: true} +const sidebar_can_comment = {...sidebar_authenticated, can_comment: true} +const sidebar_can_edit = {...sidebar_authenticated, can_edit: true} +const sidebar_can_create = {...sidebar_authenticated, can_create: true} module.exports = { ...baseConfig, @@ -60,6 +60,10 @@ module.exports = { filename: "_sidebars/create_view.html", templateParameters: {...sidebar_can_create} }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/about_view.hbs"), + filename: "about.html", + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/list_main.hbs"), filename: "articles/article_list.html", From 32b73a43f8de6842de93e0545fec141c66d9cfac Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Mon, 15 Jan 2024 01:00:11 +0200 Subject: [PATCH 81/91] Update meta and add canonical reference --- src/views/_template.hbs | 2 ++ src/views/about_view.hbs | 2 ++ src/views/detail_view.hbs | 2 ++ src/views/form_view.hbs | 2 ++ src/views/list_view.hbs | 2 ++ src/views/profile_view.hbs | 2 ++ src/views/signin_view.hbs | 2 ++ src/views/signup_view.hbs | 2 ++ 8 files changed, 16 insertions(+) diff --git a/src/views/_template.hbs b/src/views/_template.hbs index ffb6170..ebc1865 100644 --- a/src/views/_template.hbs +++ b/src/views/_template.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/about_view.hbs b/src/views/about_view.hbs index eaedb16..54ed3b2 100644 --- a/src/views/about_view.hbs +++ b/src/views/about_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/detail_view.hbs b/src/views/detail_view.hbs index f89a769..58913fa 100644 --- a/src/views/detail_view.hbs +++ b/src/views/detail_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/form_view.hbs b/src/views/form_view.hbs index 62862a2..9f9f964 100644 --- a/src/views/form_view.hbs +++ b/src/views/form_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/list_view.hbs b/src/views/list_view.hbs index 7fadc38..94908bb 100644 --- a/src/views/list_view.hbs +++ b/src/views/list_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/profile_view.hbs b/src/views/profile_view.hbs index cf3ebaf..806e307 100644 --- a/src/views/profile_view.hbs +++ b/src/views/profile_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/signin_view.hbs b/src/views/signin_view.hbs index fc37bbc..42c1958 100644 --- a/src/views/signin_view.hbs +++ b/src/views/signin_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site diff --git a/src/views/signup_view.hbs b/src/views/signup_view.hbs index f98ba52..aa2e7c6 100644 --- a/src/views/signup_view.hbs +++ b/src/views/signup_view.hbs @@ -6,8 +6,10 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + {{title}} | Blog Site From 9f8f926415e16d74d3128a0853329044cbdb119a Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Mon, 15 Jan 2024 07:00:54 +0200 Subject: [PATCH 82/91] Update upload dist to release workflow configuration --- .github/workflows/upload_to_release.yml | 51 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/.github/workflows/upload_to_release.yml b/.github/workflows/upload_to_release.yml index 5e19866..c1b8270 100644 --- a/.github/workflows/upload_to_release.yml +++ b/.github/workflows/upload_to_release.yml @@ -1,4 +1,4 @@ -name: Build dist for release +name: Upload distribution to release on: release: @@ -6,9 +6,56 @@ on: - published jobs: - deploy: + jest: runs-on: ubuntu-latest + steps: + - name: Checkout the code + uses: actions/checkout@v4 + + - name: Setup NodeJs + uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: Install dependencies + run: npm install + + - name: Test code with Jest + run: npm run test + + pytest: + runs-on: ubuntu-latest + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + + - name: Setup NodeJs + uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + npm install + pip install -r requirements.txt + + - name: Build the dist + run: npm run build:dev + + - name: Test distribution with Selenium + run: pytest + + upload: + runs-on: ubuntu-latest + needs: [jest, pytest] + steps: - name: Checkout uses: actions/checkout@v4 From 5d94270b01d10e759195dfa76e3e4f35045ed62a Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Mon, 15 Jan 2024 22:19:07 +0200 Subject: [PATCH 83/91] Move blog directory stuff to src (#86) --- {blog => src}/globals.js | 0 {blog => src}/helpers/topics.js | 0 tests/topics.test.js | 2 +- webpack.config.js | 4 ++-- webpack.dev.config.js | 4 ++-- 5 files changed, 5 insertions(+), 5 deletions(-) rename {blog => src}/globals.js (100%) rename {blog => src}/helpers/topics.js (100%) diff --git a/blog/globals.js b/src/globals.js similarity index 100% rename from blog/globals.js rename to src/globals.js diff --git a/blog/helpers/topics.js b/src/helpers/topics.js similarity index 100% rename from blog/helpers/topics.js rename to src/helpers/topics.js diff --git a/tests/topics.test.js b/tests/topics.test.js index 72f5b0a..e24eb70 100644 --- a/tests/topics.test.js +++ b/tests/topics.test.js @@ -1,4 +1,4 @@ -const topics = require("../blog/helpers/topics") +const topics = require("../src/helpers/topics") describe("Test topics handlebars helper", () => { it("single topic supported", () => { diff --git a/webpack.config.js b/webpack.config.js index 6a53c9b..ddc5745 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,7 +12,7 @@ const path = require("path") const autoprefixer = require("autoprefixer") const HTMLWebpackPlugin = require("html-webpack-plugin") const MiniCSSExtractPlugin = require("mini-css-extract-plugin") -const globals = require("./blog/globals") +const globals = require("./src/globals") // webpack config object // noinspection WebpackConfigHighlighting @@ -135,7 +135,7 @@ module.exports = { test: /\.hbs$/, loader: "handlebars-loader", options: { - helperDirs: path.join(__dirname, "blog/helpers"), + helperDirs: path.join(__dirname, "src/helpers"), precompileOptions: { knownHelpersOnly: false, } diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 20e968f..6f355c5 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -14,7 +14,7 @@ const MiniCSSExtractPlugin = require("mini-css-extract-plugin") const HTMLWebpackPlugin = require("html-webpack-plugin") const autoprefixer = require("autoprefixer"); const baseConfig = require("./webpack.config") -const globals = require("./blog/globals") +const globals = require("./src/globals") const sidebar_authenticated = {user: globals.user, authenticated: true} const sidebar_can_comment = {...sidebar_authenticated, can_comment: true} @@ -149,7 +149,7 @@ module.exports = { test: /\.hbs$/, loader: "handlebars-loader", options: { - helperDirs: path.join(__dirname, "blog/helpers"), + helperDirs: path.join(__dirname, "src/helpers"), precompileOptions: { knownHelpersOnly: false, } From 147546e490c120b6cea19a8eedcf17642bcb5cf4 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Tue, 16 Jan 2024 12:28:54 +0200 Subject: [PATCH 84/91] Rename helper to `iter_topics` --- src/helpers/iter_topics.js | 3 +++ src/helpers/topics.js | 3 --- src/views/partials/list_main.hbs | 16 ++++++++-------- src/views/partials/profile_main.hbs | 4 ++-- tests/topics.test.js | 10 +++++----- 5 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 src/helpers/iter_topics.js delete mode 100644 src/helpers/topics.js diff --git a/src/helpers/iter_topics.js b/src/helpers/iter_topics.js new file mode 100644 index 0000000..13708f3 --- /dev/null +++ b/src/helpers/iter_topics.js @@ -0,0 +1,3 @@ +const iter_topics = (value) => value.split(";").map(topic => topic.trim()) + +module.exports = iter_topics diff --git a/src/helpers/topics.js b/src/helpers/topics.js deleted file mode 100644 index bfe08e1..0000000 --- a/src/helpers/topics.js +++ /dev/null @@ -1,3 +0,0 @@ -const topics = (value) => value.split(";").map(topic => topic.trim()) - -module.exports = topics diff --git a/src/views/partials/list_main.hbs b/src/views/partials/list_main.hbs index 94ecc49..5d79984 100644 --- a/src/views/partials/list_main.hbs +++ b/src/views/partials/list_main.hbs @@ -7,7 +7,7 @@ ArticleAuthor="Wilcome Brownlock" ArticleContent="Afterlife doesn’t beautifully yearn any thing — but the guru is what remains. the cow feels?" - ArticleTopics=(topics "Fake latin;Pirate Lingo") + ArticleTopics=(iter_topics "Fake latin;Pirate Lingo") ArticleDate="November 3, 2022" }} {{>list_article @@ -17,7 +17,7 @@ Adventure, love, and power. The lagoon loves with desolation, hoist the freighter before it stutters. Bung holes whine with riddle! The scabbard breaks with courage, fight the galley before it stutters. moons scream with grace?" - ArticleTopics=(topics "Esoteric Wisdom") + ArticleTopics=(iter_topics "Esoteric Wisdom") ArticleDate="May 18, 2023" }} {{>list_article @@ -28,7 +28,7 @@ Honor, disconnection, and mind. Mystery at the holodeck was the plasma of paralysis, raised to an intelligent collective. Tribble of a post-apocalyptic tragedy, handle the alarm! Bare, brave queens cunningly question a strange, post-apocalyptic crew. kahlesses die with core?" - ArticleTopics=(topics "Fake latin;Science Fiction;Culinary Inspirations") + ArticleTopics=(iter_topics "Fake latin;Science Fiction;Culinary Inspirations") ArticleDate="July 7, 2024" }} {{>list_article @@ -37,14 +37,14 @@ ArticleContent="Going to the kingdom doesn’t visualize pain anymore than realizing creates hermetic manifestation. Career happens when you shape suffering so compassionately that whatsoever you are experimenting is your totality the lama loves?" - ArticleTopics=(topics "Fake latin") + ArticleTopics=(iter_topics "Fake latin") ArticleDate="February 22, 2022" }} {{>list_article ArticleTitle="Black, wet seashells calmly pull a gutless, misty whale" ArticleAuthor="Pippin Sackville-Baggins" ArticleContent="The lad commands with life, scrape the galley until it falls!" - ArticleTopics=(topics "Pirate Lingo;Esoteric Wisdom;Fake Latin") + ArticleTopics=(iter_topics "Pirate Lingo;Esoteric Wisdom;Fake Latin") ArticleDate="December 9, 2023" }} {{>list_article @@ -54,7 +54,7 @@ Combine squid, margerine and peanut butter. brush with divided rum and serve heated with cauliflower. Enjoy! Combine ghee, sausages and rhubarb. toss with tasty celery and serve cut with cabbage. Enjoy! with watermelons drink champaign?" - ArticleTopics=(topics "Culinary Inpiration") + ArticleTopics=(iter_topics "Culinary Inpiration") ArticleDate="April 15, 2024" }} {{>list_article @@ -64,7 +64,7 @@ mermaid. This shield has only been attacked by a lunar space. The strange klingon mechanically infiltrates the phenomenan. The ferengi is always devastated. The emitter is more hur'q now than planet. quirky and unearthly modern. unearthly imitate a transporter?" - ArticleTopics=(topics "Esoteric Wisdom;Pirate Lingo") + ArticleTopics=(iter_topics "Esoteric Wisdom;Pirate Lingo") ArticleDate="October 5, 2022" }} {{>list_article @@ -74,7 +74,7 @@ Scream cruelly like a scrawny jolly roger. The breeze breaks with booty, hoist the galley until it falls. Arrr, clear lass. you won't break the reef. Shiny, golden shipmates swiftly lead a cold, scurvy fish. never hail a bucaneer?" - ArticleTopics=(topics "Pirate Lingo") + ArticleTopics=(iter_topics "Pirate Lingo") ArticleDate="August 27, 2023" }}
diff --git a/src/views/partials/profile_main.hbs b/src/views/partials/profile_main.hbs index 981d28d..690b698 100644 --- a/src/views/partials/profile_main.hbs +++ b/src/views/partials/profile_main.hbs @@ -44,14 +44,14 @@ Honor, disconnection, and mind. Mystery at the holodeck was the plasma of paralysis, raised to an intelligent collective. Tribble of a post-apocalyptic tragedy, handle the alarm! Bare, brave queens cunningly question a strange, post-apocalyptic crew. kahlesses die with core?" - ArticleTopics=(topics "Fake latin;Science Fiction;Culinary Inspirations") + ArticleTopics=(iter_topics "Fake latin;Science Fiction;Culinary Inspirations") ArticleDate="July 7, 2024" }} {{>list_article ArticleTitle="Black, wet seashells calmly pull a gutless, misty whale" ArticleAuthor="Pippin Sackville-Baggins" ArticleContent="The lad commands with life, scrape the galley until it falls!" - ArticleTopics=(topics "Pirate Lingo;Esoteric Wisdom;Fake Latin") + ArticleTopics=(iter_topics "Pirate Lingo;Esoteric Wisdom;Fake Latin") ArticleDate="December 9, 2023" }}
diff --git a/tests/topics.test.js b/tests/topics.test.js index e24eb70..68fccd6 100644 --- a/tests/topics.test.js +++ b/tests/topics.test.js @@ -1,11 +1,11 @@ -const topics = require("../src/helpers/topics") +const iter_topics = require("../src/helpers/iter_topics") describe("Test topics handlebars helper", () => { it("single topic supported", () => { - expect(topics("Epos fuga")).toEqual["Epos fuga"] + expect(iter_topics("Epos fuga")).toEqual["Epos fuga"] }) it("leading and trailing spaces are trimmed for single topic", () => { - expect(topics(" Nuptia resisteres ")).toEqual(["Nuptia resisteres"]) + expect(iter_topics(" Nuptia resisteres ")).toEqual(["Nuptia resisteres"]) }); it("topics are split into array", () => { const origin = "Cur burgus mori;Ubi est secundus byssus" @@ -13,7 +13,7 @@ describe("Test topics handlebars helper", () => { "Cur burgus mori", "Ubi est secundus byssus" ] - expect(topics(origin)).toEqual(expected) + expect(iter_topics(origin)).toEqual(expected) }); it("leading and trailing spaces are removed", () => { const origin = "Festus orexis ; Diligenter tractares ; Bulla est." @@ -22,6 +22,6 @@ describe("Test topics handlebars helper", () => { "Diligenter tractares", "Bulla est." ] - expect(topics(origin)).toEqual(expected) + expect(iter_topics(origin)).toEqual(expected) }); }) From b1184764e62968e26b32e35c8a3dbd92814f6b49 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Tue, 16 Jan 2024 12:53:45 +0200 Subject: [PATCH 85/91] Add topics to global project variables --- src/globals.js | 68 +++++++++++++++++++++++++--------- src/views/partials/_header.hbs | 2 +- webpack.config.js | 1 + 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/globals.js b/src/globals.js index a14ac20..f3213f7 100644 --- a/src/globals.js +++ b/src/globals.js @@ -28,6 +28,46 @@ const user = { last_name: "Sackville-Baggins", } +// noinspection SpellCheckingInspection +const topics = [ + { + subscribed: true, + title: "Fake Latin", + description: "A falsis, idoleum teres turpis. " + + "Emeritis, audax historias sapienter reperire de barbatus, talis palus. " + + "Cum era observare, omnes nutrixes promissio velox, superbus rectores.", + link: "?query=fake-latin", + }, + { + subscribed: true, + title: "Esoteric Wisdom", + description: "Never acquire the karma, for you cannot discover it. " + + "The hypnosis of your mans will die purely when you illuminate that extend is the seeker.", + link: "?query=esoteric-wisdom", + }, + { + subscribed: true, + title: "Culinary Inspiration", + description: "Oysters taste best with olive oil and lots of wasabi. " + + "Marshmellow can be marinateed with sichuan-style walnut, also try whisking the soup with condensed milk.", + link: "?query=culinary-inspirations", + }, + { + subscribed: true, + title: "Pirate Lingo", + description: "All captains view dark, golden golds. Lord, lively gold. go to tubbataha reef. " + + "The mainland endures with grace, haul the galley before it sings.", + link: "?query=pirate-lingo", + }, + { + subscribed: true, + title: "Science Fiction", + description: "Tremble without attitude, and we won’t beam a particle. " + + "Alignment at the solar system was the stigma of nuclear flux, beamed to a brave vogon.", + link: "?query=science-fiction", + }, +] + const article = { title: "Ship-wide, carnivorous crews impressively deserve an extraterrestrial, devastated ferengi", topics: ["Fake latin", "Science Fiction", "Culinary Inspirations"], @@ -77,24 +117,15 @@ const article = { ] } -const - refs = { - AboutView: "./about.html", - ListView: "./index.html", - DetailView: "./detail.html", - FormView: "./form.html", - SignInView: "./sign-in.html", - SignUpView: "./sign-up.html", - ProfileView: "./profile.html", - - navs: [ - {link: "?query=fake-latin", title: "Fake Latin"}, - {link: "?query=esoteric-wisdom", title: "Esoteric Wisdom"}, - {link: "?query=culinary-inspirations", title: "Culinary Inspirations"}, - {link: "?query=pirate-lingo", title: "Pirate Lingo"}, - {link: "?query=science-fiction", title: "Science Fiction"}, - ], - } +const refs = { + AboutView: "./about.html", + ListView: "./index.html", + DetailView: "./detail.html", + FormView: "./form.html", + SignInView: "./sign-in.html", + SignUpView: "./sign-up.html", + ProfileView: "./profile.html", +} module.exports = { templateParametersDevelopment, @@ -102,4 +133,5 @@ module.exports = { article, user, refs, + topics, } diff --git a/src/views/partials/_header.hbs b/src/views/partials/_header.hbs index 9f835ce..608808c 100644 --- a/src/views/partials/_header.hbs +++ b/src/views/partials/_header.hbs @@ -14,7 +14,7 @@ diff --git a/src/views/partials/topics_main.hbs b/src/views/partials/topics_main.hbs new file mode 100644 index 0000000..c2fc62f --- /dev/null +++ b/src/views/partials/topics_main.hbs @@ -0,0 +1,13 @@ +
+
Topics
+
    + {{# each topics }} +
  • +

    {{this.title}}

    +

    {{this.description}}

    +
  • + {{/each}} +
+
diff --git a/src/views/topics_view.hbs b/src/views/topics_view.hbs new file mode 100644 index 0000000..1f1b17d --- /dev/null +++ b/src/views/topics_view.hbs @@ -0,0 +1,24 @@ + + + + + + + + + + + + {{title}} | Blog Site + + +{{>partials/_header}} +
+
+ {{>partials/topics_main}} + {{>partials/_sidebar authenticated=user}} +
+
+ + diff --git a/webpack.config.js b/webpack.config.js index 01ea16d..5517fe3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -72,6 +72,17 @@ module.exports = { topics, user, } + }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/topics_view.hbs"), + filename: refs.TopicsView, + templateParameters: { + ...statics, + ...refs, + title: "Subscriptions", + topics, + user, + } }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/profile_view.hbs"), From 1cf3f4a5d0b6987407f444ea20c711c79aeb798d Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Tue, 16 Jan 2024 15:54:55 +0200 Subject: [PATCH 89/91] Add header to dist, remove chunks (css/js) from sidebar templates --- webpack.dev.config.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 8d9d3d4..04925e6 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -38,28 +38,39 @@ module.exports = { filename: "base.html", templateParameters: {topics} }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/_header.hbs"), + filename: "_navbar.html", + chunks: [], + templateParameters: {topics}, + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), filename: "_sidebars/anonymous.html", + chunks: [], }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), filename: "_sidebars/authenticated.html", + chunks: [], templateParameters: {...sidebar_authenticated} }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), filename: "_sidebars/can_comment.html", + chunks: [], templateParameters: {...sidebar_can_comment} }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), filename: "_sidebars/can_edit.html", + chunks: [], templateParameters: {...sidebar_can_edit} }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), filename: "_sidebars/create_view.html", + chunks: [], templateParameters: {...sidebar_can_create} }), new HTMLWebpackPlugin({ From cf458838c19c5550e5af2d098c3ec35c9780d812 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Tue, 16 Jan 2024 15:58:10 +0200 Subject: [PATCH 90/91] Add static files refs to header and article list templates (dev) --- webpack.dev.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webpack.dev.config.js b/webpack.dev.config.js index 04925e6..ec5c65b 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -42,7 +42,7 @@ module.exports = { template: path.resolve(__dirname, "src/views/partials/_header.hbs"), filename: "_navbar.html", chunks: [], - templateParameters: {topics}, + templateParameters: {...statics_dev, topics}, }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/_sidebar.hbs"), @@ -82,7 +82,7 @@ module.exports = { filename: "articles/article_list.html", chunks: [], templateParameters: { - statics_dev, + ...statics_dev, topics, } }), From ceeb9a7a123cbb8fe1ac1bd7de87eb761bb720e2 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Wed, 17 Jan 2024 15:11:38 +0200 Subject: [PATCH 91/91] Add topics list sources to dev-dist package --- webpack.dev.config.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/webpack.dev.config.js b/webpack.dev.config.js index ec5c65b..69b5fa4 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -105,6 +105,16 @@ module.exports = { navs: refs.navs, } }), + new HTMLWebpackPlugin({ + template: path.resolve(__dirname, "src/views/partials/topics_main.hbs"), + filename: "articles/topic_list.html", + chunks: [], + templateParameters: { + ...statics_dev, + navs: refs.navs, + topics, + } + }), new HTMLWebpackPlugin({ template: path.resolve(__dirname, "src/views/partials/signin_form.hbs"), filename: "auth/signin_form.html",