diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..983421b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: deploy + +on: + push: + branches: + - master + +jobs: + typescript: + runs-on: ubuntu-latest + steps: + - name: Setup checkout + uses: actions/checkout@v2 + - name: Setup NodeJS v12 + uses: actions/setup-node@v1 + with: + node-version: 12 + - name: Install Dependencies + run: yarn install + - name: Check for syntax errors + run: yarn test-build + - name: ESlint check + run: yarn lint diff --git a/.gitignore b/.gitignore index 27fdd73..79293ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ Magister Auto-Login.crx -Magister Auto-Login.pem \ No newline at end of file +Magister Auto-Login.pem +node_modules +dist \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..8e97d94 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "trailingComma": "es5", + "useTabs": true, + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "printWidth": 100, + "arrowParens": "always" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ff24a05 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "prettier.configPath": ".prettierrc" +} diff --git a/builder.config.js b/builder.config.js new file mode 100644 index 0000000..3305980 --- /dev/null +++ b/builder.config.js @@ -0,0 +1,46 @@ +module.exports = { + paths: { + "@stylesheets": "css", + "@scripts": "js", + "@pages": "html", + "@icons": "icons", + "@libraries": "lib" + }, + interpreter: [ + { + input: '.', + output: '.', + type: 'js', + }, + { + input: 'pages/scripts', + output: 'js', + type: 'js', + }, + { + input: 'pages', + output: 'html', + type: 'html', + }, + { + input: 'stylesheets', + output: 'css', + type: 'sass', + }, + { + input: 'icons', + output: 'icons', + type: 'other', + }, + { + input: 'lib', + output: 'lib', + type: 'other', + }, + { + input: 'manifest.json', + output: 'manifest.json', + type: 'file', + } + ] +} \ No newline at end of file diff --git a/dark-mode.css b/dark-mode.css deleted file mode 100644 index a669350..0000000 --- a/dark-mode.css +++ /dev/null @@ -1,25 +0,0 @@ -body { - background-color: #282a2d; -} -* { - color: #c5c5c5!important; -} - .input-group-text { - color: #fff; - background-color: #1e2226; - border-color: #383f47; -} -.form-control, .bg-light { - background-color: #22262a!important; - color: #fff!important; - border-color: #383f47; -} -.btn-primary { - background-color: #0167d4; -} -.btn-primary:hover { - background-color: #0056b2; -} -.active.btn-primary { - background-color: #0052aa!important; -} \ No newline at end of file diff --git a/js/background.js b/js/background.js deleted file mode 100644 index 1e79602..0000000 --- a/js/background.js +++ /dev/null @@ -1,19 +0,0 @@ -chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { - if (changeInfo.status == 'complete' && tab.active) { - chrome.tabs.executeScript(tab.ib, { - file: 'js/login.js' - }); - } -}); - -chrome.runtime.onInstalled.addListener(function () { - // open options.html - window.open('/options/index.html', '_blank'); - - chrome.storage.sync.set({ - "enabled": true - }); - chrome.browserAction.setBadgeText({ - text: 'ON' - }); -}); \ No newline at end of file diff --git a/js/login.js b/js/login.js deleted file mode 100644 index 9a14add..0000000 --- a/js/login.js +++ /dev/null @@ -1,69 +0,0 @@ -const d = document.getElementById.bind(document); -const q = document.querySelector.bind(document); -document.querySelector('img[alt="Magister"]').remove(); // verwijderen van animatie linksboven - -// user object moet gemaakt worden vanuit chrome.storage.sync - -var snooze = ms => new Promise(res => setTimeout(res, ms)); -function login() { - chrome.storage.sync.get(['school', 'number', 'password'], async function (result) { - - if (d("scholenkiezer_value")) { - await waitForSel("#scholenkiezer_value"); - - if (d("scholenkiezer_value") && result.school) { - d("scholenkiezer_value").value = result.school; - d("scholenkiezer_value").dispatchEvent(new Event("input")); - }; - - await waitForSel(".selected"); - - if (q(".selected")) { - q(".selected").click(); - } - } - - await waitForSel("#username"); - - if (d("username") && result.number) { - d("username").value = result.number; - d("username").dispatchEvent(new Event("input")); - }; - - await waitForSel("#username_submit") - if (d("username_submit")) { - d("username_submit").click(); - }; - - await waitForSel("#rswp_password") - - if (d("rswp_password") && result.password) { - d("rswp_password").value = result.password; - d("rswp_password").dispatchEvent(new Event("input")); - }; - - await waitForSel("[id*=_submit]") - if (d("rswp_submit")) { - d("rswp_submit").click(); - }; - }); -} - -function waitForSel(s) { - return new Promise(res => { - setInterval(() => { - if (q(s)) { - res() - } - }, 10); - }); -}; - -chrome.storage.sync.get(['enabled'], function (result){ - if(result.enabled){ - login(); - }; -}); - - - diff --git a/js/save.js b/js/save.js deleted file mode 100644 index fe040a1..0000000 --- a/js/save.js +++ /dev/null @@ -1,93 +0,0 @@ -const d = document.getElementById.bind(document); -const qAll = document.querySelectorAll.bind(document); - -d("save").addEventListener("click", save); - -qAll(".login").forEach(s => { - s.addEventListener("keydown", e => { - if (e.key == "Enter") { - if (e.target.id == "school") { - d("number").focus() - }; - if (e.target.id == "number") { - d("password").focus() - }; - if (e.target.id == "password") { - save() - }; - } - }); -}); - -function save() { - - var school = d("school").value; - var number = d("number").value; - var password = d("password").value; - - try { - chrome.storage.sync.set({ - "school": school, - "number": number, - "password": password - }); - - d("save").innerHTML = "Opgeslagen!" - } catch (e) { - d("save").innerHTML = "Fout" - d("save").className = "btn btn-danger float-right" - console.error(e); - } -}; - -function onLoad() { - chrome.storage.sync.get(['school', 'number', 'password'], function (result) { - if (result.school !== undefined) { - - d("school").value = result.school - }; - - if (result.number !== undefined){ - - d("number").value = result.number - }; - - if (result.password !== undefined) { - d("password").value = "lolleukgeprobeerd" - }; - }); - - chrome.storage.sync.get(['enabled'], function (result) { - d("switch").checked = result.enabled - }); - - chrome.storage.sync.get(['darkmode'], function (result) { - d("dark-mode").checked = result.darkmode - d("dark-link").disabled = !d("dark-mode").checked - }); - - d("switch").addEventListener("click", toggle) - d("dark-mode").addEventListener("click", darkMode) -}; - -function toggle() { - var checked = d("switch").checked; - chrome.storage.sync.set({ - "enabled": checked - }); - - chrome.browserAction.setBadgeText({ - text: checked ? "ON" : "OFF" - }); -}; - -function darkMode() { - chrome.storage.sync.set({ - "darkmode": d("dark-mode").checked - }); - - d("dark-link").disabled = !d("dark-mode").checked - -} - -onLoad() diff --git a/manifest.json b/manifest.json deleted file mode 100644 index aaf50ee..0000000 --- a/manifest.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "Magister Auto-Login", - "version": "2.0", - "manifest_version": 2, - "description": "Auto-Login for Magister 6 webapp.", - "options_page": "options/index.html", - "homepage_url": "http://mb-o.nl/autologin", - "background": { - "scripts": [ - "js/background.js" - ], - "persistent": true - }, - "browser_action": { - "default_title": "Auto-login", - "default_popup": "/popup/index.html" - }, - "icons": { - "16": "/icons/16x.png", - "32": "/icons/32x.png", - "48": "/icons/48x.png", - "128": "/icons/128x.png", - "256": "/icons/256x.png" - }, - "permissions": [ - "https://accounts.magister.net/*", - "storage" - ] -} diff --git a/materials-switches.css b/materials-switches.css deleted file mode 100644 index a738ad6..0000000 --- a/materials-switches.css +++ /dev/null @@ -1,46 +0,0 @@ -.material-switch > input[type="checkbox"] { - display: none; -} - -.material-switch > label { - cursor: pointer; - margin-top: .8rem; - float: right; - height: 0px; - position: relative; - width: 40px; -} - -.material-switch > label::before { - background: rgb(0, 0, 0); - box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.5); - border-radius: 8px; - content: ''; - height: 16px; - margin-top: -8px; - position:absolute; - opacity: 0.3; - transition: all 0.4s ease-in-out; - width: 40px; -} -.material-switch > label::after { - background: rgb(255, 255, 255); - border-radius: 16px; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); - content: ''; - height: 24px; - left: -4px; - margin-top: -8px; - position: absolute; - top: -4px; - transition: all 0.3s ease-in-out; - width: 24px; -} -.material-switch > input[type="checkbox"]:checked + label::before { - background: #007bff; - opacity: 0.5; -} -.material-switch > input[type="checkbox"]:checked + label::after { - background: #007bff; - left: 20px; -} \ No newline at end of file diff --git a/options/index.css b/options/index.css deleted file mode 100644 index 0675030..0000000 --- a/options/index.css +++ /dev/null @@ -1,29 +0,0 @@ -.screen { - width: 100vw; - height: 100vh; -} -.copyright { - position: absolute; - margin: 7px; - right: 0; - bottom: 0; -} - -.switch-span { - width: 2rem; -} -.enable { - position: absolute; - left: 1rem; - bottom: 1.7rem; -} - -.darkcheck{ - position: absolute; - margin: 7px; - right: 0px; -} - -body { - min-width: 20rem; -} \ No newline at end of file diff --git a/options/index.html b/options/index.html deleted file mode 100644 index ba8edcb..0000000 --- a/options/index.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Options | Magister Auto-Login - - - - - - - - - -
-
-
-

Magister Auto-Login

- -
- - -
-
-
-
-
- - -
- : - -
- - -
- -
-
-
- -
- - - - - - \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..16e5728 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "dependencies": { + "chalk": "^4.1.1", + "chokidar": "^3.5.2", + "fs-extra": "^10.0.0", + "minify": "^7.0.2", + "prettier": "^2.3.2", + "sass": "^1.36.0" + }, + "scripts": { + "dev": "node src/builder/watch", + "build": "node src/builder", + "prettify": "prettier --write src" + } +} diff --git a/popup/index.css b/popup/index.css deleted file mode 100644 index 014d894..0000000 --- a/popup/index.css +++ /dev/null @@ -1,18 +0,0 @@ -body { - min-width: 20rem; - min-height: 24rem; -} - -.darkcheck{ - position: absolute; - margin: 7px; - right: 0px; -} - -.enable { - position: absolute; - bottom: 0; - left: 0; - margin-bottom: 10px; - margin-left: 20px; -} \ No newline at end of file diff --git a/popup/index.html b/popup/index.html deleted file mode 100644 index 5d1c9c8..0000000 --- a/popup/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - -
-
-
-
-
-
- - -
- - -
- - -
- -
- - -
-
-
-
-
- - - - - diff --git a/src/background.js b/src/background.js new file mode 100644 index 0000000..1b8f987 --- /dev/null +++ b/src/background.js @@ -0,0 +1,27 @@ +// Runs when the extensions is updated +const updated = (tabId, changeInfo, tab) => { + if (changeInfo.status == 'complete' && tab.active) { + chrome.tabs.executeScript(tab.ib, { + file: 'login.js', + }); + } +}; + +// Run when extensions is installed +const installed = () => { + window.open('@pages/options.html', '_blank'); + + chrome.storage.sync.get('accounts', (accounts) => { + chrome.storage.sync.set({ + enabled: true, + accounts: accounts || [], + }); + }); + + chrome.browserAction.setBadgeText({ + text: 'ON', + }); +}; + +chrome.tabs.onUpdated.addListener(updated); +chrome.runtime.onInstalled.addListener(installed); diff --git a/src/builder/builders.js b/src/builder/builders.js new file mode 100644 index 0000000..61ce961 --- /dev/null +++ b/src/builder/builders.js @@ -0,0 +1,128 @@ +const fs = require('fs-extra'); +const { join } = require('path'); + +const minify = require('minify'); +const sass = require('sass'); +const chalk = require('chalk'); + +const sassExtension = '.sass'; + +const config = require(join(process.cwd(), 'builder.config.js')); + +/** + * Compiles files in a directory to a given directory + * @param {string} dir - The input directory + * @param {string} outDir - The output directory + * @param {string} fileExtension - The file extension + * @returns + */ +const builder = (dir, outDir, fileExtension) => + dirChecker(outDir, () => + fs.readdir(dir, (err, files) => { + if (err) throw new Error(err); + + // Filter out other files + files = files.filter((file) => file.endsWith(fileExtension)); + + // Minify the files & write them to the build directory + files.forEach((file) => { + const t0 = performance.now(); + + compile(join(dir, file), fileExtension, (data) => { + const withPaths = replacePaths(data); + + if (fileExtension === 'sass') { + file = file.replace(sassExtension, '.min.css'); + } + + fs.writeFile(join(outDir, file), withPaths, (err) => { + if (err) throw new Error(err); + + const t1 = performance.now(); + + console.log(`${chalk.gray(file)} ${Math.round(t1 - t0)}ms`); + }); + }); + }); + }) + ); + +/** + * Compiles a string of data. + * @param {string} data + * @param {'sass' | 'js' | 'html'} type + * @param {(data) => void} callback + */ +const compile = (file, type, callback) => { + switch (type) { + case 'sass': + sass.render({ file, outputStyle: 'compressed' }, (err, data) => + callback(data.css.toString()) + ); + + return; + default: + + return minify(file).then(callback).catch(console.log('Error compiling file ' + file)) + + } +}; + +/** + * Compiles a file + * @param {string} file - The input file + */ +const fileBuilder = (file, output) => + fs.readFile(file, { encoding: 'utf-8' }, (err, data) => { + if (err) throw new Error(err); + + const t0 = performance.now(); + + const withPaths = replacePaths(data); + + fs.writeFile(output, withPaths, (err) => { + if (err) throw new Error(err); + + const t1 = performance.now(); + + const path = file.split('/'); + const fileName = path[path.length - 1]; + + console.log(`${chalk.gray(fileName)} ${Math.round(t1 - t0)}ms`); + }); + }); + +/** + * Replaces all specified paths in builder.config.js with their definitions + * @param {string} data - The data that needs its paths replaced + * @returns + */ +const replacePaths = (data) => { + if (config.paths) { + Object.keys(config.paths).forEach((key) => { + data = data.replace(new RegExp(key, 'g'), '/' + config.paths[key]); + }); + + data = data.replace(sassExtension, '.min.css'); + } + + return data; +}; + +/** + * Checks if a directory exists and creates it if it doesn't. + * @param {string} dir - The directory to check + * @param {() => void} callback - The callback function + */ +const dirChecker = (dir, callback) => { + if (!fs.existsSync(dir)) { + fs.mkdir(dir, { recursive: true }, () => callback()); + } else { + callback(); + } +}; + +module.exports = { + builder, + fileBuilder, +}; diff --git a/src/builder/index.js b/src/builder/index.js new file mode 100644 index 0000000..3f73a32 --- /dev/null +++ b/src/builder/index.js @@ -0,0 +1,24 @@ +const { join } = require('path'); +const fs = require('fs-extra'); + +const srcDir = join(process.cwd(), 'src'); +const distDir = join(process.cwd(), 'dist'); + +const config = require(join(process.cwd(), 'builder.config.js')); + +const { builder, fileBuilder, sassBuilder } = require('./builders'); + +if (config.interpreter) { + config.interpreter.forEach((interpreter) => { + const input = join(srcDir, interpreter.input); + const output = join(distDir, interpreter.output); + + if (interpreter.type === 'js' || interpreter.type === 'html' || interpreter.type === 'sass') { + builder(input, output, interpreter.type); + } else if (interpreter.type === 'file') { + fileBuilder(input, output); + } else if (interpreter.type === 'other') { + fs.copy(input, output); + } + }); +} diff --git a/src/builder/watch.js b/src/builder/watch.js new file mode 100644 index 0000000..bbb4be4 --- /dev/null +++ b/src/builder/watch.js @@ -0,0 +1,13 @@ +const chokidar = require('chokidar'); +const { join } = require('path'); + +const srcDir = join(process.cwd(), 'src'); + +const watcher = chokidar.watch(srcDir, { + persistent: true +}); + +// Check for changes in the src directory +watcher.on('change', (path) => { + const fileExtension = path.split('.').pop(); +}) \ No newline at end of file diff --git a/icons/128x.png b/src/icons/128x.png similarity index 100% rename from icons/128x.png rename to src/icons/128x.png diff --git a/icons/16x.png b/src/icons/16x.png similarity index 100% rename from icons/16x.png rename to src/icons/16x.png diff --git a/icons/256x.png b/src/icons/256x.png similarity index 100% rename from icons/256x.png rename to src/icons/256x.png diff --git a/icons/32x.png b/src/icons/32x.png similarity index 100% rename from icons/32x.png rename to src/icons/32x.png diff --git a/icons/48x.png b/src/icons/48x.png similarity index 100% rename from icons/48x.png rename to src/icons/48x.png diff --git a/icons/banner.png b/src/icons/banner.png similarity index 100% rename from icons/banner.png rename to src/icons/banner.png diff --git a/src/lib/fonts.css b/src/lib/fonts.css new file mode 100644 index 0000000..201bd08 --- /dev/null +++ b/src/lib/fonts.css @@ -0,0 +1,9 @@ +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: url(./fonts/Roboto.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, + U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/src/lib/fonts/Roboto.woff2 b/src/lib/fonts/Roboto.woff2 new file mode 100644 index 0000000..01d05fa Binary files /dev/null and b/src/lib/fonts/Roboto.woff2 differ diff --git a/src/lib/milligram.css b/src/lib/milligram.css new file mode 100644 index 0000000..04f24dd --- /dev/null +++ b/src/lib/milligram.css @@ -0,0 +1,647 @@ +/*! + * Milligram v1.4.1 + * https://milligram.io + * + * Copyright (c) 2020 CJ Patoilo + * Licensed under the MIT license + */ + +*, +*:after, +*:before { + box-sizing: inherit; +} + +html { + box-sizing: border-box; + font-size: 62.5%; +} + +body { + color: #606c76; + font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; + font-size: 1.6em; + font-weight: 300; + letter-spacing: 0.01em; + line-height: 1.6; +} + +blockquote { + border-left: 0.3rem solid #d1d1d1; + margin-left: 0; + margin-right: 0; + padding: 1rem 1.5rem; +} + +blockquote *:last-child { + margin-bottom: 0; +} + +.button, +button, +input[type='button'], +input[type='reset'], +input[type='submit'] { + background-color: #9b4dca; + border: 0.1rem solid #9b4dca; + border-radius: 0.4rem; + color: #fff; + cursor: pointer; + display: inline-block; + font-size: 1.1rem; + font-weight: 700; + height: 3.8rem; + letter-spacing: 0.1rem; + line-height: 3.8rem; + padding: 0 3rem; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; +} + +.button:focus, +.button:hover, +button:focus, +button:hover, +input[type='button']:focus, +input[type='button']:hover, +input[type='reset']:focus, +input[type='reset']:hover, +input[type='submit']:focus, +input[type='submit']:hover { + background-color: #606c76; + border-color: #606c76; + color: #fff; + outline: 0; +} + +.button[disabled], +button[disabled], +input[type='button'][disabled], +input[type='reset'][disabled], +input[type='submit'][disabled] { + cursor: default; + opacity: 0.5; +} + +.button[disabled]:focus, +.button[disabled]:hover, +button[disabled]:focus, +button[disabled]:hover, +input[type='button'][disabled]:focus, +input[type='button'][disabled]:hover, +input[type='reset'][disabled]:focus, +input[type='reset'][disabled]:hover, +input[type='submit'][disabled]:focus, +input[type='submit'][disabled]:hover { + background-color: #9b4dca; + border-color: #9b4dca; +} + +.button.button-outline, +button.button-outline, +input[type='button'].button-outline, +input[type='reset'].button-outline, +input[type='submit'].button-outline { + background-color: transparent; + color: #9b4dca; +} + +.button.button-outline:focus, +.button.button-outline:hover, +button.button-outline:focus, +button.button-outline:hover, +input[type='button'].button-outline:focus, +input[type='button'].button-outline:hover, +input[type='reset'].button-outline:focus, +input[type='reset'].button-outline:hover, +input[type='submit'].button-outline:focus, +input[type='submit'].button-outline:hover { + background-color: transparent; + border-color: #606c76; + color: #606c76; +} + +.button.button-outline[disabled]:focus, +.button.button-outline[disabled]:hover, +button.button-outline[disabled]:focus, +button.button-outline[disabled]:hover, +input[type='button'].button-outline[disabled]:focus, +input[type='button'].button-outline[disabled]:hover, +input[type='reset'].button-outline[disabled]:focus, +input[type='reset'].button-outline[disabled]:hover, +input[type='submit'].button-outline[disabled]:focus, +input[type='submit'].button-outline[disabled]:hover { + border-color: inherit; + color: #9b4dca; +} + +.button.button-clear, +button.button-clear, +input[type='button'].button-clear, +input[type='reset'].button-clear, +input[type='submit'].button-clear { + background-color: transparent; + border-color: transparent; + color: #9b4dca; +} + +.button.button-clear:focus, +.button.button-clear:hover, +button.button-clear:focus, +button.button-clear:hover, +input[type='button'].button-clear:focus, +input[type='button'].button-clear:hover, +input[type='reset'].button-clear:focus, +input[type='reset'].button-clear:hover, +input[type='submit'].button-clear:focus, +input[type='submit'].button-clear:hover { + background-color: transparent; + border-color: transparent; + color: #606c76; +} + +.button.button-clear[disabled]:focus, +.button.button-clear[disabled]:hover, +button.button-clear[disabled]:focus, +button.button-clear[disabled]:hover, +input[type='button'].button-clear[disabled]:focus, +input[type='button'].button-clear[disabled]:hover, +input[type='reset'].button-clear[disabled]:focus, +input[type='reset'].button-clear[disabled]:hover, +input[type='submit'].button-clear[disabled]:focus, +input[type='submit'].button-clear[disabled]:hover { + color: #9b4dca; +} + +code { + background: #f4f5f6; + border-radius: 0.4rem; + font-size: 86%; + margin: 0 0.2rem; + padding: 0.2rem 0.5rem; + white-space: nowrap; +} + +pre { + background: #f4f5f6; + border-left: 0.3rem solid #9b4dca; + overflow-y: hidden; +} + +pre > code { + border-radius: 0; + display: block; + padding: 1rem 1.5rem; + white-space: pre; +} + +hr { + border: 0; + border-top: 0.1rem solid #f4f5f6; + margin: 3rem 0; +} + +input[type='color'], +input[type='date'], +input[type='datetime'], +input[type='datetime-local'], +input[type='email'], +input[type='month'], +input[type='number'], +input[type='password'], +input[type='search'], +input[type='tel'], +input[type='text'], +input[type='url'], +input[type='week'], +input:not([type]), +textarea, +select { + -webkit-appearance: none; + background-color: transparent; + border: 0.1rem solid #d1d1d1; + border-radius: 0.4rem; + box-shadow: none; + box-sizing: inherit; + height: 3.8rem; + padding: 0.6rem 1rem 0.7rem; + width: 100%; +} + +input[type='color']:focus, +input[type='date']:focus, +input[type='datetime']:focus, +input[type='datetime-local']:focus, +input[type='email']:focus, +input[type='month']:focus, +input[type='number']:focus, +input[type='password']:focus, +input[type='search']:focus, +input[type='tel']:focus, +input[type='text']:focus, +input[type='url']:focus, +input[type='week']:focus, +input:not([type]):focus, +textarea:focus, +select:focus { + border-color: #9b4dca; + outline: 0; +} + +select { + background: url('data:image/svg+xml;utf8,') + center right no-repeat; + padding-right: 3rem; +} + +select:focus { + background-image: url('data:image/svg+xml;utf8,'); +} + +select[multiple] { + background: none; + height: auto; +} + +textarea { + min-height: 6.5rem; +} + +label, +legend { + display: block; + font-size: 1.6rem; + font-weight: 700; + margin-bottom: 0.5rem; +} + +fieldset { + border-width: 0; + padding: 0; +} + +input[type='checkbox'], +input[type='radio'] { + display: inline; +} + +.label-inline { + display: inline-block; + font-weight: normal; + margin-left: 0.5rem; +} + +.container { + margin: 0 auto; + max-width: 112rem; + padding: 0 2rem; + position: relative; + width: 100%; +} + +.row { + display: flex; + flex-direction: column; + padding: 0; + width: 100%; +} + +.row.row-no-padding { + padding: 0; +} + +.row.row-no-padding > .column { + padding: 0; +} + +.row.row-wrap { + flex-wrap: wrap; +} + +.row.row-top { + align-items: flex-start; +} + +.row.row-bottom { + align-items: flex-end; +} + +.row.row-center { + align-items: center; +} + +.row.row-stretch { + align-items: stretch; +} + +.row.row-baseline { + align-items: baseline; +} + +.row .column { + display: block; + flex: 1 1 auto; + margin-left: 0; + max-width: 100%; + width: 100%; +} + +.row .column.column-offset-10 { + margin-left: 10%; +} + +.row .column.column-offset-20 { + margin-left: 20%; +} + +.row .column.column-offset-25 { + margin-left: 25%; +} + +.row .column.column-offset-33, +.row .column.column-offset-34 { + margin-left: 33.3333%; +} + +.row .column.column-offset-40 { + margin-left: 40%; +} + +.row .column.column-offset-50 { + margin-left: 50%; +} + +.row .column.column-offset-60 { + margin-left: 60%; +} + +.row .column.column-offset-66, +.row .column.column-offset-67 { + margin-left: 66.6666%; +} + +.row .column.column-offset-75 { + margin-left: 75%; +} + +.row .column.column-offset-80 { + margin-left: 80%; +} + +.row .column.column-offset-90 { + margin-left: 90%; +} + +.row .column.column-10 { + flex: 0 0 10%; + max-width: 10%; +} + +.row .column.column-20 { + flex: 0 0 20%; + max-width: 20%; +} + +.row .column.column-25 { + flex: 0 0 25%; + max-width: 25%; +} + +.row .column.column-33, +.row .column.column-34 { + flex: 0 0 33.3333%; + max-width: 33.3333%; +} + +.row .column.column-40 { + flex: 0 0 40%; + max-width: 40%; +} + +.row .column.column-50 { + flex: 0 0 50%; + max-width: 50%; +} + +.row .column.column-60 { + flex: 0 0 60%; + max-width: 60%; +} + +.row .column.column-66, +.row .column.column-67 { + flex: 0 0 66.6666%; + max-width: 66.6666%; +} + +.row .column.column-75 { + flex: 0 0 75%; + max-width: 75%; +} + +.row .column.column-80 { + flex: 0 0 80%; + max-width: 80%; +} + +.row .column.column-90 { + flex: 0 0 90%; + max-width: 90%; +} + +.row .column .column-top { + align-self: flex-start; +} + +.row .column .column-bottom { + align-self: flex-end; +} + +.row .column .column-center { + align-self: center; +} + +@media (min-width: 40rem) { + .row { + flex-direction: row; + margin-left: -1rem; + width: calc(100% + 2rem); + } + .row .column { + margin-bottom: inherit; + padding: 0 1rem; + } +} + +a { + color: #9b4dca; + text-decoration: none; +} + +a:focus, +a:hover { + color: #606c76; +} + +dl, +ol, +ul { + list-style: none; + margin-top: 0; + padding-left: 0; +} + +dl dl, +dl ol, +dl ul, +ol dl, +ol ol, +ol ul, +ul dl, +ul ol, +ul ul { + font-size: 90%; + margin: 1.5rem 0 1.5rem 3rem; +} + +ol { + list-style: decimal inside; +} + +ul { + list-style: circle inside; +} + +.button, +button, +dd, +dt, +li { + margin-bottom: 1rem; +} + +fieldset, +input, +select, +textarea { + margin-bottom: 1.5rem; +} + +blockquote, +dl, +figure, +form, +ol, +p, +pre, +table, +ul { + margin-bottom: 2.5rem; +} + +table { + border-spacing: 0; + display: block; + overflow-x: auto; + text-align: left; + width: 100%; +} + +td, +th { + border-bottom: 0.1rem solid #e1e1e1; + padding: 1.2rem 1.5rem; +} + +td:first-child, +th:first-child { + padding-left: 0; +} + +td:last-child, +th:last-child { + padding-right: 0; +} + +@media (min-width: 40rem) { + table { + display: table; + overflow-x: initial; + } +} + +b, +strong { + font-weight: bold; +} + +p { + margin-top: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 300; + letter-spacing: -0.1rem; + margin-bottom: 2rem; + margin-top: 0; +} + +h1 { + font-size: 4.6rem; + line-height: 1.2; +} + +h2 { + font-size: 3.6rem; + line-height: 1.25; +} + +h3 { + font-size: 2.8rem; + line-height: 1.3; +} + +h4 { + font-size: 2.2rem; + letter-spacing: -0.08rem; + line-height: 1.35; +} + +h5 { + font-size: 1.8rem; + letter-spacing: -0.05rem; + line-height: 1.5; +} + +h6 { + font-size: 1.6rem; + letter-spacing: 0; + line-height: 1.4; +} + +img { + max-width: 100%; +} + +.clearfix:after { + clear: both; + content: ' '; + display: table; +} + +.float-left { + float: left; +} + +.float-right { + float: right; +} + +/*# sourceMappingURL=milligram.css.map */ diff --git a/src/lib/normalize.css b/src/lib/normalize.css new file mode 100644 index 0000000..53dee43 --- /dev/null +++ b/src/lib/normalize.css @@ -0,0 +1,351 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { + /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { + /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type='button']::-moz-focus-inner, +[type='reset']::-moz-focus-inner, +[type='submit']::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type='button']:-moz-focusring, +[type='reset']:-moz-focusring, +[type='submit']:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type='checkbox'], +[type='radio'] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type='number']::-webkit-inner-spin-button, +[type='number']::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type='search']::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/src/login.js b/src/login.js new file mode 100644 index 0000000..55780a8 --- /dev/null +++ b/src/login.js @@ -0,0 +1,65 @@ +const d = document.getElementById.bind(document); +const q = document.querySelector.bind(document); +document.querySelector('img[alt="Magister"]').remove(); // verwijderen van animatie linksboven + +// user object moet gemaakt worden vanuit chrome.storage.sync + +var snooze = (ms) => new Promise((res) => setTimeout(res, ms)); +function login() { + chrome.storage.sync.get(['school', 'number', 'password'], async function (result) { + if (d('scholenkiezer_value')) { + await waitForSel('#scholenkiezer_value'); + + if (d('scholenkiezer_value') && result.school) { + d('scholenkiezer_value').value = result.school; + d('scholenkiezer_value').dispatchEvent(new Event('input')); + } + + await waitForSel('.selected'); + + if (q('.selected')) { + q('.selected').click(); + } + } + + await waitForSel('#username'); + + if (d('username') && result.number) { + d('username').value = result.number; + d('username').dispatchEvent(new Event('input')); + } + + await waitForSel('#username_submit'); + if (d('username_submit')) { + d('username_submit').click(); + } + + await waitForSel('#rswp_password'); + + if (d('rswp_password') && result.password) { + d('rswp_password').value = result.password; + d('rswp_password').dispatchEvent(new Event('input')); + } + + await waitForSel('[id*=_submit]'); + if (d('rswp_submit')) { + d('rswp_submit').click(); + } + }); +} + +function waitForSel(s) { + return new Promise((res) => { + setInterval(() => { + if (q(s)) { + res(); + } + }, 10); + }); +} + +chrome.storage.sync.get(['enabled'], function (result) { + if (result.enabled) { + login(); + } +}); diff --git a/src/manifest.json b/src/manifest.json new file mode 100644 index 0000000..5efcee7 --- /dev/null +++ b/src/manifest.json @@ -0,0 +1,24 @@ +{ + "name": "Magister Auto-Login", + "version": "3.0", + "manifest_version": 2, + "description": "Auto-Login for Magister 6 webapp.", + "options_page": "@pages/options.html", + "homepage_url": "http://mb-o.nl/autologin", + "background": { + "scripts": ["/background.js"], + "persistent": true + }, + "browser_action": { + "default_title": "Auto-login", + "default_popup": "@pages/popup.html" + }, + "icons": { + "16": "@icons/16x.png", + "32": "@icons/32x.png", + "48": "@icons/48x.png", + "128": "@icons/128x.png", + "256": "@icons/256x.png" + }, + "permissions": ["https://accounts.magister.net/*", "storage"] +} diff --git a/src/pages/account.html b/src/pages/account.html new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/options.html b/src/pages/options.html new file mode 100644 index 0000000..ec0ddb6 --- /dev/null +++ b/src/pages/options.html @@ -0,0 +1,37 @@ + + + + Options | Magister Auto-Login + + + + + + + + + + + + + + + +
+
+ + +

Magister Auto Login

+ + Gemaakt door Martijn Oosterhuis & Guus van Meerveld +
+ +

Accounts

+
+
+ + + + + + diff --git a/src/pages/popup.html b/src/pages/popup.html new file mode 100644 index 0000000..aa741af --- /dev/null +++ b/src/pages/popup.html @@ -0,0 +1,58 @@ + + + + + + + + + + +
+
+
+
+
+ + +
+ + +
+ + +
+ +
+ + +
+
+
+
+
+ + + + + diff --git a/src/pages/scripts/accounts.js b/src/pages/scripts/accounts.js new file mode 100644 index 0000000..66add83 --- /dev/null +++ b/src/pages/scripts/accounts.js @@ -0,0 +1,8 @@ +const getAccounts = (accounts) => { + if (accounts.length == 0) { + $('.accounts').innerHTML = 'Je hebt nog geen accounts.'; + return; + } +}; + +const accounts = chrome.storage.sync.get('accounts', getAccounts); diff --git a/src/pages/scripts/constants.js b/src/pages/scripts/constants.js new file mode 100644 index 0000000..0ed4b25 --- /dev/null +++ b/src/pages/scripts/constants.js @@ -0,0 +1 @@ +const $ = document.querySelector.bind(document); diff --git a/src/pages/scripts/dark-mode.js b/src/pages/scripts/dark-mode.js new file mode 100644 index 0000000..656ffbc --- /dev/null +++ b/src/pages/scripts/dark-mode.js @@ -0,0 +1,19 @@ +const toggleDarkMode = () => { + const checked = $('.dark-mode').checked; + + chrome.storage.sync.set({ + 'dark-mode': checked, + }); + + $('#dark-mode-stylesheet').disabled = !checked; +}; + +const initDarkMode = () => + chrome.storage.sync.get('dark-mode', (usingDarkMode) => { + $('#dark-mode-stylesheet').disabled = !usingDarkMode; + $('.dark-mode').checked = usingDarkMode; + }); + +$('.dark-mode').addEventListener('click', toggleDarkMode); + +initDarkMode(); diff --git a/src/save.js b/src/save.js new file mode 100644 index 0000000..8614b6e --- /dev/null +++ b/src/save.js @@ -0,0 +1,77 @@ +d('save').addEventListener('click', save); + +qAll('.login').forEach((s) => { + s.addEventListener('keydown', (e) => { + if (e.key == 'Enter') { + if (e.target.id == 'school') { + d('number').focus(); + } + if (e.target.id == 'number') { + d('password').focus(); + } + if (e.target.id == 'password') { + save(); + } + } + }); +}); + +function save() { + var school = d('school').value; + var number = d('number').value; + var password = d('password').value; + + try { + chrome.storage.sync.set({ + school: school, + number: number, + password: password, + }); + + d('save').innerHTML = 'Opgeslagen!'; + } catch (e) { + d('save').innerHTML = 'Fout'; + d('save').className = 'btn btn-danger float-right'; + console.error(e); + } +} + +function onLoad() { + chrome.storage.sync.get(['school', 'number', 'password'], function (result) { + if (result.school !== undefined) { + d('school').value = result.school; + } + + if (result.number !== undefined) { + d('number').value = result.number; + } + + if (result.password !== undefined) { + d('password').value = 'lolleukgeprobeerd'; + } + }); + + chrome.storage.sync.get(['enabled'], function (result) { + d('switch').checked = result.enabled; + }); + + chrome.storage.sync.get(['darkmode'], function (result) { + d('dark-mode').checked = result.darkmode; + d('dark-link').disabled = !d('dark-mode').checked; + }); + + d('switch').addEventListener('click', toggle); +} + +function toggle() { + var checked = d('switch').checked; + chrome.storage.sync.set({ + enabled: checked, + }); + + chrome.browserAction.setBadgeText({ + text: checked ? 'ON' : 'OFF', + }); +} + +onLoad(); diff --git a/src/stylesheets/dark-mode.sass b/src/stylesheets/dark-mode.sass new file mode 100644 index 0000000..cbba64e --- /dev/null +++ b/src/stylesheets/dark-mode.sass @@ -0,0 +1,3 @@ +body + background-color: #282a2d + color: #c5c5c5 diff --git a/src/stylesheets/materials-switches.sass b/src/stylesheets/materials-switches.sass new file mode 100644 index 0000000..2459514 --- /dev/null +++ b/src/stylesheets/materials-switches.sass @@ -0,0 +1,43 @@ +.material-switch > input[type='checkbox'] + display: none + +.material-switch > label + cursor: pointer + margin-top: 0.8rem + float: right + height: 0px + position: relative + width: 40px + +.material-switch > label::before + background: rgb(0, 0, 0) + box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.5) + border-radius: 8px + content: '' + height: 16px + margin-top: -8px + position: absolute + opacity: 0.3 + transition: all 0.4s ease-in-out + width: 40px + +.material-switch > label::after + background: rgb(255, 255, 255) + border-radius: 16px + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3) + content: '' + height: 24px + left: -4px + margin-top: -8px + position: absolute + top: -4px + transition: all 0.3s ease-in-out + width: 24px + +.material-switch > input[type='checkbox']:checked + label::before + background: #007bff + opacity: 0.5 + +.material-switch > input[type='checkbox']:checked + label::after + background: #007bff + left: 20px diff --git a/src/stylesheets/options.sass b/src/stylesheets/options.sass new file mode 100644 index 0000000..0e65ff3 --- /dev/null +++ b/src/stylesheets/options.sass @@ -0,0 +1,4 @@ +.header + margin-bottom: 5rem + + text-align: center diff --git a/src/stylesheets/popup.sass b/src/stylesheets/popup.sass new file mode 100644 index 0000000..de08363 --- /dev/null +++ b/src/stylesheets/popup.sass @@ -0,0 +1,15 @@ +body + min-width: 20rem + min-height: 24rem + +.darkcheck + position: absolute + margin: 7px + right: 0px + +.enable + position: absolute + bottom: 0 + left: 0 + margin-bottom: 10px + margin-left: 20px diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..a31c675 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,358 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +camel-case@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +chalk@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + 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" + optionalDependencies: + fsevents "~2.3.2" + +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +clean-css@^5.0.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.1.3.tgz#42348778c3acb0083946ba340896802be5517ee2" + integrity sha512-qGXzUCDpLwAlPx0kYeU4QXjzQIcIYZbJjD4FNm7NnSjoP0hYMVZhHOpUYJ6AwfkMX2cceLRq54MeCgHy/va1cA== + dependencies: + source-map "~0.6.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +css-b64-images@~0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/css-b64-images/-/css-b64-images-0.2.5.tgz#42005d83204b2b4a5d93b6b1a5644133b5927a02" + integrity sha1-QgBdgyBLK0pdk7axpWRBM7WSegI= + +debug@^4.1.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +fs-extra@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +html-minifier-terser@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +minify@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/minify/-/minify-7.0.2.tgz#8ac33a490c907b581a6cb4970dc656bb6d59ac11" + integrity sha512-qWFzieSULBAKTLbTqaXY5OLFbFNuEa1b0M+piLkpgJ6pHrMyvvCw6H7WM5/d+HJIwgUCLMI0uEAAyhawAF6cbA== + dependencies: + clean-css "^5.0.1" + css-b64-images "~0.2.5" + debug "^4.1.0" + html-minifier-terser "^5.1.1" + terser "^5.3.2" + try-to-catch "^3.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +param-case@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +prettier@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +sass@^1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.36.0.tgz#5912ef9d5d16714171ba11cb17edb274c4bbc07e" + integrity sha512-fQzEjipfOv5kh930nu3Imzq3ie/sGDc/4KtQMJlt7RRdrkQSfe37Bwi/Rf/gfuYHsIuE1fIlDMvpyMcEwjnPvg== + dependencies: + chokidar ">=3.0.0 <4.0.0" + +source-map-support@~0.5.12, source-map-support@~0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +terser@^4.6.3: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +terser@^5.3.2: + version "5.7.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" + integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +try-to-catch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/try-to-catch/-/try-to-catch-3.0.0.tgz#a1903b44d13d5124c54d14a461d22ec1f52ea14b" + integrity sha512-eIm6ZXwR35jVF8By/HdbbkcaCDTBI5PpCPkejRKrYp0jyf/DbCCcRhHD7/O9jtFI3ewsqo9WctFEiJTS6i+CQA== + +tslib@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==