From 0c55a4b8d2e854532ed0c1f530cab4d7c9cbdc20 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 07:18:12 +0100 Subject: [PATCH 001/451] fix: build tailwind before runing watch mode --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83f201cb..fe900128 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "client:build": "rollup -c", "tailwind:build": "node tailwind/build.js", "start": "electron app/main/index.js", - "watch": "concurrently -k -n client,app -c magenta,yellow \"yarn client:watch\" \"yarn app:watch\"", + "watch": "yarn tailwind:build && concurrently -k -n client,app -c magenta,yellow \"yarn client:watch\" \"yarn app:watch\"", "build": "yarn tailwind:build --prod && yarn client:build", "prettify": "prettier --write ./app ./client-src", "lint": "eslint ./app ./client-src --fix && yarn prettify" From b32652786f73eac4ef79d6325341bd8dbf3f67cc Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 07:53:06 +0100 Subject: [PATCH 002/451] tailwind watch on dev mode --- package.json | 5 ++++- tailwind/build.js | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fe900128..cd6aec48 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "client:build": "rollup -c", "tailwind:build": "node tailwind/build.js", "start": "electron app/main/index.js", - "watch": "yarn tailwind:build && concurrently -k -n client,app -c magenta,yellow \"yarn client:watch\" \"yarn app:watch\"", + "watch": "concurrently -k -n tailwind,client,app -c red,magenta,yellow \"yarn tailwind:build\" \"yarn client:watch\" \"yarn app:watch\"", "build": "yarn tailwind:build --prod && yarn client:build", "prettify": "prettier --write ./app ./client-src", "lint": "eslint ./app ./client-src --fix && yarn prettify" @@ -53,5 +53,8 @@ "tailwindcss": "^1.9.6", "throttle-debounce": "^3.0.1", "uuid": "^8.3.1" + }, + "dependencies": { + "chalk": "^4.1.0" } } diff --git a/tailwind/build.js b/tailwind/build.js index fd9cd6f6..10b25dd8 100644 --- a/tailwind/build.js +++ b/tailwind/build.js @@ -4,12 +4,32 @@ const tailwind = require.resolve("tailwindcss/lib/cli.js"); const { fork } = require("child_process"); +const chalk = require("chalk"); const path = require("path"); +const colors = new chalk.Instance({ level: 3 }); const config = path.resolve(__dirname, "config.js"); const input = path.resolve(__dirname, "index.css"); const output = path.resolve(__dirname, "../app/static/css/tailwind.css"); const argv = [...process.argv.slice(2), "--no-autoprefixer"]; const args = ["build", input, "-c", config, "-o", output, ...argv]; -fork(tailwind, args, { stdio: ["inherit", "inherit", "inherit", "ipc"] }); +function build() { + fork(tailwind, args, { stdio: ["inherit", "inherit", "inherit", "ipc"] }); +} + +build(); + +if (!process.argv.includes("--prod")) { + const icon = colors.green("↺"); + const chokidar = require("chokidar"); + const watcher = chokidar.watch(__dirname); + const rootPath = path.resolve(__dirname, "../.."); + + watcher.on("ready", () => { + watcher.on("change", (source) => { + console.log(`${icon} file changed: ${path.relative(rootPath, source)}`); + build(); + }); + }); +} From 1350c55bdc446fb1e8f07e1bff27c0dbd70ff1e3 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 07:54:13 +0100 Subject: [PATCH 003/451] eslint-disable-next-line no-console --- tailwind/build.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tailwind/build.js b/tailwind/build.js index 10b25dd8..022bdcee 100644 --- a/tailwind/build.js +++ b/tailwind/build.js @@ -28,6 +28,7 @@ if (!process.argv.includes("--prod")) { watcher.on("ready", () => { watcher.on("change", (source) => { + // eslint-disable-next-line no-console console.log(`${icon} file changed: ${path.relative(rootPath, source)}`); build(); }); From 7e84e273007e0079d77110feb337e94ff18db619 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 07:57:55 +0100 Subject: [PATCH 004/451] fix: removed absolute paths from stores --- app/main/server.js | 2 +- app/main/tray.js | 4 +++- app/main/window/index.js | 4 +++- app/server/index.js | 7 ++++++- app/server/libs/files.js | 3 ++- app/server/libs/i18next/index.js | 5 +++-- app/stores/create.js | 6 +++++- app/stores/defaults/app.js | 6 ++---- app/stores/defaults/server.js | 10 ---------- app/stores/utils.js | 4 ++++ 10 files changed, 29 insertions(+), 22 deletions(-) diff --git a/app/main/server.js b/app/main/server.js index 91902439..fa54eaae 100644 --- a/app/main/server.js +++ b/app/main/server.js @@ -4,7 +4,7 @@ const chalk = require("chalk"); const path = require("path"); const dev = !store.app.get("production"); -const colors = new chalk.Instance({ level: 2 }); +const colors = new chalk.Instance({ level: 3 }); const rootPath = path.resolve(__dirname, "../.."); const serverPath = path.join(__dirname, "../server"); const serverBin = path.join(serverPath, "index.js"); diff --git a/app/main/tray.js b/app/main/tray.js index da5f6e28..8f136a6c 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -1,9 +1,11 @@ const { _ } = require("../server/libs/i18next"); +const { appPath } = require("../stores/utils"); const { Tray, Menu } = require("electron"); const createWindow = require("./window"); const capitalize = require("capitalize"); const store = require("../stores"); const quit = require("./quit"); +const path = require("path"); const open = require("open"); const { name, version, icon } = store.app.getAll(); @@ -34,7 +36,7 @@ function createMenu() { } function createTray() { - tray = new Tray(icon); + tray = new Tray(path.join(appPath, icon)); tray.setToolTip(fingerprint); tray.setContextMenu(createMenu()); diff --git a/app/main/window/index.js b/app/main/window/index.js index 3560308f..36b78ba2 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -1,10 +1,12 @@ +const { appPath } = require("../../stores/utils"); const { BrowserWindow } = require("electron"); const hideOnClose = require("./hideOnClose"); const store = require("../../stores"); +const path = require("path"); let win = null; -const icon = store.app.get("icon"); +const icon = path.join(appPath, store.app.get("icon")); const devTools = !store.app.get("production"); function createWindow() { diff --git a/app/server/index.js b/app/server/index.js index bc3db480..c7a6cefc 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -2,6 +2,7 @@ "use strict"; +const { appPath, userPaths } = require("../stores/utils"); const socket = require("./libs/socket.io"); const { json } = require("body-parser"); const stores = require("../stores"); @@ -13,9 +14,13 @@ const path = require("path"); const { i18next } = require("./libs/i18next"); const missingKeyHandler = require("./libs/i18next/missingKeyHandler"); -let { host, port, clientPath, staticPath, uploadPath } = stores.server.getAll(); +let { host, port } = stores.server.getAll(); const appFingerprint = stores.app.get("fingerprint"); +const clientPath = path.join(appPath, "client"); +const staticPath = path.join(appPath, "static"); +const uploadPath = path.join(userPaths.data, "files"); + const sirvClient = sirv(clientPath, { dev: true }); const sirvStatic = sirv(staticPath, { dev: true }); const sirvUpload = sirv(path.dirname(uploadPath), { dev: true }); diff --git a/app/server/libs/files.js b/app/server/libs/files.js index a34de588..af4e08d6 100644 --- a/app/server/libs/files.js +++ b/app/server/libs/files.js @@ -3,9 +3,10 @@ const mime = require("mime"); const fs = require("fs-extra"); const { _ } = require("./i18next"); const stores = require("../../stores"); +const { userPaths } = require("../../stores/utils"); const language = stores.i18next.get("lng", "en"); -const uploadPath = stores.server.get("uploadPath"); +const uploadPath = path.join(userPaths.data, "files"); const allowedMimeTypes = ["text", "image", "audio", "video"]; fs.ensureDirSync(uploadPath); diff --git a/app/server/libs/i18next/index.js b/app/server/libs/i18next/index.js index 1b636e23..9894b502 100644 --- a/app/server/libs/i18next/index.js +++ b/app/server/libs/i18next/index.js @@ -1,10 +1,11 @@ +const { appPath } = require("../../../stores/utils"); const backend = require("i18next-fs-backend"); +const stores = require("../../../stores"); const i18next = require("i18next"); const path = require("path"); -const stores = require("../../../stores"); const options = stores.i18next.getAll(); -const locales = path.join(stores.server.get("staticPath"), "locales"); +const locales = path.join(appPath, "static/locales"); i18next.use(backend).init({ ...options, diff --git a/app/stores/create.js b/app/stores/create.js index 23593e5a..f78c8f49 100644 --- a/app/stores/create.js +++ b/app/stores/create.js @@ -1,8 +1,12 @@ +const { userPaths } = require("./utils"); const Conf = require("conf"); +const path = require("path"); + +const cwd = path.join(userPaths.data, "stores"); class Store extends Conf { constructor(name, options = {}) { - super({ ...options, configName: name }); + super({ ...options, configName: name, cwd }); } getAll() { diff --git a/app/stores/defaults/app.js b/app/stores/defaults/app.js index e5edfa82..99ff3411 100644 --- a/app/stores/defaults/app.js +++ b/app/stores/defaults/app.js @@ -1,13 +1,11 @@ const { name, version } = require("../../package"); -const { watch, appPath } = require("../utils"); -const path = require("path"); +const { watch } = require("../utils"); module.exports = { name, version, - path: appPath, production: !watch, openOnStartup: false, + icon: "static/icon.png", fingerprint: `${name} v${version}`, - icon: path.join(appPath, "static/icon.png"), }; diff --git a/app/stores/defaults/server.js b/app/stores/defaults/server.js index b029953e..fd397ea8 100644 --- a/app/stores/defaults/server.js +++ b/app/stores/defaults/server.js @@ -1,14 +1,4 @@ -const { name } = require("../../package"); -const { appPath } = require("../utils"); -const envPaths = require("env-paths"); -const path = require("path"); - -const userDir = envPaths(name).data; - module.exports = { port: 4242, host: "localhost", - clientPath: path.join(appPath, "client"), - staticPath: path.join(appPath, "static"), - uploadPath: path.join(userDir, "files"), }; diff --git a/app/stores/utils.js b/app/stores/utils.js index 01eacb34..71aa06ad 100644 --- a/app/stores/utils.js +++ b/app/stores/utils.js @@ -1,9 +1,13 @@ +const { name } = require("../package"); +const envPaths = require("env-paths"); const path = require("path"); +const userPaths = envPaths(name); const appPath = path.resolve(__dirname, ".."); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); module.exports = { watch, appPath, + userPaths, }; From 85f5af3b201e1457945a70f069f3462c67a8efd0 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 08:07:54 +0100 Subject: [PATCH 005/451] moved utils.js to app root --- app/main/tray.js | 2 +- app/main/window/index.js | 2 +- app/server/index.js | 2 +- app/server/libs/files.js | 2 +- app/server/libs/i18next/index.js | 2 +- app/stores/create.js | 2 +- app/stores/defaults/app.js | 2 +- app/stores/defaults/i18next.js | 2 +- app/{stores => }/utils.js | 5 ++--- 9 files changed, 10 insertions(+), 11 deletions(-) rename app/{stores => }/utils.js (64%) diff --git a/app/main/tray.js b/app/main/tray.js index 8f136a6c..1f10e8e5 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -1,5 +1,5 @@ const { _ } = require("../server/libs/i18next"); -const { appPath } = require("../stores/utils"); +const { appPath } = require("../utils"); const { Tray, Menu } = require("electron"); const createWindow = require("./window"); const capitalize = require("capitalize"); diff --git a/app/main/window/index.js b/app/main/window/index.js index 36b78ba2..7db9e89a 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -1,4 +1,4 @@ -const { appPath } = require("../../stores/utils"); +const { appPath } = require("../../utils"); const { BrowserWindow } = require("electron"); const hideOnClose = require("./hideOnClose"); const store = require("../../stores"); diff --git a/app/server/index.js b/app/server/index.js index c7a6cefc..b42b0a4e 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -2,7 +2,7 @@ "use strict"; -const { appPath, userPaths } = require("../stores/utils"); +const { appPath, userPaths } = require("../utils"); const socket = require("./libs/socket.io"); const { json } = require("body-parser"); const stores = require("../stores"); diff --git a/app/server/libs/files.js b/app/server/libs/files.js index af4e08d6..486bd11b 100644 --- a/app/server/libs/files.js +++ b/app/server/libs/files.js @@ -3,7 +3,7 @@ const mime = require("mime"); const fs = require("fs-extra"); const { _ } = require("./i18next"); const stores = require("../../stores"); -const { userPaths } = require("../../stores/utils"); +const { userPaths } = require("../../utils"); const language = stores.i18next.get("lng", "en"); const uploadPath = path.join(userPaths.data, "files"); diff --git a/app/server/libs/i18next/index.js b/app/server/libs/i18next/index.js index 9894b502..5e097cda 100644 --- a/app/server/libs/i18next/index.js +++ b/app/server/libs/i18next/index.js @@ -1,4 +1,4 @@ -const { appPath } = require("../../../stores/utils"); +const { appPath } = require("../../../utils"); const backend = require("i18next-fs-backend"); const stores = require("../../../stores"); const i18next = require("i18next"); diff --git a/app/stores/create.js b/app/stores/create.js index f78c8f49..487693ff 100644 --- a/app/stores/create.js +++ b/app/stores/create.js @@ -1,4 +1,4 @@ -const { userPaths } = require("./utils"); +const { userPaths } = require("../utils"); const Conf = require("conf"); const path = require("path"); diff --git a/app/stores/defaults/app.js b/app/stores/defaults/app.js index 99ff3411..45cc9156 100644 --- a/app/stores/defaults/app.js +++ b/app/stores/defaults/app.js @@ -1,5 +1,5 @@ const { name, version } = require("../../package"); -const { watch } = require("../utils"); +const { watch } = require("../../utils"); module.exports = { name, diff --git a/app/stores/defaults/i18next.js b/app/stores/defaults/i18next.js index 6b2400a5..009b445b 100644 --- a/app/stores/defaults/i18next.js +++ b/app/stores/defaults/i18next.js @@ -1,4 +1,4 @@ -const { watch } = require("../utils"); +const { watch } = require("../../utils"); module.exports = { ns: "app", diff --git a/app/stores/utils.js b/app/utils.js similarity index 64% rename from app/stores/utils.js rename to app/utils.js index 71aa06ad..beeae1f8 100644 --- a/app/stores/utils.js +++ b/app/utils.js @@ -1,9 +1,8 @@ -const { name } = require("../package"); +const { name } = require("./package"); const envPaths = require("env-paths"); -const path = require("path"); +const appPath = __dirname; const userPaths = envPaths(name); -const appPath = path.resolve(__dirname, ".."); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); module.exports = { From 5126a99ba9bb819f2cf7c3ac8c6ef04b72b36b48 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 11:20:50 +0100 Subject: [PATCH 006/451] centralized app paths --- app/server/index.js | 18 ++++++------------ app/server/libs/files.js | 16 ++++++---------- app/stores/create.js | 7 ++----- app/utils.js | 15 +++++++++++++-- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/app/server/index.js b/app/server/index.js index b42b0a4e..a7793647 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -2,28 +2,22 @@ "use strict"; -const { appPath, userPaths } = require("../utils"); -const socket = require("./libs/socket.io"); -const { json } = require("body-parser"); -const stores = require("../stores"); -const polka = require("polka"); const sirv = require("sirv"); const http = require("http"); -const path = require("path"); - +const polka = require("polka"); +const stores = require("../stores"); +const { json } = require("body-parser"); +const socket = require("./libs/socket.io"); const { i18next } = require("./libs/i18next"); +const { uploadPath, clientPath, staticPath } = require("../utils"); const missingKeyHandler = require("./libs/i18next/missingKeyHandler"); let { host, port } = stores.server.getAll(); const appFingerprint = stores.app.get("fingerprint"); -const clientPath = path.join(appPath, "client"); -const staticPath = path.join(appPath, "static"); -const uploadPath = path.join(userPaths.data, "files"); - const sirvClient = sirv(clientPath, { dev: true }); const sirvStatic = sirv(staticPath, { dev: true }); -const sirvUpload = sirv(path.dirname(uploadPath), { dev: true }); +const sirvUpload = sirv(uploadPath, { dev: true }); let portChangeCount = 0; let portChangeMaxCount = 10; diff --git a/app/server/libs/files.js b/app/server/libs/files.js index 486bd11b..449a2516 100644 --- a/app/server/libs/files.js +++ b/app/server/libs/files.js @@ -3,13 +3,12 @@ const mime = require("mime"); const fs = require("fs-extra"); const { _ } = require("./i18next"); const stores = require("../../stores"); -const { userPaths } = require("../../utils"); +const { filesPath } = require("../../utils"); const language = stores.i18next.get("lng", "en"); -const uploadPath = path.join(userPaths.data, "files"); const allowedMimeTypes = ["text", "image", "audio", "video"]; -fs.ensureDirSync(uploadPath); +fs.ensureDirSync(filesPath); function cleanFileName(name) { return name.replace(/[^a-z0-9_.]+/gi, "_"); @@ -30,10 +29,7 @@ function getFileInfo(filename, buffer) { } function getFileInfoFromFilename(filename) { - return getFileInfo( - filename, - fs.readFileSync(path.join(uploadPath, filename)) - ); + return getFileInfo(filename, fs.readFileSync(path.join(filesPath, filename))); } function isAllowedMimeType(type) { @@ -44,7 +40,7 @@ async function upload({ name, buffer }) { return new Promise((resolve, reject) => { const filename = cleanFileName(name); const fileInfo = getFileInfo(filename, buffer); - const filePath = path.join(uploadPath, filename); + const filePath = path.join(filesPath, filename); if (!fileInfo.size) { return reject(_("sentences.file-is-empty")); @@ -71,7 +67,7 @@ async function upload({ name, buffer }) { function remove(file) { return new Promise((resolve, reject) => { try { - fs.unlinkSync(path.join(uploadPath, file.filename)); + fs.unlinkSync(path.join(filesPath, file.filename)); resolve(file); } catch (error) { reject(error); @@ -89,7 +85,7 @@ function localeSort(a, b) { function getFileList() { return new Promise((resolve, reject) => { try { - const files = fs.readdirSync(uploadPath); + const files = fs.readdirSync(filesPath); const fileList = files .sort(localeSort) .map(getFileInfoFromFilename) diff --git a/app/stores/create.js b/app/stores/create.js index 487693ff..370a553c 100644 --- a/app/stores/create.js +++ b/app/stores/create.js @@ -1,12 +1,9 @@ -const { userPaths } = require("../utils"); +const { storesPath } = require("../utils"); const Conf = require("conf"); -const path = require("path"); - -const cwd = path.join(userPaths.data, "stores"); class Store extends Conf { constructor(name, options = {}) { - super({ ...options, configName: name, cwd }); + super({ ...options, configName: name, cwd: storesPath }); } getAll() { diff --git a/app/utils.js b/app/utils.js index beeae1f8..1c244429 100644 --- a/app/utils.js +++ b/app/utils.js @@ -1,12 +1,23 @@ const { name } = require("./package"); const envPaths = require("env-paths"); +const path = require("path"); const appPath = __dirname; -const userPaths = envPaths(name); +const userPath = envPaths(name).data; +const clientPath = path.join(appPath, "client"); +const staticPath = path.join(appPath, "static"); +const uploadPath = path.join(userPath, "upload"); +const storesPath = path.join(userPath, "stores"); +const filesPath = path.join(uploadPath, "files"); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); module.exports = { watch, appPath, - userPaths, + userPath, + filesPath, + uploadPath, + storesPath, + staticPath, + clientPath, }; From b91c552370e43b5128f55ec5bb7c89d1a27f8b2b Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 11:21:01 +0100 Subject: [PATCH 007/451] fix: tailwind build order --- package.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index cd6aec48..68a9ff26 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "tailwind:build": "node tailwind/build.js", "start": "electron app/main/index.js", "watch": "concurrently -k -n tailwind,client,app -c red,magenta,yellow \"yarn tailwind:build\" \"yarn client:watch\" \"yarn app:watch\"", - "build": "yarn tailwind:build --prod && yarn client:build", + "build": "yarn client:build && yarn tailwind:build --prod", "prettify": "prettier --write ./app ./client-src", "lint": "eslint ./app ./client-src --fix && yarn prettify" }, @@ -27,6 +27,7 @@ "@rollup/plugin-node-resolve": "^9.0.0", "animejs": "^3.2.1", "capitalize": "^2.0.3", + "chalk": "^4.1.0", "clone-deep": "^4.0.1", "concurrently": "^5.3.0", "electron": "^10.1.5", @@ -53,8 +54,5 @@ "tailwindcss": "^1.9.6", "throttle-debounce": "^3.0.1", "uuid": "^8.3.1" - }, - "dependencies": { - "chalk": "^4.1.0" } } From 3382ef6fddb9d056eac71b5af4aaa78add6eb3e9 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 11:42:43 +0100 Subject: [PATCH 008/451] removed icon path from store --- app/main/server.js | 5 ++--- app/main/tray.js | 6 +++--- app/main/window/index.js | 12 ++++-------- app/stores/defaults/app.js | 3 --- 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/app/main/server.js b/app/main/server.js index fa54eaae..223fdd2e 100644 --- a/app/main/server.js +++ b/app/main/server.js @@ -1,9 +1,8 @@ const { fork } = require("child_process"); -const store = require("../stores"); +const { watch } = require("../utils"); const chalk = require("chalk"); const path = require("path"); -const dev = !store.app.get("production"); const colors = new chalk.Instance({ level: 3 }); const rootPath = path.resolve(__dirname, "../.."); const serverPath = path.join(__dirname, "../server"); @@ -53,7 +52,7 @@ function stop() { server = null; } -if (dev) { +if (watch) { const icon = colors.green("↺"); const chokidar = require("chokidar"); const watcher = chokidar.watch(path.join(serverPath, "**/*")); diff --git a/app/main/tray.js b/app/main/tray.js index 1f10e8e5..320f7e13 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -1,6 +1,6 @@ const { _ } = require("../server/libs/i18next"); -const { appPath } = require("../utils"); const { Tray, Menu } = require("electron"); +const { staticPath } = require("../utils"); const createWindow = require("./window"); const capitalize = require("capitalize"); const store = require("../stores"); @@ -8,7 +8,7 @@ const quit = require("./quit"); const path = require("path"); const open = require("open"); -const { name, version, icon } = store.app.getAll(); +const { name, version } = store.app.getAll(); const fingerprint = `${capitalize(name)} v${version}`; let tray = null; @@ -36,7 +36,7 @@ function createMenu() { } function createTray() { - tray = new Tray(path.join(appPath, icon)); + tray = new Tray(path.join(staticPath, "icon.png")); tray.setToolTip(fingerprint); tray.setContextMenu(createMenu()); diff --git a/app/main/window/index.js b/app/main/window/index.js index 7db9e89a..d66af704 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -1,25 +1,21 @@ -const { appPath } = require("../../utils"); +const { staticPath, watch } = require("../../utils"); const { BrowserWindow } = require("electron"); const hideOnClose = require("./hideOnClose"); -const store = require("../../stores"); const path = require("path"); let win = null; -const icon = path.join(appPath, store.app.get("icon")); -const devTools = !store.app.get("production"); - function createWindow() { if (win) { return win.show(); } win = new BrowserWindow({ - icon, width: 800, height: 600, show: false, - webPreferences: { devTools }, + icon: path.join(staticPath, "icon.png"), + webPreferences: { devTools: watch }, }); hideOnClose(win); @@ -29,7 +25,7 @@ function createWindow() { }); win.loadURL("http://localhost:4242/"); - devTools && win.webContents.openDevTools(); + watch && win.webContents.openDevTools(); } module.exports = createWindow; diff --git a/app/stores/defaults/app.js b/app/stores/defaults/app.js index 45cc9156..81bb395a 100644 --- a/app/stores/defaults/app.js +++ b/app/stores/defaults/app.js @@ -1,11 +1,8 @@ const { name, version } = require("../../package"); -const { watch } = require("../../utils"); module.exports = { name, version, - production: !watch, openOnStartup: false, - icon: "static/icon.png", fingerprint: `${name} v${version}`, }; From 8467739084d3437281b9f01669c1c0ba63758fb5 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 11:43:11 +0100 Subject: [PATCH 009/451] throw action on push tag v* --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e31fff8..28cc4b32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,9 @@ name: Build/release -on: push +on: + push: + tags: + - "v*" jobs: release: From 3cd3e77fb741d0a7861c61f20439996b0514a42a Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 12:18:16 +0100 Subject: [PATCH 010/451] upgrade node version --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28cc4b32..1b6157f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v1 with: - node-version: 10 + node-version: 12 - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 From 02db5faea2a98209b8b00de6529405af574864bd Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 12:18:19 +0100 Subject: [PATCH 011/451] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index ad36be27..5a9ad13f 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,15 @@ yarn build # lint project yarn lint ``` + +# How to build with npm (easier from ubuntu?): + +``` +cd marv +npm install +npm run tailwind:build --prod +npm run client:build +npm run app:build +``` + +Credit: thermo74 :) From 996b8d6c0ea4aff459a72c9e517f07548f95d40d Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 12:18:32 +0100 Subject: [PATCH 012/451] add left click to open window --- app/main/tray.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/main/tray.js b/app/main/tray.js index 320f7e13..b5b89cc0 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -39,6 +39,7 @@ function createTray() { tray = new Tray(path.join(staticPath, "icon.png")); tray.setToolTip(fingerprint); + tray.on("click", createWindow); tray.setContextMenu(createMenu()); tray.setIgnoreDoubleClickEvents(true); From 1d8a43cd47719ba26f6c96a0b5aace26084591ce Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 12:19:05 +0100 Subject: [PATCH 013/451] fix: client URL --- app/main/window/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/main/window/index.js b/app/main/window/index.js index d66af704..f0bb76dd 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -1,8 +1,11 @@ const { staticPath, watch } = require("../../utils"); const { BrowserWindow } = require("electron"); const hideOnClose = require("./hideOnClose"); +const stores = require("../../stores"); const path = require("path"); +const { host, port } = stores.server.getAll(); + let win = null; function createWindow() { @@ -24,7 +27,7 @@ function createWindow() { win.show(); }); - win.loadURL("http://localhost:4242/"); + win.loadURL(`http://${host}:${port}`); watch && win.webContents.openDevTools(); } From 2da2cf42d197f2593432d7a7a327309b4decf087 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 12:19:18 +0100 Subject: [PATCH 014/451] removed main menu --- app/main/window/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/main/window/index.js b/app/main/window/index.js index f0bb76dd..7fde1be0 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -27,6 +27,7 @@ function createWindow() { win.show(); }); + win.removeMenu(); win.loadURL(`http://${host}:${port}`); watch && win.webContents.openDevTools(); } From d6aa5c57bc8dd9c9ec5d7586d9e1fe228f01bcdc Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 14:33:55 +0100 Subject: [PATCH 015/451] fix: remove actions when widget/panel removed --- app/server/api/panels.js | 5 +++++ app/server/libs/actions.js | 1 + app/server/libs/actions/remove.js | 5 +++++ app/server/libs/panels.js | 13 +++++++++++++ client-src/api/panels.js | 2 ++ .../Panels/Panel/Widget/EditModal/Action.svelte | 11 ++++++++--- client-src/libs/panels.js | 8 +++++--- 7 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 app/server/libs/actions/remove.js diff --git a/app/server/api/panels.js b/app/server/api/panels.js index 488e869b..fbc5e94e 100644 --- a/app/server/api/panels.js +++ b/app/server/api/panels.js @@ -28,4 +28,9 @@ module.exports = { this.notify("panels.update", payload.panel); return payload; }, + removeWidgetComponent(panel, widget) { + const payload = panels.removeWidgetComponent(panel, widget); + this.notify("panels.update", payload.panel); + return payload; + }, }; diff --git a/app/server/libs/actions.js b/app/server/libs/actions.js index b209fc2c..e46932d0 100644 --- a/app/server/libs/actions.js +++ b/app/server/libs/actions.js @@ -2,5 +2,6 @@ module.exports = { get: require("./actions/get"), push: require("./actions/push"), update: require("./actions/update"), + remove: require("./actions/remove"), getState: require("./actions/state").getState, }; diff --git a/app/server/libs/actions/remove.js b/app/server/libs/actions/remove.js new file mode 100644 index 00000000..e87cc4cf --- /dev/null +++ b/app/server/libs/actions/remove.js @@ -0,0 +1,5 @@ +const { actions } = require("../../../stores"); + +module.exports = function remove(id) { + return actions.delete(`actions.${id}`); +}; diff --git a/app/server/libs/panels.js b/app/server/libs/panels.js index b6f224c0..d37be79f 100644 --- a/app/server/libs/panels.js +++ b/app/server/libs/panels.js @@ -1,4 +1,5 @@ const { panels: store } = require("../../stores"); +const actions = require("./actions"); const { v4: uuid } = require("uuid"); const { _ } = require("./i18next"); @@ -57,6 +58,9 @@ function remove(panel) { panels = panels.filter((p, i) => { if (p.id === panel.id) { pos = i; + panel.widgets.forEach((widget) => { + actions.remove(widget.id); + }); return false; } return true; @@ -77,7 +81,15 @@ function addWidget(panel, item) { return { panel: update(oldPanel), widget, item }; } +function removeWidgetComponent(panel, widget) { + if (!widget.component) return; + actions.remove(widget.id); + widget.component = null; + return { panel: update(panel), widget }; +} + function removeWidget(panel, widget) { + removeWidgetComponent(panel, widget); const oldPanel = findPanelById(panel.id); oldPanel.grid = oldPanel.grid.filter((w) => w.id !== widget.id); oldPanel.widgets = oldPanel.widgets.filter((w) => w.id !== widget.id); @@ -90,4 +102,5 @@ module.exports = { update, addWidget, removeWidget, + removeWidgetComponent, }; diff --git a/client-src/api/panels.js b/client-src/api/panels.js index 37022053..d5eaa718 100644 --- a/client-src/api/panels.js +++ b/client-src/api/panels.js @@ -8,4 +8,6 @@ export default { on: (eventName, callback) => on(`panels.${eventName}`, callback), addWidget: (panel, item) => emit("panels.addWidget", panel, item), removeWidget: (panel, widget) => emit("panels.removeWidget", panel, widget), + removeWidgetComponent: (panel, widget) => + emit("panels.removeWidgetComponent", panel, widget), }; diff --git a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte index 6391c8e4..97799122 100644 --- a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte +++ b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte @@ -1,10 +1,10 @@ diff --git a/client-src/libs/panels.js b/client-src/libs/panels.js index 10480b44..2ad96308 100644 --- a/client-src/libs/panels.js +++ b/client-src/libs/panels.js @@ -1,11 +1,13 @@ import api from "@/api/panels"; -function updateReducer({ id, x, y, w, h }) { +export function updateReducer({ id, x, y, w, h }) { return { id, x, y, w, h }; } -function update(panel) { +export function update(panel) { return api.update({ ...panel, grid: panel.grid.map(updateReducer) }); } -export { update }; +export function removeWidgetComponent(panel, widget) { + return api.removeWidgetComponent(panel, widget); +} From 6fbed5a6b6b3a84d8ebd643dd35d428ec9ace6c0 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 14:44:21 +0100 Subject: [PATCH 016/451] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5a9ad13f..3d53b3eb 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ yarn start # build application in production mode yarn build +yarn app:build # lint project yarn lint From e49972ea2e2d4bdd5352987a4c70e7dc652f6174 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 14:47:35 +0100 Subject: [PATCH 017/451] v0.4.0 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index ec9b0a30..fc636437 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.3.3", + "version": "0.4.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index 68a9ff26..54031051 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.3.3", + "version": "0.4.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 92c342cf52d705834fdd5d492bc4cd53c1621295 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 15:12:01 +0100 Subject: [PATCH 018/451] ubuntu latest -> 20.04 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1b6157f1..0492642c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - os: [macos-latest, ubuntu-latest, windows-latest] + os: [macos-latest, ubuntu-20.04, windows-latest] steps: - name: Check out Git repository From f1fe8ee647c7799f4d0f925e49aec0a11c764c82 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 15:12:14 +0100 Subject: [PATCH 019/451] v0.4.1 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index fc636437..ad49ea12 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.0", + "version": "0.4.1", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index 54031051..83f6b651 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.0", + "version": "0.4.1", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From be1d669c928c6b174b9087e0e290c672735b91c2 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 15:20:43 +0100 Subject: [PATCH 020/451] node version -> 10, reverte uhuntu version to latest --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0492642c..28cc4b32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - os: [macos-latest, ubuntu-20.04, windows-latest] + os: [macos-latest, ubuntu-latest, windows-latest] steps: - name: Check out Git repository @@ -20,7 +20,7 @@ jobs: - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 10 - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 From 019e7d910645690b3b7a2c048ad0d51b3ca0e6d1 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 15:21:12 +0100 Subject: [PATCH 021/451] v0.4.2 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index ad49ea12..16f37524 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.1", + "version": "0.4.2", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index 83f6b651..21b77479 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.1", + "version": "0.4.2", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 262b6c609bf7e05bd27bfdfcb839604938461145 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 15:36:25 +0100 Subject: [PATCH 022/451] removed release the app after building --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28cc4b32..1720c6c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v1 with: - node-version: 10 + node-version: 12 - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 @@ -31,4 +31,4 @@ jobs: # If the commit is tagged with a version (e.g. "v1.0.0"), # release the app after building - release: ${{ startsWith(github.ref, 'refs/tags/v') }} + #release: ${{ startsWith(github.ref, 'refs/tags/v') }} From 734eef158c2df53d3e068e191aad6e45c941a0d1 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 15:36:43 +0100 Subject: [PATCH 023/451] v0.4.3 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index 16f37524..726cf93f 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.2", + "version": "0.4.3", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index 21b77479..f39ff984 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.2", + "version": "0.4.3", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 0cf18434a2f5de31b864dca4278b9bbea1bb0a99 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 20 Nov 2020 16:13:30 +0100 Subject: [PATCH 024/451] v0.4.4 --- .github/workflows/build.yml | 3 ++- app/package.json | 2 +- package.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1720c6c4..3f7336c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,10 +25,11 @@ jobs: - name: Build/release Electron app uses: samuelmeuli/action-electron-builder@v1 with: + args: -c.snap.publish=github # GitHub token, automatically provided to the action # (No need to define this secret in the repo settings) github_token: ${{ secrets.github_token }} # If the commit is tagged with a version (e.g. "v1.0.0"), # release the app after building - #release: ${{ startsWith(github.ref, 'refs/tags/v') }} + release: ${{ startsWith(github.ref, 'refs/tags/v') }} diff --git a/app/package.json b/app/package.json index 726cf93f..12f36217 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.3", + "version": "0.4.4", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index f39ff984..7e64f030 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.3", + "version": "0.4.4", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 3396b333c64953837838f5ccbb67c3e8d04932b6 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 21 Nov 2020 05:55:28 +0100 Subject: [PATCH 025/451] removed i18next store --- app/server/api/i18next.js | 5 +++-- app/server/libs/files.js | 2 +- .../libs/i18next/config.js} | 4 ++-- app/server/libs/i18next/index.js | 18 ++++++++++++------ app/stores/defaults/app.js | 1 + client-src/libs/i18next.js | 2 +- client-src/stores/i18next.js | 2 +- 7 files changed, 21 insertions(+), 13 deletions(-) rename app/{stores/defaults/i18next.js => server/libs/i18next/config.js} (78%) diff --git a/app/server/api/i18next.js b/app/server/api/i18next.js index 5354b8aa..f7aad33c 100644 --- a/app/server/api/i18next.js +++ b/app/server/api/i18next.js @@ -1,9 +1,10 @@ const stores = require("../../stores"); -const { i18next } = require("../libs/i18next"); +const { i18next, getConfig } = require("../libs/i18next"); module.exports = { + getConfig: () => getConfig(), changeLanguage: (language) => { i18next.changeLanguage(language); - stores.i18next.set("lng", language); + stores.app.set("language", language); }, }; diff --git a/app/server/libs/files.js b/app/server/libs/files.js index 449a2516..1cbb2ed3 100644 --- a/app/server/libs/files.js +++ b/app/server/libs/files.js @@ -5,7 +5,7 @@ const { _ } = require("./i18next"); const stores = require("../../stores"); const { filesPath } = require("../../utils"); -const language = stores.i18next.get("lng", "en"); +const language = stores.app.get("language", "en"); const allowedMimeTypes = ["text", "image", "audio", "video"]; fs.ensureDirSync(filesPath); diff --git a/app/stores/defaults/i18next.js b/app/server/libs/i18next/config.js similarity index 78% rename from app/stores/defaults/i18next.js rename to app/server/libs/i18next/config.js index 009b445b..594c02cf 100644 --- a/app/stores/defaults/i18next.js +++ b/app/server/libs/i18next/config.js @@ -1,8 +1,8 @@ -const { watch } = require("../../utils"); +const { watch } = require("../../../utils"); module.exports = { - ns: "app", lng: "en", + ns: "app", defaultNS: "app", fallbackLng: "en", supportedLngs: ["en", "fr"], diff --git a/app/server/libs/i18next/index.js b/app/server/libs/i18next/index.js index 5e097cda..8aa2a36e 100644 --- a/app/server/libs/i18next/index.js +++ b/app/server/libs/i18next/index.js @@ -1,21 +1,27 @@ const { appPath } = require("../../../utils"); const backend = require("i18next-fs-backend"); const stores = require("../../../stores"); +const config = require("./config"); const i18next = require("i18next"); const path = require("path"); -const options = stores.i18next.getAll(); const locales = path.join(appPath, "static/locales"); +function getConfig() { + return { ...config, lng: stores.app.get("language") }; +} + +function _(...args) { + return i18next.t(...args); +} + i18next.use(backend).init({ - ...options, + ...getConfig(), initImmediate: false, backend: { - loadPath: `${locales}/{{lng}}/{{ns}}.json`, addPath: `${locales}/{{lng}}/{{ns}}.json`, + loadPath: `${locales}/{{lng}}/{{ns}}.json`, }, }); -const _ = (...args) => i18next.t(...args); - -module.exports = { i18next, _ }; +module.exports = { i18next, _, getConfig }; diff --git a/app/stores/defaults/app.js b/app/stores/defaults/app.js index 81bb395a..158557fb 100644 --- a/app/stores/defaults/app.js +++ b/app/stores/defaults/app.js @@ -3,6 +3,7 @@ const { name, version } = require("../../package"); module.exports = { name, version, + language: "en", openOnStartup: false, fingerprint: `${name} v${version}`, }; diff --git a/client-src/libs/i18next.js b/client-src/libs/i18next.js index 0677c54b..ffedd896 100644 --- a/client-src/libs/i18next.js +++ b/client-src/libs/i18next.js @@ -9,8 +9,8 @@ async function init(options) { _ = await i18next.use(HttpApi).init({ ...options, backend: { - loadPath: "/locales/{{lng}}/{{ns}}.json", addPath: "/locales/add/{{lng}}/{{ns}}", + loadPath: "/locales/{{lng}}/{{ns}}.json", }, }); diff --git a/client-src/stores/i18next.js b/client-src/stores/i18next.js index cb9d06c3..c1bb3cba 100644 --- a/client-src/stores/i18next.js +++ b/client-src/stores/i18next.js @@ -11,7 +11,7 @@ export function update(props) { } export default async function load() { - const state = await emit("stores.i18next", "getAll"); + const state = await emit("i18next.getConfig"); store.set(state); return state; } From 5023c88a0ee4412dd98a535235be80811d81bc0d Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 21 Nov 2020 05:55:57 +0100 Subject: [PATCH 026/451] show add panel button on edit mode only --- .../components/Panels/Topbar/Selector.svelte | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/client-src/components/Panels/Topbar/Selector.svelte b/client-src/components/Panels/Topbar/Selector.svelte index 9a08d4a8..0410f05c 100644 --- a/client-src/components/Panels/Topbar/Selector.svelte +++ b/client-src/components/Panels/Topbar/Selector.svelte @@ -22,24 +22,26 @@ }); function isActiveClass(p1, p2) { - return p1.id === p2.id ? "bg-secondary" : "bg-primary"; + return p1.id === p2.id ? "bg-secondary" : "bg-black bg-opacity-25"; }
{#if inQueue} - {#if running} -
-
+
+ {#if running} +
-
- {/if} -
-
+ {/if} +
Date: Sat, 21 Nov 2020 11:27:46 +0100 Subject: [PATCH 028/451] update locales --- app/static/locales/en/app.json | 3 ++- app/static/locales/fr/app.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index 71cb3bf3..4d507bef 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -58,7 +58,8 @@ "none": "none", "scene": "scene", "trigger": "trigger", - "easing": "easing" + "easing": "easing", + "language": "language" }, "obs": { "scene-list": "OBS | Scene list", diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 4e32b819..e934f09f 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -58,7 +58,8 @@ "none": "aucun", "scene": "scène", "trigger": "lanceur", - "easing": "easing" + "easing": "easing", + "language": "langue" }, "obs": { "scene-list": "OBS | Liste des scènes", From 00079eecee61a14a424a129b76fb513a14b89216 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 21 Nov 2020 11:27:53 +0100 Subject: [PATCH 029/451] add language word --- client-src/components/Dashboard/Drawer.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client-src/components/Dashboard/Drawer.svelte b/client-src/components/Dashboard/Drawer.svelte index 42ffac24..9a5bbe74 100644 --- a/client-src/components/Dashboard/Drawer.svelte +++ b/client-src/components/Dashboard/Drawer.svelte @@ -1,4 +1,5 @@ @@ -56,7 +60,7 @@
{#each $items as item, pos (item.id)} - + {/each} diff --git a/client-src/components/Anime/Timeline/Editor/Timeline/Item.svelte b/client-src/components/Anime/Timeline/Editor/Timeline/Item.svelte index 7f10a6f9..34dd8026 100644 --- a/client-src/components/Anime/Timeline/Editor/Timeline/Item.svelte +++ b/client-src/components/Anime/Timeline/Editor/Timeline/Item.svelte @@ -1,5 +1,5 @@ diff --git a/client-src/components/Widgets/Anime/Timeline/Settings.svelte b/client-src/components/Widgets/Anime/Timeline/Settings.svelte index c1e125e9..de01df82 100644 --- a/client-src/components/Widgets/Anime/Timeline/Settings.svelte +++ b/client-src/components/Widgets/Anime/Timeline/Settings.svelte @@ -28,6 +28,7 @@ } function onAnimeUpdate({ detail: anime }) { + initialItems = anime.items; update({ widget, anime }); } From 5b40a8246356e0228ab2e0445b784e7bdf158de1 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 21 Nov 2020 14:32:31 +0100 Subject: [PATCH 036/451] fix: undefined anime duration --- client-src/components/Anime/Timeline/Editor.svelte | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client-src/components/Anime/Timeline/Editor.svelte b/client-src/components/Anime/Timeline/Editor.svelte index d2ae9e57..01fd5d4c 100644 --- a/client-src/components/Anime/Timeline/Editor.svelte +++ b/client-src/components/Anime/Timeline/Editor.svelte @@ -28,6 +28,7 @@ const playables = ["audio", "video"]; $items = initialItems; + $: duration = $anime ? $anime.duration : 0; function updateAnime() { if ($anime && !$anime.paused) return; @@ -84,7 +85,7 @@ }); $anime.seek($seek); - dispatch("update", { duration: $anime.duration, items: $items }); + dispatch("update", { duration, items: $items }); } function resetAnime() { @@ -116,11 +117,11 @@ } function onRemove() { - dispatch("update", { duration: $anime.duration, items: $items }); + dispatch("update", { duration, items: $items }); } function onClose() { - dispatch("update", { duration: $anime.duration, items: $items }); + dispatch("update", { duration, items: $items }); dispatch("close"); } From 66b00ea335524e79145aecccb3039e565918f29b Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 21 Nov 2020 14:36:32 +0100 Subject: [PATCH 037/451] show tooltip only when no files added --- .../Anime/Timeline/Editor/Timeline.svelte | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client-src/components/Anime/Timeline/Editor/Timeline.svelte b/client-src/components/Anime/Timeline/Editor/Timeline.svelte index f4fd6076..47293b1f 100644 --- a/client-src/components/Anime/Timeline/Editor/Timeline.svelte +++ b/client-src/components/Anime/Timeline/Editor/Timeline.svelte @@ -13,19 +13,19 @@ // import "tippy.js/themes/translucent.css"; import tippy from "sveltejs-tippy"; - const tippyProps = { - content: _("sentences.add-file-to-timeline"), - placement: "top", - showOnCreate: true, - theme: "marv", - }; - const { anime, items } = getContext("Editor"); const dispatch = createEventDispatcher(); let fileManager = false; let splitter = { x: 200, width: 4, min: 100, max: 500 }; + $: tippyProps = { + content: _("sentences.add-file-to-timeline"), + showOnCreate: !$items.length, + placement: "top", + theme: "marv", + }; + function openFileManager() { fileManager = true; } From 8694821aacb8fd35e1692a6cbc2cd8001ee8f10e Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 21 Nov 2020 14:54:38 +0100 Subject: [PATCH 038/451] add plus icon on empty widget --- client-src/components/Panels/Panel/Widget.svelte | 13 +++++++++---- client-src/components/Widgets/WidgetWrapper.svelte | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/client-src/components/Panels/Panel/Widget.svelte b/client-src/components/Panels/Panel/Widget.svelte index 7e31306f..cc388da4 100644 --- a/client-src/components/Panels/Panel/Widget.svelte +++ b/client-src/components/Panels/Panel/Widget.svelte @@ -1,7 +1,8 @@
+
+ +
width -
+
From 44a34c3e5aec87ddf804d64a5742740622a2bec2 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sun, 22 Nov 2020 08:22:40 +0100 Subject: [PATCH 044/451] ui: frameless electron app + custom topbar --- app/main/window/index.js | 3 +- client-src/components/App.svelte | 2 ++ .../components/App/ElectronTopbar.svelte | 35 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 client-src/components/App/ElectronTopbar.svelte diff --git a/app/main/window/index.js b/app/main/window/index.js index 7fde1be0..485452ad 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -17,6 +17,7 @@ function createWindow() { width: 800, height: 600, show: false, + frame: false, icon: path.join(staticPath, "icon.png"), webPreferences: { devTools: watch }, }); @@ -28,7 +29,7 @@ function createWindow() { }); win.removeMenu(); - win.loadURL(`http://${host}:${port}`); + win.loadURL(`http://${host}:${port}?electron`); watch && win.webContents.openDevTools(); } diff --git a/client-src/components/App.svelte b/client-src/components/App.svelte index 428aadda..c479823c 100644 --- a/client-src/components/App.svelte +++ b/client-src/components/App.svelte @@ -15,6 +15,7 @@ import Connected from "@/components/App/Connected.svelte"; import Connecting from "@/components/App/Connecting.svelte"; import Disconnected from "@/components/App/Disconnected.svelte"; + import ElectronTopbar from "@/components/App/ElectronTopbar.svelte"; let component = Connecting; @@ -47,5 +48,6 @@
+
diff --git a/client-src/components/App/ElectronTopbar.svelte b/client-src/components/App/ElectronTopbar.svelte new file mode 100644 index 00000000..acaaf436 --- /dev/null +++ b/client-src/components/App/ElectronTopbar.svelte @@ -0,0 +1,35 @@ + + + + +{#if electron} +
+
+ +
+
{title}
+
+ ✕ +
+
+{/if} From 9cf161e3aaf0ddfed842dac8b944619f209b60a2 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sun, 22 Nov 2020 08:26:49 +0100 Subject: [PATCH 045/451] ui: preload electron window --- app/main/index.js | 2 ++ app/main/window/index.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/main/index.js b/app/main/index.js index f768b6d6..4004c55d 100644 --- a/app/main/index.js +++ b/app/main/index.js @@ -1,5 +1,6 @@ "use strict"; +const createWindow = require("./window"); const { app } = require("electron"); const server = require("./server"); const tray = require("./tray"); @@ -12,5 +13,6 @@ app.on("window-all-closed", (event) => { app.whenReady().then(() => { server.start(); + createWindow({ showOnLoad: false }); tray(); }); diff --git a/app/main/window/index.js b/app/main/window/index.js index 485452ad..bd499e60 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -8,7 +8,7 @@ const { host, port } = stores.server.getAll(); let win = null; -function createWindow() { +function createWindow({ showOnLoad = true } = {}) { if (win) { return win.show(); } @@ -25,7 +25,7 @@ function createWindow() { hideOnClose(win); win.webContents.once("did-finish-load", () => { - win.show(); + showOnLoad && win.show(); }); win.removeMenu(); From e655bd7e9ff50aa980dd22d3e99aea6bc8784c1c Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sun, 22 Nov 2020 08:40:34 +0100 Subject: [PATCH 046/451] ui: store electron window position --- app/main/window/index.js | 2 ++ app/main/window/storeBounds.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 app/main/window/storeBounds.js diff --git a/app/main/window/index.js b/app/main/window/index.js index bd499e60..bf12c3bc 100644 --- a/app/main/window/index.js +++ b/app/main/window/index.js @@ -1,5 +1,6 @@ const { staticPath, watch } = require("../../utils"); const { BrowserWindow } = require("electron"); +const storeBounds = require("./storeBounds"); const hideOnClose = require("./hideOnClose"); const stores = require("../../stores"); const path = require("path"); @@ -23,6 +24,7 @@ function createWindow({ showOnLoad = true } = {}) { }); hideOnClose(win); + storeBounds({ win, name: "main" }); win.webContents.once("did-finish-load", () => { showOnLoad && win.show(); diff --git a/app/main/window/storeBounds.js b/app/main/window/storeBounds.js new file mode 100644 index 00000000..81fb0fe5 --- /dev/null +++ b/app/main/window/storeBounds.js @@ -0,0 +1,28 @@ +const create = require("../../stores/create"); + +const defaults = { + bounds: { + width: 800, + height: 600, + }, +}; + +module.exports = function storeBounds({ win, name, delay = 500 } = {}) { + const store = create(`windows/${name}`, { defaults }); + + let timeout = null; + + const loadBounds = () => win.setBounds(store.get("bounds")); + const updateBounds = () => store.set("bounds", win.getBounds()); + + const updateBoundsDelay = () => { + timeout && clearTimeout(timeout); + timeout = setTimeout(updateBounds, delay); + }; + + win.on("show", loadBounds); + win.on("hide", updateBounds); + win.on("close", updateBounds); + win.on("move", updateBoundsDelay); + win.on("resize", updateBoundsDelay); +}; From aa2d77085489b40561f11fcca891c45a35eca156 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sun, 22 Nov 2020 08:58:43 +0100 Subject: [PATCH 047/451] fix: hide input checkbox --- client-src/components/UI/Input.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client-src/components/UI/Input.svelte b/client-src/components/UI/Input.svelte index 2b9ddf49..0ade604d 100644 --- a/client-src/components/UI/Input.svelte +++ b/client-src/components/UI/Input.svelte @@ -12,6 +12,7 @@ export let bgColor = "bg-dark-lighter"; $: color = `${bgColor} ${textColor}`; + $: inputHidden = type === "checkbox" ? "hidden" : ""; const dispatch = createEventDispatcher(); const debounceUpdate = debounce(500, update); @@ -50,7 +51,7 @@ on:change on:input="{input}" on:keypress="{onKeypress}" - class="{inputClass} w-full text-dark" + class="{inputClass} w-full text-dark {inputHidden}" />
From 070076abbf8fd555de65f827b6ad56e7e911406e Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sun, 22 Nov 2020 09:09:14 +0100 Subject: [PATCH 048/451] feature: open Marv window at startup (optional) --- app/main/index.js | 3 +- app/static/locales/en/app.json | 5 ++-- app/static/locales/fr/app.json | 5 ++-- client-src/api/app.js | 5 ++++ .../components/App/OpenOnStartup.svelte | 28 +++++++++++++++++++ client-src/components/Dashboard/Drawer.svelte | 2 ++ 6 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 client-src/api/app.js create mode 100644 client-src/components/App/OpenOnStartup.svelte diff --git a/app/main/index.js b/app/main/index.js index 4004c55d..8dee2c87 100644 --- a/app/main/index.js +++ b/app/main/index.js @@ -3,6 +3,7 @@ const createWindow = require("./window"); const { app } = require("electron"); const server = require("./server"); +const store = require("../stores"); const tray = require("./tray"); app.requestSingleInstanceLock() || app.quit(); @@ -13,6 +14,6 @@ app.on("window-all-closed", (event) => { app.whenReady().then(() => { server.start(); - createWindow({ showOnLoad: false }); + createWindow({ showOnLoad: store.app.get("openOnStartup") }); tray(); }); diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index 7b3ea8fb..b9621002 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -32,6 +32,7 @@ "no-file-selected": "No file selected", "no-file-added": "No file added", "add-file-to-timeline": "Click on the blue arrow to add some file.", + "electron-open-on-startup": "Open Marv on startup" }, "words": { "settings": "settings", @@ -68,9 +69,9 @@ "obs": { "scene-list": "OBS | Scene list", "go-to-scene": "OBS | Go to scene", - "toggle-scene": "OBS toggle between two scenes", + "toggle-scene": "OBS | toggle between two scenes", "no-scene-selected": "No scene selected", - "connect-at-startup": "OBS connect at startup" + "connect-at-startup": "Connect OBS at startup" }, "anime": { "timeline": "Anime | Timeline" diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 8bebfaf1..f92f23a4 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -31,7 +31,8 @@ "open-anime-timeline": "Ouvrir la timeline", "no-file-selected": "Aucun fichier sélectionné", "no-file-added": "Aucun fichier ajouté", - "add-file-to-timeline": "Clique sur la flêche blue pour ajouter un fichier." + "add-file-to-timeline": "Clique sur la flêche blue pour ajouter un fichier.", + "electron-open-on-startup": "Ouvrir Marv au démarrage" }, "words": { "settings": "options", @@ -70,7 +71,7 @@ "go-to-scene": "OBS | Aller à la scène", "toggle-scene": "OBS | Basculer entre deux scènes", "no-scene-selected": "Aucune scène sélectionnée", - "connect-at-startup": "OBS connection au démarrage" + "connect-at-startup": "Connexion à OBS au démarrage" }, "anime": { "timeline": "Anime | Timeline" diff --git a/client-src/api/app.js b/client-src/api/app.js new file mode 100644 index 00000000..3ad6daa5 --- /dev/null +++ b/client-src/api/app.js @@ -0,0 +1,5 @@ +import { emit } from "@/libs/socket.io"; + +export default { + set: (key, val) => emit("stores.app", "set", key, val), +}; diff --git a/client-src/components/App/OpenOnStartup.svelte b/client-src/components/App/OpenOnStartup.svelte new file mode 100644 index 00000000..de407e13 --- /dev/null +++ b/client-src/components/App/OpenOnStartup.svelte @@ -0,0 +1,28 @@ + + + diff --git a/client-src/components/Dashboard/Drawer.svelte b/client-src/components/Dashboard/Drawer.svelte index 9a5bbe74..4d57d6ac 100644 --- a/client-src/components/Dashboard/Drawer.svelte +++ b/client-src/components/Dashboard/Drawer.svelte @@ -2,6 +2,7 @@ import { _ } from "@/libs/i18next"; import { drawer, hide } from "@/stores/drawer"; import clickoutside from "@/libs/svelte/click-outside"; + import OpenOnStartup from "@/components/App/OpenOnStartup.svelte"; import LanguageSelect from "@/components/App/LanguageSelect.svelte"; import ConnectAtStartup from "@/components/OBS/ConnectAtStartup.svelte"; @@ -15,6 +16,7 @@
Drawer
{_('words.language')}
+
{/if} From d695100e2fc516c364ff0d759f3e3e76c59e4e04 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sun, 22 Nov 2020 09:14:04 +0100 Subject: [PATCH 049/451] fix: drawer top offset when in electron win --- client-src/components/Dashboard/Drawer.svelte | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client-src/components/Dashboard/Drawer.svelte b/client-src/components/Dashboard/Drawer.svelte index 4d57d6ac..2486a35b 100644 --- a/client-src/components/Dashboard/Drawer.svelte +++ b/client-src/components/Dashboard/Drawer.svelte @@ -5,13 +5,19 @@ import OpenOnStartup from "@/components/App/OpenOnStartup.svelte"; import LanguageSelect from "@/components/App/LanguageSelect.svelte"; import ConnectAtStartup from "@/components/OBS/ConnectAtStartup.svelte"; + + const query = new URLSearchParams(location.search); + const electron = query.has("electron"); + + let top = electron ? 29 : 0; {#if $drawer.visible}
Drawer
{_('words.language')}
From a55e6db79f42ca6cf922fcf6129d1577edc5c2dc Mon Sep 17 00:00:00 2001 From: skarab42 Date: Mon, 23 Nov 2020 08:17:20 +0100 Subject: [PATCH 050/451] Create Progressbar.svelte --- client-src/components/UI/Progressbar.svelte | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 client-src/components/UI/Progressbar.svelte diff --git a/client-src/components/UI/Progressbar.svelte b/client-src/components/UI/Progressbar.svelte new file mode 100644 index 00000000..546da553 --- /dev/null +++ b/client-src/components/UI/Progressbar.svelte @@ -0,0 +1,12 @@ + + +
+
+
From 85e7fcef7c5d16b2e7bbc27e81934825a29fbe8c Mon Sep 17 00:00:00 2001 From: skarab42 Date: Mon, 23 Nov 2020 08:18:22 +0100 Subject: [PATCH 051/451] feature: action progressbar and countdown --- app/server/libs/actions/push.js | 10 +- app/server/libs/actions/state.js | 8 +- .../components/Widgets/WidgetWrapper.svelte | 96 +++++++++++++++++-- 3 files changed, 99 insertions(+), 15 deletions(-) diff --git a/app/server/libs/actions/push.js b/app/server/libs/actions/push.js index 81ce19a0..847197af 100644 --- a/app/server/libs/actions/push.js +++ b/app/server/libs/actions/push.js @@ -11,11 +11,11 @@ let lock = false; function sendAction(action, immediat = false) { const { send } = actionTypes[action.type] || {}; - state.update({ ...action, running: true }); + state.update("start", { ...action, running: true }); if (!send) { state.decrement(action); - state.update({ ...action, running: false }); + state.update("end", { ...action, running: false }); return Promise.reject(`Undefined action type: ${action.type}`); } @@ -23,9 +23,9 @@ function sendAction(action, immediat = false) { .then((response) => ({ response })) .catch((error) => ({ error })) .then(({ error, response }) => { - const { inQueue } = state.decrement(action); - const running = immediat && !!inQueue; - state.update({ ...action, running }); + const newAction = state.decrement(action); + const running = immediat && !!newAction.inQueue; + state.update("end", { ...action, ...newAction, running }); return error || response; }); } diff --git a/app/server/libs/actions/state.js b/app/server/libs/actions/state.js index f3cea655..27a1da6a 100644 --- a/app/server/libs/actions/state.js +++ b/app/server/libs/actions/state.js @@ -8,20 +8,22 @@ function push(action) { let widgetState = state[action.widget.id]; if (!widgetState) { - state[action.widget.id] = { inQueue: 1, running: false }; + state[action.widget.id] = { ...action, inQueue: 1, running: false }; } else { widgetState.inQueue++; } + io.emit("actions.push", state[action.widget.id]); io.emit("actions.state", state); return widgetState; } -function update(action) { +function update(type, action) { let widgetState = state[action.widget.id]; state[action.widget.id] = { ...widgetState, ...action }; + io.emit(`actions.${type}`, state[action.widget.id]); io.emit("actions.state", state); return widgetState; @@ -31,7 +33,7 @@ function decrement(action) { let widgetState = state[action.widget.id]; widgetState.inQueue--; state[action.widget.id] = { ...widgetState }; - return widgetState; + return state[action.widget.id]; } function getState() { diff --git a/client-src/components/Widgets/WidgetWrapper.svelte b/client-src/components/Widgets/WidgetWrapper.svelte index 8053af72..f360d718 100644 --- a/client-src/components/Widgets/WidgetWrapper.svelte +++ b/client-src/components/Widgets/WidgetWrapper.svelte @@ -1,6 +1,9 @@
-{#if inQueue} -
- {#if running} +{#if action && action.inQueue} +
+ {#if action.running}
+ {#if elapsedTime > -1} +
+ {ms(elapsedTime)} +
+ {/if} {/if}
{inQueue} + class="{action.running ? '' : 'px-3 text-dark bg-gray-500 rounded-full'}" + >{action.inQueue}
+
+ +
{/if} From 0c0653b07a28e5ca2bea2588f7c8bd41cd9f1057 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Mon, 23 Nov 2020 13:13:55 +0100 Subject: [PATCH 052/451] twitch login (base) --- app/package.json | 2 + app/server/api/twitch.js | 13 + app/server/index.js | 4 + app/server/libs/twitch/AuthProvider.js | 98 +++++ app/server/libs/twitch/authMiddleware.js | 18 + app/server/libs/twitch/config.js | 5 + app/server/libs/twitch/index.js | 22 ++ app/server/libs/twitch/state.js | 13 + app/static/locales/en/app.json | 3 +- app/static/locales/fr/app.json | 3 +- app/stores/defaults/twitch.js | 3 + app/yarn.lock | 344 ++++++++++++++++++ client-src/api/twitch.js | 8 + client-src/assets/images/Twitch_icon.svg | 12 + client-src/assets/images/Twitch_logo.svg | 13 + client-src/assets/images/Twitch_text.svg | 11 + client-src/components/App.svelte | 2 + client-src/components/Dashboard/Drawer.svelte | 3 +- client-src/components/Twitch/Login.svelte | 44 +++ client-src/libs/twitch.js | 17 + client-src/stores/twitch.js | 13 + 21 files changed, 648 insertions(+), 3 deletions(-) create mode 100644 app/server/api/twitch.js create mode 100644 app/server/libs/twitch/AuthProvider.js create mode 100644 app/server/libs/twitch/authMiddleware.js create mode 100644 app/server/libs/twitch/config.js create mode 100644 app/server/libs/twitch/index.js create mode 100644 app/server/libs/twitch/state.js create mode 100644 app/stores/defaults/twitch.js create mode 100644 client-src/api/twitch.js create mode 100644 client-src/assets/images/Twitch_icon.svg create mode 100644 client-src/assets/images/Twitch_logo.svg create mode 100644 client-src/assets/images/Twitch_text.svg create mode 100644 client-src/components/Twitch/Login.svelte create mode 100644 client-src/libs/twitch.js create mode 100644 client-src/stores/twitch.js diff --git a/app/package.json b/app/package.json index 12f36217..ded9d09b 100644 --- a/app/package.json +++ b/app/package.json @@ -22,6 +22,8 @@ "polka": "^0.5.2", "sirv": "^1.0.7", "socket.io": "^2.3.0", + "twitch": "^4.3.0", + "twitch-auth": "^4.3.0", "uuid": "^8.3.1" } } diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js new file mode 100644 index 00000000..e9428fa6 --- /dev/null +++ b/app/server/api/twitch.js @@ -0,0 +1,13 @@ +const twitch = require("../libs/twitch"); + +module.exports = { + getMe(email = false) { + return twitch.api.helix.users.getMe(email).then(({ _data: user }) => { + this.notify("twitch.getMe", user); + twitch.state.update({ user }); + return Promise.resolve(user); + }); + }, + getState: () => twitch.state.get(), + updateState: (state) => twitch.state.update(state), +}; diff --git a/app/server/index.js b/app/server/index.js index a7793647..601cc205 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -7,6 +7,7 @@ const http = require("http"); const polka = require("polka"); const stores = require("../stores"); const { json } = require("body-parser"); +const twitch = require("./libs/twitch"); const socket = require("./libs/socket.io"); const { i18next } = require("./libs/i18next"); const { uploadPath, clientPath, staticPath } = require("../utils"); @@ -49,11 +50,14 @@ function start() { server.on("error", onError); + twitch.init(); + polka({ server }) .use(json()) .use(sirvClient) .use(sirvStatic) .use(sirvUpload) + .use(twitch.authMiddleware) .post("/locales/add/:lng/:ns", missingKeyHandler(i18next)) .listen(port, (error) => { if (error) return onError(error); diff --git a/app/server/libs/twitch/AuthProvider.js b/app/server/libs/twitch/AuthProvider.js new file mode 100644 index 00000000..571f9cc4 --- /dev/null +++ b/app/server/libs/twitch/AuthProvider.js @@ -0,0 +1,98 @@ +const open = require("open"); +const stores = require("../../../stores"); +const { AccessToken } = require("twitch"); + +const authBaseURL = "https://id.twitch.tv/oauth2/authorize?response_type=token"; + +function normalizeScopes(scopes) { + if (typeof scopes === "string") { + scopes = [scopes]; + } else if (!scopes) { + scopes = []; + } + return scopes; +} + +module.exports = class AuthProvider { + constructor({ + clientId, + redirectURI = "http://localhost", + forceVerify = false, + } = {}) { + this.clientId = clientId; + this.redirectURI = redirectURI; + this.forceVerify = forceVerify; + + this.tokenType = "user"; + this.accessToken = null; + this.currentScopes = []; + + this.__resolve = null; + } + + hasScopes(scopes) { + return scopes.every((scope) => this.currentScopes.includes(scope)); + } + + getAuthUrl(scopes) { + const redir = encodeURIComponent(this.redirectURI); + return ( + `${authBaseURL}&client_id=${this.clientId}` + + `&redirect_uri=${redir}&scope=${scopes.join(" ")}` + + `&force_verify=${this.forceVerify ? "true" : "false"}` + ); + } + + setAccessToken(token) { + this.accessToken = token; + } + + setToken({ access_token }) { + this.__resolve && this.__resolve(access_token); + } + + getAccessToken(scopes = null) { + // TODO detect and reject promise on error + return new Promise((resolve) => { + const auth = stores.twitch.get("auth", {}); + + if (auth.token) { + this.accessToken = new AccessToken({ + access_token: auth.token, + scope: auth.scopes, + refresh_token: "", + }); + + return resolve(this.accessToken); + } + + scopes = normalizeScopes(scopes); + + // eslint-disable-next-line no-console + console.log("\x1b[35m%s\x1b[0m", `Twitch request scopes [${scopes}]`); + + if (!this.forceVerify && this.accessToken && this.hasScopes(scopes)) { + return resolve(this.accessToken); + } + + this.__resolve = (accessToken) => { + scopes.forEach((scope) => this.currentScopes.push(scope)); + + this.accessToken = new AccessToken({ + access_token: accessToken, + scope: this.currentScopes, + refresh_token: "", + }); + + stores.twitch.set("auth", { + token: accessToken, + scopes: this.currentScopes, + }); + + resolve(this.accessToken); + }; + + open(this.getAuthUrl(scopes)); + }); + } +}; diff --git a/app/server/libs/twitch/authMiddleware.js b/app/server/libs/twitch/authMiddleware.js new file mode 100644 index 00000000..1761177f --- /dev/null +++ b/app/server/libs/twitch/authMiddleware.js @@ -0,0 +1,18 @@ +module.exports = async function authMiddleware(req, res, next) { + if (req.path === "/twitch-auth") { + res.end(` + + `); + } else if (req.path === "/twitch-auth/set") { + res.end(` +

Done! You can close this window :)

+ + + `); + this.setToken(req.query); + } + + next(); +}; diff --git a/app/server/libs/twitch/config.js b/app/server/libs/twitch/config.js new file mode 100644 index 00000000..0f3173f0 --- /dev/null +++ b/app/server/libs/twitch/config.js @@ -0,0 +1,5 @@ +module.exports = { + clientId: "d9szwgmmltndfb8mcg1t6mok5ghltn", + redirectURI: `http://localhost:4242/twitch-auth`, + forceVerify: false, +}; diff --git a/app/server/libs/twitch/index.js b/app/server/libs/twitch/index.js new file mode 100644 index 00000000..3855ca07 --- /dev/null +++ b/app/server/libs/twitch/index.js @@ -0,0 +1,22 @@ +const state = require("./state"); +const config = require("./config"); +const { ApiClient } = require("twitch"); +const AuthProvider = require("./AuthProvider"); +const authMiddleware = require("./authMiddleware"); + +const twitch = { + config, + authProvider: null, + authMiddleware: null, + api: null, + state, + init, +}; + +async function init() { + twitch.authProvider = new AuthProvider(twitch.config); + twitch.api = new ApiClient({ authProvider: twitch.authProvider }); + twitch.authMiddleware = authMiddleware.bind(twitch.authProvider); +} + +module.exports = twitch; diff --git a/app/server/libs/twitch/state.js b/app/server/libs/twitch/state.js new file mode 100644 index 00000000..f950c2f2 --- /dev/null +++ b/app/server/libs/twitch/state.js @@ -0,0 +1,13 @@ +let state = { + user: null, +}; + +function get() { + return { ...state }; +} + +function update(newState) { + state = { ...state, ...newState }; +} + +module.exports = { get, update }; diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index b9621002..b1697ea8 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -32,7 +32,8 @@ "no-file-selected": "No file selected", "no-file-added": "No file added", "add-file-to-timeline": "Click on the blue arrow to add some file.", - "electron-open-on-startup": "Open Marv on startup" + "electron-open-on-startup": "Open Marv on startup", + "connect-with-twitch": "Connect with Twitch" }, "words": { "settings": "settings", diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index f92f23a4..8df04d7a 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -32,7 +32,8 @@ "no-file-selected": "Aucun fichier sélectionné", "no-file-added": "Aucun fichier ajouté", "add-file-to-timeline": "Clique sur la flêche blue pour ajouter un fichier.", - "electron-open-on-startup": "Ouvrir Marv au démarrage" + "electron-open-on-startup": "Ouvrir Marv au démarrage", + "connect-with-twitch": "Connexion avec Twitch" }, "words": { "settings": "options", diff --git a/app/stores/defaults/twitch.js b/app/stores/defaults/twitch.js new file mode 100644 index 00000000..543bb824 --- /dev/null +++ b/app/stores/defaults/twitch.js @@ -0,0 +1,3 @@ +module.exports = { + auth: {}, +}; diff --git a/app/yarn.lock b/app/yarn.lock index fbc7fba0..675fa668 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -14,6 +14,68 @@ dependencies: regenerator-runtime "^0.13.4" +"@d-fischer/cache-decorators@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@d-fischer/cache-decorators/-/cache-decorators-2.1.1.tgz#0e702b69312406ecf747b76ad9fc644b154498d1" + integrity sha512-qdRejrYFStvdreFFUH4Tl1AvH+MV34vATj8yqrbis5HVwMqbLbLyb38H1hSKEiWFGBjLtCcgfJtC0LvgJivgzg== + dependencies: + "@d-fischer/shared-utils" "^2.4.1" + "@types/node" "^14.11.2" + tslib "^2.0.3" + +"@d-fischer/cross-fetch@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@d-fischer/cross-fetch/-/cross-fetch-4.0.2.tgz#1a086c0066462fee196420748c283389c66fd5aa" + integrity sha512-3ONhZxPmgCerBi8rU9kDQktF2zMpv7gkVJuoR8I+pYeO4QWccEcqQem0i1mLBh7/y7ejR474RZb3S3EO/Sdi3A== + dependencies: + node-fetch "2.6.1" + +"@d-fischer/deprecate@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@d-fischer/deprecate/-/deprecate-2.0.2.tgz#d1f0d40acc881edd771cace7992a1070460608c8" + integrity sha512-wlw3HwEanJFJKctwLzhfOM6LKwR70FPfGZGoKOhWBKyOPXk+3a9Cc6S9zhm6tka7xKtpmfxVIReGUwPnMbIaZg== + +"@d-fischer/logger@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@d-fischer/logger/-/logger-2.1.1.tgz#4c1abecd420188ba7259fdff8012272cb30d162f" + integrity sha512-E46n4a6AjSFCptzaQrw9y7FF0H2Rci4KJdi6QzjzqaGAHaxyA9IdpVcfKgpG4CCSTA0F6tD7LbgKNR0XoEHhPg== + dependencies: + detect-node "^2.0.4" + tslib "^2.0.3" + +"@d-fischer/promise.allsettled@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@d-fischer/promise.allsettled/-/promise.allsettled-2.0.1.tgz#3da8996ec95fd25017d0ec8289302c1b0afdce00" + integrity sha512-n3DCu++HfQBsuTRzwCk4hABtjQm+RgyPHecGTg6ze8ocCPKzSllsXQWTX7PEoQHKwoHEEoDiHzddTC62n+HZBA== + dependencies: + array.prototype.map "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.17.4" + iterate-value "^1.0.2" + +"@d-fischer/qs@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@d-fischer/qs/-/qs-7.0.2.tgz#21942f51590e20954086bdc32fb3e608d3525659" + integrity sha512-yAu3xDooiL+ef84Jo8nLjDjWBRk7RXk163Y6aTvRB7FauYd3spQD/dWvgT7R4CrN54Juhrrc3dMY7mc+jZGurQ== + +"@d-fischer/rate-limiter@^0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@d-fischer/rate-limiter/-/rate-limiter-0.2.7.tgz#58f8ebf4926fb110e7f20dbbc3c9fc5454e32670" + integrity sha512-gA2dRIyisT3YkcpOVGvNRbW3tw8X6RHZ10thsc4CpFerynZItNt5fHeP6SidORP8XvI6vBh0NJpwDMfVxcqWEg== + dependencies: + "@d-fischer/logger" "^2.1.1" + "@d-fischer/promise.allsettled" "^2.0.1" + "@types/node" "^12.12.5" + tslib "^2.0.3" + +"@d-fischer/shared-utils@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@d-fischer/shared-utils/-/shared-utils-2.4.1.tgz#6b2c63cf44130bd1a23c915eab34bc7637b1bdec" + integrity sha512-JFkiZ1s+Sx4uIoQ7mrMeOkxVxWBpnS4hCm6R7+UUciPmAR0qgKxNt7x079b3cUFTOSbbF0Inp6ReqNK4w/QgUQ== + dependencies: + "@types/node" "^14.11.2" + tslib "^2.0.3" + "@polka/url@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@polka/url/-/url-0.5.0.tgz#b21510597fd601e5d7c95008b76bf0d254ebfd31" @@ -24,6 +86,16 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== +"@types/node@^12.12.5": + version "12.19.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.6.tgz#fbf249fa46487dd8c7386d785231368b92a33a53" + integrity sha512-U2VopDdmBoYBmtm8Rz340mvvSz34VgX/K9+XCuckvcLGMkt3rbMX8soqFOikIPlPBc5lmw8By9NUK7bEFSBFlQ== + +"@types/node@^14.11.2": + version "14.14.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6" + integrity sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw== + accepts@~1.3.4: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -62,6 +134,17 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +array.prototype.map@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.3.tgz#1609623618d3d84134a37d4a220030c2bd18420b" + integrity sha512-nNcb30v0wfDyIe26Yif3PcV1JXQp4zEeEfupG7L4SRjnD6HLbO5b2a7eVSba53bOx4YCHYMBHt+Fp4vYstneRA== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.5" + arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" @@ -147,6 +230,14 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +call-bind@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" + integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.0" + callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" @@ -273,11 +364,23 @@ debug@~4.1.0: dependencies: ms "^2.1.1" +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + dot-prop@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -335,6 +438,69 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== +es-abstract@^1.17.4: + version "1.17.7" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" + integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.2" + is-regex "^1.1.1" + object-inspect "^1.8.0" + object-keys "^1.1.1" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-abstract@^1.18.0-next.1: + version "1.18.0-next.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" + integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.2" + is-negative-zero "^2.0.0" + is-regex "^1.1.1" + object-inspect "^1.8.0" + object-keys "^1.1.1" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.1.tgz#b93ddd867af16d5118e00881396533c1c6647ad9" + integrity sha512-qorBw8Y7B15DVLaJWy6WdEV/ZkieBcu6QCq/xzWzGOKJqgG1j754vXRfZ3NY7HSShneqU43mPB4OkQBTkvHhFw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.1" + has-symbols "^1.0.1" + is-arguments "^1.0.4" + is-map "^2.0.1" + is-set "^2.0.1" + is-string "^1.0.5" + isarray "^2.0.5" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -374,6 +540,20 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" + integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" @@ -403,6 +583,18 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -448,6 +640,11 @@ inherits@^2.0.1: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + 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" @@ -455,6 +652,16 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-callable@^1.1.4, is-callable@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" + integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + is-docker@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" @@ -472,6 +679,16 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" + integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== + +is-negative-zero@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" + integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -482,6 +699,30 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== +is-regex@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" + integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== + dependencies: + has-symbols "^1.0.1" + +is-set@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" + integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + is-wsl@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -494,11 +735,29 @@ isarray@2.0.1: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isomorphic-ws@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +iterate-iterator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" + integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== + +iterate-value@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== + dependencies: + es-get-iterator "^1.0.2" + iterate-iterator "^1.0.1" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -587,6 +846,11 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +node-fetch@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + 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" @@ -597,6 +861,26 @@ object-component@0.0.3: resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= +object-inspect@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + obs-websocket-js@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/obs-websocket-js/-/obs-websocket-js-4.0.2.tgz#b0dc6df1141f14878e04f927d12379f9ab234d52" @@ -831,6 +1115,22 @@ socket.io@^2.3.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +string.prototype.trimend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" + integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" + integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -855,6 +1155,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +top-package@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/top-package/-/top-package-1.0.1.tgz#17990e92963bd13faa61594fd7d32568ed267a14" + integrity sha512-tsuhQlHSigOTTvonxHXwqSKEVSnWMh2GvpTvXa5YmoyOwL5YvU4lTd/KNVZlKM5v7gqx44UEuQxyPQEpmaIHdg== + totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" @@ -867,6 +1172,45 @@ trouter@^2.0.1: dependencies: matchit "^1.0.0" +tslib@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" + integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== + +twitch-api-call@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/twitch-api-call/-/twitch-api-call-4.3.0.tgz#0c1abb85865cafe4590e1410cded3a1c98ca22ee" + integrity sha512-fRciZkgidQ29UfVczSOUk2Va0vWsZWpyuSUF9aJ+SFq8+lbDf4tFdB8qZTkAKdvSWoo4y3jMkP2rW8bcO3AR6Q== + dependencies: + "@d-fischer/cross-fetch" "^4.0.2" + "@d-fischer/qs" "^7.0.2" + tslib "^2.0.3" + +twitch-auth@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/twitch-auth/-/twitch-auth-4.3.0.tgz#194e61789561823154dc87fc78cd69ee7a467e1b" + integrity sha512-rT2CwAq5TxuFUUkmuBJ73IEbJHFQcBvt1kjRsaGZ1HqYLIQ4LnWO3qAXeQ0G8wbYvpPkWSrQiQiFTEIYntvM1g== + dependencies: + "@d-fischer/deprecate" "^2.0.2" + "@d-fischer/shared-utils" "^2.4.1" + tslib "^2.0.3" + twitch-api-call "^4.3.0" + +twitch@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/twitch/-/twitch-4.3.0.tgz#6b2fcae9e558392f30184172e0d149ce8165a6bc" + integrity sha512-Jn2H6YWL/T+IIpcwunYjQt/kSgOqmWog9Bn5UxjLuRxpIVWSlK69lcUz6JL0ywpp10ThCkF/S/LBiS/3z8f0sw== + dependencies: + "@d-fischer/cache-decorators" "^2.1.1" + "@d-fischer/deprecate" "^2.0.2" + "@d-fischer/logger" "^2.1.1" + "@d-fischer/rate-limiter" "^0.2.7" + "@d-fischer/shared-utils" "^2.4.1" + top-package "^1.0.0" + tslib "^2.0.3" + twitch-api-call "^4.3.0" + twitch-auth "^4.3.0" + type-is@~1.6.17: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" diff --git a/client-src/api/twitch.js b/client-src/api/twitch.js new file mode 100644 index 00000000..10090bf4 --- /dev/null +++ b/client-src/api/twitch.js @@ -0,0 +1,8 @@ +import { emit, on } from "@/libs/socket.io"; + +export default { + getState: () => emit("twitch.getState"), + updateState: (state) => emit("twitch.updateState", state), + getMe: (email = false) => emit("twitch.getMe", email), + on: (eventName, callback) => on(`twitch.${eventName}`, callback), +}; diff --git a/client-src/assets/images/Twitch_icon.svg b/client-src/assets/images/Twitch_icon.svg new file mode 100644 index 00000000..e016fb19 --- /dev/null +++ b/client-src/assets/images/Twitch_icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/client-src/assets/images/Twitch_logo.svg b/client-src/assets/images/Twitch_logo.svg new file mode 100644 index 00000000..6adeb861 --- /dev/null +++ b/client-src/assets/images/Twitch_logo.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/client-src/assets/images/Twitch_text.svg b/client-src/assets/images/Twitch_text.svg new file mode 100644 index 00000000..d70a9e0b --- /dev/null +++ b/client-src/assets/images/Twitch_text.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/client-src/components/App.svelte b/client-src/components/App.svelte index c479823c..6aa7f3e2 100644 --- a/client-src/components/App.svelte +++ b/client-src/components/App.svelte @@ -8,6 +8,7 @@ import obsStore from "@/stores/obs"; import filesStore from "@/stores/files"; import panelsStore from "@/stores/panels"; + import twitchStore from "@/stores/twitch"; import actionsStore from "@/stores/actions"; import i18nextStore from "@/stores/i18next"; import appStore, { initialized } from "@/stores/app"; @@ -23,6 +24,7 @@ await i18next(await i18nextStore()); await actionsStore(); await panelsStore(); + await twitchStore(); await filesStore(); await appStore(); await obsStore(); diff --git a/client-src/components/Dashboard/Drawer.svelte b/client-src/components/Dashboard/Drawer.svelte index 2486a35b..8323835b 100644 --- a/client-src/components/Dashboard/Drawer.svelte +++ b/client-src/components/Dashboard/Drawer.svelte @@ -2,6 +2,7 @@ import { _ } from "@/libs/i18next"; import { drawer, hide } from "@/stores/drawer"; import clickoutside from "@/libs/svelte/click-outside"; + import TwitchLogin from "@/components/Twitch/Login.svelte"; import OpenOnStartup from "@/components/App/OpenOnStartup.svelte"; import LanguageSelect from "@/components/App/LanguageSelect.svelte"; import ConnectAtStartup from "@/components/OBS/ConnectAtStartup.svelte"; @@ -19,7 +20,7 @@ style="top:{top}px" class="absolute z-50 right-0 bottom-0 flex flex-col bg-dark shadow" > -
Drawer
+
{_('words.language')}
diff --git a/client-src/components/Twitch/Login.svelte b/client-src/components/Twitch/Login.svelte new file mode 100644 index 00000000..4f1601f9 --- /dev/null +++ b/client-src/components/Twitch/Login.svelte @@ -0,0 +1,44 @@ + + +{#if $store.user} +
+
+ +
+
{$store.user.display_name}
+
+ {$store.user.display_name} +
+
+{:else} +
+
+ +
+
+ {_('sentences.connect-with-twitch')} +
+
+ +
+
+{/if} diff --git a/client-src/libs/twitch.js b/client-src/libs/twitch.js new file mode 100644 index 00000000..fa417647 --- /dev/null +++ b/client-src/libs/twitch.js @@ -0,0 +1,17 @@ +import api from "@/api/twitch"; + +export function on(eventName, cb) { + return api.on(eventName, cb); +} + +export function getMe(email = false) { + return api.getMe(email); +} + +export function getState() { + return api.getState(); +} + +export function updateState(state) { + return api.updateState(state); +} diff --git a/client-src/stores/twitch.js b/client-src/stores/twitch.js new file mode 100644 index 00000000..6dc96d9c --- /dev/null +++ b/client-src/stores/twitch.js @@ -0,0 +1,13 @@ +import { writable } from "svelte/store"; +import { getState, on } from "@/libs/twitch"; + +export const store = writable({ + user: null, +}); + +export default async function load() { + store.set(await getState()); + on("getMe", (user) => { + store.update((store) => ({ ...store, user })); + }); +} From fd43588436ca2e3aa0477d46574a2ad069b0d4fc Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 10:46:18 +0100 Subject: [PATCH 053/451] twitch login working... --- app/package.json | 6 +- app/server/api/twitch.js | 12 +- app/server/libs/twitch/AuthProvider.js | 68 ++++++----- app/server/libs/twitch/authMiddleware.js | 39 +++++-- app/server/libs/twitch/index.js | 54 ++++++++- app/server/libs/twitch/init.js | 26 +++++ app/server/libs/twitch/state.js | 18 ++- app/stores/defaults/twitch.js | 5 +- app/yarn.lock | 134 +++++++++++++++++++--- client-src/api/twitch.js | 2 +- client-src/components/Twitch/Login.svelte | 18 ++- client-src/libs/twitch.js | 4 +- client-src/stores/twitch.js | 2 +- 13 files changed, 304 insertions(+), 84 deletions(-) create mode 100644 app/server/libs/twitch/init.js diff --git a/app/package.json b/app/package.json index ded9d09b..0498f02e 100644 --- a/app/package.json +++ b/app/package.json @@ -12,6 +12,7 @@ "chalk": "^4.1.0", "chokidar": "^3.4.3", "conf": "^7.1.2", + "dot-prop": "^6.0.1", "env-paths": "^2.2.0", "fs-extra": "^9.0.1", "i18next": "^19.8.3", @@ -22,8 +23,9 @@ "polka": "^0.5.2", "sirv": "^1.0.7", "socket.io": "^2.3.0", - "twitch": "^4.3.0", - "twitch-auth": "^4.3.0", + "twitch": "^4.3.1", + "twitch-auth": "^4.3.1", + "twitch-chat-client": "^4.3.1", "uuid": "^8.3.1" } } diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js index e9428fa6..d8d94180 100644 --- a/app/server/api/twitch.js +++ b/app/server/api/twitch.js @@ -1,10 +1,18 @@ const twitch = require("../libs/twitch"); module.exports = { - getMe(email = false) { + login(email = false) { return twitch.api.helix.users.getMe(email).then(({ _data: user }) => { - this.notify("twitch.getMe", user); + this.notify("twitch.login", user); twitch.state.update({ user }); + twitch.chatConnect().then(() => { + twitch.chatJoin(user.display_name).then(({ alreadyJoined } = {}) => { + if (!alreadyJoined) { + console.log("Marv est dans la place !"); + twitch.chat.say(user.display_name, "Marv est dans la place !"); + } + }); + }); return Promise.resolve(user); }); }, diff --git a/app/server/libs/twitch/AuthProvider.js b/app/server/libs/twitch/AuthProvider.js index 571f9cc4..ade0906c 100644 --- a/app/server/libs/twitch/AuthProvider.js +++ b/app/server/libs/twitch/AuthProvider.js @@ -24,10 +24,15 @@ module.exports = class AuthProvider { this.forceVerify = forceVerify; this.tokenType = "user"; - this.accessToken = null; - this.currentScopes = []; + this.accessToken = stores.twitch.get("AccessToken", null); + this.currentScopes = stores.twitch.get("AccessToken.scope", []); - this.__resolve = null; + if (this.accessToken && this.accessToken.access_token) { + this.accessToken = new AccessToken(this.accessToken); + } + + this.__resolveToken = null; + this.__rejectToken = null; } hasScopes(scopes) { @@ -36,6 +41,7 @@ module.exports = class AuthProvider { getAuthUrl(scopes) { const redir = encodeURIComponent(this.redirectURI); + return ( `${authBaseURL}&client_id=${this.clientId}` + `&redirect_uri=${redir}&scope=${scopes.join(" ")}` + @@ -43,52 +49,44 @@ module.exports = class AuthProvider { ); } - setAccessToken(token) { - this.accessToken = token; + setAccessToken(accessToken) { + this.accessToken = accessToken; } - setToken({ access_token }) { - this.__resolve && this.__resolve(access_token); + resolveToken(response) { + this.__resolveToken && this.__resolveToken(response); + this.__resolveToken = null; } - getAccessToken(scopes = null) { - // TODO detect and reject promise on error - return new Promise((resolve) => { - const auth = stores.twitch.get("auth", {}); - - if (auth.token) { - this.accessToken = new AccessToken({ - access_token: auth.token, - scope: auth.scopes, - refresh_token: "", - }); + rejectToken(error) { + this.__rejectToken && this.__rejectToken(error); + this.__rejectToken = null; + } - return resolve(this.accessToken); - } + refresh() { + stores.twitch.set("AccessToken.access_token", null); + return this.getAccessToken(this.currentScopes, { refresh: true }); + } + getAccessToken(scopes = null, { refresh = false } = {}) { + return new Promise((resolve, reject) => { scopes = normalizeScopes(scopes); // eslint-disable-next-line no-console console.log("\x1b[35m%s\x1b[0m", `Twitch request scopes [${scopes}]`); - if (!this.forceVerify && this.accessToken && this.hasScopes(scopes)) { + const forceVerify = refresh || this.forceVerify; + + if (!forceVerify && this.accessToken && this.hasScopes(scopes)) { return resolve(this.accessToken); } - this.__resolve = (accessToken) => { - scopes.forEach((scope) => this.currentScopes.push(scope)); - - this.accessToken = new AccessToken({ - access_token: accessToken, - scope: this.currentScopes, - refresh_token: "", - }); - - stores.twitch.set("auth", { - token: accessToken, - scopes: this.currentScopes, - }); - + this.__rejectToken = reject; + this.__resolveToken = ({ access_token }) => { + this.currentScopes = [...new Set([...this.currentScopes, ...scopes])]; + const accessToken = { access_token, scope: this.currentScopes }; + this.accessToken = new AccessToken(accessToken); + stores.twitch.set("AccessToken", accessToken); resolve(this.accessToken); }; diff --git a/app/server/libs/twitch/authMiddleware.js b/app/server/libs/twitch/authMiddleware.js index 1761177f..1c693d9b 100644 --- a/app/server/libs/twitch/authMiddleware.js +++ b/app/server/libs/twitch/authMiddleware.js @@ -1,17 +1,34 @@ +function twitchAuth(req, res) { + if (req.query.error) { + this.rejectToken(req.query); + + return res.end(` +

Error! ${req.query.error_description}...

+ + `); + } + + res.end(` + + `); +} + +function twitchAuthSet(req, res) { + res.end(` +

Logged-In! You can close this window :)

+ + `); + + this.resolveToken(req.query); +} + module.exports = async function authMiddleware(req, res, next) { if (req.path === "/twitch-auth") { - res.end(` - - `); + twitchAuth.call(this, req, res); } else if (req.path === "/twitch-auth/set") { - res.end(` -

Done! You can close this window :)

- - - `); - this.setToken(req.query); + twitchAuthSet.call(this, req, res, next); } next(); diff --git a/app/server/libs/twitch/index.js b/app/server/libs/twitch/index.js index 3855ca07..020f5a37 100644 --- a/app/server/libs/twitch/index.js +++ b/app/server/libs/twitch/index.js @@ -3,20 +3,72 @@ const config = require("./config"); const { ApiClient } = require("twitch"); const AuthProvider = require("./AuthProvider"); const authMiddleware = require("./authMiddleware"); +const { ChatClient } = require("twitch-chat-client"); const twitch = { config, authProvider: null, authMiddleware: null, api: null, + chat: null, state, init, + chatJoin, + chatConnect, }; +function chatJoin(channel) { + const joinedChannels = state.get("chat.joinedChannels"); + + if (joinedChannels.includes(channel)) { + return Promise.resolve({ alreadyJoined: true }); + } + + joinedChannels.push(channel); + + return twitch.chat.join(channel).catch((error) => { + state.set( + "chat.joinedChannels", + joinedChannels.filter((c) => c !== channel) + ); + return Promise.reject(error); + }); +} + +function chatConnect() { + if (state.get("chat.connected")) { + return Promise.resolve({ alreadyConnected: true }); + } + + if (state.get("chat.connecting")) { + throw new Error("Twitch chat already connecting..."); + } + + state.set("chat.connecting", true); + + return twitch.chat + .connect() + .then(() => { + state.set("chat.connected", true); + state.set("chat.connecting", false); + return new Promise((resolve) => { + twitch.chat.onRegister(() => { + state.set("chat.registered", true); + resolve(); + }); + }); + }) + .catch((error) => { + state.set("chat.connected", false); + return Promise.reject(error); + }); +} + async function init() { twitch.authProvider = new AuthProvider(twitch.config); - twitch.api = new ApiClient({ authProvider: twitch.authProvider }); twitch.authMiddleware = authMiddleware.bind(twitch.authProvider); + twitch.api = new ApiClient({ authProvider: twitch.authProvider }); + twitch.chat = new ChatClient(twitch.authProvider); } module.exports = twitch; diff --git a/app/server/libs/twitch/init.js b/app/server/libs/twitch/init.js new file mode 100644 index 00000000..c84e598d --- /dev/null +++ b/app/server/libs/twitch/init.js @@ -0,0 +1,26 @@ +const config = require("./config"); +const state = require("./state"); +const { ApiClient } = require("twitch"); +const AuthProvider = require("./AuthProvider"); +const authMiddleware = require("./authMiddleware"); +const { ChatClient } = require("twitch-chat-client"); + +const twitch = { + state, + config, + api: null, + chat: null, + authProvider: null, + authMiddleware: null, +}; + +module.exports = function init() { + if (twitch.authProvider) return twitch; + + twitch.authProvider = new AuthProvider(twitch.config); + twitch.authMiddleware = authMiddleware.bind(twitch.authProvider); + twitch.api = new ApiClient({ authProvider: twitch.authProvider }); + twitch.chat = new ChatClient(twitch.authProvider); + + return twitch; +}; diff --git a/app/server/libs/twitch/state.js b/app/server/libs/twitch/state.js index f950c2f2..c95dd273 100644 --- a/app/server/libs/twitch/state.js +++ b/app/server/libs/twitch/state.js @@ -1,13 +1,25 @@ +const dotProp = require("dot-prop"); + let state = { user: null, + chat: { + connecting: false, + connected: false, + registered: false, + joinedChannels: [], + }, }; -function get() { - return { ...state }; +function get(key = null) { + return key ? dotProp.get(state, key) : { ...state }; +} + +function set(key, value) { + return dotProp.set(state, key, value); } function update(newState) { state = { ...state, ...newState }; } -module.exports = { get, update }; +module.exports = { get, set, update }; diff --git a/app/stores/defaults/twitch.js b/app/stores/defaults/twitch.js index 543bb824..11e8bc26 100644 --- a/app/stores/defaults/twitch.js +++ b/app/stores/defaults/twitch.js @@ -1,3 +1,6 @@ module.exports = { - auth: {}, + AccessToken: { + access_token: null, + scope: ["user:read:email", "chat:read", "chat:edit"], + }, }; diff --git a/app/yarn.lock b/app/yarn.lock index 675fa668..2c7bc141 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -23,6 +23,20 @@ "@types/node" "^14.11.2" tslib "^2.0.3" +"@d-fischer/connection@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@d-fischer/connection/-/connection-6.2.1.tgz#a631e91f3cdb37ccd64929e1f863b417c1173193" + integrity sha512-qQSMGHWjd/aE6c+lUGwxRYjur1iyD8siyuDDCYkdBYTVrvCGNSwNLgX8oRuR1UbKcM7evc1vQlxEIFGwr7lfcg== + dependencies: + "@d-fischer/isomorphic-ws" "^5.0.2" + "@d-fischer/logger" "^2.1.1" + "@d-fischer/shared-utils" "^2.4.1" + "@d-fischer/typed-event-emitter" "^3.1.1" + "@types/node" "^14.11.2" + "@types/ws" "^7.2.7" + tslib "^2.0.3" + ws "^7.3.1" + "@d-fischer/cross-fetch@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@d-fischer/cross-fetch/-/cross-fetch-4.0.2.tgz#1a086c0066462fee196420748c283389c66fd5aa" @@ -35,6 +49,16 @@ resolved "https://registry.yarnpkg.com/@d-fischer/deprecate/-/deprecate-2.0.2.tgz#d1f0d40acc881edd771cace7992a1070460608c8" integrity sha512-wlw3HwEanJFJKctwLzhfOM6LKwR70FPfGZGoKOhWBKyOPXk+3a9Cc6S9zhm6tka7xKtpmfxVIReGUwPnMbIaZg== +"@d-fischer/escape-string-regexp@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@d-fischer/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#40b1d52529c5674caf510213efc9c982877d01c4" + integrity sha512-7eoxnxcto5eVPW5h1T+ePnVFukmI9f/ZR9nlBLh1t3kyzJDUNor2C+YW9H/Terw3YnbZSDgDYrpCJCHtOtAQHw== + +"@d-fischer/isomorphic-ws@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@d-fischer/isomorphic-ws/-/isomorphic-ws-5.0.2.tgz#91bb78f520b6c9e4a820eb80c9be5dfeebdb08ed" + integrity sha512-FeULiS37jd5M7nroqUw7kfnntlIW6Kilr2kn38Xjoyw/WZqwdxSAihJ2Y09aoDamrVKEW9/flbo2/y/VwHVZ6g== + "@d-fischer/logger@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@d-fischer/logger/-/logger-2.1.1.tgz#4c1abecd420188ba7259fdff8012272cb30d162f" @@ -76,6 +100,14 @@ "@types/node" "^14.11.2" tslib "^2.0.3" +"@d-fischer/typed-event-emitter@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@d-fischer/typed-event-emitter/-/typed-event-emitter-3.1.1.tgz#5858ce3c18fdb1c2ceaf3c6635d87c5f2a0ef02d" + integrity sha512-Tfk0ACUOzf292YwR7hFkLZWhgEAfFi9cqmc5zFHYQVNH/Vt5SLsrZrI4ZZaPGJGYpbtQl3726zNMg9Mqof7Ciw== + dependencies: + "@types/node" "^14.11.2" + tslib "^2.0.3" + "@polka/url@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@polka/url/-/url-0.5.0.tgz#b21510597fd601e5d7c95008b76bf0d254ebfd31" @@ -86,15 +118,22 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== +"@types/node@*", "@types/node@^14.11.2": + version "14.14.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6" + integrity sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw== + "@types/node@^12.12.5": version "12.19.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.6.tgz#fbf249fa46487dd8c7386d785231368b92a33a53" integrity sha512-U2VopDdmBoYBmtm8Rz340mvvSz34VgX/K9+XCuckvcLGMkt3rbMX8soqFOikIPlPBc5lmw8By9NUK7bEFSBFlQ== -"@types/node@^14.11.2": - version "14.14.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.9.tgz#04afc9a25c6ff93da14deabd65dc44485b53c8d6" - integrity sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw== +"@types/ws@^7.2.7": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.0.tgz#499690ea08736e05a8186113dac37769ab251a0e" + integrity sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw== + dependencies: + "@types/node" "*" accepts@~1.3.4: version "1.3.7" @@ -165,6 +204,13 @@ atomically@^1.3.1: resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.6.0.tgz#d8d47f99834dbb88bd6266cc69a1447e2f3675ec" integrity sha512-mu394MH+yY2TSKMyH+978PcGMZ8sRNks2PuVeH6c2ED4mimR2LEE039MVcIGVhtmG54cKEMh4gKhxKL/CLaX/w== +axios@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" + integrity sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw== + dependencies: + follow-redirects "^1.10.0" + backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -388,6 +434,13 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== + dependencies: + is-obj "^2.0.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -525,6 +578,11 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +follow-redirects@^1.10.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" + integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== + fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -640,6 +698,20 @@ inherits@^2.0.1: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ircv3@^0.26.5: + version "0.26.5" + resolved "https://registry.yarnpkg.com/ircv3/-/ircv3-0.26.5.tgz#dc1217a4e15a394d96bd321fe4960f06ffc3d7be" + integrity sha512-E5IUaNv0dphO1yGxkTe0OiMwXyRDulSL2lssv+RZc9Q/F+DzGiYrYR04c2e44DOvrsMMAv3qeaVccnOni619fw== + dependencies: + "@d-fischer/connection" "^6.2.1" + "@d-fischer/escape-string-regexp" "^5.0.0" + "@d-fischer/logger" "^2.1.1" + "@d-fischer/shared-utils" "^2.4.1" + "@d-fischer/typed-event-emitter" "^3.1.1" + "@types/node" "^14.11.2" + klona "^2.0.4" + tslib "^2.0.3" + is-arguments@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" @@ -777,6 +849,11 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +klona@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" + integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -1177,29 +1254,43 @@ tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== -twitch-api-call@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/twitch-api-call/-/twitch-api-call-4.3.0.tgz#0c1abb85865cafe4590e1410cded3a1c98ca22ee" - integrity sha512-fRciZkgidQ29UfVczSOUk2Va0vWsZWpyuSUF9aJ+SFq8+lbDf4tFdB8qZTkAKdvSWoo4y3jMkP2rW8bcO3AR6Q== +twitch-api-call@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/twitch-api-call/-/twitch-api-call-4.3.1.tgz#17586c0350cfd6e90bd402fdabfc1e65fdf4b1a5" + integrity sha512-8t0rjzKKrl2JFzp6BBJlm/UIbKAE3GpSVojo9P9gFqCcGfFI7XSZ5hHBePPn6FAtDpxJ4mXlbtRmw1apXY4Tag== dependencies: "@d-fischer/cross-fetch" "^4.0.2" "@d-fischer/qs" "^7.0.2" tslib "^2.0.3" -twitch-auth@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/twitch-auth/-/twitch-auth-4.3.0.tgz#194e61789561823154dc87fc78cd69ee7a467e1b" - integrity sha512-rT2CwAq5TxuFUUkmuBJ73IEbJHFQcBvt1kjRsaGZ1HqYLIQ4LnWO3qAXeQ0G8wbYvpPkWSrQiQiFTEIYntvM1g== +twitch-auth@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/twitch-auth/-/twitch-auth-4.3.1.tgz#b7ce5f24b254e6c2a5c42839aabfcbd660356cb8" + integrity sha512-oVdhgoEF4dS1Dn4ag+9SLmQxjYArKfvLsVD/0gXxCYK4S1fStqtL7frp17LyN1E8Dy3K3zBWs7U7QTTMgdmd8w== dependencies: "@d-fischer/deprecate" "^2.0.2" + "@d-fischer/logger" "^2.1.1" "@d-fischer/shared-utils" "^2.4.1" tslib "^2.0.3" - twitch-api-call "^4.3.0" + twitch-api-call "^4.3.1" -twitch@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/twitch/-/twitch-4.3.0.tgz#6b2fcae9e558392f30184172e0d149ce8165a6bc" - integrity sha512-Jn2H6YWL/T+IIpcwunYjQt/kSgOqmWog9Bn5UxjLuRxpIVWSlK69lcUz6JL0ywpp10ThCkF/S/LBiS/3z8f0sw== +twitch-chat-client@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/twitch-chat-client/-/twitch-chat-client-4.3.1.tgz#04f5732431dda33a3ca5b9c903c024dcb038d3c8" + integrity sha512-ES1T7UlSmIzClXL9joUt+M3IHMCumLd58uFJNVmAo/6hmNXlzcjxKnW8mqzLlzsdpSkGoCaDksLSB607paUBLw== + dependencies: + "@d-fischer/cache-decorators" "^2.1.1" + "@d-fischer/deprecate" "^2.0.2" + "@d-fischer/logger" "^2.1.1" + "@d-fischer/shared-utils" "^2.4.1" + "@d-fischer/typed-event-emitter" "^3.1.1" + ircv3 "^0.26.5" + tslib "^2.0.3" + +twitch@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/twitch/-/twitch-4.3.1.tgz#d38b5eec350d46a3adca50adf21f65349c5a0e33" + integrity sha512-Lnqo0W18aKW1W34kIZlIDGxPLtvRJJUcS2aJqITqy7J+7GFPI9eG9e9dFZH3GKflgwa+pczPIYlao4p1Me3hvQ== dependencies: "@d-fischer/cache-decorators" "^2.1.1" "@d-fischer/deprecate" "^2.0.2" @@ -1208,8 +1299,8 @@ twitch@^4.3.0: "@d-fischer/shared-utils" "^2.4.1" top-package "^1.0.0" tslib "^2.0.3" - twitch-api-call "^4.3.0" - twitch-auth "^4.3.0" + twitch-api-call "^4.3.1" + twitch-auth "^4.3.1" type-is@~1.6.17: version "1.6.18" @@ -1251,6 +1342,11 @@ ws@^7.1.2, ws@^7.2.0: resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== +ws@^7.3.1: + version "7.4.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7" + integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ== + ws@~6.1.0: version "6.1.4" resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" diff --git a/client-src/api/twitch.js b/client-src/api/twitch.js index 10090bf4..3d517010 100644 --- a/client-src/api/twitch.js +++ b/client-src/api/twitch.js @@ -3,6 +3,6 @@ import { emit, on } from "@/libs/socket.io"; export default { getState: () => emit("twitch.getState"), updateState: (state) => emit("twitch.updateState", state), - getMe: (email = false) => emit("twitch.getMe", email), + login: (email = false) => emit("twitch.login", email), on: (eventName, callback) => on(`twitch.${eventName}`, callback), }; diff --git a/client-src/components/Twitch/Login.svelte b/client-src/components/Twitch/Login.svelte index 4f1601f9..e03179e2 100644 --- a/client-src/components/Twitch/Login.svelte +++ b/client-src/components/Twitch/Login.svelte @@ -1,19 +1,25 @@ {#if $store.user} -
+
@@ -28,7 +34,7 @@
{:else}
diff --git a/client-src/libs/twitch.js b/client-src/libs/twitch.js index fa417647..a865da32 100644 --- a/client-src/libs/twitch.js +++ b/client-src/libs/twitch.js @@ -4,8 +4,8 @@ export function on(eventName, cb) { return api.on(eventName, cb); } -export function getMe(email = false) { - return api.getMe(email); +export function login(email = false) { + return api.login(email); } export function getState() { diff --git a/client-src/stores/twitch.js b/client-src/stores/twitch.js index 6dc96d9c..64491405 100644 --- a/client-src/stores/twitch.js +++ b/client-src/stores/twitch.js @@ -7,7 +7,7 @@ export const store = writable({ export default async function load() { store.set(await getState()); - on("getMe", (user) => { + on("login", (user) => { store.update((store) => ({ ...store, user })); }); } From a090bd5f8c272047a3e4e17dcc43e94639a0d154 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 11:34:12 +0100 Subject: [PATCH 054/451] claenning: twitch auth --- app/server/api/twitch.js | 6 +- app/server/index.js | 5 +- app/server/libs/twitch/authMiddleware.js | 6 +- app/server/libs/twitch/chatConnect.js | 31 ++++++++++ app/server/libs/twitch/chatJoin.js | 20 +++++++ app/server/libs/twitch/index.js | 75 +++--------------------- app/server/libs/twitch/init.js | 26 -------- 7 files changed, 71 insertions(+), 98 deletions(-) create mode 100644 app/server/libs/twitch/chatConnect.js create mode 100644 app/server/libs/twitch/chatJoin.js delete mode 100644 app/server/libs/twitch/init.js diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js index d8d94180..bd71ead2 100644 --- a/app/server/api/twitch.js +++ b/app/server/api/twitch.js @@ -1,12 +1,14 @@ const twitch = require("../libs/twitch"); +const chatJoin = require("../libs/twitch/chatJoin"); +const chatConnect = require("../libs/twitch/chatConnect"); module.exports = { login(email = false) { return twitch.api.helix.users.getMe(email).then(({ _data: user }) => { this.notify("twitch.login", user); twitch.state.update({ user }); - twitch.chatConnect().then(() => { - twitch.chatJoin(user.display_name).then(({ alreadyJoined } = {}) => { + chatConnect().then(() => { + chatJoin(user.display_name).then(({ alreadyJoined } = {}) => { if (!alreadyJoined) { console.log("Marv est dans la place !"); twitch.chat.say(user.display_name, "Marv est dans la place !"); diff --git a/app/server/index.js b/app/server/index.js index 601cc205..8ad59006 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -11,6 +11,7 @@ const twitch = require("./libs/twitch"); const socket = require("./libs/socket.io"); const { i18next } = require("./libs/i18next"); const { uploadPath, clientPath, staticPath } = require("../utils"); +const twitchAuthMiddleware = require("./libs/twitch/authMiddleware"); const missingKeyHandler = require("./libs/i18next/missingKeyHandler"); let { host, port } = stores.server.getAll(); @@ -50,14 +51,12 @@ function start() { server.on("error", onError); - twitch.init(); - polka({ server }) .use(json()) .use(sirvClient) .use(sirvStatic) .use(sirvUpload) - .use(twitch.authMiddleware) + .use(twitchAuthMiddleware(twitch.authProvider)) .post("/locales/add/:lng/:ns", missingKeyHandler(i18next)) .listen(port, (error) => { if (error) return onError(error); diff --git a/app/server/libs/twitch/authMiddleware.js b/app/server/libs/twitch/authMiddleware.js index 1c693d9b..be0055c4 100644 --- a/app/server/libs/twitch/authMiddleware.js +++ b/app/server/libs/twitch/authMiddleware.js @@ -24,7 +24,7 @@ function twitchAuthSet(req, res) { this.resolveToken(req.query); } -module.exports = async function authMiddleware(req, res, next) { +function authMiddleware(req, res, next) { if (req.path === "/twitch-auth") { twitchAuth.call(this, req, res); } else if (req.path === "/twitch-auth/set") { @@ -32,4 +32,8 @@ module.exports = async function authMiddleware(req, res, next) { } next(); +} + +module.exports = (authProvider) => { + return authMiddleware.bind(authProvider); }; diff --git a/app/server/libs/twitch/chatConnect.js b/app/server/libs/twitch/chatConnect.js new file mode 100644 index 00000000..1b7a3f6f --- /dev/null +++ b/app/server/libs/twitch/chatConnect.js @@ -0,0 +1,31 @@ +const state = require("./state"); +const { chat } = require("./index"); + +module.exports = function chatConnect() { + if (state.get("chat.connected")) { + return Promise.resolve({ alreadyConnected: true }); + } + + if (state.get("chat.connecting")) { + throw new Error("Twitch chat already connecting..."); + } + + state.set("chat.connecting", true); + + return chat + .connect() + .then(() => { + state.set("chat.connected", true); + state.set("chat.connecting", false); + return new Promise((resolve) => { + chat.onRegister(() => { + state.set("chat.registered", true); + resolve(); + }); + }); + }) + .catch((error) => { + state.set("chat.connected", false); + return Promise.reject(error); + }); +}; diff --git a/app/server/libs/twitch/chatJoin.js b/app/server/libs/twitch/chatJoin.js new file mode 100644 index 00000000..72dab2b2 --- /dev/null +++ b/app/server/libs/twitch/chatJoin.js @@ -0,0 +1,20 @@ +const state = require("./state"); +const { chat } = require("./index"); + +module.exports = function chatJoin(channel) { + const joinedChannels = state.get("chat.joinedChannels"); + + if (joinedChannels.includes(channel)) { + return Promise.resolve({ alreadyJoined: true }); + } + + joinedChannels.push(channel); + + return chat.join(channel).catch((error) => { + state.set( + "chat.joinedChannels", + joinedChannels.filter((c) => c !== channel) + ); + return Promise.reject(error); + }); +}; diff --git a/app/server/libs/twitch/index.js b/app/server/libs/twitch/index.js index 020f5a37..b4769d2d 100644 --- a/app/server/libs/twitch/index.js +++ b/app/server/libs/twitch/index.js @@ -2,73 +2,16 @@ const state = require("./state"); const config = require("./config"); const { ApiClient } = require("twitch"); const AuthProvider = require("./AuthProvider"); -const authMiddleware = require("./authMiddleware"); const { ChatClient } = require("twitch-chat-client"); -const twitch = { - config, - authProvider: null, - authMiddleware: null, - api: null, - chat: null, +const authProvider = new AuthProvider(config); +const api = new ApiClient({ authProvider }); +const chat = new ChatClient(authProvider); + +module.exports = { state, - init, - chatJoin, - chatConnect, + config, + authProvider, + api, + chat, }; - -function chatJoin(channel) { - const joinedChannels = state.get("chat.joinedChannels"); - - if (joinedChannels.includes(channel)) { - return Promise.resolve({ alreadyJoined: true }); - } - - joinedChannels.push(channel); - - return twitch.chat.join(channel).catch((error) => { - state.set( - "chat.joinedChannels", - joinedChannels.filter((c) => c !== channel) - ); - return Promise.reject(error); - }); -} - -function chatConnect() { - if (state.get("chat.connected")) { - return Promise.resolve({ alreadyConnected: true }); - } - - if (state.get("chat.connecting")) { - throw new Error("Twitch chat already connecting..."); - } - - state.set("chat.connecting", true); - - return twitch.chat - .connect() - .then(() => { - state.set("chat.connected", true); - state.set("chat.connecting", false); - return new Promise((resolve) => { - twitch.chat.onRegister(() => { - state.set("chat.registered", true); - resolve(); - }); - }); - }) - .catch((error) => { - state.set("chat.connected", false); - return Promise.reject(error); - }); -} - -async function init() { - twitch.authProvider = new AuthProvider(twitch.config); - twitch.authMiddleware = authMiddleware.bind(twitch.authProvider); - twitch.api = new ApiClient({ authProvider: twitch.authProvider }); - twitch.chat = new ChatClient(twitch.authProvider); -} - -module.exports = twitch; diff --git a/app/server/libs/twitch/init.js b/app/server/libs/twitch/init.js deleted file mode 100644 index c84e598d..00000000 --- a/app/server/libs/twitch/init.js +++ /dev/null @@ -1,26 +0,0 @@ -const config = require("./config"); -const state = require("./state"); -const { ApiClient } = require("twitch"); -const AuthProvider = require("./AuthProvider"); -const authMiddleware = require("./authMiddleware"); -const { ChatClient } = require("twitch-chat-client"); - -const twitch = { - state, - config, - api: null, - chat: null, - authProvider: null, - authMiddleware: null, -}; - -module.exports = function init() { - if (twitch.authProvider) return twitch; - - twitch.authProvider = new AuthProvider(twitch.config); - twitch.authMiddleware = authMiddleware.bind(twitch.authProvider); - twitch.api = new ApiClient({ authProvider: twitch.authProvider }); - twitch.chat = new ChatClient(twitch.authProvider); - - return twitch; -}; From ed11ae30f070d14d5907a03663acfd36849e8f3a Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 15:59:25 +0100 Subject: [PATCH 055/451] upgarde electron 10 > 11 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a23c8068..adfebedc 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "chalk": "^4.1.0", "clone-deep": "^4.0.1", "concurrently": "^5.3.0", - "electron": "^10.1.5", + "electron": "^11.0.3", "electron-builder": "^22.9.1", "eslint": "^7.12.0", "eslint-plugin-svelte3": "^2.7.3", diff --git a/yarn.lock b/yarn.lock index 93e3956f..923066ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -966,10 +966,10 @@ electron-to-chromium@^1.3.571: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.583.tgz#47a9fde74740b1205dba96db2e433132964ba3ee" integrity sha512-L9BwLwJohjZW9mQESI79HRzhicPk1DFgM+8hOCfGgGCFEcA3Otpv7QK6SGtYoZvfQfE3wKLh0Hd5ptqUFv3gvQ== -electron@^10.1.5: - version "10.1.5" - resolved "https://registry.yarnpkg.com/electron/-/electron-10.1.5.tgz#f2b161310f627063e73fbac44efcb35dece83a90" - integrity sha512-fys/KnEfJq05TtMij+lFvLuKkuVH030CHYx03iZrW5DNNLwjE6cW3pysJ420lB0FRSfPjTHBMu2eVCf5TG71zQ== +electron@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/electron/-/electron-11.0.3.tgz#c29eaacda38ce561890e59906ca5f507c72b3ec4" + integrity sha512-nNfbLi7Q1xfJXOEO2adck5TS6asY4Jxc332E4Te8XfQ9hcaC3GiCdeEqk9FndNCwxhJA5Lr9jfSGRTwWebFa/w== dependencies: "@electron/get" "^1.0.1" "@types/node" "^12.0.12" From 95fad44193853953aba3950b0a23fd0f3faa3967 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 15:59:53 +0100 Subject: [PATCH 056/451] renamed index to mainWindow --- app/main/window/{index.js => mainWindow.js} | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) rename app/main/window/{index.js => mainWindow.js} (80%) diff --git a/app/main/window/index.js b/app/main/window/mainWindow.js similarity index 80% rename from app/main/window/index.js rename to app/main/window/mainWindow.js index bf12c3bc..74566048 100644 --- a/app/main/window/index.js +++ b/app/main/window/mainWindow.js @@ -1,4 +1,5 @@ const { staticPath, watch } = require("../../utils"); +const webPreferences = require("./webPreferences"); const { BrowserWindow } = require("electron"); const storeBounds = require("./storeBounds"); const hideOnClose = require("./hideOnClose"); @@ -9,7 +10,7 @@ const { host, port } = stores.server.getAll(); let win = null; -function createWindow({ showOnLoad = true } = {}) { +module.exports = function createWindow({ showOnLoad = true } = {}) { if (win) { return win.show(); } @@ -20,7 +21,7 @@ function createWindow({ showOnLoad = true } = {}) { show: false, frame: false, icon: path.join(staticPath, "icon.png"), - webPreferences: { devTools: watch }, + webPreferences: { ...webPreferences, devTools: watch }, }); hideOnClose(win); @@ -33,6 +34,4 @@ function createWindow({ showOnLoad = true } = {}) { win.removeMenu(); win.loadURL(`http://${host}:${port}?electron`); watch && win.webContents.openDevTools(); -} - -module.exports = createWindow; +}; From 35a62e0ce854b5369eda2d8868b7c3e96770b4c6 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:00:14 +0100 Subject: [PATCH 057/451] export app name and version --- app/utils.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/utils.js b/app/utils.js index 1c244429..662b9b8d 100644 --- a/app/utils.js +++ b/app/utils.js @@ -1,8 +1,9 @@ -const { name } = require("./package"); +const { name, version } = require("./package"); const envPaths = require("env-paths"); const path = require("path"); const appPath = __dirname; +const app = { name, version }; const userPath = envPaths(name).data; const clientPath = path.join(appPath, "client"); const staticPath = path.join(appPath, "static"); @@ -12,6 +13,7 @@ const filesPath = path.join(uploadPath, "files"); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); module.exports = { + app, watch, appPath, userPath, From fd682e7c1359c3176dae1951b5afdf76b73d96da Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:01:28 +0100 Subject: [PATCH 058/451] renamed createWindow to mainWindow --- app/main/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/main/index.js b/app/main/index.js index 8dee2c87..e1e02694 100644 --- a/app/main/index.js +++ b/app/main/index.js @@ -1,6 +1,6 @@ "use strict"; -const createWindow = require("./window"); +const mainWindow = require("./window/mainWindow"); const { app } = require("electron"); const server = require("./server"); const store = require("../stores"); @@ -14,6 +14,6 @@ app.on("window-all-closed", (event) => { app.whenReady().then(() => { server.start(); - createWindow({ showOnLoad: store.app.get("openOnStartup") }); + mainWindow({ showOnLoad: store.app.get("openOnStartup") }); tray(); }); From 92348a338cf6ef8436d9e0c334d4b80569afb865 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:01:36 +0100 Subject: [PATCH 059/451] update locales --- app/static/locales/en/app.json | 3 ++- app/static/locales/fr/app.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index b1697ea8..c42802cb 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -33,7 +33,8 @@ "no-file-added": "No file added", "add-file-to-timeline": "Click on the blue arrow to add some file.", "electron-open-on-startup": "Open Marv on startup", - "connect-with-twitch": "Connect with Twitch" + "connect-with-twitch": "Connect with Twitch", + "open-twitch-chat-window": "Open Twitch chat" }, "words": { "settings": "settings", diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 8df04d7a..a89e97ba 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -33,7 +33,8 @@ "no-file-added": "Aucun fichier ajouté", "add-file-to-timeline": "Clique sur la flêche blue pour ajouter un fichier.", "electron-open-on-startup": "Ouvrir Marv au démarrage", - "connect-with-twitch": "Connexion avec Twitch" + "connect-with-twitch": "Connexion avec Twitch", + "open-twitch-chat-window": "Ouvrir le chat Twitch" }, "words": { "settings": "options", From 7130bc406c69ed90529235920701146ef03e4a9a Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:02:03 +0100 Subject: [PATCH 060/451] add defaults "secure" web preferences settings --- app/main/window/webPreferences.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 app/main/window/webPreferences.js diff --git a/app/main/window/webPreferences.js b/app/main/window/webPreferences.js new file mode 100644 index 00000000..1f50e0f3 --- /dev/null +++ b/app/main/window/webPreferences.js @@ -0,0 +1,11 @@ +module.exports = { + nodeIntegration: false, + nodeIntegrationInWorker: false, + nodeIntegrationInSubFrames: false, + worldSafeExecuteJavaScript: true, + experimentalFeatures: false, + enableRemoteModule: false, + contextIsolation: true, + webviewTag: false, + sandbox: false, +}; From a5b35d6f3076531b4ad1ebd2960549e9ba8737af Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:02:44 +0100 Subject: [PATCH 061/451] add icon svg and ico --- app/static/icon.ico | Bin 0 -> 106923 bytes app/static/icon.svg | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 app/static/icon.ico create mode 100644 app/static/icon.svg diff --git a/app/static/icon.ico b/app/static/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..687fa8721cd2a4a357443b6a0e872c8c466eec68 GIT binary patch literal 106923 zcmeI52V9N&AIG0l(a<1!q>SQPWk<-Ki7O+Un-v-P+oTh@xX9iS*B+OUajlM(n~`kS z>d4B7Y_914`5e!aQ<^#@bYA!E`~05gH@@HRZ~xBIxq=`QvI{wL3Xm2;KOI5nBM5?p z#i#Ik+z-J$8yhifDF`F-3PRnwpTec<3qnylL6FPEu%1k4?12pMVScrX2*RLAGNClW z$O?Bp-G>kad)&J@1?Zm_AOZ{ljK}-blXmeL?V+zE-4l{b(-g2x?nowXLh1dHhQ6S! zb-{g*P`rfhska}dXM66F!aU-%Uv>hdlk%V*JArz8lFFC*58ExvQ}rL|ABIJYA)A58 zfPGi$zx4AL{Wr=)5ER-NPl!y)?UTfC!675ghjAE}X_%Jdj0LC*IR2 z6hPhBPgLoXF6GOoQaZ>yU?4aR-T|r3lauT#y8!*83%)EQkvohF=)>B8ReC4zoREXPNv^iVTMQ05n}*{QNkEwiL^h%4YvQl>uc- zx^OIy9UpMr3M4nLNoh49>4SPevVR7ylggK4T`)*({cvtdtS@n#WcdbQA4sbFm3VFm z*nX3W7ylXCT7Mv|t<;|@aG!HxA#f3>KU2Tv{9g@F*P7rKP=B7-HRlA5p=|41FU60i z#68Ygw2RmApG)Csc*Zf2<&*A!(o~i`=-s z4M=&#muycaOv?`?;GEVEoCgm8?Qae$gF~P&<->LoX6b25K;aH*%NdVr5U6JxCS`SvW^(H0^r{U91LaX_M^Ji$PJ4sNGW8l9b{?8i4lT z0C)vb>I0U`@s;g7Rr@bV2TG)s;5gYB%m7EgEx`GUIuTy;9>-M9&Gi7s^%UEzUT#9y zVqP*x6Hp4+1I`De4&XiN$v6pRk>I@;rEW}&To&_D5Io-sf_;=Am;)1~Am}OtL7T{N zgdidCV*zXgxiCbg5Z;1lgb6-!wYUl~y%KpbPvmcoX!b0NWwLCZQ`mqWAoiT15J6)dOUbCh)n4HRNTGmU19 zfcSBf3&%f)OD?{qo^#!*YD1#r{BSOn`bQ%E0`N4I>5{VH9`XuHL4IctCohm}sEX^< z>ah%IxUcdCnpj8EuHQi`@B}1fC-)CEfTVw0T&G3{j>VP5^qlXwPD!e~lsvnSJSvKL zdO;@FHo1?J^moT~O3IMp&`+xK05K1q5wK3B=U*e2BfXB8pDAQ=Yk=uuT-rc;Q(ERF z#N{4Lz5g>0uCpURO7l^V$M(0ZGlJ+)qpPj>WZleu-VPjSU8>a#RN3A2H1O z;2MQ%mBi8~cAvgxUyARO&bap?k^J^bX&^cNOa#gK@2D78Qax7UKJDOH@gk6zo(bK5 zhxi>pLO#ik`#vC{{pu0iHwN?@=QC}<_0ejO&{*^u_nkqUa$*g@h4`!x-t_j@> zLfqU;8~?+5pa9qp;-{7Lr`~eV6X*e+=h%Z)-~o`*`Qtjyyq!pSER*B$b+xoo9+Vtc z_}$PQ5CXaY$#zN7r$h=D!*y5S1=a$dy->2g8HZ=N|ACF54xkO}8`fYP*aPYTRetgH zRu4;YAX!%r0r#Kuu^$)%IswlAw6O}P4cLCzue`w`umW&A@&)sN9Jqp(fa%Hr3!plu zfaG(@M^A9Q4lr&`AOKy!dQw+4(Q7dceNYKh04$I54Q*ms>%noL1YFNV1F8I^Bz??z zpJSj4pl*cyJpO#a_I?sf1(pNpC^Nz;9n30;+K(>uE{;? zhy0{+tKmAKJ}c$%7SF@L0k8ycyzK>OH{0(ZKwYCzfM1ZCy{lKzylzkwcKYX@~z>CSd6UN?eFY_9v-a?&Fm+fMBMMNNMb z+&>7?qfAZaxf?phnTHUT>VSQb^SLI=(_~&86P+Y|6Bq+I-tW!C`u_#p;`m;&L9z+5 zA$SZl={HT}#d(}_U~IpYbeE*~jPvXSke=grYVBd0=K3O0-Q(Gi3voAt)RvPT@j1V6 z&ivxsP10FiBA(Qji{m;Fq=!za$&+(>K1nZiT@$;O;zE`N3Xq!eG!>VAXMZgMl5IEf zZIRMIa_!B0GO|Cgy)Op&L44Ix9A;V(u8-KKp8!qyH?e#;&I|!5YVRpA26@pA?q?c< zec(TkSovRjpL5ezP#t`+Mo)>JNyR~)QeALt>In`3mie{%O6ji zXUtoKb9D=_5L^IU`=w+p%{bIK6wCq*K)UOlkkKfYwrBzNvpQe^m(h;q@lq z1GsOh3Aj(wcsof*&y?PSK2qJVuNVMh5nl72>Um1@OG&(#n78IJF@g{aUsht6FBVZM z@Uju59Pbf9;vFLdMCmEMo@6fwNQSqN@HbNG5`QnHWLWpJR4~lHrxK-HUCLDNIq`)h z)!$~}Pdy>!f=c3zDg3FYAlFq0MO9KM)L~kaC;`Q*-hvt}$8)|3g^%11lIeAopCs<7 z!lG1As_7wxmAtQ}ugV_SA=xF_sVW5ptNh`qa*666$xpFxg5{fE&^#zG{kkLXcwX$+!s~`Gr$d?37e%gOnk|;#4gYln1FBM2dP|0 z*7qOaK8UYtdWPSiyuSh0y*wMvsHU#+H_BuG<`{MvB-EGF({}Z|xo?>REI_)p1u1{A zEMG`XtkKnNNz3&K=+h9S%NU7#rFv&S=UAQ=UDGQq$6Gg$9cZjSFfS3FW3#=dm;Rc_ z_a*f61UW#OeZV|KxEJHtt_dB}I}ffQrUCA4zS;*&D^dgU3P^9gHJLws;0eCEFCZ=L zw*Wyvle%S8Uaz1x#{(HiRXbpOz;)J2kWu=kM>$-Va9&Wg<&-!KOt^uklDxj)cBBVB%S1Zz~_MLdB#so{+T^4*NKfmlKnt@UJ3FZ$m}+y zR=+*4NwsH6s3VBBbN%=|y>E~jA8^mqPPFq27l`+ZLtY1|$@hDT%e}Me{6O6SqV4P( zy+C^I-@mo5p2I%Xe3*d!x_Gt~d}|%kyL_G_#Tf_1Fz3jdX|$hb0rYWZZbLjvD-2?r z0Ixwykk<9iBjmw#6W1K+U60J4`;wEXEQ{kH&s0_RQ;Lj-Osmd|kq6fg>|+@*hYm+M z+@FPm)adSo_>$d}ocI1rWghX%yM^@DfceQle~_MMMBI;C0+#0rSg-MQN-WHIAolwO zT=Tr(P%6?VlrMcsyCuIe|9K$2&If(e%Hv*tDM(1KgzmB5@H+)b*8;ds%X5~OO7eY-c>JD8N?R1y$`q!JpZ|NLV_R3{rBdj# zPQ1tU^uHi}y0nB>A-~vjZ(K`u@Qf}Z1!eJkq=i~KD_no=c%?wv+{`QfM=gJ@JD-BI z*es>xcOXrryrnY5F#8|JM1IF6#ZO3be(nY&zvaXA4v^Y+nRwplB;_ONqAtZ}oD)0% z+e$+Eq~_ip`5YL7wIDgY zl6ua1?Fv+S$1g~_4_OLuOiC)RVQTR?|1nRtpNe1^;24oq`bT(f4-(WxT{kHXWC@U# zwb2QrXIoXzKF&3tiL{2~zCSS={-+j~V^l|=FW$=zX$Mw-NRUt-^Kn1fGZjfW#Fg}_ zhwD3ub!Z{m6!Cp@-lM;8@}Xx`5h%<#9}+ZCpo`0UY=HgGpd9_zMIA_9^lY2m*(}F0dN#Jcs(W z1~wosU^}PpB>OFKeFsSOz&c=?p*|G=eJRCdo1p%QSeX26F)!N2I-p&A_mMhLmIloM zb>^CGKj7Mo#Bxu9`1!G{`+)7GGbjdPeUZGSabqB@ zRGv1jStk2hTQCu@E0vmjB%uT<@$u}@-$$bGG9&FmXf^KH&ksHQt|=&d`i+vaX5a31NOO1U=HvAw2$NT zSTGx`2aIzUu>DHuzonc6J!0!iylx2jGLz_+p1yev8=KK)>BDPK5L^W5S$1Z~`x0y{ z3?%cV_Rslj!B1d6`zdXWwVxLZgT~-T?gP(ZAII%DwyW9CwZhdVGsKc|O>lwv&WD;xn$xj)HHYV|td!y5~A1A=6d&_)Me|BL zo(ZIfp6QV%_s?D+J4mUy3C3f3z&UX(_}a6F^sq6pJZbwMAO}d$rqteKJ|G`h2EN69 zJuzG3-{+ou0^t0WS~HW3&-{Qf;CPT3_XrWtt3OE7*<4aiK;HBL^Y03-f%yLa7Gd_u zQ=kdZ0!f*W=4Z@bgzE#I`+UoFVid~fe%2hQ^h&dVDab%73zB0@M-U7$a$MkEW*6W& zPMXK~6quY~6qGHsg#x(l1C9XdmR|jUYq8zH8E`DhusToB0pd+b4@gtc8gQQA_@Ie> zH2rx2%m+N9RLyIUNvZVBo>4Er^Kc8$2226_0QVA+fIdlR9l?8?yBX&y*a^IW11Jd6 zeQeXT)1b4|KR6#30hIvl=?*wo4Fki$0MG+82NgkKpa)dxHLX`xexE%M^ZA3{Vc>`V z*B43!ey@NMarxlW4-%*z^A`vBI}ZFMhZrR#A}T1g@&BfwL;?!@B!Ma!{{Jzbemx;p z+N*x=041ri`7HVWvEfIOx=MynfI=l=CI3G+{KQK9ngfFTRR=>+7KIuLgzX`flyX6v z(i1WY{}UWfg`oRZwnBgfy3w*J{ACK0XxRiA9AGHOA9{XMLY4U5~>gX-#Yx5OH%X?|6e=&cuG?8W2|2ld<;J;DdBgi9#k2iUQ`J^ zQDJgu4Z(=2dPGU)46FW6KB^1;!{3QOOvL4X7QDhomi0RkpB$0(ZWJ$Ot}(g3<~tfZ`^hiDYo3SkJ0z}YxcB(()@46Wb@0))(uKYwGfV-;4AD zo?tOp54M55fcv@A;G)P$NPa)cy(iy;`4jLR53XU`gX+Kxu-&M>Z-7ixpR5Pz>jC;6 zuupSeS^;zce*o^G{{{Sh;5kU^*#-A*JO_FVZi2&rdtf(U3-SW$k-i51Wcni|&Y$l<6*{;|oIBsxk=?&Np^+DF&RzvMo^d;wFsm@p7`UZFh5~`PP zb&u`g4%h&?0}GI%@1-^5svjmB_)Y5TT#q>bKad&gJh8UMws{%M2R!$p9a&>SGA&f} z5x>(e1bTwM!84GUpTCFu)Sqh-p6llZS?wTRI}m-sdM^e>0j|q4dOlC@w)6@%9RS@y zKJe4G1IY)F+f)B<6euw%)&k3S^?DIXr6_A{7ewOFl zJ01hv>-=zMNw7)Pt|7UH=UK@M@UzryYV3Rnzl;H@{o;=>A;1>aJ?A&J?Nfl~sj2bF z&lZ>KAbw9#27K4^fvCS8q$}VV?ax-1X|Xp1{%Q%n%e5i&X4~aBHWBc9n6&ufXHCmK z(--jk`@5J9sHX_e@O;6~wy)E4TYU;2jsylEQ?~)?Ct?oi4?X}*`{QTKk7otH0~3&G z+W>U~+{gX}vetQ;ZTlQY7XY4>X1X>&oj?J=Gp($;*KFNOV;;{5*akAyH~@WE_k0g# z1;`rn)2HsGHo)(eITvJ#^#Jr>-Sc~lc_11{dS=P=^99!fToZoNeF4g6-SeHxA%O45 zWz~7c`GETZ?hU`m`2fmg-IM0v9>}WujQ7EP_}vkx>LQ~Sg;IHtWdYBrvg-cZ`GEfa z1!Pq9OZ}ejU2o2+`%KaHx#!~FC8T>BU>Shl-wy@%j)}?x6b4D$0MjO)!!MVWe^bSzbItZIp6nF z_iPJ%U!c2Ke_z!Eq_mI&0l#~W-^Q}SncFA)dqbYnrltP*4(I-?y8kZQKEIQ7X8n`Y ze#CV3Ao*QmR$u=|Fo>S|E}BqbJSl8)@N!yj1LNfP>|L4zi%J# zcSutFcZG_rHH1@cZHJAVupyF_c{%+xNkQw}T3wl%mT#v}XkM_?Qj0}Mw0sgJZJmh_Xe3^-^afrn*><*)Qe}C>p^<^DWmd#2wUs`|Bho8NbkR$ zI*Bs)cUpqcJm_CXpt4Vtbs&`>y>#OE!gXD&PvbWP z@fqW!_gIvijfbEE|DHIGilTmezl}O_Uyxirnf3WT=+5ufRQ6E<8E^yXdFHkZ`Ez|2 z$FB_Vp2$?lZ|OJIYogylU&H>-Loqmm-+7Vk1V%QMU7ko{=DM`cse?fwO zD(k;FdIb4czDdA^;JyfZ@_j#r~Vg7!)GA)A5wK+`%uMxH#|`@*%n z2l9jSK-1->G{1!?J4Jujj(92`LbeCAE2U+8%XrtIXKC<-|D_vz2Ds;CJKgPotk()(35qWq-lH(I8Ud? zTs&ONKaLLKJqyS?AT>5=A}+^8FOcfLT|pYjSF68)-l?%Y0{Yof-{d}`O|+{lI15r! zPI7T)BR}pn;;6weCrghU)eygCH9!QZ{j3?3- zQj_0({E7U&m}AAVszP!NrYW0Kk`Kr2{$lwl@=g3mQd-FR;1)f^U6(8NY4qhEAz| z50m~tIzs>K0P*wvn(!{<^Tqxe_gIcD=m>cB{tGF;1iJ6@{&rw5&0Ve zbv4p-&AdQCuoEOzc1At>2YM6$Uu_rDigbs34$`9gNuh-S5P+hB`MTA>1fOcm;tVtzE&spi8%F- zu;ed}{c)5KpK)K#z33DW2GZIN*p{q8oU$|-VBSCnj0SJP*ZM0h>G)k*s?RhM^8@md z>Zvxam0xL7Fw*5_UebrxfO^&iWyG-bSS7`K^k)Sy4Y2&LX$M@Fc>s<1C61zM0hB?z zxb9v7zDC!y)crk_$^EpNMrprfet`Y7Klqxp0LKpcBvu(-i~J7B`Jpo~;Jx@C-UDn0 zHh|}u;UG1>J&pJlAb!^A5@tDoXG=#xTIw^kY5h{sjK@BG4!D3^AVFKi`y3C70avgOM1h3-$!B>$oU+q9!14gc%wB+PJ0aat za*yrzDYy+z0G_4I07Jm9pfV^7IKC!3zafswr;w~aj<*u}xF)P8!f}LaWo?jPJ*fLo ziX*1sTweyX24g{2!1_{8BI(f?_v5dXUgO?wz`Y>#i<3?Y@V*G!VPinQoB=NZeM`U7 zN6G3h<*7+2mP=o9?ZSOoQuWR8lYRLTpzVu+;0UNU?Tj<;NbxgDqI~L{A8Z4(kz*Xk z#Rza3tOat=3DBq1-w3Gs3uGKs85UvxWuIr?=X}U^J{WL)#Ckmm!ofoj1=y#OYl8{Z zf%-kBXFkusBX9#KzzQ${xBz=#255t--s2dc7Ql1bQWHc1^>X50Kf!ah&lZ3-t9+oA zRh&!lIsL=Fmt@>H3DY4Ul@D1C%mVCxZNzY1$OLu7eU;vjYzMU20@MXPfhSlF4uGqG zb-_0E0mS!RMuz`G`A@-hunVv){sszxFTBfpz#N2ul<3KJw;S{Z^oMG0`Xb{@b_06S zPOb%1`ZBEk5uY;-+XCA}SacFxd8q9MH!jx26Ys51z#xI#MZWwH^0AExE z?*Wd}%fQ#@PXBQ3VEgd|Qd>xJ-uXh2bh-h3XdmJFC=aLrIs$L71zZNypY8c;?EfCp z?1ycfzrOG??}?0qOsg$y3tT5022(&gPzo4<3>h0x4(;I>PkW1lW?&fb11CTPcmvXE z>-Us?0qjk*KjImE#y+8Gzi^!z4*mwegHE72;Ck5@B)Go*qLC(Y1L@W4x){O@fg6|y z*yfdh`_B*Hd#W!@>dHPj7|>S=;01~Ww-sCf23XXt`_7&SF z=U(E_Ouvv zs+wmLZ2+Ig0It_KXMb;PJWJn%>x|=ScaZ4ZFSQ9VPD#ixkmb)G!v~y8e_`Dw_hB56 z18fCZ_5Wk|V4GN{$yL9!2BhTvDQgY={n!70sK-7a*|A@09AaFa*W3VEW5D* zo_|Tzo2+D9z_Z|`AglhrZy(G>9cqJQ>s^Y#xFRhf6MG*Zt6gONcEK|ro{>pan_?-} zKhNEcfvmdzK7Ftcb;s{?Q(W&-M5YlL4*4^mn}4rupJ(jdqK%NFa>wNmX*v)sd`JPqkD>{)B z%uA#@@cp3w0e-LaGx;|&+sgMf9e`?{PF1C*GO}1kZb*NS znSJuJ=*E6H7Npy_uiivZj;f78T7#@Jfp6ajxZXEqy=2sfWr_R>$@g%7mcEwR>}3Bd zC)PzqRllknu}qFRJR9bDV`lTskFL)>_`DTJ_c=eYh9#D50_g{`-oekfKJXO&?hUj+ zV%3u&_gOyRzJu=={^)%!GuX%X@<)U0AVcansY0lOND0WlL1ysLkE+9a_}2&U94@J9 z$Lg+V`49M(zWUM1=K6Xz$k2UWO6pxb z4)l}SKt)^!f*-9OzJ)!U@23K;v(??5DX*!c2-gFDfvk51zP=wkhyUatQ_c6uH9Y7m zwE_P9KIg2g^MTa2fjjV1o)Zui7#L;_r~?X58vk#YY(tp)#f3K0#6VIe&p{F z`8Rn7KwDr0ewsd?SR3Gd(GQ#xDu7Ag3gEn$o?~xD=FNKNnRsuY`kOq+q+Ie-KBG?n z+W~)nifcsfgWrLStSe2H^#rGkn+dKKLHi2>hNd z3@iZ+K-M^)n#xy;3*Sj|1AmW<-zg0Td%+T&vpbckS#iiqF8Oi^U?0;Ne7YDULXD|xP z18f^STjx7!hruau5nKXXXC4KdTeg9H#_0&FMwMR?77e8xCzM@*BNqO#&;K8YrZ&n4uID zv{msx#)bt|I5vB+fVZEYs|tuMPWYs;^7C_5fr`&zRe|!)VO4>jgDQ*EiWjIr{IHrj zDuvY45oocRIx2D-@=x(S zKQ#(_B%==KnJNXDOr=^(j7mXIhFP@O=$K6VshpLlQkcoKk1JKJ6tNHu;adQ$RIUm~ zqr8s-8Vwa>|CVbj?d7pyxyeUurAZWfg;Eg4BZ=-CrFJyKQG&f3VZmG}#P}in)d)c2_+iPjs%WUH zIAL?P0ksdpaSXIqs|rT*j2Di=9LQY6Yr_Q!CK^Q~KBfJU@k{3{}?fmg18IVs^0^irK|# zEF~A~G&Z?dN3qdGlRigRMTpIvCC13rQmbwx_RrMTj!ldV3K>8}qh?JTwm}=hrA*Mv z4$)=k`aXhCM5kH9dTmEtjl3~>f00Hz705JnSMI^AeUzK_p}P{w{k@5 z;eGY%df5h6^3T1}f2Q^>S@r?P+xd5p2j-e{*iY{1ykq641%g5GkgYi$=NOmoN+IXQ zc5CM>&elcN#W?!(oO%_@$?i1u^)!hZ-NU|q-mri^)mqFs6uH3gxr@GqOL%m1#d1Y{ zdDjiyFV-2*YDdX}*ZTxpbY37-vIq&x@mA;7((xueri^gt+CN{ElQO?)6YGAu=Z(tA zhSl}$p8IW~Atn8njHp%hd7&W{hxi;lt9|uQ+r^ghYExc3)pZn%b#AUPYjyfVL0jEL zZl@={EGJuS5i(fUSMTv8j}g6J=ta3GwWhA>5HN9r!TToHy>0EMgdVh?9d+vFylW>F zXS}AGHi7?4zrP=FPX1*O~IdPYB6g z?Sjv-VUK@N=27mh_HvZ#0-?~97puI?O^e=L{A8%Pjcm^$E6egd_2tLrx_{KQHFoZ1 zS9I>CrSjaCK2OdWuQu$zOqgSQ@Ppi37~p!`#o(2lQfKO_z5&{2+g{Uw(nh}1W}Mx+ zBfq}(-{U)9?o%()RBmhU8)`Rhl-bj;mk&%7vxjdsy0B50^1@tJ;qb=yeOz}UTwGT2 z%uAR0)4N9o*ourQkl^@K(X6 zW3FynwB=c$AybZ?U31l|*Ixrn>sDHSe^ig+y9^fwA789!X4+)1tL~inTbc^Nmz?db zHlK2FSpL!Q@wM_T=CrFLD|!2^b+(`Z$A9a8+r56EqV`p)i@7Twu4#MXxI8@CN72jec1tIZ!omO_D0j7zPwvt;c5ku`%)2tm(_?B4vM?kvNn2l6_1wae!+bjXUMXD3~)SEWo#t(^BS3m^42|7A9-w5IIPW=c5cr_aNv#f3UUcrKdu~-8ec^3|s9cd2(|=JkSM+i} zn5X-Qhb;y7k4}n)Zx5Kgn25u$XtF*iw-l?Vh$hO0S4Hd1G zsG)2#rsZFb)-_PS#i+tA6Uyt2HO{jo)Cx^F&)fXF2F$GJ@ow|cv#X0+I}bCe>wkE# zgXeh5kgc8XWXrKh2GzAkwqAayNzlBrVO}Q9iX7;8^q9df(}TxFbk8%qwo4f|!y&)@ zn!oJEx<#|OIbCR3(8+z>loyk#%>UnDttl@`=pQLMIiGujpkY%7$Xne#aJ%)Es`6fn zna2$RE4q4^zHNImfABv2s2Xm!9bK*tAM`w;R`tKxY}&b%_jIYb&3H)j<@x{Fk=-Vj zbLBJ285_KEAAL9DMa|I_mdTqb-rOHP-lcyZgQ(fHYU;e$D6`!hRe0`vcg4rizP2yw zmkAkMzrfSM`ie!5YvtH%?Ow(Hbi-s)6Mw(HRyon=nr{~S}|qB z?t)KOXCET8e>>xBHNz|WZdBhrUzl^O&R_oxcBm21HQ%+rWRC^6^&Xdl3J4=|-nS18 zDSWM^@cMDsqM@#v^3B?tyR~oksW#UCUiz>4+FHwXZ!R3stA|}x`3*LTe>Xc8E<810 zt}x=_K_?dnzc%(pO)u&+9TVeM@>JtWLGwG!_g`EcNTQ}PMs!o)9{vH!kKD z;h(Sl#7f5&=^761-B!8%FW;8F=Jh-bVwNg~DfJIq8SZ#*+pXz7L#Il=|CYCY@d%Io z)|{{#yw|pwUwwLLufV_m&C$8J;2k-2-|1_L5{eJrJ1>qIU#GbH%RZO#w=fO5erJ^b znakcKx8?J1In-@w^ti3BC-*LM|8}oM!p4u0_WAeB@E_i>RZqVKcde#%Y&xf5tMa!^ zLi@IfsNq(=aphS9JCFXgg$L^2+^bdpuwM$d?cCh-?RqOOU@_2e5t2*hG-qaQM zG1GUmYrpEZsy#|Zy{&8Azms;;doh8VJ*s<*%K5hTO5ysA$ZQAA!lR!n@_F~Nv3ggd zlU)U;MF&dyY$+0v?XL?$wMz%5Wq+f+P&;s;?HK>_bBFJ{Q!&&m_*rgrK--?>-vuo> z-2dvfC0*RI4f7QOHpRTzwmQ^)bCDKzF$f4<78a@9a`M^zm5aIQms@AH>A{uur@OVj zq+?Uq)?`n^@P2y_zZy{DLCG;CYgG9C*o!*Vid8Y+<@WaP?IZSE&0nj(VtyUDz0AC< z#g#@1BgGl{fb-@0_jtbWLY~IkOBQ=sa?+~+m&)3m8ieQm8V7b za(Fan$>H0;esX`ZjeL*wd*;w#Y?BIs411zkV}W`x1t_i~8BBn0Uf@4s&cf zt$6)x(J9M)jRz~vwbUzo)_MQjl0H_5dAh%_^iIyuor(>nO+1}GIQMVv8#XQU_)x#2 zX9xVg^b0^xpQN?SSXKmACHf@oRnM=^WcJ8*b#T)$ok){#V;@ z+{7qD`}5`IN3Zdb8SB0-UT*W*Q)Y?+rw4DSl=FUI4&OFP%lx^j&0HK}m-|Q+<%UWh zJgSsCch0V&VTmf;!=BuZc>3l*j9UexY+Wk9gfzRQ3fW z0v-e!j4Qe7ypN8L%<)W_kTOj_R_s!5xPiT5>>QVM-2%Ip4zUlK;~iCb>Z&FI6E9v^ z?f+&?nDyBari!id+jgU0hCb@EK-XC2nEg`7trs;r`r3Q0cour2r0eC6(;r&jzT{%l zvzDS?k6Oi=jcaDNzW9_ENAz4uRI_?~@^AN{(~IAj^YO#@TrZajb8fy4D*AezUf6%t zdky>FNtv!z*q_pvQ+h^K(*#g%u?$zXv7xoWcztTDSuA-vGRrfn?9qU)J zZ)P`ZgyqhF!7>;9Y_*?e>vsOKpm#B*l)QnZ&!7{^wYs^-yfiyz-J3x8=Eq{9(q0h zpS!JY6b&D@qsfx_^DbrkGG4oSd#006Iozu!(x8eo>-R%F|S`><#7LSqqVPE zx*yy=_L1ex+2fnlDO;^w%MEi!SGsxEwE5mYhhEdK>l^0npZD_C2+x0pbTnFX<+x49 z_l5jtj>u{GtcLse)gy9hzb)FcM81|EwiwT=iM3yYx!vxMl`oq=cysQ_mNR>mY2+KG zZ|h{|V_MLm>6A4kLOhGu{%U8uy*VbgQHNhd>$mm%Ygcc1<$#Gz8(;#yV!7d=pT{NR zRtvn#&bagRVev>?(`BmVo%_e%l!Xo(?i=(>-@VSG`9p`!4zRQ?5z}*3y8zQ6i$>(E zJ*Ua7{JE?u%&+$zI-9p}?lj6Xa^F9}i-T?MZeQAT=h7~t?W_vs>X<#Zd}e>$vnvkh z%o=BRv;M&yuL1@(4xT*!j~8Q|p5J_8>O9%Mi*FhC@w&==SKVKp8)4MLa%hnXU5bab zSiWf?nn1;#kE)!%{w%meo4mmRH^Xw(v^u#uQYZA>J*}=iS}JuSEylE{xy$No%!%Xo zmhI9W5xQr{oKYdGd_8(C5IRL+Of8QXC1X~El-fLeaHo;`&kYYWoHyLspoLK0dA3cz zRporv?T=Y;!mXA2_z%UcONR`0eC9OnyuVK9pA(P1E5CDM&iluI-7(3bauq$>UF)Y= zwz%B=#GI}hPOOIt&rEydtvn^lx%G|`4?Mi@e^?xHVe{e!bBzBk?%QDWrF{`+u7CWf z=r6Q*U)q0Z(4@I}=UA^>UbuT7*GA_CyDnT}8)!Xb{p-`aR)qDwpj%Wo=ZOC{+*n)4 zyOTU<#he}T$en`^wis8w+4{drAIcNf{&cCwx6iI?zj5*K&DqAuCrn=O$BXw)errxn z^Uv3F)7w*)Q}4FfxGmq2mtG4LJ9I(=pXRB0sN{o2by~gueP8Qt+7lhK)miWHzw%3} zg_`f0BRss6>xzq!f%AY?zTM~hZ*MjKO@Q^L@?P#8m$&u}n_+5PsIc5pZd{~P$o*|y z3;K_`bR}Cv`T5;+7oT3)bnV-Zjo<&?=Ao^u))o)lKiUh9C!a;wOU;y4VrRrSW>X_y^5`nB~9n>2Jrt;c@EplnUBai!BTh~#m-)ZMcS3B7JJN(@n#gNFQ z8)xU$+h?`TDkN~}P{(Hj8=c>Nt-01B*|3Z4I}QA=-u7}G)`hIBIdj(D;9tX|4P0-A z`bUpxm;dO4TC%1^4mcjL(;DkmcWGGh+DG3_)H~m}<+Do`j~$l<%~s$X;i;m*>29I@ z3tw0wJG6W5{ns0&zUVBA+2o;Jb!3-K9yNlMo6TKyudm#|NLr(u-#a${&34GptJN(d z|0%0C@Yhv+bFX+%CNwxt*vZmw@`UwSuKQ&0>*AYat4B_^4eYkbdXRJRy?5U%>aw$v zO+=R!x3_7ZSZi2Ccg18&`O5{m2mQidtrPYQ&>fiX+VB--E04bWAa4*b@s#59U;F=A zB1Hb%#Mk`%<3_=I+|L?cD!1lLr@GtcT{#ml@nqAr`pO#Fo!hNm8&YU}gI`>&q8E%Q zx2apz_it{R?fuPZ+|tp77Tr9Nqw}>w<$UtVcJ~i!7yP)c{j?E(yl9}eY<#2gEqb5p zSaiym4^OICyeJmde30V_Hz(KM|Gc@{ql4wJF_pFt-nP2E((A8)iIuhg`vV(XY;x_! zoSb@p<(h}~tI>!20vb1#b&q_t?}&WjPVLGqjdYEhzMioDDjYD#_0=R-Q-!voNTgla zm4hwMyvudpUN5?#oyGa>xAmOHb+~L?vcb$|MQY!CIIXjz5L~&@rflT~R;_R9yv!!J z)b2^8Ti&ZC)Y)v-FsRM^vjOLSEiZdnUh8As;iYCQdg9)7N&a;$1vKQ{cm40~pKg;RfF~)ITpEp!;N;X)}aSGyPW!Mck?2r z-R{qbw345cR}Xl4wScyFw!T--wMUZwOor@y-LZ&>isYmNf;UuXNASyj<0_ekyPBZf|Je6w~(A9=+wjsx%i z>$%FuRDSeqpnP9|eKwc=5yg}z99zvf_9UQv4x6>3*6rN>#Ith8lJYRw;QpS4f-d~y zaM&Qo?2#?ncI{S^YtIf^)Yi&sS(MqyKeG!x*ZDeVRSGifmv5lM`^Z*S`gOx2^xg0V zZ6n(fk$;+N2X90imr0Y3d140~R7AP3<8qrFIu`CP3lwbMa(cxUHClxC8^55`sqNW? zA!Sg!mB|i0JICH-&NEKwYPGH`s#T<{dll(D_J29#tL)5Pg!$F#FZ9?cxNNWVYk0rL-AbLYq}GPfRd&xjx@gR(JhrvZ$0t+(h~xL1j4o~ycx!@?<+KFiC5*Z;eeFm+W&?~j6u!~bH0@og_0`(wSV z?x^BDu1zgi+5d0FLDMFa%KJMtMKyNPE8=xJw@n`lU9`wd5xQ}6cSiGLhiVH>Ewa+S;aAfv)gm8@l*Eg!k& z*%CnoO@zt)uWznsIn2NPE!_f}-Ou7^&E96veZ3BBtDVik zp>mc~!i+t-#!gw*$sTzi+dET5mO7A{&Y0Mu#9rYnNM-O)Ui!__tz< zVj^SC?yg_c7wlG;mB>^ z9-}K&A03F^-hQK1-4at*mGYXYb*3LOZ@yc5?7Ra}4W{N6>TWM~__+K&vuSi$*oT37 zy;;+;&6f$N`Jy@_ij`Z~%VF_{C877MKUDXed9D=o8LQV!83ujM&phwd;N#MFZ6u(e-E2jE;72}13w1Vh93v$buJzGr`gO6%ks--E_7|*eP5Z&IuR{> zW6BMw=sy96srjDhysmI^+(*ZDTl7Ph9zB~^;jF9?>FjXXF8`Hnoek`V)iYW#+1B24 zkLi`>cKOZ^@1|uu+jhxnv!<8Ibk~k3=KfNrXL+xwisF%@94_yf=s(Ewa^CR~e-^4+ z0_U~L`aQZLt2N7v955&~u$#4iSZ^&MC-$8oGUIbT$J&N;IsD?o;WrP4076Vx|Cb{9slcUV1Hpn_E4<+bjD?~ z&0PTY{W8Cq;_}?8rTed`rVo7si{5H>=q5Zne5O{D7Dc+QGn=yDs-?Urk77-{BH^w{ zorQ6J{+*uUaKGQifz)cD?6u_uy-SyTj^_ymw8W{Do~L#b379uS91 z{hNN>#kPTk{A;(Eb9ltC`$cunXgfK#iCEY9VmCia`J84!h1^;;)w`CvX6`1x{xy5b z4lmc>XE|;1?g?9de&I|@xk1w<#wFyh-q)yd$MN#Piw5j`TU + + + + + From b19b73a85215071c04b79712dc97515784c9c8da Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:03:26 +0100 Subject: [PATCH 062/451] fix: missing default value argument --- app/server/libs/twitch/state.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/server/libs/twitch/state.js b/app/server/libs/twitch/state.js index c95dd273..fea7553d 100644 --- a/app/server/libs/twitch/state.js +++ b/app/server/libs/twitch/state.js @@ -10,8 +10,8 @@ let state = { }, }; -function get(key = null) { - return key ? dotProp.get(state, key) : { ...state }; +function get(key = null, defaultValue = null) { + return key ? dotProp.get(state, key, defaultValue) : { ...state }; } function set(key, value) { From bf881cf4f1ebd9c31ba2b88a1828a5975c4a600d Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:11:04 +0100 Subject: [PATCH 063/451] feature: electron chat window --- app/main/tray.js | 19 ++++-- app/main/window/chatWindow.js | 107 ++++++++++++++++++++++++++++++++++ app/server/api/twitch.js | 2 + app/stores/defaults/twitch.js | 3 + 4 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 app/main/window/chatWindow.js diff --git a/app/main/tray.js b/app/main/tray.js index b5b89cc0..403db156 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -1,20 +1,21 @@ +const mainWindow = require("./window/mainWindow"); +const chatWindow = require("./window/chatWindow"); const { _ } = require("../server/libs/i18next"); const { Tray, Menu } = require("electron"); const { staticPath } = require("../utils"); -const createWindow = require("./window"); const capitalize = require("capitalize"); -const store = require("../stores"); +const stores = require("../stores"); const quit = require("./quit"); const path = require("path"); const open = require("open"); -const { name, version } = store.app.getAll(); +const { name, version } = stores.app.getAll(); const fingerprint = `${capitalize(name)} v${version}`; let tray = null; function openInBrowser() { - const { host, port } = store.server.getAll(); + const { host, port } = stores.server.getAll(); open(`http://${host}:${port}`); } @@ -28,7 +29,13 @@ function createMenu() { }, { label: _("sentences.open-in-window"), - click: () => createWindow(), + click: () => mainWindow(), + }, + { + label: _("sentences.open-twitch-chat-window"), + click: () => { + chatWindow({ channel: stores.twitch.get("chatWindow.channel", "") }); + }, }, { type: "separator" }, { label: capitalize(_("words.quit")), click: () => quit() }, @@ -39,7 +46,7 @@ function createTray() { tray = new Tray(path.join(staticPath, "icon.png")); tray.setToolTip(fingerprint); - tray.on("click", createWindow); + tray.on("click", mainWindow); tray.setContextMenu(createMenu()); tray.setIgnoreDoubleClickEvents(true); diff --git a/app/main/window/chatWindow.js b/app/main/window/chatWindow.js new file mode 100644 index 00000000..066b080b --- /dev/null +++ b/app/main/window/chatWindow.js @@ -0,0 +1,107 @@ +const { staticPath, watch } = require("../../utils"); +const webPreferences = require("./webPreferences"); +const { BrowserWindow } = require("electron"); +const storeBounds = require("./storeBounds"); +const hideOnClose = require("./hideOnClose"); +const stores = require("../../stores"); +const path = require("path"); +const open = require("open"); + +let win = null; + +const { host, port } = stores.server.getAll(); +const marvURL = `http://${host}:${port}`; + +module.exports = function chatWindow({ channel, showOnLoad = true } = {}) { + if (win) { + win.loadURL(`https://www.twitch.tv/embed/${channel}/chat?parent=localhost`); + return win.show(); + } + + win = new BrowserWindow({ + width: 800, + height: 600, + show: false, + frame: false, + icon: path.join(staticPath, "icon.png"), + webPreferences: { ...webPreferences, devTools: watch }, + }); + + hideOnClose(win); + storeBounds({ win, name: "chat" }); + + win.webContents.on("new-window", (event, url) => { + event.preventDefault(); + open(url); + }); + + win.webContents.on("did-finish-load", () => { + win.webContents.insertCSS(` + #root > div.tw-top-0 { + top: 30px !important; + } + #electron-titlebar { + display: flex; + font-size: 14px; + user-select: none; + align-items: center; + color: rgb(226, 232, 240); + background-color: rgb(26, 32, 44); + } + #electron-titlebar > div { + display: flex; + height: 29px; + padding-left: 8px; + padding-right: 8px; + align-items: center; + } + #electron-titlebar > div.icon { + display: flex; + } + #electron-titlebar > div.title { + padding: 1px 0; + flex: 1 1 auto; + display: flex; + height: 24px; + } + #electron-titlebar > div.title > div { + flex: 1 1 auto; + -webkit-app-region: drag; + } + #electron-titlebar > div.cross { + cursor: pointer; + } + #electron-titlebar > div.cross:hover { + background-color: rgb(197, 48, 48); + } + `); + win.webContents.executeJavaScript(` + const $html = document.querySelector("html"); + const $body = document.querySelector("body"); + $html.classList.toggle("tw-root--theme-dark", true); + $html.classList.toggle("tw-root--theme-light", false); + const $titlebar = document.createElement('div'); + const $icon = document.createElement('div'); + const $title = document.createElement('div'); + const $cross = document.createElement('div'); + const $iconSVG = document.createElement('img'); + $titlebar.setAttribute('id', 'electron-titlebar'); + $iconSVG.setAttribute('src', '${marvURL}/icon.svg'); + $iconSVG.setAttribute('height', '16px'); + $icon.classList.add('icon'); + $title.classList.add('title'); + $cross.classList.add('cross'); + $icon.append($iconSVG); + $title.innerHTML = '
${channel} - Twitch chat
'; + $cross.innerHTML = '✕'; + $titlebar.append($icon, $title, $cross); + $cross.addEventListener('click', () => window.close()); + $body.prepend($titlebar); + `); + showOnLoad && win.show(); + }); + + win.removeMenu(); + win.loadURL(`https://www.twitch.tv/embed/${channel}/chat?parent=localhost`); + watch && win.webContents.openDevTools(); +}; diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js index bd71ead2..03dba572 100644 --- a/app/server/api/twitch.js +++ b/app/server/api/twitch.js @@ -1,3 +1,4 @@ +const stores = require("../../stores"); const twitch = require("../libs/twitch"); const chatJoin = require("../libs/twitch/chatJoin"); const chatConnect = require("../libs/twitch/chatConnect"); @@ -11,6 +12,7 @@ module.exports = { chatJoin(user.display_name).then(({ alreadyJoined } = {}) => { if (!alreadyJoined) { console.log("Marv est dans la place !"); + stores.twitch.set("chatWindow.channel", user.display_name); twitch.chat.say(user.display_name, "Marv est dans la place !"); } }); diff --git a/app/stores/defaults/twitch.js b/app/stores/defaults/twitch.js index 11e8bc26..e048f762 100644 --- a/app/stores/defaults/twitch.js +++ b/app/stores/defaults/twitch.js @@ -1,4 +1,7 @@ module.exports = { + chatWindow: { + channel: null, + }, AccessToken: { access_token: null, scope: ["user:read:email", "chat:read", "chat:edit"], From bea5bb8bdcbd045c8cc85087d28665aa48e007e1 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:14:33 +0100 Subject: [PATCH 064/451] v0.5.0 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index 0498f02e..b35b1900 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.4", + "version": "0.5.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index adfebedc..360d4f80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.4.4", + "version": "0.5.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 779e6769cecacbbdc96de8d7268d70e2f4ae5c6a Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 16:59:04 +0100 Subject: [PATCH 065/451] fix: version number up to date --- app/main/tray.js | 2 +- client-src/components/App/Connecting.svelte | 5 ++--- client-src/components/App/ElectronTopbar.svelte | 7 ++----- client-src/components/App/SplashScreen.svelte | 4 +--- client-src/stores/app.js | 3 +++ package.json | 1 + rollup.config.js | 2 ++ yarn.lock | 9 ++++++++- 8 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/main/tray.js b/app/main/tray.js index 403db156..0353c0f5 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -9,7 +9,7 @@ const quit = require("./quit"); const path = require("path"); const open = require("open"); -const { name, version } = stores.app.getAll(); +const { name, version } = require("../package"); const fingerprint = `${capitalize(name)} v${version}`; let tray = null; diff --git a/client-src/components/App/Connecting.svelte b/client-src/components/App/Connecting.svelte index a9acd84e..51ea447a 100644 --- a/client-src/components/App/Connecting.svelte +++ b/client-src/components/App/Connecting.svelte @@ -1,13 +1,12 @@ diff --git a/client-src/components/App/ElectronTopbar.svelte b/client-src/components/App/ElectronTopbar.svelte index acaaf436..4018eac0 100644 --- a/client-src/components/App/ElectronTopbar.svelte +++ b/client-src/components/App/ElectronTopbar.svelte @@ -1,13 +1,10 @@ diff --git a/client-src/stores/app.js b/client-src/stores/app.js index ed99073f..c5a98f17 100644 --- a/client-src/stores/app.js +++ b/client-src/stores/app.js @@ -1,8 +1,11 @@ +import { name, version } from "../../package"; import { writable } from "svelte/store"; import { emit } from "@/libs/socket.io"; +import capitalize from "capitalize"; export const store = writable(null); export const initialized = writable(false); +export const fingerprint = capitalize(`${name} - v${version}`); export default async function load() { store.set(await emit("stores.app", "getAll")); diff --git a/package.json b/package.json index 360d4f80..fad9de70 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "devDependencies": { "@rollup/plugin-alias": "^3.1.1", "@rollup/plugin-commonjs": "^15.1.0", + "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^9.0.0", "animejs": "^3.2.1", "capitalize": "^2.0.3", diff --git a/rollup.config.js b/rollup.config.js index 4e97cde8..535c0d64 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -7,6 +7,7 @@ import cleaner from "rollup-plugin-cleaner"; import svelte from "rollup-plugin-svelte"; import alias from "@rollup/plugin-alias"; import css from "rollup-plugin-css-only"; +import json from "@rollup/plugin-json"; const watch = process.env.ROLLUP_WATCH; @@ -24,6 +25,7 @@ export default { sourcemap: true, }, plugins: [ + json(), alias({ entries: [{ find: "@", replacement: `${__dirname}/${clientDir}` }], }), diff --git a/yarn.lock b/yarn.lock index 923066ef..573cecad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -108,6 +108,13 @@ magic-string "^0.25.7" resolve "^1.17.0" +"@rollup/plugin-json@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" + integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw== + dependencies: + "@rollup/pluginutils" "^3.0.8" + "@rollup/plugin-node-resolve@^9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz#39bd0034ce9126b39c1699695f440b4b7d2b62e6" @@ -120,7 +127,7 @@ is-module "^1.0.0" resolve "^1.17.0" -"@rollup/pluginutils@^3.0.0", "@rollup/pluginutils@^3.1.0": +"@rollup/pluginutils@^3.0.0", "@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== From bd8db9ac499dd4ab66799970db3bae504c84742e Mon Sep 17 00:00:00 2001 From: skarab42 Date: Tue, 24 Nov 2020 17:10:55 +0100 Subject: [PATCH 066/451] fix: systray icon for window OS --- app/main/tray.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/main/tray.js b/app/main/tray.js index 0353c0f5..0c802798 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -9,6 +9,8 @@ const quit = require("./quit"); const path = require("path"); const open = require("open"); +const isWin32 = process.platform === "win32"; +const icon = `icon.${isWin32 ? "ico" : "png"}`; const { name, version } = require("../package"); const fingerprint = `${capitalize(name)} v${version}`; @@ -43,7 +45,7 @@ function createMenu() { } function createTray() { - tray = new Tray(path.join(staticPath, "icon.png")); + tray = new Tray(path.join(staticPath, icon)); tray.setToolTip(fingerprint); tray.on("click", mainWindow); From d26b21250fa2aabaae91184282263c4bc5825f41 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 07:19:19 +0100 Subject: [PATCH 067/451] fix: unused prop Pass data object instead of individual prop --- .../components/Panels/Panel/Widget/EditModal/Action.svelte | 7 ++----- .../components/Widgets/Anime/Timeline/Settings.svelte | 7 +++---- .../components/Widgets/OBS/GoToScene/Settings.svelte | 5 +++-- .../components/Widgets/OBS/ToggleScene/Settings.svelte | 5 +++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte index 97799122..e83dbd1e 100644 --- a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte +++ b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte @@ -16,6 +16,7 @@ ...getWidgetsList(), ]; + $: data = { panel, widget }; $: component = widget.component; $: componentName = (component && component.name) || ""; @@ -50,11 +51,7 @@ items="{triggerTypes}" />
- + diff --git a/client-src/components/Widgets/Anime/Timeline/Settings.svelte b/client-src/components/Widgets/Anime/Timeline/Settings.svelte index de01df82..78f56c37 100644 --- a/client-src/components/Widgets/Anime/Timeline/Settings.svelte +++ b/client-src/components/Widgets/Anime/Timeline/Settings.svelte @@ -6,10 +6,11 @@ import Editor from "@/components/Anime/Timeline/Editor.svelte"; import FullScreenModal from "@/components/UI/FullScreenModal.svelte"; - export let panel = null; - export let widget; + export let data; + let { widget } = data; let initialItems = []; + let timelineOpened = false; get(widget.id).then(({ items } = {}) => { if (items) { @@ -17,8 +18,6 @@ } }); - let timelineOpened = false; - function openTimeline() { timelineOpened = true; } diff --git a/client-src/components/Widgets/OBS/GoToScene/Settings.svelte b/client-src/components/Widgets/OBS/GoToScene/Settings.svelte index 761a47a8..dbeceb3a 100644 --- a/client-src/components/Widgets/OBS/GoToScene/Settings.svelte +++ b/client-src/components/Widgets/OBS/GoToScene/Settings.svelte @@ -4,8 +4,9 @@ import { update } from "@/libs/panels"; import Select from "@/components/UI/Select.svelte"; - export let panel; - export let widget; + export let data; + + let { panel, widget } = data; $: scenes = $state.scenes || []; $: props = widget.component.props; diff --git a/client-src/components/Widgets/OBS/ToggleScene/Settings.svelte b/client-src/components/Widgets/OBS/ToggleScene/Settings.svelte index 29c8f717..989421c0 100644 --- a/client-src/components/Widgets/OBS/ToggleScene/Settings.svelte +++ b/client-src/components/Widgets/OBS/ToggleScene/Settings.svelte @@ -4,8 +4,9 @@ import { update } from "@/libs/panels"; import Select from "@/components/UI/Select.svelte"; - export let panel; - export let widget; + export let data; + + let { panel, widget } = data; $: scenes = $state.scenes || []; $: props = widget.component.props; From e8a6b3fa5424300c939b751dbac8d6814c4b4fab Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 12:55:28 +0100 Subject: [PATCH 068/451] connect to twitch at startup (UI) --- app/server/api/stores.js | 1 + app/server/api/twitch.js | 5 ++-- app/stores/defaults/twitch.js | 1 + client-src/api/twitch.js | 2 ++ .../components/App/OpenOnStartup.svelte | 1 + client-src/components/Dashboard/Drawer.svelte | 6 ++-- .../components/OBS/ConnectAtStartup.svelte | 1 + .../components/Twitch/ConnectAtStartup.svelte | 29 +++++++++++++++++++ client-src/components/Twitch/Login.svelte | 12 ++++---- client-src/libs/twitch.js | 4 +++ client-src/stores/obs.js | 8 ++--- client-src/stores/twitch.js | 25 +++++++++++----- 12 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 client-src/components/Twitch/ConnectAtStartup.svelte diff --git a/app/server/api/stores.js b/app/server/api/stores.js index 28575cfd..e8765a36 100644 --- a/app/server/api/stores.js +++ b/app/server/api/stores.js @@ -3,6 +3,7 @@ const stores = require("../../stores"); module.exports = { obs: (method, ...args) => stores.obs[method](...args), app: (method, ...args) => stores.app[method](...args), + twitch: (method, ...args) => stores.twitch[method](...args), panels: (method, ...args) => stores.panels[method](...args), i18next: (method, ...args) => stores.i18next[method](...args), }; diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js index 03dba572..1f5915b0 100644 --- a/app/server/api/twitch.js +++ b/app/server/api/twitch.js @@ -4,8 +4,8 @@ const chatJoin = require("../libs/twitch/chatJoin"); const chatConnect = require("../libs/twitch/chatConnect"); module.exports = { - login(email = false) { - return twitch.api.helix.users.getMe(email).then(({ _data: user }) => { + login() { + return twitch.api.helix.users.getMe(true).then(({ _data: user }) => { this.notify("twitch.login", user); twitch.state.update({ user }); chatConnect().then(() => { @@ -21,5 +21,6 @@ module.exports = { }); }, getState: () => twitch.state.get(), + getStore: () => stores.twitch.getAll(), updateState: (state) => twitch.state.update(state), }; diff --git a/app/stores/defaults/twitch.js b/app/stores/defaults/twitch.js index e048f762..4dc53a08 100644 --- a/app/stores/defaults/twitch.js +++ b/app/stores/defaults/twitch.js @@ -1,4 +1,5 @@ module.exports = { + connectOnStartup: false, chatWindow: { channel: null, }, diff --git a/client-src/api/twitch.js b/client-src/api/twitch.js index 3d517010..1607bf8b 100644 --- a/client-src/api/twitch.js +++ b/client-src/api/twitch.js @@ -2,7 +2,9 @@ import { emit, on } from "@/libs/socket.io"; export default { getState: () => emit("twitch.getState"), + getStore: () => emit("twitch.getStore"), updateState: (state) => emit("twitch.updateState", state), login: (email = false) => emit("twitch.login", email), + set: (key, val) => emit("stores.twitch", "set", key, val), on: (eventName, callback) => on(`twitch.${eventName}`, callback), }; diff --git a/client-src/components/App/OpenOnStartup.svelte b/client-src/components/App/OpenOnStartup.svelte index de407e13..30df2bf9 100644 --- a/client-src/components/App/OpenOnStartup.svelte +++ b/client-src/components/App/OpenOnStartup.svelte @@ -13,6 +13,7 @@ function onChange(event) { checked = event.target.checked; + $store.openOnStartup = checked; app.set("openOnStartup", checked); } diff --git a/client-src/components/Dashboard/Drawer.svelte b/client-src/components/Dashboard/Drawer.svelte index 8323835b..238e4a60 100644 --- a/client-src/components/Dashboard/Drawer.svelte +++ b/client-src/components/Dashboard/Drawer.svelte @@ -5,7 +5,8 @@ import TwitchLogin from "@/components/Twitch/Login.svelte"; import OpenOnStartup from "@/components/App/OpenOnStartup.svelte"; import LanguageSelect from "@/components/App/LanguageSelect.svelte"; - import ConnectAtStartup from "@/components/OBS/ConnectAtStartup.svelte"; + import OBSConnectAtStartup from "@/components/OBS/ConnectAtStartup.svelte"; + import TwitchConnectAtStartup from "@/components/Twitch/ConnectAtStartup.svelte"; const query = new URLSearchParams(location.search); const electron = query.has("electron"); @@ -24,6 +25,7 @@
{_('words.language')}
- + +
{/if} diff --git a/client-src/components/OBS/ConnectAtStartup.svelte b/client-src/components/OBS/ConnectAtStartup.svelte index cafa39da..69f52dce 100644 --- a/client-src/components/OBS/ConnectAtStartup.svelte +++ b/client-src/components/OBS/ConnectAtStartup.svelte @@ -13,6 +13,7 @@ function onChange(event) { checked = event.target.checked; + $store.connectOnStartup = checked; obs.set("connectOnStartup", checked); } diff --git a/client-src/components/Twitch/ConnectAtStartup.svelte b/client-src/components/Twitch/ConnectAtStartup.svelte new file mode 100644 index 00000000..dbc7d6cf --- /dev/null +++ b/client-src/components/Twitch/ConnectAtStartup.svelte @@ -0,0 +1,29 @@ + + + diff --git a/client-src/components/Twitch/Login.svelte b/client-src/components/Twitch/Login.svelte index e03179e2..e2333ad7 100644 --- a/client-src/components/Twitch/Login.svelte +++ b/client-src/components/Twitch/Login.svelte @@ -1,13 +1,13 @@ -{#if $store.user} +{#if $state.user}
-
{$store.user.display_name}
+
{$state.user.display_name}
{$store.user.display_name}
diff --git a/client-src/libs/twitch.js b/client-src/libs/twitch.js index a865da32..fad7dba7 100644 --- a/client-src/libs/twitch.js +++ b/client-src/libs/twitch.js @@ -12,6 +12,10 @@ export function getState() { return api.getState(); } +export function getStore() { + return api.getStore(); +} + export function updateState(state) { return api.updateState(state); } diff --git a/client-src/stores/obs.js b/client-src/stores/obs.js index 94f3e401..d13072b4 100644 --- a/client-src/stores/obs.js +++ b/client-src/stores/obs.js @@ -1,5 +1,5 @@ import { writable } from "svelte/store"; -import obs from "@/api/obs"; +import api from "@/api/obs"; export const store = writable(null); export const state = writable(null); @@ -9,13 +9,13 @@ let loaded = false; function loadOnce() { if (loaded) return; - obs.on("state", state.set); + api.on("state", state.set); loaded = true; } export default async function load() { - store.set(await obs.getStore()); - state.set(await obs.getState()); + store.set(await api.getStore()); + state.set(await api.getState()); loadOnce(); } diff --git a/client-src/stores/twitch.js b/client-src/stores/twitch.js index 64491405..9efdac72 100644 --- a/client-src/stores/twitch.js +++ b/client-src/stores/twitch.js @@ -1,13 +1,24 @@ +import { getStore, getState, on } from "@/libs/twitch"; import { writable } from "svelte/store"; -import { getState, on } from "@/libs/twitch"; -export const store = writable({ - user: null, -}); +export const store = writable(null); +export const state = writable(null); -export default async function load() { - store.set(await getState()); +let loaded = false; + +function loadOnce() { + if (loaded) return; + + on("state", state.set); on("login", (user) => { - store.update((store) => ({ ...store, user })); + state.update((newState) => ({ ...newState, user })); }); + + loaded = true; +} + +export default async function load() { + store.set(await getStore()); + state.set(await getState()); + loadOnce(); } From 43018b461d0875432ef8b0028e88f60983d39514 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 12:55:36 +0100 Subject: [PATCH 069/451] update locales --- app/static/locales/en/app.json | 3 +++ app/static/locales/fr/app.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index c42802cb..7947fb91 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -77,5 +77,8 @@ }, "anime": { "timeline": "Anime | Timeline" + }, + "twitch": { + "connect-at-startup": "Connect Twitch at startup" } } diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index a89e97ba..5b516cbf 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -77,5 +77,8 @@ }, "anime": { "timeline": "Anime | Timeline" + }, + "twitch": { + "connect-at-startup": "Connection a Twitch au " } } From 0219732b2f57004ab4f216682d1728e00591e20a Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 13:28:56 +0100 Subject: [PATCH 070/451] connect to Twitch at startup (optionall) --- app/server/api/twitch.js | 13 +++++++------ app/server/index.js | 2 ++ app/server/libs/twitch/login.js | 13 +++++++++++++ app/static/locales/fr/app.json | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 app/server/libs/twitch/login.js diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js index 1f5915b0..c138f41b 100644 --- a/app/server/api/twitch.js +++ b/app/server/api/twitch.js @@ -1,23 +1,24 @@ const stores = require("../../stores"); const twitch = require("../libs/twitch"); +const twitchLogin = require("../libs/twitch/login"); const chatJoin = require("../libs/twitch/chatJoin"); const chatConnect = require("../libs/twitch/chatConnect"); +const banner = "🤖 Marv est dans la place !"; + module.exports = { login() { - return twitch.api.helix.users.getMe(true).then(({ _data: user }) => { - this.notify("twitch.login", user); - twitch.state.update({ user }); + return twitchLogin().then((user) => { chatConnect().then(() => { chatJoin(user.display_name).then(({ alreadyJoined } = {}) => { if (!alreadyJoined) { - console.log("Marv est dans la place !"); + console.log(banner); + twitch.chat.say(user.display_name, banner); stores.twitch.set("chatWindow.channel", user.display_name); - twitch.chat.say(user.display_name, "Marv est dans la place !"); } }); }); - return Promise.resolve(user); + return user; }); }, getState: () => twitch.state.get(), diff --git a/app/server/index.js b/app/server/index.js index 8ad59006..2377ca22 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -14,6 +14,8 @@ const { uploadPath, clientPath, staticPath } = require("../utils"); const twitchAuthMiddleware = require("./libs/twitch/authMiddleware"); const missingKeyHandler = require("./libs/i18next/missingKeyHandler"); +require("./libs/twitch/logs"); + let { host, port } = stores.server.getAll(); const appFingerprint = stores.app.get("fingerprint"); diff --git a/app/server/libs/twitch/login.js b/app/server/libs/twitch/login.js new file mode 100644 index 00000000..dd300104 --- /dev/null +++ b/app/server/libs/twitch/login.js @@ -0,0 +1,13 @@ +const socket = require("../socket.io"); +const twitch = require("./index"); +const state = require("./state"); + +const io = socket(); + +module.exports = function login() { + return twitch.api.helix.users.getMe(true).then(({ _data: user }) => { + io.emit("twitch.login", user); + state.update({ user }); + return user; + }); +}; diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 5b516cbf..0016eb26 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -79,6 +79,6 @@ "timeline": "Anime | Timeline" }, "twitch": { - "connect-at-startup": "Connection a Twitch au " + "connect-at-startup": "Connection a Twitch au démarrage" } } From dc9584f69b68dfdf34a6d901b9b01ff2a53d1164 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 13:29:30 +0100 Subject: [PATCH 071/451] connect to Twitch at startup (optionall) --- app/server/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/server/index.js b/app/server/index.js index 2377ca22..3d0405fa 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -48,6 +48,12 @@ function obsAutoConnect() { connect(); } +function twitchAutoConnect() { + if (!stores.twitch.get("connectOnStartup")) return; + const api = require("./api/twitch"); + api.login(); +} + function start() { const server = http.createServer(); @@ -63,6 +69,7 @@ function start() { .listen(port, (error) => { if (error) return onError(error); socket(server); + twitchAutoConnect(); obsAutoConnect(); printBanner(); }); From 2d71c8b27d8ac453e0745b00a7410c0f07d32318 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 15:32:31 +0100 Subject: [PATCH 072/451] require state directly --- app/server/api/twitch.js | 8 ++++---- app/server/libs/twitch/index.js | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/server/api/twitch.js b/app/server/api/twitch.js index c138f41b..ea263ce5 100644 --- a/app/server/api/twitch.js +++ b/app/server/api/twitch.js @@ -1,5 +1,5 @@ const stores = require("../../stores"); -const twitch = require("../libs/twitch"); +const state = require("../libs/twitch/state"); const twitchLogin = require("../libs/twitch/login"); const chatJoin = require("../libs/twitch/chatJoin"); const chatConnect = require("../libs/twitch/chatConnect"); @@ -13,7 +13,7 @@ module.exports = { chatJoin(user.display_name).then(({ alreadyJoined } = {}) => { if (!alreadyJoined) { console.log(banner); - twitch.chat.say(user.display_name, banner); + // twitch.chat.say(user.display_name, banner); stores.twitch.set("chatWindow.channel", user.display_name); } }); @@ -21,7 +21,7 @@ module.exports = { return user; }); }, - getState: () => twitch.state.get(), + getState: () => state.get(), getStore: () => stores.twitch.getAll(), - updateState: (state) => twitch.state.update(state), + updateState: (state) => state.update(state), }; diff --git a/app/server/libs/twitch/index.js b/app/server/libs/twitch/index.js index b4769d2d..9991e477 100644 --- a/app/server/libs/twitch/index.js +++ b/app/server/libs/twitch/index.js @@ -1,4 +1,3 @@ -const state = require("./state"); const config = require("./config"); const { ApiClient } = require("twitch"); const AuthProvider = require("./AuthProvider"); @@ -9,9 +8,8 @@ const api = new ApiClient({ authProvider }); const chat = new ChatClient(authProvider); module.exports = { - state, - config, authProvider, - api, + config, chat, + api, }; From 88aa0b73f58a78e8386493c9d8302f8da5a9f11b Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 15:32:49 +0100 Subject: [PATCH 073/451] removed console.log --- app/server/libs/twitch/AuthProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/server/libs/twitch/AuthProvider.js b/app/server/libs/twitch/AuthProvider.js index ade0906c..e6c6fa81 100644 --- a/app/server/libs/twitch/AuthProvider.js +++ b/app/server/libs/twitch/AuthProvider.js @@ -73,7 +73,7 @@ module.exports = class AuthProvider { scopes = normalizeScopes(scopes); // eslint-disable-next-line no-console - console.log("\x1b[35m%s\x1b[0m", `Twitch request scopes [${scopes}]`); + // console.log("\x1b[35m%s\x1b[0m", `Twitch request scopes [${scopes}]`); const forceVerify = refresh || this.forceVerify; From 1c0eb1987a440ba6dc99224c058840080f33145e Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 15:33:41 +0100 Subject: [PATCH 074/451] update state globaly --- app/server/libs/twitch/login.js | 21 ++++++++++++++++++--- app/server/libs/twitch/state.js | 8 +++++++- client-src/stores/twitch.js | 3 --- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/app/server/libs/twitch/login.js b/app/server/libs/twitch/login.js index dd300104..1c25d6f8 100644 --- a/app/server/libs/twitch/login.js +++ b/app/server/libs/twitch/login.js @@ -1,13 +1,28 @@ -const socket = require("../socket.io"); const twitch = require("./index"); const state = require("./state"); -const io = socket(); +async function getStreamByChannel(channel) { + channel = channel[0] === "#" ? channel.slice(1) : channel; + const user = await twitch.api.helix.users.getUserByName(channel); + const { _data } = await twitch.api.helix.streams.getStreamByUserId(user); + return _data; +} + +async function streamStatePlugin() { + const channel = state.get("user.display_name"); + const stream = await getStreamByChannel(channel); + state.update({ stream }); + setTimeout(streamStatePlugin, 5000); +} + +function initTwitchPlugins() { + streamStatePlugin(); +} module.exports = function login() { return twitch.api.helix.users.getMe(true).then(({ _data: user }) => { - io.emit("twitch.login", user); state.update({ user }); + initTwitchPlugins(); return user; }); }; diff --git a/app/server/libs/twitch/state.js b/app/server/libs/twitch/state.js index fea7553d..1ec00839 100644 --- a/app/server/libs/twitch/state.js +++ b/app/server/libs/twitch/state.js @@ -1,7 +1,11 @@ +const socket = require("../socket.io"); const dotProp = require("dot-prop"); +const io = socket(); + let state = { user: null, + stream: null, chat: { connecting: false, connected: false, @@ -15,11 +19,13 @@ function get(key = null, defaultValue = null) { } function set(key, value) { - return dotProp.set(state, key, value); + dotProp.set(state, key, value); + io.emit("twitch.state", state); } function update(newState) { state = { ...state, ...newState }; + io.emit("twitch.state", state); } module.exports = { get, set, update }; diff --git a/client-src/stores/twitch.js b/client-src/stores/twitch.js index 9efdac72..1721e99c 100644 --- a/client-src/stores/twitch.js +++ b/client-src/stores/twitch.js @@ -10,9 +10,6 @@ function loadOnce() { if (loaded) return; on("state", state.set); - on("login", (user) => { - state.update((newState) => ({ ...newState, user })); - }); loaded = true; } From 3f4d38127492475fac1a10fe2dd15dcaee25a0a0 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 15:34:27 +0100 Subject: [PATCH 075/451] stream status --- client-src/components/Dashboard/Topbar.svelte | 2 ++ client-src/components/Twitch/StreamStatus.svelte | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 client-src/components/Twitch/StreamStatus.svelte diff --git a/client-src/components/Dashboard/Topbar.svelte b/client-src/components/Dashboard/Topbar.svelte index d89ea8a8..62103d9e 100644 --- a/client-src/components/Dashboard/Topbar.svelte +++ b/client-src/components/Dashboard/Topbar.svelte @@ -4,12 +4,14 @@ import OBSConnect from "@/components/OBS/Connect.svelte"; import OBSStatus from "@/components/OBS/Status.svelte"; + import StreamStatus from "@/components/Twitch/StreamStatus.svelte"; import DrawerToggle from "./Drawer/Toggle.svelte"; + diff --git a/client-src/components/Twitch/StreamStatus.svelte b/client-src/components/Twitch/StreamStatus.svelte new file mode 100644 index 00000000..66fcfa4a --- /dev/null +++ b/client-src/components/Twitch/StreamStatus.svelte @@ -0,0 +1,16 @@ + + +
+ {#if $state.stream} +
+ + {$state.stream.viewer_count} +
+ {/if} +
From bd6e8767180a86e31cf4a3c9d71bae3196fc2eda Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 15:34:40 +0100 Subject: [PATCH 076/451] removed user log --- client-src/components/Twitch/Login.svelte | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/client-src/components/Twitch/Login.svelte b/client-src/components/Twitch/Login.svelte index e2333ad7..08809b4f 100644 --- a/client-src/components/Twitch/Login.svelte +++ b/client-src/components/Twitch/Login.svelte @@ -7,14 +7,10 @@ import MdAccountCircle from "svelte-icons/md/MdAccountCircle.svelte"; function onLogin() { - if (state.user) return; - login(true) - .then((user) => { - console.log("Loged-in:", user); - }) - .catch((error) => { - console.log("error:", error); - }); + if ($state.user) return; + login(true).catch((error) => { + console.log("error:", error); + }); } From 93c57a5e568fb83a0fa6053c50e895bcdcac4f27 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Wed, 25 Nov 2020 16:00:52 +0100 Subject: [PATCH 077/451] open link in native browser --- app/main/window/chatWindow.js | 8 ++------ app/main/window/mainWindow.js | 2 ++ app/main/window/openLinkInBrowser.js | 8 ++++++++ 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 app/main/window/openLinkInBrowser.js diff --git a/app/main/window/chatWindow.js b/app/main/window/chatWindow.js index 066b080b..efa9c4c1 100644 --- a/app/main/window/chatWindow.js +++ b/app/main/window/chatWindow.js @@ -1,3 +1,4 @@ +const openLinkInBrowser = require("./openLinkInBrowser"); const { staticPath, watch } = require("../../utils"); const webPreferences = require("./webPreferences"); const { BrowserWindow } = require("electron"); @@ -5,7 +6,6 @@ const storeBounds = require("./storeBounds"); const hideOnClose = require("./hideOnClose"); const stores = require("../../stores"); const path = require("path"); -const open = require("open"); let win = null; @@ -28,13 +28,9 @@ module.exports = function chatWindow({ channel, showOnLoad = true } = {}) { }); hideOnClose(win); + openLinkInBrowser(win); storeBounds({ win, name: "chat" }); - win.webContents.on("new-window", (event, url) => { - event.preventDefault(); - open(url); - }); - win.webContents.on("did-finish-load", () => { win.webContents.insertCSS(` #root > div.tw-top-0 { diff --git a/app/main/window/mainWindow.js b/app/main/window/mainWindow.js index 74566048..1d7024b7 100644 --- a/app/main/window/mainWindow.js +++ b/app/main/window/mainWindow.js @@ -1,3 +1,4 @@ +const openLinkInBrowser = require("./openLinkInBrowser"); const { staticPath, watch } = require("../../utils"); const webPreferences = require("./webPreferences"); const { BrowserWindow } = require("electron"); @@ -25,6 +26,7 @@ module.exports = function createWindow({ showOnLoad = true } = {}) { }); hideOnClose(win); + openLinkInBrowser(win); storeBounds({ win, name: "main" }); win.webContents.once("did-finish-load", () => { diff --git a/app/main/window/openLinkInBrowser.js b/app/main/window/openLinkInBrowser.js new file mode 100644 index 00000000..27410cf6 --- /dev/null +++ b/app/main/window/openLinkInBrowser.js @@ -0,0 +1,8 @@ +const open = require("open"); + +module.exports = function openLinkInBrowser(win) { + win.webContents.on("new-window", (event, url) => { + event.preventDefault(); + open(url); + }); +}; From e40a404c24c44fb6ccdc4c4dc5d72c8b1f252dab Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 05:33:07 +0100 Subject: [PATCH 078/451] fix: get stream return null --- app/server/libs/twitch/login.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/server/libs/twitch/login.js b/app/server/libs/twitch/login.js index 1c25d6f8..392a95cd 100644 --- a/app/server/libs/twitch/login.js +++ b/app/server/libs/twitch/login.js @@ -4,8 +4,8 @@ const state = require("./state"); async function getStreamByChannel(channel) { channel = channel[0] === "#" ? channel.slice(1) : channel; const user = await twitch.api.helix.users.getUserByName(channel); - const { _data } = await twitch.api.helix.streams.getStreamByUserId(user); - return _data; + const stream = await twitch.api.helix.streams.getStreamByUserId(user); + return stream ? stream._data : null; } async function streamStatePlugin() { @@ -19,10 +19,9 @@ function initTwitchPlugins() { streamStatePlugin(); } -module.exports = function login() { - return twitch.api.helix.users.getMe(true).then(({ _data: user }) => { - state.update({ user }); - initTwitchPlugins(); - return user; - }); +module.exports = async function login() { + const user = await twitch.api.helix.users.getMe(true); + state.update({ user: user._data }); + initTwitchPlugins(); + return user._data; }; From 5e33b4dbe09f95f84807f9bf5a72364580fee299 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 05:34:51 +0100 Subject: [PATCH 079/451] update locales --- app/static/locales/en/app.json | 7 +++++-- app/static/locales/fr/app.json | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index 7947fb91..dae095e9 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -66,7 +66,9 @@ "trigger": "trigger", "easing": "easing", "language": "language", - "keyframe": "keyframe" + "keyframe": "keyframe", + "theme": "theme", + "channel": "channel" }, "obs": { "scene-list": "OBS | Scene list", @@ -79,6 +81,7 @@ "timeline": "Anime | Timeline" }, "twitch": { - "connect-at-startup": "Connect Twitch at startup" + "connect-at-startup": "Connect Twitch at startup", + "chat": "Twitch chat" } } diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 0016eb26..2b40ce21 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -66,7 +66,9 @@ "trigger": "lanceur", "easing": "easing", "language": "langue", - "keyframe": "Clé d'animation" + "keyframe": "Clé d'animation", + "theme": "Thème", + "channel": "salon" }, "obs": { "scene-list": "OBS | Liste des scènes", @@ -79,6 +81,7 @@ "timeline": "Anime | Timeline" }, "twitch": { - "connect-at-startup": "Connection a Twitch au démarrage" + "connect-at-startup": "Connection a Twitch au démarrage", + "chat": "Twitch chat" } } From 8e9a4f59312526cce5fe915eeef275f490779124 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 06:55:01 +0100 Subject: [PATCH 080/451] fix: input spacing --- client-src/components/Widgets/OBS/GoToScene/Settings.svelte | 2 +- client-src/components/Widgets/OBS/ToggleScene/Settings.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client-src/components/Widgets/OBS/GoToScene/Settings.svelte b/client-src/components/Widgets/OBS/GoToScene/Settings.svelte index dbeceb3a..65529ec6 100644 --- a/client-src/components/Widgets/OBS/GoToScene/Settings.svelte +++ b/client-src/components/Widgets/OBS/GoToScene/Settings.svelte @@ -18,7 +18,7 @@ } -
+
Date: Thu, 26 Nov 2020 07:09:18 +0100 Subject: [PATCH 081/451] fix: widget config / clone deep --- .../components/Panels/Panel/Widget/EditModal/Action.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte index e83dbd1e..2a86ed71 100644 --- a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte +++ b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte @@ -1,4 +1,5 @@ diff --git a/client-src/stores/app.js b/client-src/stores/app.js index c5a98f17..dd12532a 100644 --- a/client-src/stores/app.js +++ b/client-src/stores/app.js @@ -3,9 +3,12 @@ import { writable } from "svelte/store"; import { emit } from "@/libs/socket.io"; import capitalize from "capitalize"; +const query = new URLSearchParams(location.search); + export const store = writable(null); export const initialized = writable(false); export const fingerprint = capitalize(`${name} - v${version}`); +export const electron = query.has("electron"); export default async function load() { store.set(await emit("stores.app", "getAll")); From c9b2da4f9676cb3ca5d4f9157c4242e0f57dd179 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 07:24:28 +0100 Subject: [PATCH 083/451] fix: modal top offset when in electron window --- client-src/components/UI/Modal.svelte | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client-src/components/UI/Modal.svelte b/client-src/components/UI/Modal.svelte index 71f4b3e9..ebb34d02 100644 --- a/client-src/components/UI/Modal.svelte +++ b/client-src/components/UI/Modal.svelte @@ -1,8 +1,9 @@ -
+
{#if closable} From 25d9505a65ef1923017c8c342d4041e566bbe9d6 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 07:28:43 +0100 Subject: [PATCH 084/451] fix: modal top offset when in electron window --- client-src/components/UI/FullScreenModal.svelte | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client-src/components/UI/FullScreenModal.svelte b/client-src/components/UI/FullScreenModal.svelte index 74e94d70..fbfbb637 100644 --- a/client-src/components/UI/FullScreenModal.svelte +++ b/client-src/components/UI/FullScreenModal.svelte @@ -1,7 +1,9 @@ -
+
From dec0d0847f8b2ac45ae4e3b61b18cf64b21f35a8 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 07:33:34 +0100 Subject: [PATCH 085/451] feature: Twitch chat widget --- .../Widgets/Twitch/Chat/Settings.svelte | 38 +++++++++++++++++++ .../Widgets/Twitch/Chat/Widget.svelte | 25 ++++++++++++ .../components/Widgets/Twitch/Chat/config.js | 9 +++++ .../components/Widgets/Twitch/Chat/index.js | 3 ++ client-src/components/Widgets/index.js | 2 + 5 files changed, 77 insertions(+) create mode 100644 client-src/components/Widgets/Twitch/Chat/Settings.svelte create mode 100644 client-src/components/Widgets/Twitch/Chat/Widget.svelte create mode 100644 client-src/components/Widgets/Twitch/Chat/config.js create mode 100644 client-src/components/Widgets/Twitch/Chat/index.js diff --git a/client-src/components/Widgets/Twitch/Chat/Settings.svelte b/client-src/components/Widgets/Twitch/Chat/Settings.svelte new file mode 100644 index 00000000..dcf5fef3 --- /dev/null +++ b/client-src/components/Widgets/Twitch/Chat/Settings.svelte @@ -0,0 +1,38 @@ + + +
+ + diff --git a/package.json b/package.json index 7723c567..ac6a813c 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^9.0.0", "animejs": "^3.2.1", + "axios": "^0.21.0", "capitalize": "^2.0.3", "chalk": "^4.1.0", "clone-deep": "^4.0.1", diff --git a/yarn.lock b/yarn.lock index 573cecad..867e06e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -375,6 +375,13 @@ autoprefixer@^9.4.5: postcss "^7.0.32" postcss-value-parser "^4.1.0" +axios@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" + integrity sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw== + dependencies: + follow-redirects "^1.10.0" + backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -1286,6 +1293,11 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +follow-redirects@^1.10.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" + integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== + fs-extra@^8.0.0, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" From ba63f2c396f75cb40f99979089d60ade15dd772f Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 17:47:32 +0100 Subject: [PATCH 102/451] use new Checkbox component --- client-src/components/App/OpenOnStartup.svelte | 13 ++----------- client-src/components/OBS/ConnectAtStartup.svelte | 13 ++----------- .../components/Twitch/ConnectAtStartup.svelte | 13 ++----------- 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/client-src/components/App/OpenOnStartup.svelte b/client-src/components/App/OpenOnStartup.svelte index 30df2bf9..81f5508b 100644 --- a/client-src/components/App/OpenOnStartup.svelte +++ b/client-src/components/App/OpenOnStartup.svelte @@ -2,15 +2,10 @@ import app from "@/api/app"; import { _ } from "@/libs/i18next"; import { store } from "@/stores/app"; - import Input from "@/components/UI/Input.svelte"; - import MdCheckBox from "svelte-icons/md/MdCheckBox.svelte"; - import MdCheckBoxOutlineBlank from "svelte-icons/md/MdCheckBoxOutlineBlank.svelte"; + import Checkbox from "@/components/UI/Checkbox.svelte"; let checked = $store.openOnStartup; - $: bgColor = checked ? "bg-green-600" : "bg-primary"; - $: icon = checked ? MdCheckBox : MdCheckBoxOutlineBlank; - function onChange(event) { checked = event.target.checked; $store.openOnStartup = checked; @@ -18,12 +13,8 @@ } - diff --git a/client-src/components/OBS/ConnectAtStartup.svelte b/client-src/components/OBS/ConnectAtStartup.svelte index 69f52dce..473844fc 100644 --- a/client-src/components/OBS/ConnectAtStartup.svelte +++ b/client-src/components/OBS/ConnectAtStartup.svelte @@ -2,15 +2,10 @@ import obs from "@/api/obs"; import { _ } from "@/libs/i18next"; import { store } from "@/stores/obs"; - import Input from "@/components/UI/Input.svelte"; - import MdCheckBox from "svelte-icons/md/MdCheckBox.svelte"; - import MdCheckBoxOutlineBlank from "svelte-icons/md/MdCheckBoxOutlineBlank.svelte"; + import Checkbox from "@/components/UI/Checkbox.svelte"; let checked = $store.connectOnStartup; - $: bgColor = checked ? "bg-green-600" : "bg-primary"; - $: icon = checked ? MdCheckBox : MdCheckBoxOutlineBlank; - function onChange(event) { checked = event.target.checked; $store.connectOnStartup = checked; @@ -18,12 +13,8 @@ } - diff --git a/client-src/components/Twitch/ConnectAtStartup.svelte b/client-src/components/Twitch/ConnectAtStartup.svelte index dbc7d6cf..2a58cdca 100644 --- a/client-src/components/Twitch/ConnectAtStartup.svelte +++ b/client-src/components/Twitch/ConnectAtStartup.svelte @@ -2,15 +2,10 @@ import twitch from "@/api/twitch"; import { _ } from "@/libs/i18next"; import { store } from "@/stores/twitch"; - import Input from "@/components/UI/Input.svelte"; - import MdCheckBox from "svelte-icons/md/MdCheckBox.svelte"; - import MdCheckBoxOutlineBlank from "svelte-icons/md/MdCheckBoxOutlineBlank.svelte"; + import Checkbox from "@/components/UI/Checkbox.svelte"; let checked = $store.connectOnStartup; - $: bgColor = checked ? "bg-green-600" : "bg-primary"; - $: icon = checked ? MdCheckBox : MdCheckBoxOutlineBlank; - function onChange(event) { checked = event.target.checked; $store.connectOnStartup = checked; @@ -18,12 +13,8 @@ } - From 2fd9bcd19313304009fdd746e1423f22d1362771 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 17:47:35 +0100 Subject: [PATCH 103/451] Update yarn.lock --- app/yarn.lock | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/yarn.lock b/app/yarn.lock index 0c6717a6..2c7bc141 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -204,6 +204,13 @@ atomically@^1.3.1: resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.6.0.tgz#d8d47f99834dbb88bd6266cc69a1447e2f3675ec" integrity sha512-mu394MH+yY2TSKMyH+978PcGMZ8sRNks2PuVeH6c2ED4mimR2LEE039MVcIGVhtmG54cKEMh4gKhxKL/CLaX/w== +axios@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" + integrity sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw== + dependencies: + follow-redirects "^1.10.0" + backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -571,6 +578,11 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +follow-redirects@^1.10.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" + integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== + fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" From 2303dc4c897c669e7c7de9a521518967afc447a9 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 17:47:40 +0100 Subject: [PATCH 104/451] Update package.json --- app/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/package.json b/app/package.json index fef377d9..10bdc438 100644 --- a/app/package.json +++ b/app/package.json @@ -7,6 +7,7 @@ "license": "MIT", "main": "main/index.js", "dependencies": { + "axios": "^0.21.0", "body-parser": "^1.19.0", "capitalize": "^2.0.3", "chalk": "^4.1.0", From 9ebf08005c6aa41506ab5d193a2a1931b624b8f0 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 18:06:58 +0100 Subject: [PATCH 105/451] feature: add panl on double click on free space --- client-src/components/Panels/Panel.svelte | 24 +++++++++++++++++-- .../Panels/Panel/Widget/EditMode.svelte | 4 ++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/client-src/components/Panels/Panel.svelte b/client-src/components/Panels/Panel.svelte index 24a692bc..87097873 100644 --- a/client-src/components/Panels/Panel.svelte +++ b/client-src/components/Panels/Panel.svelte @@ -1,14 +1,34 @@ -
+
{#each $panels as panel}
{#if panel.grid.length} diff --git a/client-src/components/Panels/Panel/Widget/EditMode.svelte b/client-src/components/Panels/Panel/Widget/EditMode.svelte index 50ff558c..1cbc2952 100644 --- a/client-src/components/Panels/Panel/Widget/EditMode.svelte +++ b/client-src/components/Panels/Panel/Widget/EditMode.svelte @@ -45,8 +45,8 @@
From 636890ae7f67c363ef3d94a85537fbdb1194edca Mon Sep 17 00:00:00 2001 From: skarab42 Date: Thu, 26 Nov 2020 18:07:50 +0100 Subject: [PATCH 106/451] v0.7.0 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index 10bdc438..7cdab68f 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.6.1", + "version": "0.7.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index ac6a813c..87d6582f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.6.1", + "version": "0.7.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 19d787b558e00d4f955b203dd265afe3cfaaf805 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:19:37 +0100 Subject: [PATCH 107/451] add sqlite3/sequelize --- app/package.json | 2 + yarn.lock | 922 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 904 insertions(+), 20 deletions(-) diff --git a/app/package.json b/app/package.json index 7cdab68f..1d63b3e0 100644 --- a/app/package.json +++ b/app/package.json @@ -22,8 +22,10 @@ "obs-websocket-js": "^4.0.2", "open": "^7.3.0", "polka": "^0.5.2", + "sequelize": "^6.3.5", "sirv": "^1.0.7", "socket.io": "^2.3.0", + "sqlite3": "^5.0.0", "twitch": "^4.3.1", "twitch-auth": "^4.3.1", "twitch-chat-client": "^4.3.1", diff --git a/yarn.lock b/yarn.lock index 867e06e7..667c6963 100644 --- a/yarn.lock +++ b/yarn.lock @@ -83,6 +83,13 @@ postcss "7.0.32" purgecss "^2.3.0" +"@malept/cross-spawn-promise@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.0.tgz#258fde4098f5004a56db67c35f33033af64810f6" + integrity sha512-GeIK5rfU1Yd7BZJQPTGZMMmcZy5nhRToPXZcjaDwQDRSewdhp648GT2E4dh+L7+Io7AOW6WQ+GR44QSzja4qxg== + dependencies: + cross-spawn "^7.0.1" + "@popperjs/core@^2.1.0": version "2.5.4" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.4.tgz#de25b5da9f727985a3757fd59b5d028aba75841a" @@ -141,6 +148,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sindresorhus/is@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" + integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -148,6 +160,23 @@ dependencies: defer-to-connect "^1.0.1" +"@szmarczak/http-timer@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" + integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== + dependencies: + defer-to-connect "^2.0.0" + +"@types/cacheable-request@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" + integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + "@types/debug@^4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" @@ -170,6 +199,18 @@ dependencies: "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" + integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== + +"@types/keyv@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" + integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== + dependencies: + "@types/node" "*" + "@types/node@*": version "14.14.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.2.tgz#d25295f9e4ca5989a2c610754dc02a9721235eeb" @@ -187,6 +228,13 @@ dependencies: "@types/node" "*" +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -199,6 +247,11 @@ dependencies: "@types/yargs-parser" "*" +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + acorn-jsx@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" @@ -233,7 +286,7 @@ ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -260,6 +313,16 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -325,6 +388,19 @@ app-builder-lib@22.9.1: semver "^7.3.2" temp-file "^3.3.7" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -337,6 +413,18 @@ arraybuffer.slice@~0.0.7: resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -357,6 +445,11 @@ async@0.9.x: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" @@ -375,6 +468,16 @@ autoprefixer@^9.4.5: postcss "^7.0.32" postcss-value-parser "^4.1.0" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + axios@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" @@ -397,6 +500,13 @@ base64-arraybuffer@0.1.4: resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + binary-extensions@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" @@ -511,6 +621,11 @@ bytes@^3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +cacheable-lookup@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" + integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== + cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -524,6 +639,19 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" +cacheable-request@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" + integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^2.0.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -554,6 +682,11 @@ capitalize@^2.0.3: resolved "https://registry.yarnpkg.com/capitalize/-/capitalize-2.0.3.tgz#ccfeb1046d2a054eb30f34af907a70c3e90f3b73" integrity sha512-Qc5ksT1/zEJBbFYD05h99hCNEW0cgyD0zzE5WvkgisNnppJ+16zfaSk34evF0j6pGW8hejkRUeygJ5uN5k22SQ== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -594,6 +727,16 @@ chokidar@^3.3.0: optionalDependencies: fsevents "~2.1.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chromium-pickle-js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" @@ -609,6 +752,18 @@ cli-boxes@^2.2.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.4.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz#12763e47251bf951cb75c201dfa58ff1bcb2d047" + integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ== + cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -643,6 +798,16 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -688,6 +853,18 @@ colorette@^1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colors@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -768,17 +945,22 @@ configstore@^5.0.1: write-file-atomic "^3.0.0" xdg-basedir "^4.0.0" +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + core-js@^3.0.1, core-js@^3.6.5: version "3.6.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== -core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cross-spawn@^7.0.2: +cross-spawn@^7.0.1, cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -802,6 +984,13 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + date-fns@^2.0.1: version "2.16.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.16.1.tgz#05775792c3f3331da812af253e1a935851d3834b" @@ -814,6 +1003,13 @@ debug@^2.6.9: dependencies: ms "2.0.0" +debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" @@ -847,6 +1043,13 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -862,11 +1065,23 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + defer-to-connect@^1.0.1: version "1.1.3" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +defer-to-connect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" + integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -879,6 +1094,21 @@ defined@^1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^1.0.2, detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + detect-node@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" @@ -934,6 +1164,14 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ejs@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b" @@ -975,6 +1213,24 @@ electron-publish@22.9.1: lazy-val "^1.0.4" mime "^2.4.6" +electron-rebuild@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/electron-rebuild/-/electron-rebuild-2.3.2.tgz#42da553a1e4e844ae4d3c3b97e42be836b2924b3" + integrity sha512-VLd3iIn65PmYWmvL+nx0oKspbohkDUhCAz8I2EWbMJcOFzWKW1UXJZ+ZG53iEDJFldm9PahE4q2Bx3ns4bdzeQ== + dependencies: + "@malept/cross-spawn-promise" "^1.1.0" + colors "^1.3.3" + debug "^4.1.1" + detect-libc "^1.0.3" + fs-extra "^9.0.1" + got "^11.7.0" + lzma-native "^6.0.1" + node-abi "^2.19.1" + node-gyp "^7.1.0" + ora "^5.1.0" + tar "^6.0.5" + yargs "^16.0.0" + electron-to-chromium@^1.3.571: version "1.3.583" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.583.tgz#47a9fde74740b1205dba96db2e433132964ba3ee" @@ -1219,6 +1475,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + extract-zip@^1.0.3: version "1.7.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" @@ -1229,6 +1490,16 @@ extract-zip@^1.0.3: mkdirp "^0.5.4" yauzl "^2.10.0" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1298,6 +1569,20 @@ follow-redirects@^1.10.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fs-extra@^8.0.0, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -1317,6 +1602,20 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^1.0.0" +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1337,6 +1636,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1356,6 +1669,13 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob-parent@^5.0.0, glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" @@ -1363,7 +1683,7 @@ glob-parent@^5.0.0, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.6: +glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -1419,6 +1739,23 @@ globalthis@^1.0.1: dependencies: define-properties "^1.1.3" +got@^11.7.0: + version "11.8.0" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.0.tgz#be0920c3586b07fd94add3b5b27cb28f49e6545f" + integrity sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.1" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -1436,11 +1773,24 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + has-binary2@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" @@ -1463,6 +1813,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-yarn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" @@ -1497,6 +1852,23 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.0-beta.5.2" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3" + integrity sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + i18next-http-backend@^1.0.21: version "1.0.21" resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-1.0.21.tgz#cee901b3527dad5165fa91de973b6aa6404c1c37" @@ -1511,6 +1883,13 @@ i18next@^19.8.3: dependencies: "@babel/runtime" "^7.12.0" +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + iconv-lite@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" @@ -1518,6 +1897,13 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -1605,6 +1991,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -1630,6 +2023,11 @@ is-installed-globally@^0.3.1: global-dirs "^2.0.1" is-path-inside "^3.0.1" +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -1669,7 +2067,7 @@ is-reference@^1.2.1: dependencies: "@types/estree" "*" -is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -1704,6 +2102,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + jake@^10.6.1: version "10.8.2" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" @@ -1736,11 +2139,21 @@ js-yaml@^3.13.1, js-yaml@^3.14.0: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -1751,12 +2164,17 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@^5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -1784,6 +2202,16 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -1791,6 +2219,13 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" +keyv@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" + integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -1864,6 +2299,13 @@ lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +log-symbols@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -1881,6 +2323,16 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lzma-native@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/lzma-native/-/lzma-native-6.0.1.tgz#eec231d31b9f9ba5aea5afc86326669f01dedb58" + integrity sha512-O6oWF0xe1AFvOCjU8uOZBZ/lhjaMNwHfVNaqVMqmoQXlRwBcFWpCAToiZOdXcKVMdo/5s/D0a2QgA5laMErxHQ== + dependencies: + node-addon-api "^1.6.0" + node-pre-gyp "^0.11.0" + readable-stream "^2.3.5" + rimraf "^2.7.1" + magic-string@^0.25.7: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" @@ -1907,16 +2359,38 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + mime@^2.4.6: version "2.4.6" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -1929,28 +2403,89 @@ minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -mkdirp@^0.5.1, mkdirp@^0.5.4: +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minipass@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.2: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +needle@^2.2.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a" + integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +node-abi@^2.19.1: + version "2.19.3" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.3.tgz#252f5dcab12dad1b5503b2d27eddd4733930282d" + integrity sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg== + dependencies: + semver "^5.4.1" + +node-addon-api@^1.6.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" + integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== + node-emoji@^1.8.1: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -1963,11 +2498,58 @@ node-fetch@2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-gyp@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" + integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.3" + nopt "^5.0.0" + npmlog "^4.1.2" + request "^2.88.2" + rimraf "^3.0.2" + semver "^7.3.2" + tar "^6.0.2" + which "^2.0.2" + +node-pre-gyp@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" + integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + node-releases@^1.1.61: version "1.1.64" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.64.tgz#71b4ae988e9b1dd7c1ffce58dd9e561752dfebc5" integrity sha512-Iec8O9166/x2HRMJyLLLWkd0sFFLrFNy+Xf+JQfSQsdBJzPcHpNl3JQ9gD4j+aJxmCa25jNsIbM4bmACtSbkSg== +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -1998,6 +2580,13 @@ normalize.css@^8.0.1: resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" integrity sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg== +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + npm-conf@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" @@ -2006,12 +2595,46 @@ npm-conf@^1.1.3: config-chain "^1.1.11" pify "^3.0.0" +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +npmlog@^4.0.2, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= -object-assign@^4.1.1: +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -2033,6 +2656,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -2050,11 +2680,48 @@ optionator@^0.9.1: resolved "https://registry.yarnpkg.com/opts/-/opts-2.0.2.tgz#a17e189fbbfee171da559edd8a42423bc5993ce1" integrity sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg== +ora@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.1.0.tgz#b188cf8cd2d4d9b13fd25383bc3e5cba352c94f8" + integrity sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w== + dependencies: + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.4.0" + is-interactive "^1.0.0" + log-symbols "^4.0.0" + mute-stream "0.0.8" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== +p-cancelable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" + integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== + p-limit@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2134,6 +2801,11 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -2257,6 +2929,11 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -2265,7 +2942,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -2287,6 +2964,16 @@ purgecss@^2.3.0: postcss "7.0.32" postcss-selector-parser "^6.0.2" +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -2294,7 +2981,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -rc@^1.2.8: +rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -2324,7 +3011,7 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -readable-stream@^2.2.2: +readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.5: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -2376,6 +3063,32 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -2396,6 +3109,11 @@ resize-observer-polyfill@^1.5.1: resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== +resolve-alpn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" + integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -2416,6 +3134,21 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" +responselike@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" + integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== + dependencies: + lowercase-keys "^2.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -2423,13 +3156,20 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" -rimraf@^2.6.3: +rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + roarr@^2.15.3: version "2.15.4" resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" @@ -2519,7 +3259,7 @@ rxjs@^6.5.2: dependencies: tslib "^1.9.0" -safe-buffer@^5.1.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2529,7 +3269,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -2558,7 +3298,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5": +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -2587,7 +3327,7 @@ serialize-javascript@^4.0.0: dependencies: randombytes "^2.1.0" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -2611,7 +3351,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.2: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -2739,11 +3479,43 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + stat-mode@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-1.0.0.tgz#68b55cb61ea639ff57136f36b216a291800d1465" integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -2769,6 +3541,20 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -2887,6 +3673,31 @@ tailwindcss@^1.9.6: reduce-css-calc "^2.1.6" resolve "^1.14.2" +tar@^4: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +tar@^6.0.2, tar@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" + integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + temp-file@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.3.7.tgz#686885d635f872748e384e871855958470aeb18a" @@ -2948,6 +3759,14 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -2965,11 +3784,23 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -3064,6 +3895,11 @@ util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + uuid@^8.3.1: version "8.3.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" @@ -3082,18 +3918,41 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -3185,6 +4044,16 @@ y18n@^5.0.2: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.4.tgz#0ab2db89dd5873b5ec4682d8e703e833373ea897" integrity sha512-deLOfD+RvFgrpAmSZgfGdWYE+OKyHcVHaRQ7NphG/63scpRvTHHeQMAxGGvaLVGJ+HYVcCXlzcTK0ZehFf+eHQ== +y18n@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" + integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + +yallist@^3.0.0, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -3219,6 +4088,19 @@ yargs@^13.3.0: y18n "^4.0.0" yargs-parser "^13.1.2" +yargs@^16.0.0: + version "16.1.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.1.tgz#5a4a095bd1ca806b0a50d0c03611d38034d219a1" + integrity sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^16.0.3: version "16.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a" From 81bef9c3dbb040db8d68bd5cdc38400c2012e669 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:21:10 +0100 Subject: [PATCH 108/451] sequelize init module --- app/server/db/index.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/server/db/index.js diff --git a/app/server/db/index.js b/app/server/db/index.js new file mode 100644 index 00000000..3178fa2f --- /dev/null +++ b/app/server/db/index.js @@ -0,0 +1,14 @@ +const { databasePath } = require("../../utils"); +const { Sequelize } = require("sequelize"); +const fs = require("fs-extra"); +const path = require("path"); + +fs.ensureDirSync(databasePath); + +const sequelize = new Sequelize({ + logging: false, + dialect: "sqlite", + storage: path.join(databasePath, "marv.sqlite"), +}); + +module.exports = sequelize; From c48ad8168bafef9952aa668500788f49b0b6f1be Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:21:27 +0100 Subject: [PATCH 109/451] created Viewer Model --- app/server/db/Models/Viewer.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 app/server/db/Models/Viewer.js diff --git a/app/server/db/Models/Viewer.js b/app/server/db/Models/Viewer.js new file mode 100644 index 00000000..7701d799 --- /dev/null +++ b/app/server/db/Models/Viewer.js @@ -0,0 +1,26 @@ +const { DataTypes } = require("sequelize"); +const sequelize = require("../index"); + +const Viewer = sequelize.define("Viewer", { + id: { + type: DataTypes.STRING, + allowNull: false, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + allowNull: false, + }, + followedAt: { + type: DataTypes.DATE, + allowNull: false, + }, + isFollowing: { + type: DataTypes.BOOLEAN, + allowNull: false, + }, +}); + +module.exports = Viewer; + +Viewer.sync({ alter: true }); // TODO: remove for prod From 35004e45a8dcc1237ffbc57a0bc47b331048b94b Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:22:29 +0100 Subject: [PATCH 110/451] init db --- app/server/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/server/index.js b/app/server/index.js index fb4e9f2e..0dcde02a 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -14,7 +14,10 @@ const { uploadPath, clientPath, staticPath } = require("../utils"); const twitchAuthMiddleware = require("./libs/twitch/authMiddleware"); const missingKeyHandler = require("./libs/i18next/missingKeyHandler"); -// require("./libs/twitch/logs"); +require("./db"); + +// require("./libs/twitch/chat/onMessage"); +// require("./libs/twitch/webhooks_"); let { host, port } = stores.server.getAll(); const appFingerprint = stores.app.get("fingerprint"); From a9da3aaf05a4d6aeb6fc53a3743b89490a347669 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:23:11 +0100 Subject: [PATCH 111/451] get follows and get last follows helpers --- app/server/libs/twitch/api/getFollows.js | 45 ++++++++++++++++++++ app/server/libs/twitch/api/getLastFollows.js | 32 ++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 app/server/libs/twitch/api/getFollows.js create mode 100644 app/server/libs/twitch/api/getLastFollows.js diff --git a/app/server/libs/twitch/api/getFollows.js b/app/server/libs/twitch/api/getFollows.js new file mode 100644 index 00000000..eb2f039c --- /dev/null +++ b/app/server/libs/twitch/api/getFollows.js @@ -0,0 +1,45 @@ +const twitch = require("../index"); +const Viewer = require("../../../db/Models/Viewer"); + +module.exports = async function getFollows({ delay = 2 } = {}) { + const user = await twitch.api.helix.users.getMe(true); + const followsPaginated = await twitch.api.helix.users.getFollowsPaginated({ + followedUser: user, + }); + + const oldFollows = []; + const newFollows = []; + + return new Promise((resolve) => { + const getNext = async () => { + let follows = await followsPaginated.getNext(); + + if (!follows.length) { + return resolve({ oldFollows, newFollows }); + } + + for (let i = 0, l = follows.length; i < l; i++) { + const { _data } = follows[i]; + + const oldFollow = await Viewer.findByPk(_data.from_id); + + if (oldFollow) { + oldFollows.push(oldFollow); + } else { + const newFollow = await Viewer.create({ + id: _data.from_id, + name: _data.from_name, + followedAt: _data.followed_at, + isFollowing: true, + }); + + newFollows.push(newFollow); + } + } + + setTimeout(getNext, delay * 1000); + }; + + getNext(); + }); +}; diff --git a/app/server/libs/twitch/api/getLastFollows.js b/app/server/libs/twitch/api/getLastFollows.js new file mode 100644 index 00000000..b0ae572d --- /dev/null +++ b/app/server/libs/twitch/api/getLastFollows.js @@ -0,0 +1,32 @@ +const twitch = require("../index"); +const Viewer = require("../../../db/Models/Viewer"); + +module.exports = async function getLastFollows() { + const user = await twitch.api.helix.users.getMe(true); + const followsPaginated = await twitch.api.helix.users.getFollowsPaginated({ + followedUser: user, + }); + + const newFollows = []; + + let follows = await followsPaginated.getNext(); + + for (let i = 0, l = follows.length; i < l; i++) { + const { _data } = follows[i]; + + const oldFollow = await Viewer.findByPk(_data.from_id); + + if (oldFollow) break; + + const newFollow = await Viewer.create({ + id: _data.from_id, + name: _data.from_name, + followedAt: _data.followed_at, + isFollowing: true, + }); + + newFollows.push(newFollow); + } + + return newFollows; +}; From d2c4cfdced043611f34894ea50dcd30d0ef3e2a8 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:25:08 +0100 Subject: [PATCH 112/451] add db path --- app/server/libs/twitch/plugins/install.js | 7 +++++++ app/utils.js | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 app/server/libs/twitch/plugins/install.js diff --git a/app/server/libs/twitch/plugins/install.js b/app/server/libs/twitch/plugins/install.js new file mode 100644 index 00000000..f3352608 --- /dev/null +++ b/app/server/libs/twitch/plugins/install.js @@ -0,0 +1,7 @@ +const streamStatePlugin = require("./streamState"); +const followsPlugin = require("./followsPlugin"); + +module.exports = function install() { + streamStatePlugin(); + followsPlugin(); +}; diff --git a/app/utils.js b/app/utils.js index 662b9b8d..74c78bc3 100644 --- a/app/utils.js +++ b/app/utils.js @@ -9,6 +9,7 @@ const clientPath = path.join(appPath, "client"); const staticPath = path.join(appPath, "static"); const uploadPath = path.join(userPath, "upload"); const storesPath = path.join(userPath, "stores"); +const databasePath = path.join(userPath, "database"); const filesPath = path.join(uploadPath, "files"); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); @@ -22,4 +23,5 @@ module.exports = { storesPath, staticPath, clientPath, + databasePath, }; From dd98ff6862f41441ed95e5babd5d5b3a51099294 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:25:17 +0100 Subject: [PATCH 113/451] Revert "add db path" This reverts commit d2c4cfdced043611f34894ea50dcd30d0ef3e2a8. --- app/server/libs/twitch/plugins/install.js | 7 ------- app/utils.js | 2 -- 2 files changed, 9 deletions(-) delete mode 100644 app/server/libs/twitch/plugins/install.js diff --git a/app/server/libs/twitch/plugins/install.js b/app/server/libs/twitch/plugins/install.js deleted file mode 100644 index f3352608..00000000 --- a/app/server/libs/twitch/plugins/install.js +++ /dev/null @@ -1,7 +0,0 @@ -const streamStatePlugin = require("./streamState"); -const followsPlugin = require("./followsPlugin"); - -module.exports = function install() { - streamStatePlugin(); - followsPlugin(); -}; diff --git a/app/utils.js b/app/utils.js index 74c78bc3..662b9b8d 100644 --- a/app/utils.js +++ b/app/utils.js @@ -9,7 +9,6 @@ const clientPath = path.join(appPath, "client"); const staticPath = path.join(appPath, "static"); const uploadPath = path.join(userPath, "upload"); const storesPath = path.join(userPath, "stores"); -const databasePath = path.join(userPath, "database"); const filesPath = path.join(uploadPath, "files"); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); @@ -23,5 +22,4 @@ module.exports = { storesPath, staticPath, clientPath, - databasePath, }; From 658aac25b81bcf7b5edc2b93cd08c65965268ac4 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:25:43 +0100 Subject: [PATCH 114/451] update locales --- app/static/locales/en/app.json | 3 ++- app/static/locales/fr/app.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index 6b94821e..4c3e6491 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -72,7 +72,8 @@ "theme": "theme", "channel": "channel", "loading": "loading", - "download": "download" + "download": "download", + "event": "event" }, "obs": { "scene-list": "OBS | Scene list", diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 0f2d1280..e06893d5 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -72,7 +72,8 @@ "theme": "Thème", "channel": "salon", "loading": "chargement", - "download": "téléchargement" + "download": "téléchargement", + "event": "évènement" }, "obs": { "scene-list": "OBS | Liste des scènes", From a80ac81cfc87ac6b59a7fe24e749c2b17ba4c7b7 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:26:11 +0100 Subject: [PATCH 115/451] add electron-rebuild and postinstall script --- app/yarn.lock | 892 +++++++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 + 2 files changed, 882 insertions(+), 12 deletions(-) diff --git a/app/yarn.lock b/app/yarn.lock index 2c7bc141..01b68f74 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -135,6 +135,11 @@ dependencies: "@types/node" "*" +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.4: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -148,7 +153,7 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -ajv@^6.12.2: +ajv@^6.12.2, ajv@^6.12.3: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -158,6 +163,16 @@ ajv@^6.12.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -165,6 +180,11 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +any-promise@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + anymatch@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" @@ -173,6 +193,19 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + array.prototype.map@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.3.tgz#1609623618d3d84134a37d4a220030c2bd18420b" @@ -189,11 +222,28 @@ arraybuffer.slice@~0.0.7: resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" @@ -204,6 +254,16 @@ atomically@^1.3.1: resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.6.0.tgz#d8d47f99834dbb88bd6266cc69a1447e2f3675ec" integrity sha512-mu394MH+yY2TSKMyH+978PcGMZ8sRNks2PuVeH6c2ED4mimR2LEE039MVcIGVhtmG54cKEMh4gKhxKL/CLaX/w== +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + axios@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" @@ -216,6 +276,11 @@ backo2@1.0.2: resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + base64-arraybuffer@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" @@ -231,6 +296,13 @@ base64id@2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + better-assert@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" @@ -248,6 +320,13 @@ blob@0.0.5: resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + body-parser@^1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -264,6 +343,14 @@ body-parser@^1.19.0: raw-body "2.4.0" type-is "~1.6.17" +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -294,6 +381,11 @@ capitalize@^2.0.3: resolved "https://registry.yarnpkg.com/capitalize/-/capitalize-2.0.3.tgz#ccfeb1046d2a054eb30f34af907a70c3e90f3b73" integrity sha512-Qc5ksT1/zEJBbFYD05h99hCNEW0cgyD0zzE5WvkgisNnppJ+16zfaSk34evF0j6pGW8hejkRUeygJ5uN5k22SQ== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -317,6 +409,16 @@ chokidar@^3.4.3: optionalDependencies: fsevents "~2.1.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -329,6 +431,13 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" @@ -349,6 +458,11 @@ component-inherit@0.0.3: resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + conf@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/conf/-/conf-7.1.2.tgz#d9678a9d8f04de8bf5cd475105da8fdae49c2ec4" @@ -365,6 +479,11 @@ conf@^7.1.2: pkg-up "^3.1.0" semver "^7.3.2" +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -375,6 +494,18 @@ cookie@0.3.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + debounce-fn@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/debounce-fn/-/debounce-fn-4.0.0.tgz#ed76d206d8a50e60de0dd66d494d82835ffe61c7" @@ -389,6 +520,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debug@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" @@ -396,6 +534,13 @@ debug@^4.1.0: dependencies: ms "2.1.2" +debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -410,6 +555,11 @@ debug@~4.1.0: dependencies: ms "^2.1.1" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -417,11 +567,26 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + detect-node@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" @@ -441,6 +606,19 @@ dot-prop@^6.0.1: dependencies: is-obj "^2.0.0" +dottie@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.2.tgz#cc91c0726ce3a054ebf11c55fbc92a7f266dd154" + integrity sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -554,6 +732,21 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -583,6 +776,20 @@ follow-redirects@^1.10.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -593,16 +800,52 @@ fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^1.0.0" +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + fsevents@~2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" @@ -612,6 +855,13 @@ get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: has "^1.0.3" has-symbols "^1.0.1" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" @@ -619,11 +869,36 @@ glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -graceful-fs@^4.1.6, graceful-fs@^4.2.0: +glob@^7.0.3, glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + has-binary2@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" @@ -646,6 +921,11 @@ has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -664,6 +944,15 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + i18next-fs-backend@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-1.0.7.tgz#00ca4587e306f8948740408389dda73461a5d07f" @@ -676,27 +965,52 @@ i18next@^19.8.3: dependencies: "@babel/runtime" "^7.12.0" -iconv-lite@0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= +inflection@1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" + integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -inherits@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== ircv3@^0.26.5: version "0.26.5" @@ -744,6 +1058,18 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + 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" @@ -795,6 +1121,11 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + is-wsl@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -812,11 +1143,26 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + isomorphic-ws@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + iterate-iterator@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" @@ -830,6 +1176,11 @@ iterate-value@^1.0.2: es-get-iterator "^1.0.2" iterate-iterator "^1.0.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -840,6 +1191,16 @@ json-schema-typed@^7.0.3: resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9" integrity sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A== +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -849,6 +1210,16 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + klona@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" @@ -862,6 +1233,11 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash@^4.17.15: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -886,7 +1262,7 @@ mime-db@1.44.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== @@ -908,6 +1284,52 @@ mimic-fn@^3.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +moment-timezone@^0.5.31: + version "0.5.32" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.32.tgz#db7677cc3cc680fd30303ebd90b0da1ca0dfecc2" + integrity sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA== + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.9.0", moment@^2.26.0: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -918,21 +1340,130 @@ ms@2.1.2, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +needle@^2.2.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a" + integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +node-addon-api@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b" + integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA== + node-fetch@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-gyp@3.x: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-pre-gyp@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" + integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + 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== +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + object-component@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" @@ -975,6 +1506,13 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + onetime@^5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -990,6 +1528,24 @@ open@^7.3.0: is-docker "^2.0.0" is-wsl "^2.1.1" +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-limit@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -1038,6 +1594,16 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -1058,7 +1624,17 @@ polka@^0.5.2: "@polka/url" "^0.5.0" trouter "^2.0.1" -punycode@^2.1.0: +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -1068,6 +1644,11 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + raw-body@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" @@ -1078,6 +1659,29 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^2.0.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + 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" + readdirp@~3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" @@ -1090,16 +1694,71 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== -safe-buffer@^5.0.1: +request@^2.87.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +retry-as-promised@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-3.2.0.tgz#769f63d536bec4783549db0777cb56dadd9d8543" + integrity sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg== + dependencies: + any-promise "^1.3.0" + +rimraf@2, rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +safe-buffer@^5.0.1, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -"safer-buffer@>= 2.1.2 < 3": +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -1110,6 +1769,40 @@ semver@^7.3.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +sequelize-pool@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668" + integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== + +sequelize@^6.3.5: + version "6.3.5" + resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.3.5.tgz#80e3db7ac8b76d98c45ca93334197eb6e2335158" + integrity sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw== + dependencies: + debug "^4.1.1" + dottie "^2.0.0" + inflection "1.12.0" + lodash "^4.17.15" + moment "^2.26.0" + moment-timezone "^0.5.31" + retry-as-promised "^3.2.0" + semver "^7.3.2" + sequelize-pool "^6.0.0" + toposort-class "^1.0.1" + uuid "^8.1.0" + validator "^10.11.0" + wkx "^0.5.0" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" @@ -1123,6 +1816,11 @@ sha.js@^2.4.9: inherits "^2.0.1" safe-buffer "^5.0.1" +signal-exit@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + sirv@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.7.tgz#ad8ca1f84430777a59162592626c2b8e9b9f1384" @@ -1187,11 +1885,53 @@ socket.io@^2.3.0: socket.io-client "2.3.0" socket.io-parser "~3.4.0" +sqlite3@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.0.tgz#1bfef2151c6bc48a3ab1a6c126088bb8dd233566" + integrity sha512-rjvqHFUaSGnzxDy2AHCwhHy6Zp6MNJzCPGYju4kD8yi6bze4d1/zMTg6C7JI49b7/EM7jKMTvyfN/4ylBKdwfw== + dependencies: + node-addon-api "2.0.0" + node-pre-gyp "^0.11.0" + optionalDependencies: + node-gyp "3.x" + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + "statuses@>= 1.5.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string.prototype.trimend@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" @@ -1208,6 +1948,32 @@ string.prototype.trimstart@^1.0.1: call-bind "^1.0.0" define-properties "^1.1.3" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1215,6 +1981,28 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + +tar@^4: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + to-array@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" @@ -1237,11 +2025,24 @@ top-package@^1.0.0: resolved "https://registry.yarnpkg.com/top-package/-/top-package-1.0.1.tgz#17990e92963bd13faa61594fd7d32568ed267a14" integrity sha512-tsuhQlHSigOTTvonxHXwqSKEVSnWMh2GvpTvXa5YmoyOwL5YvU4lTd/KNVZlKM5v7gqx44UEuQxyPQEpmaIHdg== +toposort-class@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988" + integrity sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg= + totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + trouter@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/trouter/-/trouter-2.0.1.tgz#2726a5f8558e090d24c3a393f09eaab1df232df6" @@ -1254,6 +2055,18 @@ tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + twitch-api-call@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/twitch-api-call/-/twitch-api-call-4.3.1.tgz#17586c0350cfd6e90bd402fdabfc1e65fdf4b1a5" @@ -1332,11 +2145,61 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -uuid@^8.3.1: +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.1.0, uuid@^8.3.1: version "8.3.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== +validator@^10.11.0: + version "10.11.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228" + integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +which@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wkx@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" + integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg== + dependencies: + "@types/node" "*" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + ws@^7.1.2, ws@^7.2.0: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" @@ -1359,6 +2222,11 @@ xmlhttprequest-ssl@~1.5.4: resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= +yallist@^3.0.0, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" diff --git a/package.json b/package.json index 87d6582f..491ca8f5 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "author": "skarab42 ", "license": "MIT", "scripts": { + "postinstall": "electron-builder install-app-deps", "app:watch": "electron app/main/index.js -w", "app:build": "electron-builder build", "client:watch": "rollup -c -w", @@ -34,6 +35,7 @@ "concurrently": "^5.3.0", "electron": "^11.0.3", "electron-builder": "^22.9.1", + "electron-rebuild": "^2.3.2", "eslint": "^7.12.0", "eslint-plugin-svelte3": "^2.7.3", "i18next": "^19.8.3", From 1fcb671ac2b5055ac0178030ad7f5439607e640c Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:29:18 +0100 Subject: [PATCH 116/451] handle/replace variables props in text anime --- overlay-src/overlay.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/overlay-src/overlay.js b/overlay-src/overlay.js index f896b16b..96f7b81f 100644 --- a/overlay-src/overlay.js +++ b/overlay-src/overlay.js @@ -37,11 +37,14 @@ function runAnime(action, cb) { createElementFromTarget(item.target).then((element) => { const style = getStyle(item.target.style); const trans = getTrans(item.target.trans); + element.setAttribute("id", `item-${item.id}`); element.setAttribute("style", `${style};${trans}`); + Object.entries(item.target.attrs).forEach(([key, val]) => { element.setAttribute(key, val); }); + element.style.position = "absolute"; const targets = element; @@ -69,6 +72,12 @@ function runAnime(action, cb) { } ); + if (element.innerText !== "") { + Object.entries(action.eventProps).forEach(([key, val]) => { + element.innerText = element.innerText.replace(`$${key}`, val); + }); + } + return element; }) ); From 75bc98b03d7f152fca487187b5fc790f23fb2fa6 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:29:44 +0100 Subject: [PATCH 117/451] select event name --- .../Panel/Widget/EditModal/Action.svelte | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte index 2a86ed71..e86457dd 100644 --- a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte +++ b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte @@ -10,6 +10,7 @@ export let panel; export let widget; + const eventNames = ["none", "follow", "sub", "raid"]; const triggerTypes = ["immediat", "queue", "asap"]; const widgetsList = [ @@ -41,6 +42,11 @@ console.log("ERRRO:", error); }); } + + function onEventChange({ detail: eventName }) { + widget.eventName = eventName; + update(panel); + } {#if component} @@ -52,6 +58,14 @@ items="{triggerTypes}" />
+
+
From f4027c22899526d4c5a522536be9059cbb053b95 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:30:20 +0100 Subject: [PATCH 118/451] follow plugin (draft) --- app/server/libs/actions/create.js | 1 + app/server/libs/panels.js | 1 + app/server/libs/twitch/login.js | 8 ++--- .../libs/twitch/plugins/followsPlugin.js | 35 +++++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 app/server/libs/twitch/plugins/followsPlugin.js diff --git a/app/server/libs/actions/create.js b/app/server/libs/actions/create.js index 221906c3..fe9d80a4 100644 --- a/app/server/libs/actions/create.js +++ b/app/server/libs/actions/create.js @@ -5,6 +5,7 @@ module.exports = function create(action, data = null) { id: uuid(), type: null, widget: null, + eventProps: {}, data, ...action, }; diff --git a/app/server/libs/panels.js b/app/server/libs/panels.js index d37be79f..65d211c8 100644 --- a/app/server/libs/panels.js +++ b/app/server/libs/panels.js @@ -24,6 +24,7 @@ function createWidget() { id: uuid(), component: null, trigger: "immediat", + eventName: "none", label: null, labelSize: 16, labelPadding: 8, diff --git a/app/server/libs/twitch/login.js b/app/server/libs/twitch/login.js index e16693fc..4a7965ec 100644 --- a/app/server/libs/twitch/login.js +++ b/app/server/libs/twitch/login.js @@ -1,14 +1,10 @@ const state = require("./state"); +const installPlugings = require("./plugins/install"); const getConnectedUser = require("./api/getConnectedUser"); -const streamStatePlugin = require("./plugins/streamState"); - -function initTwitchPlugins() { - streamStatePlugin(); -} module.exports = async function login() { const user = await getConnectedUser(); state.set("user", user); - initTwitchPlugins(); + installPlugings(); return user; }; diff --git a/app/server/libs/twitch/plugins/followsPlugin.js b/app/server/libs/twitch/plugins/followsPlugin.js new file mode 100644 index 00000000..6305d0c6 --- /dev/null +++ b/app/server/libs/twitch/plugins/followsPlugin.js @@ -0,0 +1,35 @@ +const getLastFollows = require("../api/getLastFollows"); +const stores = require("../../../../stores"); +const { push } = require("../../actions"); + +const types = { + AnimeTimeline: "anime", +}; + +function pushActions(eventProps) { + stores.panels.get("panels").forEach(({ widgets }) => { + widgets.forEach((widget) => { + if (!widget.component) return; + + const type = types[widget.component.name]; + + if (type === "anime" && widget.eventName === "follow") { + push({ type, widget, eventProps }); + } + }); + }); +} + +module.exports = async function streamStatePlugin({ delay = 2 } = {}) { + const follows = await getLastFollows(); + + follows.forEach((viewer) => { + pushActions({ user: viewer.name }); + }); + + if (follows.length) { + console.log("New follows:", follows.length); + } + + setTimeout(streamStatePlugin, delay * 1000); +}; From 5dd3496f8c3bef0b3edb06c75653bf7c24b34c1f Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:52:14 +0100 Subject: [PATCH 119/451] add isFirstStart flag --- app/utils.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/utils.js b/app/utils.js index 662b9b8d..fa2c7af1 100644 --- a/app/utils.js +++ b/app/utils.js @@ -1,15 +1,20 @@ const { name, version } = require("./package"); const envPaths = require("env-paths"); +const fs = require("fs-extra"); const path = require("path"); -const appPath = __dirname; const app = { name, version }; + +const appPath = __dirname; const userPath = envPaths(name).data; const clientPath = path.join(appPath, "client"); const staticPath = path.join(appPath, "static"); const uploadPath = path.join(userPath, "upload"); const storesPath = path.join(userPath, "stores"); const filesPath = path.join(uploadPath, "files"); +const databasePath = path.join(userPath, "database"); + +const isFirstStart = !fs.existsSync(databasePath); const watch = process.argv.includes("--watch") || process.argv.includes("-w"); module.exports = { @@ -22,4 +27,6 @@ module.exports = { storesPath, staticPath, clientPath, + databasePath, + isFirstStart, }; From 23b8cf1fc4d1566c766f5e15d8394779fcb4a406 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:52:33 +0100 Subject: [PATCH 120/451] install Twitch plugin (draft) --- app/server/libs/twitch/plugins/install.js | 12 ++++++++++++ .../libs/twitch/plugins/updateFollowsPlugin.js | 9 +++++++++ 2 files changed, 21 insertions(+) create mode 100644 app/server/libs/twitch/plugins/install.js create mode 100644 app/server/libs/twitch/plugins/updateFollowsPlugin.js diff --git a/app/server/libs/twitch/plugins/install.js b/app/server/libs/twitch/plugins/install.js new file mode 100644 index 00000000..bdcc1269 --- /dev/null +++ b/app/server/libs/twitch/plugins/install.js @@ -0,0 +1,12 @@ +const updateFollowsPlugin = require("./updateFollowsPlugin"); +const { isFirstStart } = require("../../../../utils"); +const streamStatePlugin = require("./streamState"); +const followsPlugin = require("./followsPlugin"); + +module.exports = async function install() { + if (isFirstStart) { + await updateFollowsPlugin(); + } + await streamStatePlugin(); + await followsPlugin(); +}; diff --git a/app/server/libs/twitch/plugins/updateFollowsPlugin.js b/app/server/libs/twitch/plugins/updateFollowsPlugin.js new file mode 100644 index 00000000..edc3749c --- /dev/null +++ b/app/server/libs/twitch/plugins/updateFollowsPlugin.js @@ -0,0 +1,9 @@ +const getFollows = require("../api/getFollows"); + +module.exports = async function updateFollowPlugin() { + const { oldFollows, newFollows } = await getFollows(); + const follows = [...oldFollows, ...newFollows]; + + console.log("Total follows:", follows.length); + console.log("New follows:", newFollows.length); +}; From d0014699576c286363f5cb5b4a33b07e4f4f7dd8 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 20:53:09 +0100 Subject: [PATCH 121/451] v0.8.0 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index 1d63b3e0..4ddd27b0 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.7.0", + "version": "0.8.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index 491ca8f5..caa3d145 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.7.0", + "version": "0.8.0", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 2aa0c89d9963f696f12f485d386167687281e4e9 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 21:17:07 +0100 Subject: [PATCH 122/451] v0.8.1 --- app/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/package.json b/app/package.json index 4ddd27b0..447de072 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.8.0", + "version": "0.8.1", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", diff --git a/package.json b/package.json index caa3d145..25f7b9be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marv", - "version": "0.8.0", + "version": "0.8.1", "description": "Marv - Twitch Bot", "repository": "github:skarab42/marv", "author": "skarab42 ", From 370e54bf4ed9648c1a9ffaee26d63e6698903502 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 21:17:46 +0100 Subject: [PATCH 123/451] fail safe --- app/server/libs/twitch/plugins/install.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/server/libs/twitch/plugins/install.js b/app/server/libs/twitch/plugins/install.js index bdcc1269..7d2fb48a 100644 --- a/app/server/libs/twitch/plugins/install.js +++ b/app/server/libs/twitch/plugins/install.js @@ -3,10 +3,13 @@ const { isFirstStart } = require("../../../../utils"); const streamStatePlugin = require("./streamState"); const followsPlugin = require("./followsPlugin"); -module.exports = async function install() { - if (isFirstStart) { - await updateFollowsPlugin(); +let lock = false; + +module.exports = function install() { + if (isFirstStart && !lock) { + updateFollowsPlugin(); + lock = true; } - await streamStatePlugin(); - await followsPlugin(); + streamStatePlugin(); + followsPlugin(); }; From 337aca952573e18621e797ae9f207969d844182c Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 27 Nov 2020 21:36:43 +0100 Subject: [PATCH 124/451] fix: user store undefined when never logged to Twitch --- client-src/components/Widgets/Twitch/Chat/Settings.svelte | 2 +- client-src/components/Widgets/Twitch/Chat/Widget.svelte | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client-src/components/Widgets/Twitch/Chat/Settings.svelte b/client-src/components/Widgets/Twitch/Chat/Settings.svelte index dcf5fef3..85f25610 100644 --- a/client-src/components/Widgets/Twitch/Chat/Settings.svelte +++ b/client-src/components/Widgets/Twitch/Chat/Settings.svelte @@ -27,7 +27,7 @@ label="{_('words.channel')}" value="{props.channel}" on:update="{onChannelChange}" - placeholder="{$user.display_name}" + placeholder="{$user ? $user.display_name : '#channel'}" /> + + +
diff --git a/client-src/components/Widgets/Twitch/Stream/Widget.svelte b/client-src/components/Widgets/Twitch/Stream/Widget.svelte new file mode 100644 index 00000000..5f0a8106 --- /dev/null +++ b/client-src/components/Widgets/Twitch/Stream/Widget.svelte @@ -0,0 +1,24 @@ + + + + + diff --git a/client-src/components/Widgets/Twitch/Stream/config.js b/client-src/components/Widgets/Twitch/Stream/config.js new file mode 100644 index 00000000..7275c497 --- /dev/null +++ b/client-src/components/Widgets/Twitch/Stream/config.js @@ -0,0 +1,9 @@ +export default { + name: "TwitchStream", + label: "twitch.stream", + props: { + channel: null, + autoplay: true, + muted: true, + }, +}; diff --git a/client-src/components/Widgets/Twitch/Stream/index.js b/client-src/components/Widgets/Twitch/Stream/index.js new file mode 100644 index 00000000..72c78896 --- /dev/null +++ b/client-src/components/Widgets/Twitch/Stream/index.js @@ -0,0 +1,3 @@ +export { default as Settings } from "./Settings.svelte"; +export { default as Widget } from "./Widget.svelte"; +export { default as config } from "./config"; diff --git a/client-src/components/Widgets/index.js b/client-src/components/Widgets/index.js index d10b6965..64f7e640 100644 --- a/client-src/components/Widgets/index.js +++ b/client-src/components/Widgets/index.js @@ -3,6 +3,7 @@ import * as GoToScene from "./OBS/GoToScene"; import * as ToggleScene from "./OBS/ToggleScene"; import * as AnimeTimeline from "./Anime/Timeline"; import * as TwitchChat from "./Twitch/Chat"; +import * as TwitchStream from "./Twitch/Stream"; const widgets = { SceneList, @@ -10,6 +11,7 @@ const widgets = { ToggleScene, AnimeTimeline, TwitchChat, + TwitchStream, }; export default widgets; From 4629f644c5563065663e1041961aaee1b73f69b6 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 08:24:34 +0100 Subject: [PATCH 130/451] better install lock --- app/server/libs/twitch/plugins/install.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/server/libs/twitch/plugins/install.js b/app/server/libs/twitch/plugins/install.js index 7d2fb48a..b485a9fa 100644 --- a/app/server/libs/twitch/plugins/install.js +++ b/app/server/libs/twitch/plugins/install.js @@ -3,13 +3,17 @@ const { isFirstStart } = require("../../../../utils"); const streamStatePlugin = require("./streamState"); const followsPlugin = require("./followsPlugin"); -let lock = false; +let installLock = false; -module.exports = function install() { - if (isFirstStart && !lock) { - updateFollowsPlugin(); - lock = true; +module.exports = async function install() { + if (installLock) return; + + installLock = true; + + if (isFirstStart) { + await updateFollowsPlugin(); } + streamStatePlugin(); followsPlugin(); }; From 3dfabd18f7e4fb7e000c533d7218756a5d1fcb04 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 12:13:37 +0100 Subject: [PATCH 131/451] add text-align --- client-src/components/Anime/Timeline/libs/settings.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client-src/components/Anime/Timeline/libs/settings.js b/client-src/components/Anime/Timeline/libs/settings.js index c1709809..51e96553 100644 --- a/client-src/components/Anime/Timeline/libs/settings.js +++ b/client-src/components/Anime/Timeline/libs/settings.js @@ -11,6 +11,7 @@ export const defaultStyles = { "font-size", "font-family", "font-weight", + "text-align", "color", "opacity", "z-index", @@ -74,6 +75,10 @@ export const styleDefs = { default: "monospace", input: { type: "text" }, }, + "text-align": { + default: "center", + input: { type: "text" }, + }, color: { default: "#420042", input: { type: "text" }, From ceee6c4f2e217afbf68ed9576b1a3fad3e82df77 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 12:13:59 +0100 Subject: [PATCH 132/451] split module --- .../libs/twitch/plugins/followsPlugin.js | 23 ++----------------- app/server/libs/twitch/pushActions.js | 20 ++++++++++++++++ 2 files changed, 22 insertions(+), 21 deletions(-) create mode 100644 app/server/libs/twitch/pushActions.js diff --git a/app/server/libs/twitch/plugins/followsPlugin.js b/app/server/libs/twitch/plugins/followsPlugin.js index 6305d0c6..49e4a9f2 100644 --- a/app/server/libs/twitch/plugins/followsPlugin.js +++ b/app/server/libs/twitch/plugins/followsPlugin.js @@ -1,30 +1,11 @@ const getLastFollows = require("../api/getLastFollows"); -const stores = require("../../../../stores"); -const { push } = require("../../actions"); - -const types = { - AnimeTimeline: "anime", -}; - -function pushActions(eventProps) { - stores.panels.get("panels").forEach(({ widgets }) => { - widgets.forEach((widget) => { - if (!widget.component) return; - - const type = types[widget.component.name]; - - if (type === "anime" && widget.eventName === "follow") { - push({ type, widget, eventProps }); - } - }); - }); -} +const pushActions = require("../pushActions"); module.exports = async function streamStatePlugin({ delay = 2 } = {}) { const follows = await getLastFollows(); follows.forEach((viewer) => { - pushActions({ user: viewer.name }); + pushActions("follow", { user: viewer.name }); }); if (follows.length) { diff --git a/app/server/libs/twitch/pushActions.js b/app/server/libs/twitch/pushActions.js new file mode 100644 index 00000000..26ab03bd --- /dev/null +++ b/app/server/libs/twitch/pushActions.js @@ -0,0 +1,20 @@ +const stores = require("../../../stores"); +const { push } = require("../actions"); + +const types = { + AnimeTimeline: "anime", +}; + +module.exports = function pushActions(eventName, eventProps) { + stores.panels.get("panels").forEach(({ widgets }) => { + widgets.forEach((widget) => { + if (!widget.component) return; + + const type = types[widget.component.name]; + + if (type === "anime" && widget.eventName === eventName) { + push({ type, widget, eventProps }); + } + }); + }); +}; From 0b7e4e4320e72438f4aa39d1ad6e49b1661137fd Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 12:14:18 +0100 Subject: [PATCH 133/451] add host/raid events trigger --- app/server/index.js | 5 ++++- app/server/libs/twitch/chat/events/index.js | 5 +++++ app/server/libs/twitch/chat/events/onHosted.js | 6 ++++++ app/server/libs/twitch/chat/events/onMessage.js | 14 ++++++++++++++ app/server/libs/twitch/chat/events/onRaid.js | 7 +++++++ .../Panels/Panel/Widget/EditModal/Action.svelte | 2 +- 6 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 app/server/libs/twitch/chat/events/index.js create mode 100644 app/server/libs/twitch/chat/events/onHosted.js create mode 100644 app/server/libs/twitch/chat/events/onMessage.js create mode 100644 app/server/libs/twitch/chat/events/onRaid.js diff --git a/app/server/index.js b/app/server/index.js index 0dcde02a..adf45b4e 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -16,8 +16,10 @@ const missingKeyHandler = require("./libs/i18next/missingKeyHandler"); require("./db"); -// require("./libs/twitch/chat/onMessage"); // require("./libs/twitch/webhooks_"); +function initEvents() { + require("./libs/twitch/chat/events"); +} let { host, port } = stores.server.getAll(); const appFingerprint = stores.app.get("fingerprint"); @@ -75,6 +77,7 @@ function start() { twitchAutoConnect(); obsAutoConnect(); printBanner(); + initEvents(); }); } diff --git a/app/server/libs/twitch/chat/events/index.js b/app/server/libs/twitch/chat/events/index.js new file mode 100644 index 00000000..dd43d8a0 --- /dev/null +++ b/app/server/libs/twitch/chat/events/index.js @@ -0,0 +1,5 @@ +const twitch = require("../../index"); + +twitch.chat.onRaid(require("./onRaid")); +twitch.chat.onHosted(require("./onHosted")); +twitch.chat.onMessage(require("./onMessage")); diff --git a/app/server/libs/twitch/chat/events/onHosted.js b/app/server/libs/twitch/chat/events/onHosted.js new file mode 100644 index 00000000..162d39b4 --- /dev/null +++ b/app/server/libs/twitch/chat/events/onHosted.js @@ -0,0 +1,6 @@ +const pushActions = require("../../pushActions"); + +module.exports = function onHosted(channel, byChannel, auto, viewers) { + console.log(">>> hosted:", { channel, byChannel, auto, viewers }); + pushActions("hosted", { channel: byChannel, viewerCount: viewers || "???" }); +}; diff --git a/app/server/libs/twitch/chat/events/onMessage.js b/app/server/libs/twitch/chat/events/onMessage.js new file mode 100644 index 00000000..2dca68c2 --- /dev/null +++ b/app/server/libs/twitch/chat/events/onMessage.js @@ -0,0 +1,14 @@ +const getStreamByChannel = require("../../api/getStreamByChannel"); +const chalk = require("chalk"); + +const colors = new chalk.Instance({ level: 3 }); + +module.exports = async function onMessage(channel, nick, message, data) { + const color = colors.hex(data._tags.get("color")); + console.log("\x1b[35m%s\x1b[0m", "[chat]", color(`<${nick}>`), message); + + if (message === "!stream") { + const { viewer_count } = await getStreamByChannel(channel); + this.say(channel, `Vous êtes ${viewer_count} :)`); + } +}; diff --git a/app/server/libs/twitch/chat/events/onRaid.js b/app/server/libs/twitch/chat/events/onRaid.js new file mode 100644 index 00000000..6c825a18 --- /dev/null +++ b/app/server/libs/twitch/chat/events/onRaid.js @@ -0,0 +1,7 @@ +const pushActions = require("../../pushActions"); + +module.exports = function onRaid(channel, user, raidInfo) { + console.log(">>> raid:", { channel, user, raidInfo }); + const { displayName, viewerCount } = raidInfo; + pushActions("raid", { channel: displayName, viewerCount }); +}; diff --git a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte index e86457dd..fdcc3cfa 100644 --- a/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte +++ b/client-src/components/Panels/Panel/Widget/EditModal/Action.svelte @@ -10,7 +10,7 @@ export let panel; export let widget; - const eventNames = ["none", "follow", "sub", "raid"]; + const eventNames = ["none", "follow", "sub", "raid", "hosted"]; const triggerTypes = ["immediat", "queue", "asap"]; const widgetsList = [ From 2b0fba5697fb357ad1dcc6ea890a9e2a0f714c56 Mon Sep 17 00:00:00 2001 From: btor Date: Sat, 28 Nov 2020 13:34:16 +0100 Subject: [PATCH 134/451] fix: Force window to be shown by default / Add icon for MacOS --- app/main/tray.js | 4 ++-- app/main/window/mainWindow.js | 2 +- app/main/window/trayIcon.js | 16 ++++++++++++++++ app/static/icon_macos.png | Bin 0 -> 328 bytes 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 app/main/window/trayIcon.js create mode 100644 app/static/icon_macos.png diff --git a/app/main/tray.js b/app/main/tray.js index 0c802798..ad6485db 100644 --- a/app/main/tray.js +++ b/app/main/tray.js @@ -1,3 +1,4 @@ +const getTrayIconByPlatform = require("./window/trayIcon"); const mainWindow = require("./window/mainWindow"); const chatWindow = require("./window/chatWindow"); const { _ } = require("../server/libs/i18next"); @@ -9,8 +10,7 @@ const quit = require("./quit"); const path = require("path"); const open = require("open"); -const isWin32 = process.platform === "win32"; -const icon = `icon.${isWin32 ? "ico" : "png"}`; +const icon = getTrayIconByPlatform(); const { name, version } = require("../package"); const fingerprint = `${capitalize(name)} v${version}`; diff --git a/app/main/window/mainWindow.js b/app/main/window/mainWindow.js index 1d7024b7..95a42640 100644 --- a/app/main/window/mainWindow.js +++ b/app/main/window/mainWindow.js @@ -19,7 +19,7 @@ module.exports = function createWindow({ showOnLoad = true } = {}) { win = new BrowserWindow({ width: 800, height: 600, - show: false, + show: true, frame: false, icon: path.join(staticPath, "icon.png"), webPreferences: { ...webPreferences, devTools: watch }, diff --git a/app/main/window/trayIcon.js b/app/main/window/trayIcon.js new file mode 100644 index 00000000..94a989f7 --- /dev/null +++ b/app/main/window/trayIcon.js @@ -0,0 +1,16 @@ +module.exports = function getTrayIconByPlatform() { + let icon; + switch (process.platform) { + default: + icon = 'icon.png'; + break; + case 'win32': + icon = 'icon.ico'; + break; + case "darwin": + icon = 'icon_macos.png'; + break; + } + + return icon +} \ No newline at end of file diff --git a/app/static/icon_macos.png b/app/static/icon_macos.png new file mode 100644 index 0000000000000000000000000000000000000000..41abca2d1c78f7dd1a67314735941a8dd91dae89 GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6XVU3I`u#fXMsm#F#`j) zFbFd;%$g$s6m$*n32_C||0xDRbBhlF4H7R2@(X4#$gki3KjFQ?fr1YU95!5tSU;h^ zJ)j}}fd(f~Nu{TYV@SoEQ2&ceEeagXOu^i**Y*AXf5myzCfkjS(hMOF4EmT4v8t2> zOg?mkcd~XxaquF}PU{K0AGkRx_(lpHlz; literal 0 HcmV?d00001 From 24cc9159f06dfa3180bbbe1bcbc2be69315a7f68 Mon Sep 17 00:00:00 2001 From: btor Date: Sat, 28 Nov 2020 13:40:20 +0100 Subject: [PATCH 135/451] fix: add new line at end of the file --- app/main/window/trayIcon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main/window/trayIcon.js b/app/main/window/trayIcon.js index 94a989f7..2a11bc1c 100644 --- a/app/main/window/trayIcon.js +++ b/app/main/window/trayIcon.js @@ -13,4 +13,4 @@ module.exports = function getTrayIconByPlatform() { } return icon -} \ No newline at end of file +} From 047774a2b9f4c9c7f6684156ceea261d7aa10e60 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 14:21:02 +0100 Subject: [PATCH 136/451] add position prop --- client-src/components/UI/ColorPicker.svelte | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/client-src/components/UI/ColorPicker.svelte b/client-src/components/UI/ColorPicker.svelte index d5973bac..7bf2aa28 100644 --- a/client-src/components/UI/ColorPicker.svelte +++ b/client-src/components/UI/ColorPicker.svelte @@ -11,6 +11,12 @@ export let alpha = false; export let colapsed = true; export let previewClass = ""; + export let position = "left"; + + let cls = "flex-auto"; + export { cls as class }; + + let pos = position === "left" ? "left-0" : "right-0"; function onColor(event) { color = event.detail.hex; @@ -29,12 +35,14 @@ } -
+
-
{label}
+ {#if label} +
{label}
+ {/if}
-
+
Date: Sat, 28 Nov 2020 14:21:14 +0100 Subject: [PATCH 137/451] renamed event callback --- client-src/components/UI/Input.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client-src/components/UI/Input.svelte b/client-src/components/UI/Input.svelte index 0ade604d..42573eda 100644 --- a/client-src/components/UI/Input.svelte +++ b/client-src/components/UI/Input.svelte @@ -27,7 +27,7 @@ dispatch("update", target.value); } - function input(event) { + function onInput(event) { debounceUpdate(event); dispatch("input", event); } @@ -49,7 +49,7 @@ type="{type}" on:blur on:change - on:input="{input}" + on:input="{onInput}" on:keypress="{onKeypress}" class="{inputClass} w-full text-dark {inputHidden}" /> From 9c2afd15709dd12c05ccc896d12d9d751eeabf98 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 14:21:34 +0100 Subject: [PATCH 138/451] feature: Colorpicker for text color --- .../Timeline/Editor/Settings/Input.svelte | 33 ++++++++++++++----- .../Editor/Settings/Panels/Style.svelte | 11 +++++-- .../Anime/Timeline/libs/settings.js | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte b/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte index 2a5dd79c..f4c5b578 100644 --- a/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte +++ b/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte @@ -1,17 +1,23 @@
@@ -25,12 +31,23 @@ /> {/if}
- + {#if type === 'colorpicker'} + + {:else} + + {/if}
diff --git a/client-src/components/Anime/Timeline/Editor/Settings/Panels/Style.svelte b/client-src/components/Anime/Timeline/Editor/Settings/Panels/Style.svelte index 7f43f755..a51a56c0 100644 --- a/client-src/components/Anime/Timeline/Editor/Settings/Panels/Style.svelte +++ b/client-src/components/Anime/Timeline/Editor/Settings/Panels/Style.svelte @@ -20,8 +20,9 @@ ); $: selectedStyle = styleNames[0] || ""; - function onChange(key, { target }) { - dispatch("change", { key, value: target.value }); + function onChange(key, { target, detail }) { + const value = detail ? detail.hex : target.value; + dispatch("change", { key, value }); } function onRemove(key) { @@ -42,6 +43,10 @@ function isRemovable(/*key*/) { return true; } + + function inputProps(key) { + return styleDefs[key].input; + } @@ -63,7 +68,7 @@ Date: Sat, 28 Nov 2020 15:01:06 +0100 Subject: [PATCH 139/451] feature: text align select --- .../Anime/Timeline/Editor/Settings/Input.svelte | 14 ++++++++++++-- .../Timeline/Editor/Settings/Panels/Style.svelte | 2 +- .../components/Anime/Timeline/libs/settings.js | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte b/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte index f4c5b578..4e16e2c1 100644 --- a/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte +++ b/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte @@ -1,5 +1,6 @@ @@ -36,9 +38,17 @@ label="{false}" color="{value}" position="right" - on:color="{onColor}" + on:color="{onChange}" previewClass="w-10" /> + {:else if type === 'select'} + Date: Sat, 28 Nov 2020 15:03:13 +0100 Subject: [PATCH 140/451] start marv by default at startup --- app/stores/defaults/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/stores/defaults/app.js b/app/stores/defaults/app.js index 8d937ba1..1739944c 100644 --- a/app/stores/defaults/app.js +++ b/app/stores/defaults/app.js @@ -4,7 +4,7 @@ module.exports = { name, version, language: "en", - openOnStartup: false, + openOnStartup: true, showFirstStartInfo: true, fingerprint: `${name} v${version}`, }; From ca506a361dcb868371510553642e0364dbbcd459 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 15:11:11 +0100 Subject: [PATCH 141/451] start Marv maximized by default --- app/static/locales/en/app.json | 8 ++++---- app/static/locales/fr/app.json | 8 ++++---- client-src/components/App/OpenOnStartup.svelte | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/static/locales/en/app.json b/app/static/locales/en/app.json index ca73a929..ece6bed3 100644 --- a/app/static/locales/en/app.json +++ b/app/static/locales/en/app.json @@ -32,7 +32,7 @@ "no-file-selected": "No file selected", "no-file-added": "No file added", "add-file-to-timeline": "Click on the blue arrow to add some file.", - "electron-open-on-startup": "Open Marv on startup", + "electron-open-on-startup": "Open Marv minified", "connect-with-twitch": "Connect with Twitch", "open-twitch-chat-window": "Open Twitch chat", "dont-ask-me-again": "Dont ask me again", @@ -74,8 +74,8 @@ "loading": "loading", "download": "download", "event": "event", - "muted": "words.muted", - "autoplay": "words.autoplay" + "muted": "muted", + "autoplay": "autoplay" }, "obs": { "scene-list": "OBS | Scene list", @@ -93,4 +93,4 @@ "chat": "Twitch chat", "stream": "Twitch stream" } -} \ No newline at end of file +} diff --git a/app/static/locales/fr/app.json b/app/static/locales/fr/app.json index 00b5bf13..5f4f70ee 100644 --- a/app/static/locales/fr/app.json +++ b/app/static/locales/fr/app.json @@ -32,7 +32,7 @@ "no-file-selected": "Aucun fichier sélectionné", "no-file-added": "Aucun fichier ajouté", "add-file-to-timeline": "Clique sur la flêche blue pour ajouter un fichier.", - "electron-open-on-startup": "Ouvrir Marv au démarrage", + "electron-open-on-startup": "Ouvrir Marv minifier", "connect-with-twitch": "Connexion avec Twitch", "open-twitch-chat-window": "Ouvrir le chat Twitch", "dont-ask-me-again": "Ne plus me le demander", @@ -74,8 +74,8 @@ "loading": "chargement", "download": "téléchargement", "event": "évènement", - "muted": "words.muted", - "autoplay": "words.autoplay" + "muted": "en sourdine", + "autoplay": "lecture automatique" }, "obs": { "scene-list": "OBS | Liste des scènes", @@ -93,4 +93,4 @@ "chat": "Twitch chat", "stream": "Twitch stream" } -} \ No newline at end of file +} diff --git a/client-src/components/App/OpenOnStartup.svelte b/client-src/components/App/OpenOnStartup.svelte index 81f5508b..94c9a289 100644 --- a/client-src/components/App/OpenOnStartup.svelte +++ b/client-src/components/App/OpenOnStartup.svelte @@ -14,7 +14,7 @@ From 67eac0efbbe98b8970ab29f6a9e6904d6df324db Mon Sep 17 00:00:00 2001 From: btor Date: Sat, 28 Nov 2020 15:13:35 +0100 Subject: [PATCH 142/451] fix: revert `show` to false --- app/main/window/mainWindow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main/window/mainWindow.js b/app/main/window/mainWindow.js index 95a42640..1d7024b7 100644 --- a/app/main/window/mainWindow.js +++ b/app/main/window/mainWindow.js @@ -19,7 +19,7 @@ module.exports = function createWindow({ showOnLoad = true } = {}) { win = new BrowserWindow({ width: 800, height: 600, - show: true, + show: false, frame: false, icon: path.join(staticPath, "icon.png"), webPreferences: { ...webPreferences, devTools: watch }, From 3164dea6af70344fb46bb6e6c01046f37e5b9c9c Mon Sep 17 00:00:00 2001 From: skarab42 Date: Sat, 28 Nov 2020 17:04:31 +0100 Subject: [PATCH 143/451] poc: custom fonts --- app/server/api/app.js | 15 ++++++++++ app/server/libs/files.js | 2 +- client-src/api/app.js | 1 + .../Timeline/Editor/Settings/Input.svelte | 3 ++ .../Anime/Timeline/Editor/Timeline.svelte | 4 ++- .../Anime/Timeline/libs/settings.js | 2 +- client-src/components/FileManager/Main.svelte | 8 ++++- client-src/components/UI/FileIcon.svelte | 4 ++- client-src/components/UI/Fontpicker.svelte | 29 +++++++++++++++++++ client-src/components/UI/loadFonts.js | 22 ++++++++++++++ 10 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 client-src/components/UI/Fontpicker.svelte create mode 100644 client-src/components/UI/loadFonts.js diff --git a/app/server/api/app.js b/app/server/api/app.js index cd4de5f2..18e16a7b 100644 --- a/app/server/api/app.js +++ b/app/server/api/app.js @@ -1,5 +1,20 @@ +const { filesPath } = require("../../utils"); +const fs = require("fs"); + +const allowedExts = ["ttf", "otf"]; + +function getFonts() { + return fs.readdirSync(filesPath).filter((filename) => { + const ext = filename.split(".").pop(); + return allowedExts.includes(ext); + }); +} + module.exports = { getOS: () => { return process.platform; }, + getFonts: () => { + return getFonts(); + }, }; diff --git a/app/server/libs/files.js b/app/server/libs/files.js index 1cbb2ed3..33ef4bfb 100644 --- a/app/server/libs/files.js +++ b/app/server/libs/files.js @@ -6,7 +6,7 @@ const stores = require("../../stores"); const { filesPath } = require("../../utils"); const language = stores.app.get("language", "en"); -const allowedMimeTypes = ["text", "image", "audio", "video"]; +const allowedMimeTypes = ["text", "image", "audio", "video", "font"]; fs.ensureDirSync(filesPath); diff --git a/client-src/api/app.js b/client-src/api/app.js index 3adf368d..b1aae377 100644 --- a/client-src/api/app.js +++ b/client-src/api/app.js @@ -2,5 +2,6 @@ import { emit } from "@/libs/socket.io"; export default { getOS: () => emit("app.getOS"), + getFonts: () => emit("app.getFonts"), set: (key, val) => emit("stores.app", "set", key, val), }; diff --git a/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte b/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte index 4e16e2c1..72e938de 100644 --- a/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte +++ b/client-src/components/Anime/Timeline/Editor/Settings/Input.svelte @@ -1,6 +1,7 @@ + +
+ {#await loadFonts()} + Loading fonts list... + {:then fonts} + {:else} diff --git a/front-src/client/components/Anime/Timeline/Editor/Settings/Keyframe.svelte b/front-src/client/components/Anime/Timeline/Editor/Settings/Keyframe.svelte index c58e8953..786f8881 100644 --- a/front-src/client/components/Anime/Timeline/Editor/Settings/Keyframe.svelte +++ b/front-src/client/components/Anime/Timeline/Editor/Settings/Keyframe.svelte @@ -64,13 +64,14 @@ value="{$selectedKeyframe.duration}" on:change="{onKeyframeChange.bind(null, 'duration')}" /> -
+
+
+
{_('words.easing')}
+
-
- {#await loadFonts()} - Loading fonts list... - {:then fonts} - +{:catch error} +
{error.message}
+{/await} diff --git a/front-src/client/components/UI/Select.svelte b/front-src/client/components/UI/Select.svelte index 33d78f83..1ae74705 100644 --- a/front-src/client/components/UI/Select.svelte +++ b/front-src/client/components/UI/Select.svelte @@ -5,6 +5,7 @@ export let value = null; export let label = null; export let object = false; + export let rootClass = ""; export let inputClass = "p-2"; export let textColor = "text-light"; export let bgColor = "bg-dark-lighter"; @@ -20,7 +21,7 @@ -