From fd30b5aa36d5716cb31f5d317f70f9e7334c84f6 Mon Sep 17 00:00:00 2001 From: lukew3 Date: Mon, 31 May 2021 23:47:58 -0400 Subject: [PATCH] brought back firebase analytics and authentication --- .firebaserc_example | 5 + backend/models/analytics.js | 16 - backend/models/user.js | 5 +- backend/mongo-todo.md | 22 +- backend/server.js | 481 ++-- firebase.json | 24 + functions/index.js | 2718 ++++++++++++++++++++- functions/non-migrated.js | 372 --- functions/package-lock.json | 579 +++-- gulpfile.js | 11 +- package-lock.json | 3586 +++++++++++++++++++++------- package.json | 12 +- src/js/account-controller.js | 268 ++- src/js/account.js | 2 +- src/js/axios-instance.js | 46 +- src/js/commandline.js | 21 +- src/js/config.js | 19 +- src/js/db.js | 16 +- src/js/elements/account-button.js | 3 +- src/js/elements/leaderboards.js | 6 +- src/js/misc.js | 5 +- src/js/popups/result-tags-popup.js | 2 +- src/js/ready.js | 5 +- src/js/route-controller.js | 3 +- src/js/settings.js | 10 +- src/js/simple-popups.js | 4 +- src/js/test/test-leaderboards.js | 3 +- src/js/test/test-logic.js | 50 +- src/js/test/test-ui.js | 2 +- src/js/theme-controller.js | 10 +- src/js/ui.js | 9 +- static/index.html | 11 + static/quotes/english.json | 6 + static/webfonts/fa-brands-400.eot | Bin 133034 -> 147746 bytes 34 files changed, 6247 insertions(+), 2085 deletions(-) create mode 100644 .firebaserc_example delete mode 100644 backend/models/analytics.js create mode 100644 firebase.json delete mode 100644 functions/non-migrated.js diff --git a/.firebaserc_example b/.firebaserc_example new file mode 100644 index 000000000..9ecda8060 --- /dev/null +++ b/.firebaserc_example @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "your-firebase-project-id" + } +} \ No newline at end of file diff --git a/backend/models/analytics.js b/backend/models/analytics.js deleted file mode 100644 index 36543b9ef..000000000 --- a/backend/models/analytics.js +++ /dev/null @@ -1,16 +0,0 @@ -const mongoose = require("mongoose"); -const Schema = mongoose.Schema; - -const analyticsSchema = new Schema( - { - event: { type: String, required: true }, - data: { type: Schema.Types.Mixed }, - }, - { - timestamps: true, - } -); - -const Analytics = mongoose.model("Analytics", analyticsSchema); - -module.exports = { Analytics }; diff --git a/backend/models/user.js b/backend/models/user.js index 0b9ab5339..6510fd255 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -16,6 +16,7 @@ const userSchema = new Schema( zen: { type: Schema.Types.Mixed, default: {} }, }, name: { type: String, required: true }, + uid: { type: String, required: true }, presets: [{ type: presetSchema, default: {} }], tags: [{ type: tagSchema, default: {} }], favouriteThemes: [], @@ -40,9 +41,7 @@ const userSchema = new Schema( started: { type: Number, default: 0 }, //number of started tests completed: { type: Number, default: 0 }, }, - email: { type: String, required: true }, - password: { type: String, required: true }, - refreshTokens: [{ type: String, required: true }], + email: { type: String }, config: { type: configSchema, default: {} }, bananas: { t60bananas: { type: Number, default: 0 }, diff --git a/backend/mongo-todo.md b/backend/mongo-todo.md index 154db66c3..3e5cad79c 100644 --- a/backend/mongo-todo.md +++ b/backend/mongo-todo.md @@ -1,19 +1,15 @@ # Todo -- Get google login working -- Account data should be updated when new result is added/test completed -- Fix localhost, production, development server detection - - Should be a setting in the .env - - Maybe it could be set through package.json - - When a specific script is run, a certain mode will be activated - Tags and leaderboard are still buggy - Creating the first tag shows error "Unknown error, cannot read property \_id of undefined" - Check for tag pb doesn't always work - Leaderboard doesn't show the time until the daily reset - User's Leaderboard history is not edited, and therefore distance moved on leaderboard does not work properly +- Account data should be updated when new result is added/test completed - Graph bugs out when new result is added but page is not refreshed - Graph loops back from earliest point to the new points - Results list isn't updated either +- Save config doesn't actually return data? ### leaderboard @@ -25,7 +21,6 @@ ## After beta is ready -- Get somebody else to check over security due to my lack of expertise - Work on transfering data from firebase to mongo - Make sure that development can be done on mac and windows computers as well - directories in server.js might cause issues @@ -33,19 +28,6 @@ - Could reverse processing of results, but that would add more complexity to code - Figure out why if (page == "account") pageTransition = false; gets rid of endless account loading bug when accessing via url -### Analytics / Admin panel - -- Create admin panel or public stats page to make use of analytics data - - What data needs to be in the analytics table - - New Account, sessions, number of tests started, which tests people take and how fast they are taking them - - Things like theme, popular languages, etc can be derived from user models - - Wouldn't be able to see change over time if you went with this method - - Could check and save once a day - - Could use google analytics for easy data analysis - - Result is duplicated in analytics - - Does entire result need to be stored in analytics - - Should result be stored in seperate collection and then referenced in user doc and analytics? - ## User transfer - Create a script to pull all data from monkeytype and move it to the new mongo server diff --git a/backend/server.js b/backend/server.js index d96c63b8f..12d97e410 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,39 +1,29 @@ -require("dotenv").config(); const express = require("express"); const bodyParser = require("body-parser"); const mongoose = require("mongoose"); -const jwt = require("jsonwebtoken"); -const nodemailer = require("nodemailer"); -const bcrypt = require("bcrypt"); -const saltRounds = 10; +const cors = require("cors"); +const admin = require("firebase-admin"); const { User } = require("./models/user"); -const { Analytics } = require("./models/analytics"); const { Leaderboard } = require("./models/leaderboard"); +// Firebase admin setup +//currently uses account key in functions to prevent repetition +const serviceAccount = require("../functions/serviceAccountKey.json"); + +admin.initializeApp({ + credential: admin.credential.cert(serviceAccount), +}); // MIDDLEWARE & SETUP - const app = express(); +app.use(cors()); -const port = process.env.PORT || "5000"; +const port = process.env.PORT || "5005"; mongoose.connect("mongodb://localhost:27017/monkeytype", { useNewUrlParser: true, useUnifiedTopology: true, }); -let transporter = nodemailer.createTransport({ - service: "gmail", - auth: { - //should use OAuth in production - //type: 'OAuth2', - user: process.env.MAIL_ADDRESS, - pass: process.env.MAIL_PASSWORD, - //clientId: process.env.OAUTH_CLIENTID, - //clientSecret: process.env.OAUTH_CLIENT_SECRET, - //refreshToken: process.env.OAUTH_REFRESH_TOKEN - }, -}); - const mtRootDir = __dirname.substring(0, __dirname.length - 8); //will this work for windows and mac computers? app.use(express.static(mtRootDir + "/dist")); app.use(bodyParser.json()); @@ -78,16 +68,18 @@ Leaderboard.findOne((err, lb) => { clearDailyLeaderboards(); }); -function authenticateToken(req, res, next) { +async function authenticateToken(req, res, next) { const authHeader = req.headers["authorization"]; - const token = authHeader && authHeader.split(" ")[1]; - if (token == null) return res.sendStatus(401); - - jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, identity) => { - if (err) return res.sendStatus(403); - req.name = identity.name; + const token = await admin + .auth() + .verifyIdToken(req.headers.authorization.split(" ")[1]); + if (token == null) { + return res.sendStatus(401); + } else { + req.name = token.name; + req.uid = token.user_id; next(); - }); + } } // NON-ROUTE FUNCTIONS @@ -174,7 +166,7 @@ async function checkIfPB(obj, userdata) { throw new Error("pb is undefined"); } } catch (e) { - User.findOne({ name: userdata.name }, (err, user) => { + User.findOne({ uid: userdata.uid }, (err, user) => { user.personalBests = { [obj.mode]: { [obj.mode2]: [ @@ -260,7 +252,7 @@ async function checkIfPB(obj, userdata) { } if (toUpdate) { - User.findOne({ name: userdata.name }, (err, user) => { + User.findOne({ uid: userdata.uid }, (err, user) => { user.personalBests = pbs; user.save(); }); @@ -282,7 +274,7 @@ async function checkIfTagPB(obj, userdata) { let restags = obj.tags; //result tags try { let snap; - await User.findOne({ name: userdata.name }, (err, user) => { + await User.findOne({ uid: userdata.uid }, (err, user) => { snap = user.tags; }); snap.forEach((doc) => { @@ -312,7 +304,7 @@ async function checkIfTagPB(obj, userdata) { } catch (e) { console.log("PBs undefined"); //undefined personal best = new personal best - await User.findOne({ name: userdata.name }, (err, user) => { + await User.findOne({ uid: userdata.uid }, (err, user) => { //it might be more convenient if tags was an object with ids as the keys for (let j = 0; j < user.tags.length; j++) { console.log(user.tags[j]); @@ -407,7 +399,7 @@ async function checkIfTagPB(obj, userdata) { if (toUpdate) { console.log("Adding new pb at end"); - await User.findOne({ name: userdata.name }, (err, user) => { + await User.findOne({ uid: userdata.uid }, (err, user) => { //it might be more convenient if tags was an object with ids as the keys for (let j = 0; j < user.tags.length; j++) { console.log(user.tags[j]); @@ -426,7 +418,7 @@ async function checkIfTagPB(obj, userdata) { return ret; } -async function stripAndSave(username, obj) { +async function stripAndSave(uid, obj) { if (obj.bailedOut === false) delete obj.bailedOut; if (obj.blindMode === false) delete obj.blindMode; if (obj.difficulty === "normal") delete obj.difficulty; @@ -438,13 +430,13 @@ async function stripAndSave(username, obj) { if (obj.numbers === false) delete obj.numbers; if (obj.punctuation === false) delete obj.punctuation; - await User.findOne({ name: username }, (err, user) => { + await User.findOne({ uid: uid }, (err, user) => { user.results.push(obj); user.save(); }); } -function incrementT60Bananas(username, result, userData) { +function incrementT60Bananas(uid, result, userData) { try { let best60; try { @@ -464,7 +456,7 @@ function incrementT60Bananas(username, result, userData) { } else { //increment // console.log("checking"); - User.findOne({ name: username }, (err, user) => { + User.findOne({ uid: uid }, (err, user) => { if (user.bananas === undefined) { user.bananas.t60bananas = 1; } else { @@ -524,7 +516,7 @@ async function incrementGlobalTypingStats(userData, resultObj) { // timeTyping: roundTo2(newTime), // }); incrementPublicTypingStats(resultObj.restartCount + 1, 1, tt); - User.findOne({ name: userData.name }, (err, user) => { + User.findOne({ uid: userData.uid }, (err, user) => { user.globalStats = { started: newStarted, completed: newCompleted, @@ -538,8 +530,6 @@ async function incrementGlobalTypingStats(userData, resultObj) { } async function incrementPublicTypingStats(started, completed, time) { - //maybe this should be added to analytics - //analytics should be able to track usage over time and show a graph /* try { time = roundTo2(time); @@ -562,8 +552,54 @@ function isTagPresetNameValid(name) { return /^[0-9a-zA-Z_.-]+$/.test(name); } +function isUsernameValid(name) { + if (name === null || name === undefined || name === "") return false; + if (/miodec/.test(name.toLowerCase())) return false; + if (/bitly/.test(name.toLowerCase())) return false; + if (name.length > 14) return false; + if (/^\..*/.test(name.toLowerCase())) return false; + return /^[0-9a-zA-Z_.-]+$/.test(name); +} + // API +app.get("/api/nameCheck/:name", (req, res) => { + if (!isUsernameValid(req.params.name)) { + res.status(200).send({ + resultCode: -2, + message: "Username is not valid", + }); + return; + } + User.findOne({ name: req.params.name }, (err, user) => { + if (user) { + res.status(200).send({ + resultCode: -1, + message: "Username is taken", + }); + return; + } else { + res.status(200).send({ + resultCode: 1, + message: "Username is available", + }); + return; + } + }); +}); + +app.post("/api/signUp", (req, res) => { + const newuser = new User({ + name: req.body.name, + email: req.body.email, + uid: req.body.uid, + }); + newuser.save(); + res.status(200); + res.json({ user: newuser }); + return; +}); + app.post("/api/updateName", (req, res) => { //this might be a put/patch request //update the name of user with given uid @@ -571,177 +607,6 @@ app.post("/api/updateName", (req, res) => { const name = req.body.name; }); -function sendVerificationEmail(username, email) { - const host = "localhost:5000"; - const hash = Math.random().toString(16).substr(2, 12); - const link = `http://${host}/verifyEmail?name=${username}&hash=${hash}`; - User.findOne({ name: username }, (err, user) => { - user.verificationHashes.push(hash); - user.save(); - }); - const mailOptions = { - from: process.env.MAIL_ADDRESS, - to: email, - subject: "Monkeytype User Verification", - text: `Hello ${username},\nFollow this link to verify your email address:\n${link}\nIf you didn’t ask to verify this address, you can ignore this email.\nThanks,\nYour monkeytype team`, - }; - - transporter.sendMail(mailOptions, function (error, info) { - if (error) { - console.log(error); - } else { - console.log("Email sent: " + info.response); - } - }); -} - -app.get("/verifyEmail", (req, res) => { - let success = false; - User.findOne({ name: req.query.name }, (err, user) => { - if (user.verificationHashes.includes(req.query.hash)) { - success = true; - user.verificationHashes = []; - user.verified = true; - user.emailVerified = true; - user.save(); - } - }).then(() => { - if (success) { - res.send( - "

Email verified successfully

Go back to monkeytype

" - ); - } else { - res.send( - "

Email verification failed

Go back to monkeytype

" - ); - } - }); -}); - -app.post("/api/sendEmailVerification", authenticateToken, (req, res) => { - User.findOne({ name: req.name }, (err, user) => { - sendVerificationEmail(req.name, user.email); - }); - res.sendStatus(200); -}); - -app.post("/api/signIn", (req, res) => { - /* Takes email and password */ - //Login and send tokens - User.findOne({ email: req.body.email }, (err, user) => { - if (err) res.status(500).send({ error: err }); - if (user === null) { - res.status(500).send({ error: "No user found with that email" }); - return; - } - bcrypt.compare(req.body.password, user.password, (err, result) => { - if (err) - res.status(500).send({ error: "Error during password validation" }); - if (result) { - //if password matches hash - const accessToken = jwt.sign( - { name: user.name }, - process.env.ACCESS_TOKEN_SECRET - ); - const refreshToken = jwt.sign( - { name: user.name }, - process.env.REFRESH_TOKEN_SECRET - ); - user.refreshTokens.push(refreshToken); - user.save(); - const retUser = { - uid: user._id, - name: user.name, - email: user.email, - emailVerified: user.emailVerified, - metadata: { creationTime: user.createdAt }, - }; - res.json({ - accessToken: accessToken, - refreshToken: refreshToken, - user: retUser, - }); - } else { - //if password doesn't match hash - res.status(500).send({ error: "Password invalid" }); - } - }); - }); -}); - -app.post("/api/signUp", (req, res) => { - /* Takes name, email, password */ - //check if name has been taken - User.exists({ name: req.body.name }).then((exists) => { - //should also check if email is used - if (exists) { - //user with that name already exists - res.status(500).send({ error: "Username taken" }); - } - bcrypt.hash(req.body.password, saltRounds, function (err, hash) { - if (err) console.log(err); - const newuser = new User({ - name: req.body.name, - email: req.body.email, - emailVerified: false, - password: hash, - }); - newuser - .save() - .then((user) => { - //send email verification - sendVerificationEmail(user.name, user.email); - //add account created event to analytics - - //return user data and access token - const accessToken = jwt.sign( - { name: req.body.name }, - process.env.ACCESS_TOKEN_SECRET - ); - const refreshToken = jwt.sign( - { name: user.name }, - process.env.REFRESH_TOKEN_SECRET - ); - user.refreshTokens.push(refreshToken); - user.save(); - const retUser = { - uid: user._id, - name: user.name, - email: user.email, - emailVerified: user.emailVerified, - metadata: { creationTime: user.createdAt }, - }; - res.json({ - accessToken: accessToken, - refreshToken: refreshToken, - user: retUser, - }); - }) - .catch((e) => { - console.log(e); - res.status(500).send({ error: "Error when adding user" }); - }); - }); - }); -}); - -app.post("/api/refreshToken", (req, res) => { - const authHeader = req.headers["authorization"]; - const token = authHeader && authHeader.split(" ")[1]; - if (token == null) return res.sendStatus(401); - jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, identity) => { - if (err) return res.sendStatus(403); - User.findOne({ name: identity.name }, (err, user) => { - if (!user.refreshTokens.includes(token)) return res.sendStatus(403); - const accessToken = jwt.sign( - { name: identity.name }, - process.env.ACCESS_TOKEN_SECRET - ); - res.json({ accessToken: accessToken }); - }); - }); -}); - app.post("/api/passwordReset", (req, res) => { const email = req.body.email; //send email to the passed email requesting password reset @@ -750,13 +615,15 @@ app.post("/api/passwordReset", (req, res) => { app.get("/api/fetchSnapshot", authenticateToken, (req, res) => { /* Takes token and returns snap */ - User.findOne({ name: req.name }, (err, user) => { + console.log("UID: " + req.uid); + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); + if (!user) res.status(200).send({ message: "No user found" }); //client doesn't do anything with this //populate snap object with data from user document let snap = user; - delete snap.password; //return user data res.send({ snap: snap }); + return; }); }); @@ -769,10 +636,7 @@ function stdDev(array) { } app.post("/api/testCompleted", authenticateToken, (req, res) => { - //return createdId - //return user data - //this is actually REALLY hard - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); request = req.body; if (request === undefined) { @@ -780,7 +644,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { return; } try { - if (req.name === undefined || request.obj === undefined) { + if (req.uid === undefined || request.obj === undefined) { console.error(`error saving result for - missing input`); res.status(200).send({ data: { resultCode: -999 } }); return; @@ -790,7 +654,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { if (obj.incompleteTestSeconds > 500) console.log( - `FUCK, HIGH INCOMPLETE TEST SECONDS ${req.name}: ${JSON.stringify( + `FUCK, HIGH INCOMPLETE TEST SECONDS ${req.uid}: ${JSON.stringify( obj )}` ); @@ -817,7 +681,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { if (errCount > 0) { console.error( `error saving result for ${ - req.name + req.uid } error count ${errCount} - bad input - ${JSON.stringify( request.obj )}` @@ -896,7 +760,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { }; } catch (e) { console.error( - `cant verify key spacing or duration for user ${req.name}! - ${e} - ${obj.keySpacing} ${obj.keyDuration}` + `cant verify key spacing or duration for user ${req.uid}! - ${e} - ${obj.keySpacing} ${obj.keyDuration}` ); } @@ -911,7 +775,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { // emailVerified = await admin // .auth() - // .getUser(req.name) + // .getUser(req.uid) // .then((user) => { // return user.emailVerified; // }); @@ -956,7 +820,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { console.error( `very close to bot detected threshold by user (${obj.wpm} ${ obj.rawWpm - } ${obj.acc}) ${req.name} ${name} - spacing ${JSON.stringify( + } ${obj.acc}) ${req.uid} ${name} - spacing ${JSON.stringify( keySpacing )} duration ${JSON.stringify(keyDuration)}` ); @@ -979,7 +843,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { } catch (e) {} // return db - // .collection(`users/${req.name}/results`) + // .collection(`users/${req.uid}/results`) // .add(obj) // .then((e) => { @@ -1012,7 +876,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { // console.log(values); if (obj.mode === "time" && String(obj.mode2) === "60") { - incrementT60Bananas(req.name, obj, userdata); + incrementT60Bananas(req.uid, obj, userdata); } await incrementGlobalTypingStats(userdata, obj); @@ -1032,9 +896,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { logobj.keySpacing = "removed"; logobj.keyDuration = "removed"; console.log( - `saved result for ${req.name} (new PB) - ${JSON.stringify( - logobj - )}` + `saved result for ${req.uid} (new PB) - ${JSON.stringify(logobj)}` ); /* User.findOne({ name: userdata.name }, (err, user2) => { @@ -1053,7 +915,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { ) { if (verified !== false) { console.log( - `sending command to the bot to update the role for user ${req.name} with wpm ${obj.wpm}` + `sending command to the bot to update the role for user ${req.uid} with wpm ${obj.wpm}` ); updateDiscordRole(userdata.discordId, Math.round(obj.wpm)); } @@ -1065,17 +927,17 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { logobj.keyDuration = "removed"; request.obj.isPb = false; console.log( - `saved result for ${req.name} - ${JSON.stringify(logobj)}` + `saved result for ${req.uid} - ${JSON.stringify(logobj)}` ); returnobj.resultCode = 1; } - stripAndSave(req.name, request.obj); + stripAndSave(req.uid, request.obj); res.status(200).send({ data: returnobj }); return; }) .catch((e) => { console.error( - `error saving result when checking for PB / checking leaderboards for ${req.name} - ${e.message}` + `error saving result when checking for PB / checking leaderboards for ${req.uid} - ${e.message}` ); res .status(200) @@ -1084,7 +946,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { }); } catch (e) { console.error( - `error saving result for ${req.name} - ${JSON.stringify( + `error saving result for ${req.uid} - ${JSON.stringify( request.obj )} - ${e}` ); @@ -1095,7 +957,7 @@ app.post("/api/testCompleted", authenticateToken, (req, res) => { }); app.get("/api/userResults", authenticateToken, (req, res) => { - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); }); //return list of results @@ -1110,8 +972,8 @@ function isConfigKeyValid(name) { app.post("/api/saveConfig", authenticateToken, (req, res) => { try { - if (req.name === undefined || req.body.obj === undefined) { - console.error(`error saving config for ${req.name} - missing input`); + if (req.uid === undefined || req.body.obj === undefined) { + console.error(`error saving config for ${req.uid} - missing input`); return { resultCode: -1, message: "Missing input", @@ -1150,7 +1012,7 @@ app.post("/api/saveConfig", authenticateToken, (req, res) => { }); if (err) { console.error( - `error saving config for ${req.name} - bad input - ${JSON.stringify( + `error saving config for ${req.uid} - bad input - ${JSON.stringify( request.obj )}` ); @@ -1160,7 +1022,7 @@ app.post("/api/saveConfig", authenticateToken, (req, res) => { }; } - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); user.config = obj; //what does {merge: true} do in firebase @@ -1174,7 +1036,7 @@ app.post("/api/saveConfig", authenticateToken, (req, res) => { }) .catch((e) => { console.error( - `error saving config to DB for ${req.name} - ${e.message}` + `error saving config to DB for ${req.uid} - ${e.message}` ); return { resultCode: -1, @@ -1182,7 +1044,7 @@ app.post("/api/saveConfig", authenticateToken, (req, res) => { }; }); } catch (e) { - console.error(`error saving config for ${req.name} - ${e}`); + console.error(`error saving config for ${req.uid} - ${e}`); return { resultCode: -999, message: e, @@ -1194,8 +1056,8 @@ app.post("/api/addPreset", authenticateToken, (req, res) => { try { if (!isTagPresetNameValid(req.body.obj.name)) { return { resultCode: -1 }; - } else if (req.name === undefined || req.body.obj === undefined) { - console.error(`error saving config for ${req.name} - missing input`); + } else if (req.uid === undefined || req.body.obj === undefined) { + console.error(`error saving config for ${req.uid} - missing input`); res.json({ resultCode: -1, message: "Missing input", @@ -1233,7 +1095,7 @@ app.post("/api/addPreset", authenticateToken, (req, res) => { }); if (err) { console.error( - `error adding preset for ${req.name} - bad input - ${JSON.stringify( + `error adding preset for ${req.uid} - bad input - ${JSON.stringify( req.body.obj )}` ); @@ -1243,7 +1105,7 @@ app.post("/api/addPreset", authenticateToken, (req, res) => { }); } - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (user.presets.length >= 10) { res.json({ resultCode: -2, @@ -1263,7 +1125,7 @@ app.post("/api/addPreset", authenticateToken, (req, res) => { }) .catch((e) => { console.error( - `error adding preset to DB for ${req.name} - ${e.message}` + `error adding preset to DB for ${req.uid} - ${e.message}` ); res.json({ resultCode: -1, @@ -1272,7 +1134,7 @@ app.post("/api/addPreset", authenticateToken, (req, res) => { }); } } catch (e) { - console.error(`error adding preset for ${req.name} - ${e}`); + console.error(`error adding preset for ${req.uid} - ${e}`); res.json({ resultCode: -999, message: e, @@ -1285,7 +1147,7 @@ app.post("/api/editPreset", authenticateToken, (req, res) => { if (!isTagPresetNameValid(req.body.presetName)) { return { resultCode: -1 }; } else { - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { for (i = 0; i < user.presets.length; i++) { if (user.presets[i]._id.toString() == req.body.presetid.toString()) { user.presets[i] = { @@ -1299,7 +1161,7 @@ app.post("/api/editPreset", authenticateToken, (req, res) => { }) .then((e) => { console.log( - `user ${req.name} updated a preset: ${req.body.presetName}` + `user ${req.uid} updated a preset: ${req.body.presetName}` ); res.send({ resultCode: 1, @@ -1307,20 +1169,20 @@ app.post("/api/editPreset", authenticateToken, (req, res) => { }) .catch((e) => { console.error( - `error while updating preset for user ${req.name}: ${e.message}` + `error while updating preset for user ${req.uid}: ${e.message}` ); res.send({ resultCode: -999, message: e.message }); }); } } catch (e) { - console.error(`error updating preset for ${req.name} - ${e}`); + console.error(`error updating preset for ${req.uid} - ${e}`); return { resultCode: -999, message: e.message }; } }); app.post("/api/removePreset", authenticateToken, (req, res) => { try { - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { for (i = 0; i < user.presets.length; i++) { if (user.presets[i]._id.toString() == req.body.presetid.toString()) { user.presets.splice(i, 1); @@ -1330,17 +1192,17 @@ app.post("/api/removePreset", authenticateToken, (req, res) => { user.save(); }) .then((e) => { - console.log(`user ${req.name} deleted a preset`); + console.log(`user ${req.uid} deleted a preset`); res.send({ resultCode: 1 }); }) .catch((e) => { console.error( - `error deleting preset for user ${req.name}: ${e.message}` + `error deleting preset for user ${req.uid}: ${e.message}` ); res.send({ resultCode: -999 }); }); } catch (e) { - console.error(`error deleting preset for ${req.name} - ${e}`); + console.error(`error deleting preset for ${req.uid} - ${e}`); res.send({ resultCode: -999 }); } }); @@ -1355,7 +1217,7 @@ function isTagPresetNameValid(name) { app.post("/api/addTag", authenticateToken, (req, res) => { try { if (!isTagPresetNameValid(req.body.tagName)) return { resultCode: -1 }; - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); if (user.tags.includes(req.body.tagName)) { return { resultCode: -999, message: "Duplicate tag" }; @@ -1365,7 +1227,7 @@ app.post("/api/addTag", authenticateToken, (req, res) => { user.save(); }) .then((updatedUser) => { - console.log(`user ${req.name} created a tag: ${req.body.tagName}`); + console.log(`user ${req.uid} created a tag: ${req.body.tagName}`); res.json({ resultCode: 1, id: updatedUser.tags[updatedUser.tags.length - 1]._id, @@ -1373,12 +1235,12 @@ app.post("/api/addTag", authenticateToken, (req, res) => { }) .catch((e) => { console.error( - `error while creating tag for user ${req.name}: ${e.message}` + `error while creating tag for user ${req.uid}: ${e.message}` ); res.json({ resultCode: -999, message: e.message }); }); } catch (e) { - console.error(`error adding tag for ${req.name} - ${e}`); + console.error(`error adding tag for ${req.uid} - ${e}`); res.json({ resultCode: -999, message: e.message }); } }); @@ -1386,7 +1248,7 @@ app.post("/api/addTag", authenticateToken, (req, res) => { app.post("/api/editTag", authenticateToken, (req, res) => { try { if (!isTagPresetNameValid(req.body.tagName)) return { resultCode: -1 }; - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); for (var i = 0; i < user.tags.length; i++) { if (user.tags[i]._id == req.body.tagId) { @@ -1396,24 +1258,24 @@ app.post("/api/editTag", authenticateToken, (req, res) => { user.save(); }) .then((updatedUser) => { - console.log(`user ${req.name} updated a tag: ${req.name}`); + console.log(`user ${req.uid} updated a tag: ${req.body.tagName}`); res.json({ resultCode: 1 }); }) .catch((e) => { console.error( - `error while updating tag for user ${req.name}: ${e.message}` + `error while updating tag for user ${req.uid}: ${e.message}` ); res.json({ resultCode: -999, message: e.message }); }); } catch (e) { - console.error(`error updating tag for ${req.name} - ${e}`); + console.error(`error updating tag for ${req.uid} - ${e}`); res.json({ resultCode: -999, message: e.message }); } }); app.post("/api/removeTag", authenticateToken, (req, res) => { try { - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); for (var i = 0; i < user.tags.length; i++) { if (user.tags[i]._id == req.body.tagId) { @@ -1423,22 +1285,22 @@ app.post("/api/removeTag", authenticateToken, (req, res) => { user.save(); }) .then((updatedUser) => { - console.log(`user ${req.name} deleted a tag`); + console.log(`user ${req.uid} deleted a tag`); res.json({ resultCode: 1 }); }) .catch((e) => { - console.error(`error deleting tag for user ${req.name}: ${e.message}`); + console.error(`error deleting tag for user ${req.uid}: ${e.message}`); res.json({ resultCode: -999 }); }); } catch (e) { - console.error(`error deleting tag for ${req.name} - ${e}`); + console.error(`error deleting tag for ${req.uid} - ${e}`); res.json({ resultCode: -999 }); } }); app.post("/api/resetPersonalBests", authenticateToken, (req, res) => { try { - User.findOne({ name: req.name }, (err, user) => { + User.findOne({ uid: req.uid }, (err, user) => { if (err) res.status(500).send({ error: err }); user.personalBests = {}; user.save(); @@ -1522,9 +1384,11 @@ app.post("/api/attemptAddToLeaderboards", authenticateToken, (req, res) => { lb.board.length < lb.size || result.wpm > lb.board.slice(-1)[0].wpm ) { - lb, (lbPosData = addToLeaderboard(lb, result, req.name)); - retData[lb.type] = lbPosData; - lb.save(); + User.findOne({ uid: req.uid }, (err, user) => { + lb, (lbPosData = addToLeaderboard(lb, result, user.name)); //should uid be added instead of name + retData[lb.type] = lbPosData; + lb.save(); + }); } }); } @@ -1549,81 +1413,6 @@ app.get("/api/getLeaderboard/:type/:mode/:mode2", (req, res) => { ); }); -// ANALYTICS API - -function newAnalyticsEvent(event, data) { - let newEvent = { - event: event, - }; - if (data) newEvent.data = data; - const newEventObj = new Analytics(newEvent); - newEventObj.save(); -} - -app.post("/api/analytics/usedCommandLine", (req, res) => { - //save command used from command line to analytics - newAnalyticsEvent("usedCommandLine", { command: req.body.command }); - res.sendStatus(200); -}); - -app.post("/api/analytics/changedLanguage", (req, res) => { - //save what a user changed their language to - newAnalyticsEvent("changedLanguage", { language: req.body.language }); - res.sendStatus(200); -}); - -app.post("/api/analytics/changedTheme", (req, res) => { - //save what a user changed their theme to - newAnalyticsEvent("changedTheme", { theme: req.body.theme }); - res.sendStatus(200); -}); - -app.post("/api/analytics/testStarted", (req, res) => { - //log that a test was started - newAnalyticsEvent("testStarted"); - res.sendStatus(200); -}); - -app.post("/api/analytics/testStartedNoLogin", (req, res) => { - //log that a test was started without login - newAnalyticsEvent("testStartedNoLogin"); - res.sendStatus(200); -}); - -app.post("/api/analytics/testCompleted", (req, res) => { - //log that a test was completed - newAnalyticsEvent("testCompleted", { - completedEvent: req.body.completedEvent, - }); - res.sendStatus(200); -}); - -app.post("/api/analytics/testCompletedNoLogin", (req, res) => { - //log that a test was completed and user was not logged in - newAnalyticsEvent("testCompletedNoLogin", { - completedEvent: req.body.completedEvent, - }); - res.sendStatus(200); -}); - -app.post("/api/analytics/testCompletedInvalid", (req, res) => { - //log that a test was completed and is invalid - newAnalyticsEvent("testCompletedInvalid", { - completedEvent: req.body.completedEvent, - }); - res.sendStatus(200); -}); - -// STATIC FILES -app.get("/privacy-policy", (req, res) => { - res.sendFile(mtRootDir + "/dist/privacy-policy.html"); -}); - -app.use((req, res, next) => { - //sends index.html if the route is not found above - res.sendFile(mtRootDir + "/dist/index.html"); -}); - // LISTENER app.listen(port, () => { console.log(`Listening to requests on http://localhost:${port}`); diff --git a/firebase.json b/firebase.json new file mode 100644 index 000000000..b902ce9a9 --- /dev/null +++ b/firebase.json @@ -0,0 +1,24 @@ +{ + "hosting": { + "public": "dist", + "ignore": ["firebase.json", "**/.*", "**/node_modules/**"], + "rewrites": [ + { + "source": "/privacy-policy", + "destination": "/privacy-policy.html" + }, + { + "source": "**", + "destination": "/index.html" + } + ], + "cleanUrls": true, + "trailingSlash": false + } + // }, + // "functions": { + // "predeploy": [ + // "npm --prefix \"$RESOURCE_DIR\" run lint" + // ] + // } +} diff --git a/functions/index.js b/functions/index.js index 010b5dbe9..254381290 100644 --- a/functions/index.js +++ b/functions/index.js @@ -18,37 +18,901 @@ const db = admin.firestore(); const auth = admin.auth(); const fetch = require("node-fetch"); -exports.changename = functions.https.onCall(async (request, response) => { - try { - if (!isUsernameValid(request.name)) - return { status: -1, message: "Name not valid" }; - let taken = await db - .collection("takenNames") - .doc(request.name.toLowerCase()) - .get(); - taken = taken.data(); - if (taken === undefined || taken.taken === false) { - //not taken - let oldname = admin.auth().getUser(request.uid); - oldname = (await oldname).name; - await admin.auth().updateUser(request.uid, { name: request.name }); - await db - .collection("users") - .doc(request.uid) - .set({ name: request.name }, { merge: true }); - await db.collection("takenNames").doc(request.name.toLowerCase()).set( - { - taken: true, - }, - { merge: true } +async function getAllNames() { + // return admin + // .auth() + // .listUsers() + // .then((data) => { + // let names = []; + // data.users.forEach((user) => { + // names.push(user.displayName); + // }); + // return names; + // }); + + let ret = []; + + async function getAll(nextPageToken) { + // List batch of users, 1000 at a time. + let listUsersResult = await admin.auth().listUsers(1000, nextPageToken); + for (let i = 0; i < listUsersResult.users.length; i++) { + ret.push(listUsersResult.users[i].displayName); + } + if (listUsersResult.pageToken) { + // List next batch of users. + await getAll(listUsersResult.pageToken); + } + } + + await getAll(); + return ret; +} + +async function getAllUsers() { + // return admin + // .auth() + // .listUsers() + // .then((data) => { + // let names = []; + // data.users.forEach((user) => { + // names.push(user.displayName); + // }); + // return names; + // }); + + let ret = []; + + async function getAll(nextPageToken) { + // List batch of users, 1000 at a time. + let listUsersResult = await auth.listUsers(1000, nextPageToken); + for (let i = 0; i < listUsersResult.users.length; i++) { + let loopuser = listUsersResult.users[i]; + + //if custom claim is undefined check, if its true then ignore + + // if (loopuser === undefined || loopuser.customClaims === undefined || loopuser.customClaims['nameChecked'] === undefined) { + ret.push(listUsersResult.users[i]); + // } + + // console.log(loopuser.customClaims['asd']); + + // let userdata = await db.collection('users').doc(listUsersResult.users[i].uid).get(); + + // let data = userdata.data(); + + // if (data === undefined || data.needsToChangeName === undefined) { + // // console.log(data); + // ret.push(listUsersResult.users[i]); + // // console.log('user added'); + // } else { + // // console.log('user already added'); + // } + } + if (listUsersResult.pageToken) { + // List next batch of users. + await getAll(listUsersResult.pageToken); + } + } + await getAll(); + return ret; +} + +function isUsernameValid(name) { + if (name === null || name === undefined || name === "") return false; + if (/miodec/.test(name.toLowerCase())) return false; + if (/bitly/.test(name.toLowerCase())) return false; + if (name.length > 14) return false; + if (/^\..*/.test(name.toLowerCase())) return false; + return /^[0-9a-zA-Z_.-]+$/.test(name); +} + +exports.reserveDisplayName = functions.https.onCall( + async (request, response) => { + try { + let udata = await db.collection("users").doc(request.uid).get(); + udata = udata.data(); + if (request.name.toLowerCase() === udata.name.toLowerCase()) { + db.collection("takenNames").doc(request.name.toLowerCase()).set( + { + taken: true, + }, + { merge: true } + ); + console.log(`Reserved name ${request.name}`); + } else { + console.error( + `Could not reserve name. ${request.name.toLowerCase()} != ${udata.name.toLowerCase()}` + ); + } + } catch (e) { + console.error(`Could not reserve name. ${e}`); + } + } +); + +exports.changeDisplayName = functions.https.onCall( + async (request, response) => { + try { + if (!isUsernameValid(request.name)) + return { status: -1, message: "Name not valid" }; + let taken = await db + .collection("takenNames") + .doc(request.name.toLowerCase()) + .get(); + taken = taken.data(); + if (taken === undefined || taken.taken === false) { + //not taken + let oldname = admin.auth().getUser(request.uid); + oldname = (await oldname).displayName; + await admin + .auth() + .updateUser(request.uid, { displayName: request.name }); + await db + .collection("users") + .doc(request.uid) + .set({ name: request.name }, { merge: true }); + await db.collection("takenNames").doc(request.name.toLowerCase()).set( + { + taken: true, + }, + { merge: true } + ); + await db.collection("takenNames").doc(oldname.toLowerCase()).delete(); + return { status: 1, message: "Updated" }; + } else { + return { status: -2, message: "Name taken." }; + } + } catch (e) { + return { status: -999, message: "Error: " + e.message }; + } + } +); + +exports.clearName = functions.auth.user().onDelete((user) => { + db.collection("takenNames").doc(user.displayName.toLowerCase()).delete(); + db.collection("users").doc(user.uid).delete(); +}); + +exports.checkNameAvailability = functions.https.onRequest( + async (request, response) => { + response.set("Access-Control-Allow-Origin", origin); + if (request.method === "OPTIONS") { + // Send response to OPTIONS requests + response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); + response.set( + "Access-Control-Allow-Headers", + "Authorization,Content-Type" ); - await db.collection("takenNames").doc(oldname.toLowerCase()).delete(); - return { status: 1, message: "Updated" }; - } else { - return { status: -2, message: "Name taken." }; + response.set("Access-Control-Max-Age", "3600"); + response.status(204).send(""); + return; + } + request = request.body.data; + + // 1 - available + // -1 - unavailable (taken) + // -2 - not valid name + // -999 - unknown error + try { + if (!isUsernameValid(request.name)) { + response.status(200).send({ + data: { + resultCode: -2, + message: "Username is not valid", + }, + }); + return; + } + + let takendata = await db + .collection("takenNames") + .doc(request.name.toLowerCase()) + .get(); + + takendata = takendata.data(); + + if (takendata !== undefined && takendata.taken) { + response.status(200).send({ + data: { + resultCode: -1, + message: "Username is taken", + }, + }); + return; + } else { + response.status(200).send({ + data: { + resultCode: 1, + message: "Username is available", + }, + }); + return; + } + + // return getAllNames().then((data) => { + // let available = 1; + // data.forEach((name) => { + // try { + // if (name.toLowerCase() === request.name.toLowerCase()) available = -1; + // } catch (e) { + // // + // } + // }); + // return available; + // }); + } catch (e) { + console.error( + `Error while checking name availability for ${request.name}:` + + e.message + ); + response.status(200).send({ + data: { + resultCode: -999, + message: "Unexpected error: " + e, + }, + }); + return; + } + } +); + +// exports.changeName = functions.https.onCall((request, response) => { +// try { +// if (!isUsernameValid(request.name)) { +// console.warn( +// `${request.uid} tried to change their name to ${request.name} - not valid` +// ); +// return 0; +// } +// return getAllNames().then((data) => { +// let available = 1; +// data.forEach((name) => { +// try { +// if (name.toLowerCase() === request.name.toLowerCase()) available = 0; +// } catch (e) { +// // +// } +// }); +// if (available === 1) { +// return admin +// .auth() +// .updateUser(request.uid, { +// displayName: request.name, +// }) +// .then((d) => { +// console.log( +// `${request.uid} changed their name to ${request.name} - done` +// ); +// return 1; +// }) +// .catch((e) => { +// console.error( +// `${request.uid} tried to change their name to ${request.name} - ${e.message}` +// ); +// return -1; +// }); +// } else { +// console.warn( +// `${request.uid} tried to change their name to ${request.name} - already taken` +// ); +// return 0; +// } +// }); +// } catch (e) { +// console.error( +// `${request.uid} tried to change their name to ${request.name} - ${e}` +// ); +// return -1; +// } +// }); + +// exports.checkIfNeedsToChangeName = functions.https.onCall( +// (request, response) => { +// try { +// return db +// .collection("users") +// .doc(request.uid) +// .get() +// .then((doc) => { +// if ( +// doc.data().name === undefined || +// doc.data().name === null || +// doc.data().name === "" +// ) { +// return admin +// .auth() +// .getUser(request.uid) +// .then((requestUser) => { +// if (!isUsernameValid(requestUser.displayName)) { +// //invalid name, needs to change +// console.log( +// `user ${requestUser.uid} ${requestUser.displayName} needs to change name` +// ); +// return 1; +// } else { +// //valid name, but need to change if not duplicate + +// return getAllUsers() +// .then((users) => { +// let sameName = []; + +// //look for name names +// users.forEach((user) => { +// if (user.uid !== requestUser.uid) { +// try { +// if ( +// user.displayName.toLowerCase() === +// requestUser.displayName.toLowerCase() +// ) { +// sameName.push(user); +// } +// } catch (e) { +// // +// } +// } +// }); + +// if (sameName.length === 0) { +// db.collection("users") +// .doc(request.uid) +// .update({ name: requestUser.displayName }) +// .then(() => { +// return 0; +// }); +// } else { +// //check when the request user made the account compared to others +// let earliestTimestamp = 999999999999999; +// sameName.forEach((sn) => { +// let ts = +// new Date(sn.metadata.creationTime).getTime() / 1000; +// if (ts <= earliestTimestamp) { +// earliestTimestamp = ts; +// } +// }); + +// if ( +// new Date( +// requestUser.metadata.creationTime +// ).getTime() / +// 1000 > +// earliestTimestamp +// ) { +// console.log( +// `user ${requestUser.uid} ${requestUser.displayName} needs to change name` +// ); +// return 2; +// } else { +// db.collection("users") +// .doc(request.uid) +// .update({ name: requestUser.displayName }) +// .then(() => { +// return 0; +// }); +// } +// } +// }) +// .catch((e) => { +// console.error(`error getting all users - ${e}`); +// }); +// } +// }); +// } else { +// // console.log("name is good"); +// return 0; +// } +// }); +// } catch (e) { +// return -1; +// } +// } +// ); + +exports.removeSmallTestsAndQPB = functions.https.onCall( + async (request, response) => { + let uid = request.uid; + + try { + let docs = await db + .collection(`users/${uid}/results`) + .where("mode", "==", "time") + .where("mode2", "<", 15) + .get(); + docs.forEach(async (doc) => { + db.collection(`users/${uid}/results`).doc(doc.id).delete(); + }); + let docs2 = await db + .collection(`users/${uid}/results`) + .where("mode", "==", "words") + .where("mode2", "<", 10) + .get(); + docs2.forEach(async (doc) => { + db.collection(`users/${uid}/results`).doc(doc.id).delete(); + }); + let docs3 = await db + .collection(`users/${uid}/results`) + .where("mode", "==", "custom") + .where("testDuration", "<", 10) + .get(); + docs3.forEach(async (doc) => { + db.collection(`users/${uid}/results`).doc(doc.id).delete(); + }); + // console.log(`removing small tests for ${uid}: ${docs.size} time, ${docs2.size} words, ${docs3.size} custom`); + let userdata = await db.collection(`users`).doc(uid).get(); + userdata = userdata.data(); + try { + pbs = userdata.personalBests; + // console.log(`removing ${Object.keys(pbs.quote).length} quote pb`); + delete pbs.quote; + await db.collection("users").doc(uid).update({ personalBests: pbs }); + } catch {} + db.collection("users") + .doc(uid) + .set({ refactored: true }, { merge: true }); + console.log("removed small tests for " + uid); + } catch (e) { + console.log(`something went wrong for ${uid}: ${e.message}`); + } + } +); + +exports.resetPersonalBests = functions.https.onCall( + async (request, response) => { + let uid = request.uid; + + try { + var user = await db.collection("users").doc(uid); + await user.update({ personalBests: {} }); + return true; + } catch (e) { + console.log( + `something went wrong when deleting personal bests for ${uid}: ${e.message}` + ); + return false; + } + } +); + +async function checkIfPB(uid, obj, userdata) { + let pbs = null; + if (obj.mode == "quote") { + return false; + } + if (obj.funbox !== "none") { + return false; + } + try { + pbs = userdata.personalBests; + if (pbs === undefined) { + throw new Error("pb is undefined"); } } catch (e) { - return { status: -999, message: "Error: " + e.message }; + return db + .collection("users") + .doc(uid) + .update({ + personalBests: { + [obj.mode]: { + [obj.mode2]: [ + { + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }, + ], + }, + }, + }) + .then((e) => { + return true; + }) + .catch((e) => { + return db + .collection("users") + .doc(uid) + .set({ + personalBests: { + [obj.mode]: { + [obj.mode2]: [ + { + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }, + ], + }, + }, + }) + .then((e) => { + return true; + }); + }); + } + // //check mode, mode2, punctuation, language and difficulty + + let toUpdate = false; + let found = false; + try { + if (pbs[obj.mode][obj.mode2] === undefined) { + pbs[obj.mode][obj.mode2] = []; + } + pbs[obj.mode][obj.mode2].forEach((pb) => { + if ( + pb.punctuation === obj.punctuation && + pb.difficulty === obj.difficulty && + pb.language === obj.language + ) { + //entry like this already exists, compare wpm + found = true; + if (pb.wpm < obj.wpm) { + //new pb + pb.wpm = obj.wpm; + pb.acc = obj.acc; + pb.raw = obj.rawWpm; + pb.timestamp = Date.now(); + pb.consistency = obj.consistency; + toUpdate = true; + } else { + //no pb + return false; + } + } + }); + //checked all pbs, nothing found - meaning this is a new pb + if (!found) { + pbs[obj.mode][obj.mode2].push({ + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }); + toUpdate = true; + } + } catch (e) { + // console.log(e); + pbs[obj.mode] = {}; + pbs[obj.mode][obj.mode2] = [ + { + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }, + ]; + toUpdate = true; + } + + if (toUpdate) { + db.collection("users").doc(uid).update({ personalBests: pbs }); + return true; + } else { + return false; + } +} + +async function checkIfTagPB(uid, obj, userdata) { + if (obj.tags.length === 0) { + return []; + } + if (obj.mode == "quote") { + return []; + } + let dbtags = []; + let restags = obj.tags; + try { + let snap = await db.collection(`users/${uid}/tags`).get(); + snap.forEach((doc) => { + if (restags.includes(doc.id)) { + let data = doc.data(); + data.id = doc.id; + dbtags.push(data); + } + }); + } catch { + return []; + } + + let ret = []; + for (let i = 0; i < dbtags.length; i++) { + let pbs = null; + try { + pbs = dbtags[i].personalBests; + if (pbs === undefined) { + throw new Error("pb is undefined"); + } + } catch (e) { + //undefined personal best = new personal best + db.collection(`users/${uid}/tags`) + .doc(dbtags[i].id) + .set( + { + personalBests: { + [obj.mode]: { + [obj.mode2]: [ + { + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }, + ], + }, + }, + }, + { merge: true } + ) + .then((e) => { + ret.push(dbtags[i].id); + }); + continue; + } + let toUpdate = false; + let found = false; + try { + if (pbs[obj.mode][obj.mode2] === undefined) { + pbs[obj.mode][obj.mode2] = []; + } + pbs[obj.mode][obj.mode2].forEach((pb) => { + if ( + pb.punctuation === obj.punctuation && + pb.difficulty === obj.difficulty && + pb.language === obj.language + ) { + //entry like this already exists, compare wpm + found = true; + if (pb.wpm < obj.wpm) { + //new pb + pb.wpm = obj.wpm; + pb.acc = obj.acc; + pb.raw = obj.rawWpm; + pb.timestamp = Date.now(); + pb.consistency = obj.consistency; + toUpdate = true; + } else { + //no pb + return false; + } + } + }); + //checked all pbs, nothing found - meaning this is a new pb + if (!found) { + pbs[obj.mode][obj.mode2].push({ + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }); + toUpdate = true; + } + } catch (e) { + // console.log(e); + pbs[obj.mode] = {}; + pbs[obj.mode][obj.mode2] = [ + { + language: obj.language, + difficulty: obj.difficulty, + punctuation: obj.punctuation, + wpm: obj.wpm, + acc: obj.acc, + raw: obj.rawWpm, + timestamp: Date.now(), + consistency: obj.consistency, + }, + ]; + toUpdate = true; + } + + if (toUpdate) { + db.collection(`users/${uid}/tags`) + .doc(dbtags[i].id) + .update({ personalBests: pbs }); + ret.push(dbtags[i].id); + } + } + return ret; +} + +//old +// async function checkIfTagPB(uid, obj) { +// if (obj.tags.length === 0) { +// return []; +// } +// let dbtags = []; +// let restags = obj.tags; +// try { +// let snap = await db.collection(`users/${uid}/tags`).get(); +// snap.forEach((doc) => { +// if (restags.includes(doc.id)) { +// let data = doc.data(); +// data.id = doc.id; +// dbtags.push(data); +// } +// }); +// } catch (e) { +// return []; +// } +// let wpm = obj.wpm; +// let ret = []; +// for (let i = 0; i < dbtags.length; i++) { +// let dbtag = dbtags[i]; +// if (dbtag.pb === undefined || dbtag.pb < wpm) { +// //no pb found, meaning this one is a pb +// await db.collection(`users/${uid}/tags`).doc(dbtag.id).update({ +// pb: wpm, +// }); +// ret.push(dbtag.id); +// } +// } +// return ret; +// } + +exports.clearTagPb = functions.https.onCall((request, response) => { + try { + return db + .collection(`users/${request.uid}/tags`) + .doc(request.tagid) + .update({ + pb: 0, + }) + .then((e) => { + return { + resultCode: 1, + }; + }) + .catch((e) => { + console.error( + `error deleting tag pb for user ${request.uid}: ${e.message}` + ); + return { + resultCode: -999, + message: e.message, + }; + }); + } catch (e) { + console.error(`error deleting tag pb for ${request.uid} - ${e}`); + return { resultCode: -999 }; + } +}); + +function stdDev(array) { + const n = array.length; + const mean = array.reduce((a, b) => a + b) / n; + return Math.sqrt( + array.map((x) => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n + ); +} + +function roundTo2(num) { + return Math.round((num + Number.EPSILON) * 100) / 100; +} + +function validateResult(result) { + if (result.wpm > result.rawWpm) { + console.error( + `Could not validate result for ${result.uid}. ${result.wpm} > ${result.rawWpm}` + ); + return false; + } + let wpm = roundTo2((result.correctChars * (60 / result.testDuration)) / 5); + if ( + wpm < result.wpm - result.wpm * 0.01 || + wpm > result.wpm + result.wpm * 0.01 + ) { + console.error( + `Could not validate result for ${result.uid}. wpm ${wpm} != ${result.wpm}` + ); + return false; + } + // if (result.allChars != undefined) { + // let raw = roundTo2((result.allChars * (60 / result.testDuration)) / 5); + // if ( + // raw < result.rawWpm - result.rawWpm * 0.01 || + // raw > result.rawWpm + result.rawWpm * 0.01 + // ) { + // console.error( + // `Could not validate result for ${result.uid}. raw ${raw} != ${result.rawWpm}` + // ); + // return false; + // } + // } + if (result.mode === "time" && (result.mode2 === 15 || result.mode2 === 60)) { + let keyPressTimeSum = + result.keySpacing.reduce((total, val) => { + return total + val; + }) / 1000; + if ( + keyPressTimeSum < result.testDuration - 1 || + keyPressTimeSum > result.testDuration + 1 + ) { + console.error( + `Could not validate key spacing sum for ${result.uid}. ${keyPressTimeSum} !~ ${result.testDuration}` + ); + return false; + } + + if ( + result.testDuration < result.mode2 - 1 || + result.testDuration > result.mode2 + 1 + ) { + console.error( + `Could not validate test duration for ${result.uid}. ${result.testDuration} !~ ${result.mode2}` + ); + return false; + } + } + + if (result.chartData.raw !== undefined) { + if (result.chartData.raw.filter((w) => w > 350).length > 0) return false; + } + + if (result.wpm > 100 && result.consistency < 10) return false; + + return true; +} + +exports.requestTest = functions.https.onRequest((request, response) => { + response.set("Access-Control-Allow-Origin", origin); + response.set("Access-Control-Allow-Headers", "*"); + response.set("Access-Control-Allow-Credentials", "true"); + response.status(200).send({ data: "test" }); +}); + +exports.getPatreons = functions.https.onRequest(async (request, response) => { + response.set("Access-Control-Allow-Origin", origin); + response.set("Access-Control-Allow-Headers", "*"); + response.set("Access-Control-Allow-Credentials", "true"); + if (request.method === "OPTIONS") { + // Send response to OPTIONS requests + response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); + response.set("Access-Control-Allow-Headers", "Authorization,Content-Type"); + response.set("Access-Control-Max-Age", "3600"); + response.status(204).send(""); + return; + } + request = request.body.data; + try { + let patreon = await db.collection("patreon").doc("patreons").get(); + let data = patreon.data().list; + + data = data.sort((a, b) => { + return b.value - a.value; + }); + + let ret = []; + data.forEach((pdoc) => { + ret.push(pdoc.name); + }); + + response.status(200).send({ data: ret }); + return; + } catch (e) { + response.status(200).send({ e }); + return; } }); @@ -122,6 +986,113 @@ exports.verifyUser = functions.https.onRequest(async (request, response) => { } }); +function incrementT60Bananas(uid, result, userData) { + try { + let best60; + try { + best60 = Math.max( + ...userData.personalBests.time[60].map((best) => best.wpm) + ); + if (!Number.isFinite(best60)) { + throw "Not finite"; + } + } catch (e) { + best60 = undefined; + } + + if (best60 != undefined && result.wpm < best60 - best60 * 0.25) { + // console.log("returning"); + return; + } else { + //increment + // console.log("checking"); + db.collection(`users/${uid}/bananas`) + .doc("bananas") + .get() + .then((docRef) => { + let data = docRef.data(); + if (data === undefined) { + //create doc + db.collection(`users/${uid}/bananas`).doc("bananas").set( + { + t60bananas: 1, + }, + { merge: true } + ); + } else { + //increment + db.collection(`users/${uid}/bananas`) + .doc("bananas") + .set( + { + t60bananas: admin.firestore.FieldValue.increment(1), + }, + { merge: true } + ); + } + }); + } + } catch (e) { + console.log( + "something went wrong when trying to increment bananas " + e.message + ); + } +} + +async function getIncrementedTypingStats(userData, resultObj) { + try { + let newStarted; + let newCompleted; + let newTime; + + let tt = 0; + let afk = resultObj.afkDuration; + if (afk == undefined) { + afk = 0; + } + tt = resultObj.testDuration + resultObj.incompleteTestSeconds - afk; + + if (tt > 500) + console.log( + `FUCK, INCREASING BY A LOT ${resultObj.uid}: ${JSON.stringify( + resultObj + )}` + ); + + if (userData.startedTests === undefined) { + newStarted = resultObj.restartCount + 1; + } else { + newStarted = userData.startedTests + resultObj.restartCount + 1; + } + if (userData.completedTests === undefined) { + newCompleted = 1; + } else { + newCompleted = userData.completedTests + 1; + } + if (userData.timeTyping === undefined) { + newTime = tt; + } else { + newTime = userData.timeTyping + tt; + } + // db.collection("users") + // .doc(uid) + // .update({ + // startedTests: newStarted, + // completedTests: newCompleted, + // timeTyping: roundTo2(newTime), + // }); + incrementPublicTypingStats(resultObj.restartCount + 1, 1, tt); + + return { + newStarted: newStarted, + newCompleted: newCompleted, + newTime: roundTo2(newTime), + }; + } catch (e) { + console.error(`Error while incrementing stats for user ${uid}: ${e}`); + } +} + async function getUpdatedLbMemory(userdata, mode, mode2, globallb, dailylb) { let lbmemory = userdata.lbMemory; @@ -159,6 +1130,470 @@ async function getUpdatedLbMemory(userdata, mode, mode2, globallb, dailylb) { return lbmemory; } +async function incrementPublicTypingStats(started, completed, time) { + try { + time = roundTo2(time); + db.collection("public") + .doc("stats") + .update({ + completedTests: admin.firestore.FieldValue.increment(completed), + startedTests: admin.firestore.FieldValue.increment(started), + timeTyping: admin.firestore.FieldValue.increment(time), + }); + } catch (e) { + console.error(`Error while incrementing public stats: ${e}`); + } +} + +async function incrementTestCounter(uid, userData) { + try { + if (userData.completedTests === undefined) { + let results = await db.collection(`users/${uid}/results`).get(); + let count = results.docs.length; + db.collection("users") + .doc(uid) + .update({ + completedTests: admin.firestore.FieldValue.increment(count), + }); + db.collection("public") + .doc("stats") + .update({ + completedTests: admin.firestore.FieldValue.increment(count), + }); + } else { + db.collection("users") + .doc(uid) + .update({ completedTests: admin.firestore.FieldValue.increment(1) }); + db.collection("public") + .doc("stats") + .update({ completedTests: admin.firestore.FieldValue.increment(1) }); + } + } catch (e) { + console.error( + `Error while incrementing completed tests for user ${uid}: ${e}` + ); + } +} + +async function incrementStartedTestCounter(uid, num, userData) { + try { + if (userData.startedTests === undefined) { + let stepSize = 1000; + let results = []; + let query = await db + .collection(`users/${uid}/results`) + .orderBy("timestamp", "desc") + .limit(stepSize) + .get(); + let lastDoc; + while (query.docs.length > 0) { + lastDoc = query.docs[query.docs.length - 1]; + query.docs.forEach((doc) => { + results.push({ restartCount: doc.data().restartCount }); + }); + query = await db + .collection(`users/${uid}/results`) + .orderBy("timestamp", "desc") + .limit(stepSize) + .startAfter(lastDoc) + .get(); + } + + let count = 0; + results.forEach((result) => { + try { + let rc = result.restartCount; + if (rc === undefined) { + rc = 0; + } + + count += parseInt(rc); + } catch (e) {} + }); + count += results.length; + db.collection("users") + .doc(uid) + .update({ + startedTests: admin.firestore.FieldValue.increment(count), + }); + db.collection("public") + .doc("stats") + .update({ + startedTests: admin.firestore.FieldValue.increment(count), + }); + } else { + db.collection("users") + .doc(uid) + .update({ startedTests: admin.firestore.FieldValue.increment(num) }); + db.collection("public") + .doc("stats") + .update({ startedTests: admin.firestore.FieldValue.increment(num) }); + } + } catch (e) { + console.error( + `Error while incrementing started tests for user ${uid}: ${e}` + ); + } +} + +exports.testCompleted = functions.https.onRequest(async (request, response) => { + response.set("Access-Control-Allow-Origin", origin); + if (request.method === "OPTIONS") { + // Send response to OPTIONS requests + response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); + response.set("Access-Control-Allow-Headers", "Authorization,Content-Type"); + response.set("Access-Control-Max-Age", "3600"); + response.status(204).send(""); + return; + } + request = request.body.data; + if (request === undefined) { + response.status(200).send({ data: { resultCode: -999 } }); + return; + } + try { + if (request.uid === undefined || request.obj === undefined) { + console.error(`error saving result for - missing input`); + response.status(200).send({ data: { resultCode: -999 } }); + return; + } + + let obj = request.obj; + + if (obj.incompleteTestSeconds > 500) + console.log( + `FUCK, HIGH INCOMPLETE TEST SECONDS ${request.uid}: ${JSON.stringify( + obj + )}` + ); + + function verifyValue(val) { + let errCount = 0; + if (val === null || val === undefined) { + } else if (Array.isArray(val)) { + //array + val.forEach((val2) => { + errCount += verifyValue(val2); + }); + } else if (typeof val === "object" && !Array.isArray(val)) { + //object + Object.keys(val).forEach((valkey) => { + errCount += verifyValue(val[valkey]); + }); + } else { + if (!/^[0-9a-zA-Z._\-\+]+$/.test(val)) errCount++; + } + return errCount; + } + let errCount = verifyValue(obj); + if (errCount > 0) { + console.error( + `error saving result for ${ + request.uid + } error count ${errCount} - bad input - ${JSON.stringify(request.obj)}` + ); + response.status(200).send({ data: { resultCode: -1 } }); + return; + } + + if ( + obj.wpm <= 0 || + obj.wpm > 350 || + obj.acc < 50 || + obj.acc > 100 || + obj.consistency > 100 + ) { + response.status(200).send({ data: { resultCode: -1 } }); + return; + } + if ( + (obj.mode === "time" && obj.mode2 < 15 && obj.mode2 > 0) || + (obj.mode === "time" && obj.mode2 == 0 && obj.testDuration < 15) || + (obj.mode === "words" && obj.mode2 < 10 && obj.mode2 > 0) || + (obj.mode === "words" && obj.mode2 == 0 && obj.testDuration < 15) || + (obj.mode === "custom" && + obj.customText !== undefined && + !obj.customText.isWordRandom && + !obj.customText.isTimeRandom && + obj.customText.textLen < 10) || + (obj.mode === "custom" && + obj.customText !== undefined && + obj.customText.isWordRandom && + !obj.customText.isTimeRandom && + obj.customText.word < 10) || + (obj.mode === "custom" && + obj.customText !== undefined && + !obj.customText.isWordRandom && + obj.customText.isTimeRandom && + obj.customText.time < 15) + ) { + response + .status(200) + .send({ data: { resultCode: -5, message: "Test too short" } }); + return; + } + if (!validateResult(obj)) { + if ( + obj.bailedOut && + ((obj.mode === "time" && obj.mode2 >= 3600) || + (obj.mode === "words" && obj.mode2 >= 5000) || + obj.mode === "custom") + ) { + //dont give an error + } else { + response.status(200).send({ data: { resultCode: -4 } }); + return; + } + } + + let keySpacing = null; + let keyDuration = null; + try { + keySpacing = { + average: + obj.keySpacing.reduce((previous, current) => (current += previous)) / + obj.keySpacing.length, + sd: stdDev(obj.keySpacing), + }; + + keyDuration = { + average: + obj.keyDuration.reduce((previous, current) => (current += previous)) / + obj.keyDuration.length, + sd: stdDev(obj.keyDuration), + }; + } catch (e) { + console.error( + `cant verify key spacing or duration for user ${request.uid}! - ${e} - ${obj.keySpacing} ${obj.keyDuration}` + ); + } + + obj.keySpacingStats = keySpacing; + obj.keyDurationStats = keyDuration; + + if (obj.mode == "time" && (obj.mode2 == 15 || obj.mode2 == 60)) { + } else { + obj.keySpacing = "removed"; + obj.keyDuration = "removed"; + } + + // emailVerified = await admin + // .auth() + // .getUser(request.uid) + // .then((user) => { + // return user.emailVerified; + // }); + // emailVerified = true; + + // if (obj.funbox === "nospace") { + // response.status(200).send({ data: { resultCode: -1 } }); + // return; + // } + return db + .collection("users") + .doc(request.uid) + .get() + .then((ret) => { + let userdata = ret.data(); + let name = userdata.name === undefined ? false : userdata.name; + let banned = userdata.banned === undefined ? false : userdata.banned; + let verified = userdata.verified; + request.obj.name = name; + + //check keyspacing and duration here + if (obj.mode === "time" && obj.wpm > 130 && obj.testDuration < 122) { + if (verified === false || verified === undefined) { + if (keySpacing !== null && keyDuration !== null) { + if ( + keySpacing.sd <= 15 || + keyDuration.sd <= 10 || + keyDuration.average < 15 || + (obj.wpm > 200 && obj.consistency < 70) + ) { + console.error( + `possible bot detected by user (${obj.wpm} ${obj.rawWpm} ${ + obj.acc + }) ${request.uid} ${name} - spacing ${JSON.stringify( + keySpacing + )} duration ${JSON.stringify(keyDuration)}` + ); + response.status(200).send({ data: { resultCode: -2 } }); + return; + } + if ( + (keySpacing.sd > 15 && keySpacing.sd <= 25) || + (keyDuration.sd > 10 && keyDuration.sd <= 15) || + (keyDuration.average > 15 && keyDuration.average <= 20) + ) { + console.error( + `very close to bot detected threshold by user (${obj.wpm} ${ + obj.rawWpm + } ${obj.acc}) ${ + request.uid + } ${name} - spacing ${JSON.stringify( + keySpacing + )} duration ${JSON.stringify(keyDuration)}` + ); + } + } else { + response.status(200).send({ data: { resultCode: -3 } }); + return; + } + } + } + + //yeet the key data + obj.keySpacing = null; + obj.keyDuration = null; + try { + obj.keyDurationStats.average = roundTo2(obj.keyDurationStats.average); + obj.keyDurationStats.sd = roundTo2(obj.keyDurationStats.sd); + obj.keySpacingStats.average = roundTo2(obj.keySpacingStats.average); + obj.keySpacingStats.sd = roundTo2(obj.keySpacingStats.sd); + } catch (e) {} + + // return db + // .collection(`users/${request.uid}/results`) + // .add(obj) + // .then((e) => { + + // let createdDocId = e.id; + return Promise.all([ + // checkLeaderboards( + // request.obj, + // "global", + // banned, + // name, + // verified, + // emailVerified + // ), + // checkLeaderboards( + // request.obj, + // "daily", + // banned, + // name, + // verified, + // emailVerified + // ), + checkIfPB(request.uid, request.obj, userdata), + checkIfTagPB(request.uid, request.obj), + ]) + .then(async (values) => { + // let globallb = values[0].insertedAt; + // let dailylb = values[1].insertedAt; + let ispb = values[0]; + let tagPbs = values[1]; + let createdDocId = await stripAndSave(request.uid, request.obj); + createdDocId = createdDocId.id; + // console.log(values); + + if (obj.mode === "time" && String(obj.mode2) === "60") { + incrementT60Bananas(request.uid, obj, userdata); + } + + let newTypingStats = await getIncrementedTypingStats(userdata, obj); + + db.collection("users").doc(request.uid).update({ + startedTests: newTypingStats.newStarted, + completedTests: newTypingStats.newCompleted, + timeTyping: newTypingStats.newTime, + }); + // } + + let returnobj = { + resultCode: null, + // globalLeaderboard: globallb, + // dailyLeaderboard: dailylb, + // lbBanned: banned, + name: name, + createdId: createdDocId, + needsToVerify: values[0].needsToVerify, + needsToVerifyEmail: values[0].needsToVerifyEmail, + tagPbs: tagPbs, + }; + if (ispb) { + let logobj = request.obj; + logobj.keySpacing = "removed"; + logobj.keyDuration = "removed"; + console.log( + `saved result for ${request.uid} (new PB) - ${JSON.stringify( + logobj + )}` + ); + await db + .collection(`users/${request.uid}/results/`) + .doc(createdDocId) + .update({ isPb: true }); + if ( + obj.mode === "time" && + String(obj.mode2) === "60" && + userdata.discordId !== null && + userdata.discordId !== undefined + ) { + if (verified !== false) { + console.log( + `sending command to the bot to update the role for user ${request.uid} with wpm ${obj.wpm}` + ); + updateDiscordRole(userdata.discordId, Math.round(obj.wpm)); + } + } + returnobj.resultCode = 2; + } else { + let logobj = request.obj; + logobj.keySpacing = "removed"; + logobj.keyDuration = "removed"; + console.log( + `saved result for ${request.uid} - ${JSON.stringify(logobj)}` + ); + returnobj.resultCode = 1; + } + response.status(200).send({ data: returnobj }); + return; + }) + .catch((e) => { + console.error( + `error saving result when checking for PB / checking leaderboards for ${request.uid} - ${e.message}` + ); + response + .status(200) + .send({ data: { resultCode: -999, message: e.message } }); + return; + }); + }) + .catch((e) => { + console.error( + `error saving result when getting user data for ${request.uid} - ${e.message}` + ); + response + .status(200) + .send({ data: { resultCode: -999, message: e.message } }); + return; + }); + } catch (e) { + console.error( + `error saving result for ${request.uid} - ${JSON.stringify( + request.obj + )} - ${e}` + ); + response + .status(200) + .send({ data: { resultCode: -999, message: e.message } }); + return; + } +}); + +async function stripAndSave(uid, obj) { + if (obj.bailedOut === false) delete obj.bailedOut; + if (obj.blindMode === false) delete obj.blindMode; + if (obj.difficulty === "normal") delete obj.difficulty; + if (obj.funbox === "none") delete obj.funbox; + if (obj.language === "english") delete obj.language; + if (obj.numbers === false) delete obj.numbers; + if (obj.punctuation === false) delete obj.punctuation; + + return await db.collection(`users/${uid}/results`).add(obj); +} + exports.updateEmail = functions.https.onCall(async (request, response) => { try { let previousEmail = await admin.auth().getUser(request.uid); @@ -192,6 +1627,96 @@ function updateDiscordRole(discordId, wpm) { }); } +function isTagPresetNameValid(name) { + if (name === null || name === undefined || name === "") return false; + if (name.length > 16) return false; + return /^[0-9a-zA-Z_.-]+$/.test(name); +} + +exports.addTag = functions.https.onCall((request, response) => { + try { + if (!isTagPresetNameValid(request.name)) { + return { resultCode: -1 }; + } else { + return db + .collection(`users/${request.uid}/tags`) + .add({ + name: request.name, + }) + .then((e) => { + console.log(`user ${request.uid} created a tag: ${request.name}`); + return { + resultCode: 1, + id: e.id, + }; + }) + .catch((e) => { + console.error( + `error while creating tag for user ${request.uid}: ${e.message}` + ); + return { resultCode: -999, message: e.message }; + }); + } + } catch (e) { + console.error(`error adding tag for ${request.uid} - ${e}`); + return { resultCode: -999, message: e.message }; + } +}); + +exports.editTag = functions.https.onCall((request, response) => { + try { + if (!isTagPresetNameValid(request.name)) { + return { resultCode: -1 }; + } else { + return db + .collection(`users/${request.uid}/tags`) + .doc(request.tagid) + .update({ + name: request.name, + }) + .then((e) => { + console.log(`user ${request.uid} updated a tag: ${request.name}`); + return { + resultCode: 1, + }; + }) + .catch((e) => { + console.error( + `error while updating tag for user ${request.uid}: ${e.message}` + ); + return { resultCode: -999, message: e.message }; + }); + } + } catch (e) { + console.error(`error updating tag for ${request.uid} - ${e}`); + return { resultCode: -999, message: e.message }; + } +}); + +exports.removeTag = functions.https.onCall((request, response) => { + try { + return db + .collection(`users/${request.uid}/tags`) + .doc(request.tagid) + .delete() + .then((e) => { + console.log(`user ${request.uid} deleted a tag`); + return { + resultCode: 1, + }; + }) + .catch((e) => { + console.error( + `error deleting tag for user ${request.uid}: ${e.message}` + ); + return { resultCode: -999 }; + }); + } catch (e) { + console.error(`error deleting tag for ${request.uid} - ${e}`); + return { resultCode: -999 }; + } +}); + exports.updateResultTags = functions.https.onCall((request, response) => { try { let validTags = true; @@ -229,6 +1754,637 @@ exports.updateResultTags = functions.https.onCall((request, response) => { } }); +function isConfigKeyValid(name) { + if (name === null || name === undefined || name === "") return false; + if (name.length > 30) return false; + return /^[0-9a-zA-Z_.\-#+]+$/.test(name); +} + +exports.saveConfig = functions.https.onCall((request, response) => { + try { + if (request.uid === undefined || request.obj === undefined) { + console.error(`error saving config for ${request.uid} - missing input`); + return { + resultCode: -1, + message: "Missing input", + }; + } + + let obj = request.obj; + let errorMessage = ""; + let err = false; + Object.keys(obj).forEach((key) => { + if (err) return; + if (!isConfigKeyValid(key)) { + err = true; + console.error(`${key} failed regex check`); + errorMessage = `${key} failed regex check`; + } + if (err) return; + if (key === "resultFilters") return; + if (key === "customBackground") return; + if (key === "customLayoutfluid") return; + let val = obj[key]; + if (Array.isArray(val)) { + val.forEach((valarr) => { + if (!isConfigKeyValid(valarr)) { + err = true; + console.error(`${key}: ${valarr} failed regex check`); + errorMessage = `${key}: ${valarr} failed regex check`; + } + }); + } else { + if (!isConfigKeyValid(val)) { + err = true; + console.error(`${key}: ${val} failed regex check`); + errorMessage = `${key}: ${val} failed regex check`; + } + } + }); + if (err) { + console.error( + `error saving config for ${request.uid} - bad input - ${JSON.stringify( + request.obj + )}` + ); + return { + resultCode: -1, + message: "Bad input. " + errorMessage, + }; + } + + return db + .collection(`users`) + .doc(request.uid) + .set( + { + config: obj, + }, + { merge: true } + ) + .then((e) => { + return { + resultCode: 1, + message: "Saved", + }; + }) + .catch((e) => { + console.error( + `error saving config to DB for ${request.uid} - ${e.message}` + ); + return { + resultCode: -1, + message: e.message, + }; + }); + } catch (e) { + console.error(`error saving config for ${request.uid} - ${e}`); + return { + resultCode: -999, + message: e, + }; + } +}); + +exports.addPreset = functions.https.onCall(async (request, response) => { + try { + if (!isTagPresetNameValid(request.obj.name)) { + return { resultCode: -1 }; + } else if (request.uid === undefined || request.obj === undefined) { + console.error(`error saving config for ${request.uid} - missing input`); + return { + resultCode: -1, + message: "Missing input", + }; + } else { + let config = request.obj.config; + let errorMessage = ""; + let err = false; + Object.keys(config).forEach((key) => { + if (err) return; + if (!isConfigKeyValid(key)) { + err = true; + console.error(`${key} failed regex check`); + errorMessage = `${key} failed regex check`; + } + if (err) return; + if (key === "resultFilters") return; + if (key === "customBackground") return; + let val = config[key]; + if (Array.isArray(val)) { + val.forEach((valarr) => { + if (!isConfigKeyValid(valarr)) { + err = true; + console.error(`${key}: ${valarr} failed regex check`); + errorMessage = `${key}: ${valarr} failed regex check`; + } + }); + } else { + if (!isConfigKeyValid(val)) { + err = true; + console.error(`${key}: ${val} failed regex check`); + errorMessage = `${key}: ${val} failed regex check`; + } + } + }); + if (err) { + console.error( + `error adding preset for ${ + request.uid + } - bad input - ${JSON.stringify(request.obj)}` + ); + return { + resultCode: -1, + message: "Bad input. " + errorMessage, + }; + } + + let presets = await db.collection(`users/${request.uid}/presets`).get(); + if (presets.docs.length >= 10) { + return { + resultCode: -2, + message: "Preset limit", + }; + } + + return db + .collection(`users/${request.uid}/presets`) + .add(request.obj) + .then((e) => { + return { + resultCode: 1, + message: "Saved", + id: e.id, + }; + }) + .catch((e) => { + console.error( + `error adding preset to DB for ${request.uid} - ${e.message}` + ); + return { + resultCode: -1, + message: e.message, + }; + }); + } + } catch (e) { + console.error(`error adding preset for ${request.uid} - ${e}`); + return { + resultCode: -999, + message: e, + }; + } +}); + +exports.editPreset = functions.https.onCall((request, response) => { + try { + if (!isTagPresetNameValid(request.name)) { + return { resultCode: -1 }; + } else { + return db + .collection(`users/${request.uid}/presets`) + .doc(request.presetid) + .set({ + config: request.config, + name: request.name, + }) + .then((e) => { + console.log(`user ${request.uid} updated a preset: ${request.name}`); + return { + resultCode: 1, + }; + }) + .catch((e) => { + console.error( + `error while updating preset for user ${request.uid}: ${e.message}` + ); + return { resultCode: -999, message: e.message }; + }); + } + } catch (e) { + console.error(`error updating preset for ${request.uid} - ${e}`); + return { resultCode: -999, message: e.message }; + } +}); + +exports.removePreset = functions.https.onCall((request, response) => { + try { + return db + .collection(`users/${request.uid}/presets`) + .doc(request.presetid) + .delete() + .then((e) => { + console.log(`user ${request.uid} deleted a tag`); + return { + resultCode: 1, + }; + }) + .catch((e) => { + console.error( + `error deleting tag for user ${request.uid}: ${e.message}` + ); + return { resultCode: -999 }; + }); + } catch (e) { + console.error(`error deleting tag for ${request.uid} - ${e}`); + return { resultCode: -999 }; + } +}); + +// exports.saveLbMemory = functions.https.onCall((request, response) => { +// try { +// if (request.uid === undefined || request.obj === undefined) { +// console.error( +// `error saving lb memory for ${request.uid} - missing input` +// ); +// return { +// returnCode: -1, +// message: "Missing input", +// }; +// } + +// let obj = request.obj; +// return db +// .collection(`users`) +// .doc(request.uid) +// .set( +// { +// lbMemory: obj, +// }, +// { merge: true } +// ) +// .then((e) => { +// return { +// returnCode: 1, +// message: "Saved", +// }; +// }) +// .catch((e) => { +// console.error( +// `error saving lb memory to DB for ${request.uid} - ${e.message}` +// ); +// return { +// returnCode: -1, +// message: e.message, +// }; +// }); +// } catch (e) { +// console.error(`error saving lb memory for ${request.uid} - ${e}`); +// return { +// resultCode: -999, +// message: e, +// }; +// } +// }); + +function generate(n) { + var add = 1, + max = 12 - add; + + if (n > max) { + return generate(max) + generate(n - max); + } + + max = Math.pow(10, n + add); + var min = max / 10; // Math.pow(10, n) basically + var number = Math.floor(Math.random() * (max - min + 1)) + min; + + return ("" + number).substring(add); +} + +class Leaderboard { + constructor(size, mode, mode2, type, starting) { + this.size = size; + this.board = []; + this.mode = mode; + this.mode2 = parseInt(mode2); + this.type = type; + if (starting !== undefined && starting !== null) { + starting.forEach((entry) => { + if ( + entry.mode == this.mode && + parseInt(entry.mode2) === parseInt(this.mode2) + ) { + let hid = entry.hidden === undefined ? false : entry.hidden; + this.board.push({ + uid: entry.uid, + name: entry.name, + wpm: parseFloat(entry.wpm), + raw: parseFloat(entry.raw), + acc: parseFloat(entry.acc), + consistency: isNaN(parseInt(entry.consistency)) + ? "-" + : parseInt(entry.consistency), + mode: entry.mode, + mode2: parseInt(entry.mode2), + timestamp: entry.timestamp, + hidden: hid, + }); + } + }); + } + this.sortBoard(); + this.clipBoard(); + } + sortBoard() { + this.board.sort((a, b) => { + if (a.wpm === b.wpm) { + if (a.acc === b.acc) { + return a.timestamp - b.timestamp; + } else { + return b.acc - a.acc; + } + } else { + return b.wpm - a.wpm; + } + }); + } + clipBoard() { + let boardLength = this.board.length; + if (boardLength > this.size) { + while (this.board.length !== this.size) { + this.board.pop(); + } + } + } + logBoard() { + console.log(this.board); + } + getMinWpm() { + return this.board[this.board.length - 1].wpm; + } + removeDuplicates(insertedAt, uid) { + //return true if a better result is found + let found = false; + // let ret; + let foundAt = null; + if (this.board !== undefined) { + this.board.forEach((entry, index) => { + if (entry.uid === uid) { + if (found) { + this.board.splice(index, 1); + // if (index > insertedAt) { + // //removed old result + // ret = false; + // } else { + // ret = true; + // } + } else { + found = true; + foundAt = index; + } + } + }); + } + // console.log(ret); + // return ret; + return foundAt; + } + insert(a) { + let insertedAt = -1; + if (a.mode == this.mode && parseInt(a.mode2) === parseInt(this.mode2)) { + if ( + this.board.length !== this.size || + (this.board.length === this.size && a.wpm > this.getMinWpm()) + ) { + this.board.forEach((b, index) => { + if (insertedAt !== -1) return; + if (a.wpm === b.wpm) { + if (a.acc === b.acc) { + if (a.timestamp < b.timestamp) { + this.board.splice(index, 0, { + uid: a.uid, + name: a.name, + wpm: parseFloat(a.wpm), + raw: parseFloat(a.rawWpm), + acc: parseFloat(a.acc), + consistency: isNaN(parseInt(a.consistency)) + ? "-" + : parseInt(a.consistency), + mode: a.mode, + mode2: parseInt(a.mode2), + timestamp: a.timestamp, + hidden: a.hidden === undefined ? false : a.hidden, + }); + insertedAt = index; + } + } else { + if (a.acc > b.acc) { + this.board.splice(index, 0, { + uid: a.uid, + name: a.name, + wpm: parseFloat(a.wpm), + raw: parseFloat(a.rawWpm), + acc: parseFloat(a.acc), + consistency: isNaN(parseInt(a.consistency)) + ? "-" + : parseInt(a.consistency), + mode: a.mode, + mode2: parseInt(a.mode2), + timestamp: a.timestamp, + hidden: a.hidden === undefined ? false : a.hidden, + }); + insertedAt = index; + } + } + } else { + if (a.wpm > b.wpm) { + this.board.splice(index, 0, { + uid: a.uid, + name: a.name, + wpm: parseFloat(a.wpm), + raw: parseFloat(a.rawWpm), + acc: parseFloat(a.acc), + consistency: isNaN(parseInt(a.consistency)) + ? "-" + : parseInt(a.consistency), + mode: a.mode, + mode2: parseInt(a.mode2), + timestamp: a.timestamp, + hidden: a.hidden === undefined ? false : a.hidden, + }); + insertedAt = index; + } + } + }); + if (this.board.length < this.size && insertedAt === -1) { + this.board.push({ + uid: a.uid, + name: a.name, + wpm: parseFloat(a.wpm), + raw: parseFloat(a.rawWpm), + acc: parseFloat(a.acc), + consistency: isNaN(parseInt(a.consistency)) + ? "-" + : parseInt(a.consistency), + mode: a.mode, + mode2: parseInt(a.mode2), + timestamp: a.timestamp, + hidden: a.hidden === undefined ? false : a.hidden, + }); + insertedAt = this.board.length - 1; + } + // console.log("before duplicate remove"); + // console.log(this.board); + let newBest = false; + let foundAt = null; + if (insertedAt >= 0) { + // if (this.removeDuplicates(insertedAt, a.uid)) { + // insertedAt = -2; + // } + foundAt = this.removeDuplicates(insertedAt, a.uid); + + if (foundAt >= insertedAt) { + //new better result + newBest = true; + } + } + // console.log(this.board); + this.clipBoard(); + return { + insertedAt: insertedAt, + newBest: newBest, + foundAt: foundAt, + }; + } else { + return { + insertedAt: -999, + }; + } + } else { + return { + insertedAt: -999, + }; + } + } +} + +// exports.generatePairingCode = functions +// .runWith({ +// timeoutSeconds: 100, +// memory: "2GB", +// }) +// .https.onRequest((request, response) => { +// response.set("Access-Control-Allow-Origin", "*"); +// if (request.method === "OPTIONS") { +// // Send response to OPTIONS requests +// response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); +// response.set( +// "Access-Control-Allow-Headers", +// "Authorization,Content-Type" +// ); +// response.set("Access-Control-Max-Age", "3600"); +// response.status(204).send(""); +// return; +// } +// request = request.body.data; +// try { +// if (request === null) { +// console.error( +// `error while trying to generate discord pairing code - no input` +// ); +// response.status(200).send({ data: { status: -999 } }); +// return; +// } + +// return db +// .collection("users") +// .doc(request.uid) +// .get() +// .then(async (userDoc) => { +// userDocData = userDoc.data(); +// if ( +// userDocData.discordPairingCode !== undefined && +// userDocData.discordPairingCode !== null +// ) { +// console.log( +// `user ${request.uid} already has code ${userDocData.discordPairingCode}` +// ); +// response.status(200).send({ +// data: { +// status: -999, +// pairingCode: userDocData.discordPairingCode, +// }, +// }); +// } else { +// let stepSize = 1000; +// let existingCodes = []; +// let query = await db +// .collection(`users`) +// .where("discordPairingCode", ">", "") +// .limit(stepSize) +// .get(); +// let lastDoc; +// while (query.docs.length > 0) { +// lastDoc = query.docs[query.docs.length - 1]; +// query.docs.forEach((doc) => { +// let docData = doc.data(); +// if ( +// docData.discordPairingCode !== undefined && +// docData.discordPairingCode !== null +// ) { +// existingCodes.push(docData.discordPairingCode); +// } +// }); +// query = await db +// .collection(`users`) +// .where("discordPairingCode", ">", "") +// .limit(stepSize) +// .startAfter(lastDoc) +// .get(); +// } + +// let randomCode = generate(9); + +// while (existingCodes.includes(randomCode)) { +// randomCode = generate(9); +// } + +// return db +// .collection("users") +// .doc(request.uid) +// .update( +// { +// discordPairingCode: randomCode, +// }, +// { merge: true } +// ) +// .then((res) => { +// console.log(`generated ${randomCode} for user ${request.uid}`); +// response.status(200).send({ +// data: { +// status: 1, +// pairingCode: randomCode, +// }, +// }); +// return; +// }) +// .catch((e) => { +// console.error( +// `error while trying to set discord pairing code ${randomCode} for user ${request.uid} - ${e}` +// ); +// response.status(200).send({ +// data: { +// status: -999, +// }, +// }); +// return; +// }); +// } +// }); +// } catch (e) { +// console.error( +// `error while trying to generate discord pairing code for user ${request.uid} - ${e}` +// ); +// response.status(200).send({ +// data: { +// status: -999, +// }, +// }); +// return; +// } +// }); + exports.unlinkDiscord = functions.https.onRequest((request, response) => { response.set("Access-Control-Allow-Origin", origin); if (request.method === "OPTIONS") { @@ -282,6 +2438,503 @@ exports.unlinkDiscord = functions.https.onRequest((request, response) => { } }); +exports.checkLeaderboards = functions.https.onRequest( + async (request, response) => { + response.set("Access-Control-Allow-Origin", origin); + if (request.method === "OPTIONS") { + // Send response to OPTIONS requests + response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); + response.set( + "Access-Control-Allow-Headers", + "Authorization,Content-Type" + ); + response.set("Access-Control-Max-Age", "3600"); + response.status(204).send(""); + return; + } + request = request.body.data; + + function verifyValue(val) { + let errCount = 0; + if (val === null || val === undefined) { + } else if (Array.isArray(val)) { + //array + val.forEach((val2) => { + errCount += verifyValue(val2); + }); + } else if (typeof val === "object" && !Array.isArray(val)) { + //object + Object.keys(val).forEach((valkey) => { + errCount += verifyValue(val[valkey]); + }); + } else { + if (!/^[0-9a-zA-Z._\-\+]+$/.test(val)) errCount++; + } + return errCount; + } + let errCount = verifyValue(request); + if (errCount > 0) { + console.error( + `error checking leaderboard for ${ + request.uid + } error count ${errCount} - bad input - ${JSON.stringify(request.obj)}` + ); + response.status(200).send({ + data: { + status: -999, + message: "Bad input", + }, + }); + return; + } + + let emailVerified = await admin + .auth() + .getUser(request.uid) + .then((user) => { + return user.emailVerified; + }); + + try { + if (emailVerified === false) { + response.status(200).send({ + data: { + needsToVerifyEmail: true, + }, + }); + return; + } + if (request.name === undefined) { + response.status(200).send({ + data: { + noName: true, + }, + }); + return; + } + if (request.banned) { + response.status(200).send({ + data: { + banned: true, + }, + }); + return; + } + if (request.verified === false) { + response.status(200).send({ + data: { + needsToVerify: true, + }, + }); + return; + } + + request.result.name = request.name; + + if ( + request.result.mode === "time" && + ["15", "60"].includes(String(request.result.mode2)) && + request.result.language === "english" && + request.result.funbox === "none" + ) { + let global = await db + .runTransaction(async (t) => { + const lbdoc = await t.get( + db + .collection("leaderboards") + .where("mode", "==", String(request.result.mode)) + .where("mode2", "==", String(request.result.mode2)) + .where("type", "==", "global") + ); + // let lbData; + let docid = `${String(request.result.mode)}_${String( + request.result.mode2 + )}_${"global"}`; + // if (lbdoc.docs.length === 0) { + // console.log( + // `no ${request.mode} ${request.mode2} ${type} leaderboard found - creating` + // ); + // let toAdd = { + // size: 20, + // mode: String(request.mode), + // mode2: String(request.mode2), + // type: type, + // }; + // t.set( + // db + // .collection("leaderboards") + // .doc( + // `${String(request.mode)}_${String(request.mode2)}_${type}` + // ), + // toAdd + // ); + // lbData = toAdd; + // } else { + // lbData = lbdoc.docs[0].data(); + // } + let boardInfo = lbdoc.docs[0].data(); + if ( + boardInfo.minWpm === undefined || + boardInfo.board.length !== boardInfo.size || + (boardInfo.minWpm !== undefined && + request.result.wpm > boardInfo.minWpm && + boardInfo.board.length === boardInfo.size) + ) { + let boardData = boardInfo.board; + let lb = new Leaderboard( + boardInfo.size, + request.result.mode, + request.result.mode2, + boardInfo.type, + boardData + ); + let insertResult = lb.insert(request.result); + if (insertResult.insertedAt >= 0) { + t.update(db.collection("leaderboards").doc(docid), { + size: lb.size, + type: lb.type, + board: lb.board, + minWpm: lb.getMinWpm(), + }); + } + return insertResult; + } else { + //not above leaderboard minwpm + return { + insertedAt: -1, + }; + } + }) + .catch((error) => { + console.error( + `error in transaction checking leaderboards - ${error}` + ); + response.status(200).send({ + data: { + status: -999, + message: error, + }, + }); + }); + + let daily = await db + .runTransaction(async (t) => { + const lbdoc = await t.get( + db + .collection("leaderboards") + .where("mode", "==", String(request.result.mode)) + .where("mode2", "==", String(request.result.mode2)) + .where("type", "==", "daily") + ); + // let lbData; + let docid = `${String(request.result.mode)}_${String( + request.result.mode2 + )}_${"daily"}`; + // if (lbdoc.docs.length === 0) { + // console.log( + // `no ${request.mode} ${request.mode2} ${type} leaderboard found - creating` + // ); + // let toAdd = { + // size: 20, + // mode: String(request.mode), + // mode2: String(request.mode2), + // type: type, + // }; + // t.set( + // db + // .collection("leaderboards") + // .doc( + // `${String(request.mode)}_${String(request.mode2)}_${type}` + // ), + // toAdd + // ); + // lbData = toAdd; + // } else { + // lbData = lbdoc.docs[0].data(); + // } + let boardInfo = lbdoc.docs[0].data(); + if ( + boardInfo.minWpm === undefined || + boardInfo.board.length !== boardInfo.size || + (boardInfo.minWpm !== undefined && + request.result.wpm > boardInfo.minWpm && + boardInfo.board.length === boardInfo.size) + ) { + let boardData = boardInfo.board; + let lb = new Leaderboard( + boardInfo.size, + request.result.mode, + request.result.mode2, + boardInfo.type, + boardData + ); + let insertResult = lb.insert(request.result); + if (insertResult.insertedAt >= 0) { + t.update(db.collection("leaderboards").doc(docid), { + size: lb.size, + type: lb.type, + board: lb.board, + minWpm: lb.getMinWpm(), + }); + } + return insertResult; + } else { + //not above leaderboard minwpm + return { + insertedAt: -1, + }; + } + }) + .catch((error) => { + console.error( + `error in transaction checking leaderboards - ${error}` + ); + response.status(200).send({ + data: { + status: -999, + message: error, + }, + }); + }); + + //send discord update + let usr = + request.discordId != undefined ? request.discordId : request.name; + + if ( + global !== null && + global.insertedAt >= 0 && + global.insertedAt <= 9 && + global.newBest + ) { + let lbstring = `${request.result.mode} ${request.result.mode2} global`; + console.log( + `sending command to the bot to announce lb update ${usr} ${ + global.insertedAt + 1 + } ${lbstring} ${request.result.wpm}` + ); + + announceLbUpdate( + usr, + global.insertedAt + 1, + lbstring, + request.result.wpm, + request.result.rawWpm, + request.result.acc, + request.result.consistency + ); + } + + // + + if ( + // obj.mode === "time" && + // (obj.mode2 == "15" || obj.mode2 == "60") && + // obj.language === "english" + global !== null || + daily !== null + ) { + let updatedLbMemory = await getUpdatedLbMemory( + request.lbMemory, + request.result.mode, + request.result.mode2, + global, + daily + ); + db.collection("users").doc(request.uid).update({ + lbMemory: updatedLbMemory, + }); + } + + response.status(200).send({ + data: { + status: 2, + daily: daily, + global: global, + }, + }); + return; + } else { + response.status(200).send({ + data: { + status: 1, + daily: { + insertedAt: null, + }, + global: { + insertedAt: null, + }, + }, + }); + return; + } + } catch (e) { + console.log(e); + response.status(200).send({ + data: { + status: -999, + message: e, + }, + }); + return; + } + } +); + +// async function checkLeaderboards( +// resultObj, +// type, +// banned, +// name, +// verified, +// emailVerified +// ) { +// //lb disable +// // return { +// // insertedAt: null, +// // }; +// // +// try { + +// } catch (e) { +// console.error( +// `error while checking leaderboards - ${e} - ${type} ${resultObj}` +// ); +// return { +// insertedAt: null, +// }; +// } +// } + +exports.getLeaderboard = functions.https.onCall((request, response) => { + return db + .collection("leaderboards") + .where("mode", "==", String(request.mode)) + .where("mode2", "==", String(request.mode2)) + .where("type", "==", String(request.type)) + .get() + .then(async (data) => { + // console.log("got data"); + if (data.docs.length === 0) return null; + let lbdata = data.docs[0].data(); + if (lbdata.board !== undefined) { + // console.log("replacing users"); + + // for (let i = 0; i < lbdata.board.length; i++) { + // await db + // .collection("users") + // .doc(lbdata.board[i].uid) + // .get() + // .then((doc) => { + // if ( + // lbdata.board[i].uid !== null && + // lbdata.board[i].uid === request.uid + // ) { + // lbdata.board[i].currentUser = true; + // } + // lbdata.board[i].name = doc.data().name; + // lbdata.board[i].uid = null; + // }); + // } + + lbdata.board.forEach((boardentry) => { + if (boardentry.uid !== null && boardentry.uid === request.uid) { + boardentry.currentUser = true; + } + boardentry.uid = null; + }); + + // console.log(lbdata); + if (request.type === "daily") { + let resetTime = new Date(Date.now()); + resetTime.setHours(0, 0, 0, 0); + resetTime.setDate(resetTime.getUTCDate() + 1); + resetTime = resetTime.valueOf(); + lbdata.resetTime = resetTime; + } + + return lbdata; + } else { + if ( + lbdata.board === undefined || + lbdata.board === [] || + lbdata.board.length === 0 + ) { + return lbdata; + } else { + return []; + } + } + }); +}); + +exports.scheduledFunctionCrontab = functions.pubsub + .schedule("00 00 * * *") + .timeZone("Africa/Abidjan") + .onRun((context) => { + try { + console.log("moving daily leaderboards to history"); + db.collection("leaderboards") + .where("type", "==", "daily") + .get() + .then(async (res) => { + for (let i = 0; i < res.docs.length; i++) { + let doc = res.docs[i]; + + let lbdata = doc.data(); + + let winnerUid = lbdata.board[0].uid; + await db + .collection("users") + .doc(winnerUid) + .get() + .then(async (userDoc) => { + let userData = userDoc.data(); + let lbwins = userData.dailyLbWins; + + let lbname = lbdata.mode + lbdata.mode2; + + if (lbwins === undefined) { + //first win ever + lbwins = { + [lbname]: 1, + }; + } else { + //object already exists + if (lbwins[lbname] === undefined) { + lbwins[lbname] = 1; + } else { + lbwins[lbname] = lbwins[lbname] + 1; + } + } + await db.collection("users").doc(winnerUid).update({ + dailyLbWins: lbwins, + }); + }); + + announceDailyLbResult(lbdata); + t = new Date(); + // db.collection("leaderboards_history") + // .doc( + // `${t.getUTCDate()}_${t.getUTCMonth()}_${t.getUTCFullYear()}_${ + // lbdata.mode + // }_${lbdata.mode2}` + // ) + // .set(lbdata); + db.collection("leaderboards").doc(doc.id).set( + { + board: [], + }, + { merge: true } + ); + } + }); + return null; + } catch (e) { + console.error(`error while moving daily leaderboards to history - ${e}`); + } + }); + async function announceLbUpdate(discordId, pos, lb, wpm, raw, acc, con) { db.collection("bot-commands").add({ command: "sayLbUpdate", @@ -290,3 +2943,12 @@ async function announceLbUpdate(discordId, pos, lb, wpm, raw, acc, con) { requestTimestamp: Date.now(), }); } + +async function announceDailyLbResult(lbdata) { + db.collection("bot-commands").add({ + command: "announceDailyLbResult", + arguments: [lbdata], + executed: false, + requestTimestamp: Date.now(), + }); +} diff --git a/functions/non-migrated.js b/functions/non-migrated.js deleted file mode 100644 index f4750a7e4..000000000 --- a/functions/non-migrated.js +++ /dev/null @@ -1,372 +0,0 @@ -exports.requestTest = functions.https.onRequest((request, response) => { - response.set("Access-Control-Allow-Origin", origin); - response.set("Access-Control-Allow-Headers", "*"); - response.set("Access-Control-Allow-Credentials", "true"); - response.status(200).send({ data: "test" }); -}); - -exports.getPatreons = functions.https.onRequest(async (request, response) => { - response.set("Access-Control-Allow-Origin", origin); - response.set("Access-Control-Allow-Headers", "*"); - response.set("Access-Control-Allow-Credentials", "true"); - if (request.method === "OPTIONS") { - // Send response to OPTIONS requests - response.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); - response.set("Access-Control-Allow-Headers", "Authorization,Content-Type"); - response.set("Access-Control-Max-Age", "3600"); - response.status(204).send(""); - return; - } - request = request.body.data; - try { - let patreon = await db.collection("patreon").doc("patreons").get(); - let data = patreon.data().list; - - data = data.sort((a, b) => { - return b.value - a.value; - }); - - let ret = []; - data.forEach((pdoc) => { - ret.push(pdoc.name); - }); - - response.status(200).send({ data: ret }); - return; - } catch (e) { - response.status(200).send({ e }); - return; - } -}); - -exports.clearTagPb = functions.https.onCall((request, response) => { - //It looks like this button is not used anymore - try { - return db - .collection(`users/${request.uid}/tags`) - .doc(request.tagid) - .update({ - pb: 0, - }) - .then((e) => { - return { - resultCode: 1, - }; - }) - .catch((e) => { - console.error( - `error deleting tag pb for user ${request.uid}: ${e.message}` - ); - return { - resultCode: -999, - message: e.message, - }; - }); - } catch (e) { - console.error(`error deleting tag pb for ${request.uid} - ${e}`); - return { resultCode: -999 }; - } -}); - -exports.removeSmallTestsAndQPB = functions.https.onCall( - async (request, response) => { - let uid = request.uid; - - try { - let docs = await db - .collection(`users/${uid}/results`) - .where("mode", "==", "time") - .where("mode2", "<", 15) - .get(); - docs.forEach(async (doc) => { - db.collection(`users/${uid}/results`).doc(doc.id).delete(); - }); - let docs2 = await db - .collection(`users/${uid}/results`) - .where("mode", "==", "words") - .where("mode2", "<", 10) - .get(); - docs2.forEach(async (doc) => { - db.collection(`users/${uid}/results`).doc(doc.id).delete(); - }); - let docs3 = await db - .collection(`users/${uid}/results`) - .where("mode", "==", "custom") - .where("testDuration", "<", 10) - .get(); - docs3.forEach(async (doc) => { - db.collection(`users/${uid}/results`).doc(doc.id).delete(); - }); - // console.log(`removing small tests for ${uid}: ${docs.size} time, ${docs2.size} words, ${docs3.size} custom`); - let userdata = await db.collection(`users`).doc(uid).get(); - userdata = userdata.data(); - try { - pbs = userdata.personalBests; - // console.log(`removing ${Object.keys(pbs.quote).length} quote pb`); - delete pbs.quote; - await db.collection("users").doc(uid).update({ personalBests: pbs }); - } catch {} - db.collection("users") - .doc(uid) - .set({ refactored: true }, { merge: true }); - console.log("removed small tests for " + uid); - } catch (e) { - console.log(`something went wrong for ${uid}: ${e.message}`); - } - } -); - -async function getAllNames() { - // return admin - // .auth() - // .listUsers() - // .then((data) => { - // let names = []; - // data.users.forEach((user) => { - // names.push(user.name); - // }); - // return names; - // }); - - let ret = []; - - async function getAll(nextPageToken) { - // List batch of users, 1000 at a time. - let listUsersResult = await admin.auth().listUsers(1000, nextPageToken); - for (let i = 0; i < listUsersResult.users.length; i++) { - ret.push(listUsersResult.users[i].name); - } - if (listUsersResult.pageToken) { - // List next batch of users. - await getAll(listUsersResult.pageToken); - } - } - - await getAll(); - return ret; -} - -async function getAllUsers() { - // return admin - // .auth() - // .listUsers() - // .then((data) => { - // let names = []; - // data.users.forEach((user) => { - // names.push(user.name); - // }); - // return names; - // }); - - let ret = []; - - async function getAll(nextPageToken) { - // List batch of users, 1000 at a time. - let listUsersResult = await auth.listUsers(1000, nextPageToken); - for (let i = 0; i < listUsersResult.users.length; i++) { - let loopuser = listUsersResult.users[i]; - - //if custom claim is undefined check, if its true then ignore - - // if (loopuser === undefined || loopuser.customClaims === undefined || loopuser.customClaims['nameChecked'] === undefined) { - ret.push(listUsersResult.users[i]); - // } - - // console.log(loopuser.customClaims['asd']); - - // let userdata = await db.collection('users').doc(listUsersResult.users[i].uid).get(); - - // let data = userdata.data(); - - // if (data === undefined || data.needsToChangeName === undefined) { - // // console.log(data); - // ret.push(listUsersResult.users[i]); - // // console.log('user added'); - // } else { - // // console.log('user already added'); - // } - } - if (listUsersResult.pageToken) { - // List next batch of users. - await getAll(listUsersResult.pageToken); - } - } - await getAll(); - return ret; -} - -function isUsernameValid(name) { - if (name === null || name === undefined || name === "") return false; - if (/miodec/.test(name.toLowerCase())) return false; - if (/bitly/.test(name.toLowerCase())) return false; - if (name.length > 14) return false; - if (/^\..*/.test(name.toLowerCase())) return false; - return /^[0-9a-zA-Z_.-]+$/.test(name); -} - -async function incrementTestCounter(uid, userData) { - try { - if (userData.completedTests === undefined) { - let results = await db.collection(`users/${uid}/results`).get(); - let count = results.docs.length; - db.collection("users") - .doc(uid) - .update({ - completedTests: admin.firestore.FieldValue.increment(count), - }); - db.collection("public") - .doc("stats") - .update({ - completedTests: admin.firestore.FieldValue.increment(count), - }); - } else { - db.collection("users") - .doc(uid) - .update({ completedTests: admin.firestore.FieldValue.increment(1) }); - db.collection("public") - .doc("stats") - .update({ completedTests: admin.firestore.FieldValue.increment(1) }); - } - } catch (e) { - console.error( - `Error while incrementing completed tests for user ${uid}: ${e}` - ); - } -} - -async function incrementStartedTestCounter(uid, num, userData) { - try { - if (userData.startedTests === undefined) { - let stepSize = 1000; - let results = []; - let query = await db - .collection(`users/${uid}/results`) - .orderBy("timestamp", "desc") - .limit(stepSize) - .get(); - let lastDoc; - while (query.docs.length > 0) { - lastDoc = query.docs[query.docs.length - 1]; - query.docs.forEach((doc) => { - results.push({ restartCount: doc.data().restartCount }); - }); - query = await db - .collection(`users/${uid}/results`) - .orderBy("timestamp", "desc") - .limit(stepSize) - .startAfter(lastDoc) - .get(); - } - - let count = 0; - results.forEach((result) => { - try { - let rc = result.restartCount; - if (rc === undefined) { - rc = 0; - } - - count += parseInt(rc); - } catch (e) {} - }); - count += results.length; - db.collection("users") - .doc(uid) - .update({ - startedTests: admin.firestore.FieldValue.increment(count), - }); - db.collection("public") - .doc("stats") - .update({ - startedTests: admin.firestore.FieldValue.increment(count), - }); - } else { - db.collection("users") - .doc(uid) - .update({ startedTests: admin.firestore.FieldValue.increment(num) }); - db.collection("public") - .doc("stats") - .update({ startedTests: admin.firestore.FieldValue.increment(num) }); - } - } catch (e) { - console.error( - `Error while incrementing started tests for user ${uid}: ${e}` - ); - } -} - -exports.scheduledFunctionCrontab = functions.pubsub - .schedule("00 00 * * *") - .timeZone("Africa/Abidjan") - .onRun((context) => { - try { - console.log("moving daily leaderboards to history"); - db.collection("leaderboards") - .where("type", "==", "daily") - .get() - .then(async (res) => { - for (let i = 0; i < res.docs.length; i++) { - let doc = res.docs[i]; - - let lbdata = doc.data(); - - let winnerUid = lbdata.board[0].uid; - await db - .collection("users") - .doc(winnerUid) - .get() - .then(async (userDoc) => { - let userData = userDoc.data(); - let lbwins = userData.dailyLbWins; - - let lbname = lbdata.mode + lbdata.mode2; - - if (lbwins === undefined) { - //first win ever - lbwins = { - [lbname]: 1, - }; - } else { - //object already exists - if (lbwins[lbname] === undefined) { - lbwins[lbname] = 1; - } else { - lbwins[lbname] = lbwins[lbname] + 1; - } - } - await db.collection("users").doc(winnerUid).update({ - dailyLbWins: lbwins, - }); - }); - - announceDailyLbResult(lbdata); - t = new Date(); - // db.collection("leaderboards_history") - // .doc( - // `${t.getUTCDate()}_${t.getUTCMonth()}_${t.getUTCFullYear()}_${ - // lbdata.mode - // }_${lbdata.mode2}` - // ) - // .set(lbdata); - db.collection("leaderboards").doc(doc.id).set( - { - board: [], - }, - { merge: true } - ); - } - }); - return null; - } catch (e) { - console.error(`error while moving daily leaderboards to history - ${e}`); - } - }); - -async function announceDailyLbResult(lbdata) { - db.collection("bot-commands").add({ - command: "announceDailyLbResult", - arguments: [lbdata], - executed: false, - requestTimestamp: Date.now(), - }); -} diff --git a/functions/package-lock.json b/functions/package-lock.json index 4381a499b..1630d02bd 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -44,58 +44,62 @@ "js-tokens": "^4.0.0" } }, + "node_modules/@firebase/app-types": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.2.tgz", + "integrity": "sha512-2VXvq/K+n8XMdM4L2xy5bYp2ZXMawJXluUIDzUBvMthVR+lhxK4pfFiqr1mmDbv9ydXvEAuFsD+6DpcZuJcSSw==" + }, "node_modules/@firebase/auth-interop-types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz", - "integrity": "sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==" + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } }, "node_modules/@firebase/component": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.21.tgz", - "integrity": "sha512-kd5sVmCLB95EK81Pj+yDTea8pzN2qo/1yr0ua9yVi6UgMzm6zAeih73iVUkaat96MAHy26yosMufkvd3zC4IKg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.0.tgz", + "integrity": "sha512-v18csWtXb0ri+3m7wuGLY/UDgcb89vuMlZGQ//+7jEPLIQeLbylvZhol1uzW9WzoOpxMxOS2W5qyVGX36wZvEA==", "dependencies": { - "@firebase/util": "0.3.4", - "tslib": "^1.11.1" + "@firebase/util": "1.1.0", + "tslib": "^2.1.0" } }, "node_modules/@firebase/database": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.8.3.tgz", - "integrity": "sha512-i29rr3kcPltIkA8La9M1lgsSxx9bfu5lCQ0T+tbJptZ3UpqpcL1NzCcZa24cJjiLgq3HQNPyLvUvCtcPSFDlRg==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.1.tgz", + "integrity": "sha512-umT0kynJKc5VpVBOg3+YTDzdJORssh+QqPjoHfbSvtmgZizNiV8mgmKRcDhlVM6CisPb6v5xBn9l8JbK/WRQ1Q==", "dependencies": { - "@firebase/auth-interop-types": "0.1.5", - "@firebase/component": "0.1.21", - "@firebase/database-types": "0.6.1", + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.0", + "@firebase/database-types": "0.7.2", "@firebase/logger": "0.2.6", - "@firebase/util": "0.3.4", + "@firebase/util": "1.1.0", "faye-websocket": "0.11.3", - "tslib": "^1.11.1" + "tslib": "^2.1.0" } }, "node_modules/@firebase/database-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.6.1.tgz", - "integrity": "sha512-JtL3FUbWG+bM59iYuphfx9WOu2Mzf0OZNaqWiQ7lJR8wBe7bS9rIm9jlBFtksB7xcya1lZSQPA/GAy2jIlMIkA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.2.tgz", + "integrity": "sha512-cdAd/dgwvC0r3oLEDUR+ULs1vBsEvy0b27nlzKhU6LQgm9fCDzgaH9nFGv8x+S9dly4B0egAXkONkVoWcOAisg==", "dependencies": { - "@firebase/app-types": "0.6.1" + "@firebase/app-types": "0.6.2" } }, - "node_modules/@firebase/database-types/node_modules/@firebase/app-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz", - "integrity": "sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==" - }, "node_modules/@firebase/logger": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" }, "node_modules/@firebase/util": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.3.4.tgz", - "integrity": "sha512-VwjJUE2Vgr2UMfH63ZtIX9Hd7x+6gayi6RUXaTqEYxSbf/JmehLmAEYSuxS/NckfzAXWeGnKclvnXVibDgpjQQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.1.0.tgz", + "integrity": "sha512-lfuSASuPKNdfebuFR8rjFamMQUPH9iiZHcKS755Rkm/5gRT0qC7BMhCh3ZkHf7NVbplzIc/GhmX2jM+igDRCag==", "dependencies": { - "tslib": "^1.11.1" + "tslib": "^2.1.0" } }, "node_modules/@google-cloud/common": { @@ -119,14 +123,14 @@ } }, "node_modules/@google-cloud/firestore": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.11.0.tgz", - "integrity": "sha512-Do9WJzEkFBBB+zVFvFfrrrIFEz086lrdgKQic7XsdoTgtYtq0yMu2u3kGLyxMbdasl2c2yf49FE4YvO3AYjQMQ==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.11.1.tgz", + "integrity": "sha512-iNsCGYwKBxYZS+TpkUAJLGkGko2QtWaf11JDNx6kvqOVN0359qSnZlF1SWFTvm26ZsKyX6uR4oAiFmmjfXTlCg==", "optional": true, "dependencies": { "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", - "google-gax": "^2.9.2", + "google-gax": "^2.12.0", "protobufjs": "^6.8.6" }, "engines": { @@ -197,9 +201,9 @@ } }, "node_modules/@grpc/grpc-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.0.tgz", - "integrity": "sha512-fiL7ZaGg2HBiFtmv6m34d5jEgEtNXfctjzB3f7b3iuT7olBX4mHLMOqOBmGTTSOTfNRQJH5+vsyk6mEz3I0Q7Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.1.tgz", + "integrity": "sha512-zyFq9eW0U4vGyhJS/oeW3mIeKTzB13we9rBclcisfRHxGQbC9FCOKQ5BBA2129yZwRVMt4hQia1igGzECeuY9g==", "optional": true, "dependencies": { "@types/node": ">=12.12.47" @@ -208,16 +212,10 @@ "node": "^8.13.0 || >=10.10.0" } }, - "node_modules/@grpc/grpc-js/node_modules/@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", - "optional": true - }, "node_modules/@grpc/proto-loader": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.1.tgz", - "integrity": "sha512-4DIvEOZhw5nGj3RQngIoiMXRsre3InEH136krZTcirs/G2em3WMXdtx4Lqlnb4E2ertbWGs5gPeVDKU5BHffXw==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", + "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", "optional": true, "dependencies": { "@types/long": "^4.0.1", @@ -233,6 +231,14 @@ "node": ">=6" } }, + "node_modules/@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -333,6 +339,15 @@ "@types/serve-static": "*" } }, + "node_modules/@types/express-jwt": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", + "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", + "dependencies": { + "@types/express": "*", + "@types/express-unless": "*" + } + }, "node_modules/@types/express-serve-static-core": { "version": "4.17.19", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", @@ -343,10 +358,18 @@ "@types/range-parser": "*" } }, + "node_modules/@types/express-unless": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", + "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/lodash": { - "version": "4.14.168", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", - "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", + "version": "4.14.169", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz", + "integrity": "sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw==", "dev": true }, "node_modules/@types/long": { @@ -366,9 +389,9 @@ "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" }, "node_modules/@types/node": { - "version": "10.17.59", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.59.tgz", - "integrity": "sha512-7Uc8IRrL8yZz5ti45RaFxpbU8TxlzdC3HvxV+hOWo1EyLsuKv/w7y0n+TwZzwL3vdx3oZ2k3ubxPq131hNtXyg==" + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz", + "integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ==" }, "node_modules/@types/qs": { "version": "6.9.6", @@ -429,7 +452,10 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, "node_modules/agent-base": { "version": "6.0.2", @@ -453,6 +479,10 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-escapes": { @@ -550,6 +580,20 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "optional": true }, "node_modules/bignumber.js": { @@ -846,12 +890,16 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "devOptional": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/deep-is": { @@ -1198,6 +1246,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/execa/node_modules/cross-spawn": { @@ -1222,6 +1273,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/execa/node_modules/path-key": { @@ -1440,15 +1494,16 @@ } }, "node_modules/firebase-admin": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.7.0.tgz", - "integrity": "sha512-dvxy4lK2P2BikE9lB2hj4dUXGm9tuoGRVtobXzCpk7uhi0/FuTOU1yp4IW7vlMI20fxTdm6FmCXdwUlMeSljBA==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.8.0.tgz", + "integrity": "sha512-v8B1qU8McZZT2hlLZ018TKz2FoKlfFkZq9mOIyzN7wJUOlAywqQX0JyqNpVGyPeU+B+77ojlvmkGTNXt2OFkgw==", "dependencies": { - "@firebase/database": "^0.8.1", - "@firebase/database-types": "^0.6.1", - "@types/node": "^10.10.0", + "@firebase/database": "^0.10.0", + "@firebase/database-types": "^0.7.2", + "@types/node": ">=12.12.47", "dicer": "^0.3.0", "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", "node-forge": "^0.10.0" }, "engines": { @@ -1460,9 +1515,9 @@ } }, "node_modules/firebase-functions": { - "version": "3.13.2", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.13.2.tgz", - "integrity": "sha512-XHgAQZqA62awr4l9mNlJv6qnv5MkMkLuo+hafdW0T7IJj1PgrZtuIo5x+ib2npAcB0XhX5Sg0QR1hMYPAlfbaA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.14.0.tgz", + "integrity": "sha512-8f/UNxxbMBoNJkakGRmEoV+3i6LUVEOuiJdsMZR0L9x9NQ3rV0xCpUMPCA01HB+Mcx/NqAJCzE6n4gxg2uzcxg==", "dependencies": { "@types/express": "4.17.3", "cors": "^2.8.5", @@ -1471,6 +1526,9 @@ }, "engines": { "node": "^8.13.0 || >=10.10.0" + }, + "peerDependencies": { + "firebase-admin": "^8.0.0 || ^9.0.0" } }, "node_modules/firebase-functions-test": { @@ -1484,6 +1542,10 @@ }, "engines": { "node": ">=8.0.0" + }, + "peerDependencies": { + "firebase-admin": ">=6.0.0", + "firebase-functions": ">=2.0.0" } }, "node_modules/flat-cache": { @@ -1600,6 +1662,9 @@ "optional": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/glob": { @@ -1617,6 +1682,9 @@ }, "engines": { "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/globals": { @@ -1649,9 +1717,9 @@ } }, "node_modules/google-gax": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.12.0.tgz", - "integrity": "sha512-UDx4ZZx85vXBe6GZ0sdRSzuegLrRQdRjCxlauX+U7i5YwOoSgcSaIM71BhcdHwGPhEkvO/SSHrEfc1wpL/J6JA==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.13.0.tgz", + "integrity": "sha512-aKNJy2+Vv2I7flyNYbwpq0aYBHp6Qv32HZn+wr6ZhZ8xlSCLS9K9k7izfh2nd1rCJQcsqB6KMxHV0Vwny6Rc1g==", "optional": true, "dependencies": { "@grpc/grpc-js": "~1.3.0", @@ -1815,6 +1883,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { @@ -1938,6 +2009,20 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "node_modules/jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "dependencies": { + "@panva/asn1.js": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0 < 13 || >=13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2029,6 +2114,21 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/jwks-rsa": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.3.tgz", + "integrity": "sha512-/rkjXRWAp0cS00tunsHResw68P5iTQru8+jHufLNv3JHc4nObFEndfEUSuPugh09N+V9XYxKUqi7QrkmCHSSSg==", + "dependencies": { + "@types/express-jwt": "0.0.42", + "debug": "^4.1.0", + "jose": "^2.0.5", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.2" + }, + "engines": { + "node": ">=10 < 13 || >=14" + } + }, "node_modules/jws": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", @@ -2052,6 +2152,11 @@ "node": ">= 0.8.0" } }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2074,6 +2179,11 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "optional": true }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -2127,6 +2237,29 @@ "node": ">=10" } }, + "node_modules/lru-memoizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -2137,6 +2270,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { @@ -2377,6 +2513,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -2415,6 +2554,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -2437,6 +2579,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -2513,6 +2658,18 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/pretty-quick": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.0.tgz", @@ -2530,6 +2687,9 @@ }, "engines": { "node": ">=10.13" + }, + "peerDependencies": { + "prettier": ">=2.0.0" } }, "node_modules/pretty-quick/node_modules/ansi-styles": { @@ -2541,6 +2701,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/pretty-quick/node_modules/chalk": { @@ -2633,12 +2796,6 @@ "pbts": "bin/pbts" } }, - "node_modules/protobufjs/node_modules/@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", - "optional": true - }, "node_modules/proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -2651,6 +2808,11 @@ "node": ">= 0.10" } }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2839,6 +3001,12 @@ "npm": ">=2.0.0" } }, + "node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3024,6 +3192,20 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "optional": true }, "node_modules/string-width": { @@ -3191,9 +3373,9 @@ } }, "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" }, "node_modules/type-check": { "version": "0.3.2", @@ -3342,6 +3524,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { @@ -3363,6 +3548,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { @@ -3549,6 +3737,9 @@ "optional": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } }, @@ -3579,47 +3770,46 @@ "js-tokens": "^4.0.0" } }, + "@firebase/app-types": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.2.tgz", + "integrity": "sha512-2VXvq/K+n8XMdM4L2xy5bYp2ZXMawJXluUIDzUBvMthVR+lhxK4pfFiqr1mmDbv9ydXvEAuFsD+6DpcZuJcSSw==" + }, "@firebase/auth-interop-types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz", - "integrity": "sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==" + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "requires": {} }, "@firebase/component": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.21.tgz", - "integrity": "sha512-kd5sVmCLB95EK81Pj+yDTea8pzN2qo/1yr0ua9yVi6UgMzm6zAeih73iVUkaat96MAHy26yosMufkvd3zC4IKg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.0.tgz", + "integrity": "sha512-v18csWtXb0ri+3m7wuGLY/UDgcb89vuMlZGQ//+7jEPLIQeLbylvZhol1uzW9WzoOpxMxOS2W5qyVGX36wZvEA==", "requires": { - "@firebase/util": "0.3.4", - "tslib": "^1.11.1" + "@firebase/util": "1.1.0", + "tslib": "^2.1.0" } }, "@firebase/database": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.8.3.tgz", - "integrity": "sha512-i29rr3kcPltIkA8La9M1lgsSxx9bfu5lCQ0T+tbJptZ3UpqpcL1NzCcZa24cJjiLgq3HQNPyLvUvCtcPSFDlRg==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.1.tgz", + "integrity": "sha512-umT0kynJKc5VpVBOg3+YTDzdJORssh+QqPjoHfbSvtmgZizNiV8mgmKRcDhlVM6CisPb6v5xBn9l8JbK/WRQ1Q==", "requires": { - "@firebase/auth-interop-types": "0.1.5", - "@firebase/component": "0.1.21", - "@firebase/database-types": "0.6.1", + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.0", + "@firebase/database-types": "0.7.2", "@firebase/logger": "0.2.6", - "@firebase/util": "0.3.4", + "@firebase/util": "1.1.0", "faye-websocket": "0.11.3", - "tslib": "^1.11.1" + "tslib": "^2.1.0" } }, "@firebase/database-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.6.1.tgz", - "integrity": "sha512-JtL3FUbWG+bM59iYuphfx9WOu2Mzf0OZNaqWiQ7lJR8wBe7bS9rIm9jlBFtksB7xcya1lZSQPA/GAy2jIlMIkA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.2.tgz", + "integrity": "sha512-cdAd/dgwvC0r3oLEDUR+ULs1vBsEvy0b27nlzKhU6LQgm9fCDzgaH9nFGv8x+S9dly4B0egAXkONkVoWcOAisg==", "requires": { - "@firebase/app-types": "0.6.1" - }, - "dependencies": { - "@firebase/app-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz", - "integrity": "sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==" - } + "@firebase/app-types": "0.6.2" } }, "@firebase/logger": { @@ -3628,11 +3818,11 @@ "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" }, "@firebase/util": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.3.4.tgz", - "integrity": "sha512-VwjJUE2Vgr2UMfH63ZtIX9Hd7x+6gayi6RUXaTqEYxSbf/JmehLmAEYSuxS/NckfzAXWeGnKclvnXVibDgpjQQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.1.0.tgz", + "integrity": "sha512-lfuSASuPKNdfebuFR8rjFamMQUPH9iiZHcKS755Rkm/5gRT0qC7BMhCh3ZkHf7NVbplzIc/GhmX2jM+igDRCag==", "requires": { - "tslib": "^1.11.1" + "tslib": "^2.1.0" } }, "@google-cloud/common": { @@ -3653,14 +3843,14 @@ } }, "@google-cloud/firestore": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.11.0.tgz", - "integrity": "sha512-Do9WJzEkFBBB+zVFvFfrrrIFEz086lrdgKQic7XsdoTgtYtq0yMu2u3kGLyxMbdasl2c2yf49FE4YvO3AYjQMQ==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.11.1.tgz", + "integrity": "sha512-iNsCGYwKBxYZS+TpkUAJLGkGko2QtWaf11JDNx6kvqOVN0359qSnZlF1SWFTvm26ZsKyX6uR4oAiFmmjfXTlCg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", - "google-gax": "^2.9.2", + "google-gax": "^2.12.0", "protobufjs": "^6.8.6" } }, @@ -3716,26 +3906,18 @@ } }, "@grpc/grpc-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.0.tgz", - "integrity": "sha512-fiL7ZaGg2HBiFtmv6m34d5jEgEtNXfctjzB3f7b3iuT7olBX4mHLMOqOBmGTTSOTfNRQJH5+vsyk6mEz3I0Q7Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.1.tgz", + "integrity": "sha512-zyFq9eW0U4vGyhJS/oeW3mIeKTzB13we9rBclcisfRHxGQbC9FCOKQ5BBA2129yZwRVMt4hQia1igGzECeuY9g==", "optional": true, "requires": { "@types/node": ">=12.12.47" - }, - "dependencies": { - "@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", - "optional": true - } } }, "@grpc/proto-loader": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.1.tgz", - "integrity": "sha512-4DIvEOZhw5nGj3RQngIoiMXRsre3InEH136krZTcirs/G2em3WMXdtx4Lqlnb4E2ertbWGs5gPeVDKU5BHffXw==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", + "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", "optional": true, "requires": { "@types/long": "^4.0.1", @@ -3745,6 +3927,11 @@ "yargs": "^16.1.1" } }, + "@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -3842,6 +4029,15 @@ "@types/serve-static": "*" } }, + "@types/express-jwt": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", + "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", + "requires": { + "@types/express": "*", + "@types/express-unless": "*" + } + }, "@types/express-serve-static-core": { "version": "4.17.19", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", @@ -3852,10 +4048,18 @@ "@types/range-parser": "*" } }, + "@types/express-unless": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", + "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", + "requires": { + "@types/express": "*" + } + }, "@types/lodash": { - "version": "4.14.168", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", - "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", + "version": "4.14.169", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz", + "integrity": "sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw==", "dev": true }, "@types/long": { @@ -3875,9 +4079,9 @@ "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" }, "@types/node": { - "version": "10.17.59", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.59.tgz", - "integrity": "sha512-7Uc8IRrL8yZz5ti45RaFxpbU8TxlzdC3HvxV+hOWo1EyLsuKv/w7y0n+TwZzwL3vdx3oZ2k3ubxPq131hNtXyg==" + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz", + "integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ==" }, "@types/qs": { "version": "6.9.6", @@ -3926,7 +4130,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "requires": {} }, "agent-base": { "version": "6.0.2", @@ -4269,7 +4474,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "devOptional": true, "requires": { "ms": "2.1.2" } @@ -4752,24 +4956,25 @@ } }, "firebase-admin": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.7.0.tgz", - "integrity": "sha512-dvxy4lK2P2BikE9lB2hj4dUXGm9tuoGRVtobXzCpk7uhi0/FuTOU1yp4IW7vlMI20fxTdm6FmCXdwUlMeSljBA==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.8.0.tgz", + "integrity": "sha512-v8B1qU8McZZT2hlLZ018TKz2FoKlfFkZq9mOIyzN7wJUOlAywqQX0JyqNpVGyPeU+B+77ojlvmkGTNXt2OFkgw==", "requires": { - "@firebase/database": "^0.8.1", - "@firebase/database-types": "^0.6.1", + "@firebase/database": "^0.10.0", + "@firebase/database-types": "^0.7.2", "@google-cloud/firestore": "^4.5.0", "@google-cloud/storage": "^5.3.0", - "@types/node": "^10.10.0", + "@types/node": ">=12.12.47", "dicer": "^0.3.0", "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", "node-forge": "^0.10.0" } }, "firebase-functions": { - "version": "3.13.2", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.13.2.tgz", - "integrity": "sha512-XHgAQZqA62awr4l9mNlJv6qnv5MkMkLuo+hafdW0T7IJj1PgrZtuIo5x+ib2npAcB0XhX5Sg0QR1hMYPAlfbaA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.14.0.tgz", + "integrity": "sha512-8f/UNxxbMBoNJkakGRmEoV+3i6LUVEOuiJdsMZR0L9x9NQ3rV0xCpUMPCA01HB+Mcx/NqAJCzE6n4gxg2uzcxg==", "requires": { "@types/express": "4.17.3", "cors": "^2.8.5", @@ -4914,9 +5119,9 @@ } }, "google-gax": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.12.0.tgz", - "integrity": "sha512-UDx4ZZx85vXBe6GZ0sdRSzuegLrRQdRjCxlauX+U7i5YwOoSgcSaIM71BhcdHwGPhEkvO/SSHrEfc1wpL/J6JA==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.13.0.tgz", + "integrity": "sha512-aKNJy2+Vv2I7flyNYbwpq0aYBHp6Qv32HZn+wr6ZhZ8xlSCLS9K9k7izfh2nd1rCJQcsqB6KMxHV0Vwny6Rc1g==", "optional": true, "requires": { "@grpc/grpc-js": "~1.3.0", @@ -5144,6 +5349,14 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "requires": { + "@panva/asn1.js": "^1.0.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5230,6 +5443,18 @@ "safe-buffer": "^5.0.1" } }, + "jwks-rsa": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.3.tgz", + "integrity": "sha512-/rkjXRWAp0cS00tunsHResw68P5iTQru8+jHufLNv3JHc4nObFEndfEUSuPugh09N+V9XYxKUqi7QrkmCHSSSg==", + "requires": { + "@types/express-jwt": "0.0.42", + "debug": "^4.1.0", + "jose": "^2.0.5", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.2" + } + }, "jws": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", @@ -5250,6 +5475,11 @@ "type-check": "~0.3.2" } }, + "limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -5269,6 +5499,11 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "optional": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -5319,6 +5554,31 @@ "yallist": "^4.0.0" } }, + "lru-memoizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -5609,6 +5869,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.0.tgz", + "integrity": "sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==", + "peer": true + }, "pretty-quick": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.0.tgz", @@ -5697,14 +5963,6 @@ "@types/long": "^4.0.1", "@types/node": ">=13.7.0", "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", - "optional": true - } } }, "proxy-addr": { @@ -5716,6 +5974,11 @@ "ipaddr.js": "1.9.1" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -5856,6 +6119,14 @@ "dev": true, "requires": { "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } } }, "safe-buffer": { @@ -6152,9 +6423,9 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" }, "type-check": { "version": "0.3.2", diff --git a/gulpfile.js b/gulpfile.js index 826baa131..8c27b9a08 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,6 +1,6 @@ const { task, src, dest, series, watch } = require("gulp"); -const browserify = require("browserify"); const axios = require("axios"); +const browserify = require("browserify"); const babelify = require("babelify"); const concat = require("gulp-concat"); const del = require("del"); @@ -13,7 +13,14 @@ sass.compiler = require("dart-sass"); let eslintConfig = { parser: "babel-eslint", - globals: ["jQuery", "$", "moment", "html2canvas", "ClipboardItem"], + globals: [ + "jQuery", + "$", + "firebase", + "moment", + "html2canvas", + "ClipboardItem", + ], envs: ["es6", "browser", "node"], rules: { "constructor-super": "error", diff --git a/package-lock.json b/package-lock.json index a507af3de..d08efef6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,16 +12,15 @@ "dependencies": { "@babel/runtime": "^7.12.5", "axios": "^0.21.1", - "bcrypt": "^5.0.1", "chart.js": "^2.9.4", "chartjs-plugin-annotation": "^0.5.7", "chartjs-plugin-trendline": "^0.2.2", - "dotenv": "^9.0.2", + "cors": "^2.8.5", "express": "^4.17.1", + "firebase-admin": "^9.9.0", "howler": "^2.2.1", - "jsonwebtoken": "^8.5.1", - "mongoose": "^5.12.8", - "nodemailer": "^6.6.1", + "mongoose": "^5.12.12", + "nodemon": "^2.0.7", "tinycolor2": "^1.4.2" }, "devDependencies": { @@ -40,7 +39,6 @@ "gulp-eslint": "^6.0.0", "gulp-sass": "^4.1.0", "husky": "^4.3.0", - "nodemon": "^2.0.7", "prettier": "2.1.2", "pretty-quick": "^3.1.0", "vinyl-buffer": "^1.0.1", @@ -67,20 +65,20 @@ "dev": true }, "node_modules/@babel/core": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", - "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.2.tgz", + "integrity": "sha512-OgC1mON+l4U4B4wiohJlQNUU3H73mpTyYY3j/c8U9dr9UagGGSm+WFpzjy/YLdoyjiG++c1kIDgxCo/mLwQJeQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", + "@babel/generator": "^7.14.2", "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-module-transforms": "^7.14.2", "@babel/helpers": "^7.14.0", - "@babel/parser": "^7.14.0", + "@babel/parser": "^7.14.2", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -97,12 +95,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.2.tgz", + "integrity": "sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ==", "dev": true, "dependencies": { - "@babel/types": "^7.14.1", + "@babel/types": "^7.14.2", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -142,13 +140,13 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz", - "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.2.tgz", + "integrity": "sha512-6YctwVsmlkchxfGUogvVrrhzyD3grFJyluj5JgDlQrwfMLJSt5tdAzFZfPf4H2Xoi5YLcQ6BxfJlaOBHuctyIw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", + "@babel/helper-function-name": "^7.14.2", "@babel/helper-member-expression-to-functions": "^7.13.12", "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-replace-supers": "^7.13.12", @@ -200,14 +198,14 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", "dev": true, "dependencies": { "@babel/helper-get-function-arity": "^7.12.13", "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.2" } }, "node_modules/@babel/helper-get-function-arity": { @@ -248,9 +246,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", - "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz", + "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.13.12", @@ -259,8 +257,8 @@ "@babel/helper-split-export-declaration": "^7.12.13", "@babel/helper-validator-identifier": "^7.14.0", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0" + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.2" } }, "node_modules/@babel/helper-optimise-call-expression": { @@ -375,9 +373,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.2.tgz", + "integrity": "sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -401,9 +399,9 @@ } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", - "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz", + "integrity": "sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -441,9 +439,9 @@ } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", - "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz", + "integrity": "sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -454,12 +452,12 @@ } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", - "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz", + "integrity": "sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "peerDependencies": { @@ -467,9 +465,9 @@ } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", - "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz", + "integrity": "sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -480,9 +478,9 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", - "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz", + "integrity": "sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -493,9 +491,9 @@ } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", - "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz", + "integrity": "sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -506,12 +504,12 @@ } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", - "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz", + "integrity": "sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "peerDependencies": { @@ -519,25 +517,25 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", - "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.2.tgz", + "integrity": "sha512-hBIQFxwZi8GIp934+nj5uV31mqclC1aYDhctDu5khTi9PCCUOczyy0b34W0oE9U/eJXiqQaKyVsmjeagOaSlbw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", + "@babel/compat-data": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" + "@babel/plugin-transform-parameters": "^7.14.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", - "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz", + "integrity": "sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -548,9 +546,9 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", - "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz", + "integrity": "sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0", @@ -812,9 +810,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz", - "integrity": "sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.2.tgz", + "integrity": "sha512-neZZcP19NugZZqNwMTH+KoBjx5WyvESPSIOQb4JHpfd+zPfqcH65RMu5xJju5+6q/Y2VzYrleQTr+b6METyyxg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" @@ -824,16 +822,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", - "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.2.tgz", + "integrity": "sha512-7oafAVcucHquA/VZCsXv/gmuiHeYd64UJyyTYU+MPfNu0KeNlxw06IeENBO8bJjXVbolu+j1MM5aKQtH1OMCNg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", + "@babel/helper-function-name": "^7.14.2", "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.12", "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" }, @@ -953,12 +951,12 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz", - "integrity": "sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz", + "integrity": "sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-module-transforms": "^7.14.2", "@babel/helper-plugin-utils": "^7.13.0", "babel-plugin-dynamic-import-node": "^2.3.3" }, @@ -1048,9 +1046,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", - "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz", + "integrity": "sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.13.0" @@ -1096,9 +1094,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz", - "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.2.tgz", + "integrity": "sha512-LyA2AiPkaYzI7G5e2YI4NCasTfFe7mZvlupNprDOB7CdNUHb2DQC4uV6oeZ0396gOcicUzUCh0MShL6wiUgk+Q==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.13.12", @@ -1199,9 +1197,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.1.tgz", - "integrity": "sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.2.tgz", + "integrity": "sha512-7dD7lVT8GMrE73v4lvDEb85cgcQhdES91BSD7jS/xjC6QY8PnRhux35ac+GCpbiRhp8crexBvZZqnaL6VrY8TQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.14.0", @@ -1209,18 +1207,18 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-validator-option": "^7.12.17", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", + "@babel/plugin-proposal-async-generator-functions": "^7.14.2", "@babel/plugin-proposal-class-properties": "^7.13.0", "@babel/plugin-proposal-class-static-block": "^7.13.11", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-dynamic-import": "^7.14.2", + "@babel/plugin-proposal-export-namespace-from": "^7.14.2", + "@babel/plugin-proposal-json-strings": "^7.14.2", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.2", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2", + "@babel/plugin-proposal-numeric-separator": "^7.14.2", + "@babel/plugin-proposal-object-rest-spread": "^7.14.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.2", + "@babel/plugin-proposal-optional-chaining": "^7.14.2", "@babel/plugin-proposal-private-methods": "^7.13.0", "@babel/plugin-proposal-private-property-in-object": "^7.14.0", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", @@ -1241,8 +1239,8 @@ "@babel/plugin-transform-arrow-functions": "^7.13.0", "@babel/plugin-transform-async-to-generator": "^7.13.0", "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.14.1", - "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-block-scoping": "^7.14.2", + "@babel/plugin-transform-classes": "^7.14.2", "@babel/plugin-transform-computed-properties": "^7.13.0", "@babel/plugin-transform-destructuring": "^7.13.17", "@babel/plugin-transform-dotall-regex": "^7.12.13", @@ -1252,14 +1250,14 @@ "@babel/plugin-transform-function-name": "^7.12.13", "@babel/plugin-transform-literals": "^7.12.13", "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.14.0", + "@babel/plugin-transform-modules-amd": "^7.14.2", "@babel/plugin-transform-modules-commonjs": "^7.14.0", "@babel/plugin-transform-modules-systemjs": "^7.13.8", "@babel/plugin-transform-modules-umd": "^7.14.0", "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", "@babel/plugin-transform-new-target": "^7.12.13", "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-parameters": "^7.14.2", "@babel/plugin-transform-property-literals": "^7.12.13", "@babel/plugin-transform-regenerator": "^7.13.15", "@babel/plugin-transform-reserved-words": "^7.12.13", @@ -1271,7 +1269,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.12.13", "@babel/plugin-transform-unicode-regex": "^7.12.13", "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.14.1", + "@babel/types": "^7.14.2", "babel-plugin-polyfill-corejs2": "^0.2.0", "babel-plugin-polyfill-corejs3": "^0.2.0", "babel-plugin-polyfill-regenerator": "^0.2.0", @@ -1318,121 +1316,432 @@ } }, "node_modules/@babel/traverse": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", - "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", - "@babel/helper-function-name": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.0", - "@babel/types": "^7.14.0", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", "debug": "^4.1.0", "globals": "^11.1.0" } }, "node_modules/@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", - "dependencies": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.1", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.4", - "tar": "^6.1.0" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" + "node_modules/@firebase/app-types": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.2.tgz", + "integrity": "sha512-2VXvq/K+n8XMdM4L2xy5bYp2ZXMawJXluUIDzUBvMthVR+lhxK4pfFiqr1mmDbv9ydXvEAuFsD+6DpcZuJcSSw==" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/@firebase/component": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.0.tgz", + "integrity": "sha512-v18csWtXb0ri+3m7wuGLY/UDgcb89vuMlZGQ//+7jEPLIQeLbylvZhol1uzW9WzoOpxMxOS2W5qyVGX36wZvEA==", "dependencies": { - "yallist": "^4.0.0" + "@firebase/util": "1.1.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/component/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + }, + "node_modules/@firebase/database": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.2.tgz", + "integrity": "sha512-jMGtl5eBES9k0rOIZd6/EAuVB6m3LzRei1lvEiqWWBje2Xoz//7sjZcxOYtAKCCLldEI1EUrzW8Tv5yEAoPPpg==", + "dependencies": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.0", + "@firebase/database-types": "0.7.2", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.1.0", + "faye-websocket": "0.11.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.2.tgz", + "integrity": "sha512-cdAd/dgwvC0r3oLEDUR+ULs1vBsEvy0b27nlzKhU6LQgm9fCDzgaH9nFGv8x+S9dly4B0egAXkONkVoWcOAisg==", + "dependencies": { + "@firebase/app-types": "0.6.2" + } + }, + "node_modules/@firebase/database/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + }, + "node_modules/@firebase/logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", + "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" + }, + "node_modules/@firebase/util": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.1.0.tgz", + "integrity": "sha512-lfuSASuPKNdfebuFR8rjFamMQUPH9iiZHcKS755Rkm/5gRT0qC7BMhCh3ZkHf7NVbplzIc/GhmX2jM+igDRCag==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/util/node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + }, + "node_modules/@google-cloud/common": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", + "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", + "optional": true, + "dependencies": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^7.0.2", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" }, "engines": { "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" + "node_modules/@google-cloud/common/node_modules/duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/@google-cloud/common/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.12.2.tgz", + "integrity": "sha512-5rurTAJXQ0SANEf8K9eA2JAB5zAh+pu4tGRnkZx5gBWQLZXdBFdtepS+irvKuSXw1KbeAQOuRANSc/nguys6SQ==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^2.12.0", + "protobufjs": "^6.8.6" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", + "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" }, "engines": { "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "node_modules/@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/storage": { + "version": "5.8.5", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.8.5.tgz", + "integrity": "sha512-i0gB9CRwQeOBYP7xuvn14M40LhHCwMjceBjxE4CTvsqL519sVY5yVKxLiAedHWGwUZHJNRa7Q2CmNfkdRwVNPg==", + "optional": true, "dependencies": { - "abbrev": "1" + "@google-cloud/common": "^3.6.0", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.0", + "async-retry": "^1.3.1", + "compressible": "^2.0.12", + "date-and-time": "^1.0.0", + "duplexify": "^4.0.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "gcs-resumable-upload": "^3.1.4", + "get-stream": "^6.0.0", + "hash-stream-validation": "^0.2.2", + "mime": "^2.2.0", + "mime-types": "^2.0.8", + "onetime": "^5.1.0", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "snakeize": "^0.1.0", + "stream-events": "^1.0.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/storage/node_modules/duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@google-cloud/storage/node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "optional": true, + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz", + "integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==", + "optional": true, + "dependencies": { + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", + "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", + "optional": true, + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.1.1" }, "bin": { - "nopt": "bin/nopt.js" + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" }, "engines": { "node": ">=6" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/@grpc/proto-loader/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@grpc/proto-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "optional": true, "dependencies": { - "lru-cache": "^6.0.0" + "color-convert": "^2.0.1" }, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/@grpc/proto-loader/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "optional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@grpc/proto-loader/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@grpc/proto-loader/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, + "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" }, "engines": { "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "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" - }, + "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "optional": true, "engines": { - "node": ">= 10" + "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", @@ -1468,11 +1777,82 @@ "node": ">= 8" } }, + "node_modules/@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", + "optional": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "optional": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "optional": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", + "optional": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", + "optional": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", + "optional": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", + "optional": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", + "optional": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "optional": true + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, "engines": { "node": ">=6" } @@ -1481,7 +1861,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, "dependencies": { "defer-to-connect": "^1.0.1" }, @@ -1489,6 +1868,24 @@ "node": ">=6" } }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, "node_modules/@types/bson": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", @@ -1497,6 +1894,63 @@ "@types/node": "*" } }, + "node_modules/@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", + "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-jwt": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", + "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", + "dependencies": { + "@types/express": "*", + "@types/express-unless": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.20.tgz", + "integrity": "sha512-8qqFN4W53IEWa9bdmuVrUcVkFemQWnt5DKPQ/oa8xKDYgtjCr2OO6NX5TIK49NLFr3mPYU2cLh92DQquC3oWWQ==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/express-unless": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", + "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, "node_modules/@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -1504,18 +1958,18 @@ "dev": true }, "node_modules/@types/mongodb": { - "version": "3.6.12", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", - "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", + "version": "3.6.17", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.17.tgz", + "integrity": "sha512-9hhgvYPdC5iHyyksPcKCu45gfaAIPQHKHGdvNXu4582DmOZX3wrUJIJPT40o4G1oTKPgpMMFqZglOTjhnYoF+A==", "dependencies": { "@types/bson": "*", "@types/node": "*" } }, "node_modules/@types/node": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz", - "integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ==" + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", + "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -1523,11 +1977,42 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "node_modules/@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "optional": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -1585,6 +2070,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, "dependencies": { "debug": "4" }, @@ -1634,7 +2120,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, "dependencies": { "string-width": "^3.0.0" } @@ -1642,14 +2127,12 @@ "node_modules/ansi-align/node_modules/emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, "engines": { "node": ">=4" } @@ -1658,7 +2141,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -1711,7 +2193,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, "engines": { "node": ">=6" } @@ -1741,7 +2222,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1765,7 +2245,8 @@ "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true }, "node_modules/archy": { "version": "1.0.0", @@ -1777,6 +2258,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -1968,7 +2450,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -2082,6 +2564,15 @@ "node": "*" } }, + "node_modules/async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "optional": true, + "dependencies": { + "retry": "0.12.0" + } + }, "node_modules/async-settle": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", @@ -2290,7 +2781,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -2306,19 +2797,6 @@ } ] }, - "node_modules/bcrypt": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", - "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", - "hasInstallScript": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "node-addon-api": "^3.1.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -2328,15 +2806,33 @@ "tweetnacl": "^0.14.3" } }, + "node_modules/bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", @@ -2415,7 +2911,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", @@ -2437,7 +2932,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2452,7 +2946,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, "engines": { "node": ">=6" } @@ -2461,7 +2954,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2474,7 +2966,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2486,7 +2977,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -2495,7 +2985,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -2507,7 +2996,6 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, "engines": { "node": ">=8" } @@ -2525,7 +3013,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -2819,7 +3306,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -2837,7 +3323,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, "engines": { "node": ">=8" } @@ -2893,10 +3378,14 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001223", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", - "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", - "dev": true + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, "node_modules/caseless": { "version": "0.12.0", @@ -2967,7 +3456,6 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, "dependencies": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -2984,19 +3472,10 @@ "fsevents": "~2.3.1" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "node_modules/cipher-base": { "version": "1.0.4", @@ -3110,7 +3589,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, "engines": { "node": ">=6" }, @@ -3201,7 +3679,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "dependencies": { "mimic-response": "^1.0.0" } @@ -3227,6 +3704,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3333,6 +3811,18 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3410,7 +3900,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, "dependencies": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -3432,7 +3921,8 @@ "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true }, "node_modules/constants-browserify": { "version": "1.0.0", @@ -3539,6 +4029,18 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", @@ -3649,7 +4151,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, "engines": { "node": ">=8" } @@ -3710,6 +4211,12 @@ "node": ">=0.10" } }, + "node_modules/date-and-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-1.0.1.tgz", + "integrity": "sha512-7u+uNfnjWkX+YFQfivvW24TjaJG6ahvTrfw1auq7KlC7osuGcZBIWGBvB9UcENjH6JnLVhMqlRripk1dSHjAUA==", + "optional": true + }, "node_modules/date-fns": { "version": "2.21.3", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.3.tgz", @@ -3761,7 +4268,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, "dependencies": { "mimic-response": "^1.0.0" }, @@ -3773,7 +4279,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "engines": { "node": ">=4.0.0" } @@ -3808,8 +4313,7 @@ "node_modules/defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, "node_modules/define-properties": { "version": "1.1.3", @@ -3876,7 +4380,8 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true }, "node_modules/denque": { "version": "1.5.0", @@ -3933,17 +4438,6 @@ "node": ">=0.10.0" } }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -3961,6 +4455,17 @@ "node": ">=0.8.0" } }, + "node_modules/dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "dependencies": { + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=4.5.0" + } + }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -4016,7 +4521,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, "dependencies": { "is-obj": "^2.0.0" }, @@ -4024,14 +4528,6 @@ "node": ">=8" } }, - "node_modules/dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "engines": { - "node": ">=10" - } - }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -4044,8 +4540,7 @@ "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "node_modules/duplexify": { "version": "3.7.1", @@ -4134,8 +4629,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -4149,11 +4643,16 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "optional": true + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4258,7 +4757,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -4267,7 +4766,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, "engines": { "node": ">=8" } @@ -4493,6 +4991,15 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -4819,7 +5326,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "devOptional": true }, "node_modules/extend-shallow": { "version": "3.0.2", @@ -4928,7 +5435,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "devOptional": true }, "node_modules/fast-glob": { "version": "3.2.5", @@ -4965,6 +5472,12 @@ "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", "dev": true }, + "node_modules/fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", + "optional": true + }, "node_modules/fastq": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", @@ -4974,6 +5487,17 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -5001,11 +5525,17 @@ "node": ">=4" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5256,6 +5786,27 @@ "node": ">=0.10.0" } }, + "node_modules/firebase-admin": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.9.0.tgz", + "integrity": "sha512-04HT7JAAqcJYty95qf15IBD9CXf+vr7S8zNU6Zt1ayC1J05DLaCsUd19/sCNAjZ614KHexAYUtyLgZoJwu2wOQ==", + "dependencies": { + "@firebase/database": "^0.10.0", + "@firebase/database-types": "^0.7.2", + "@types/node": ">=12.12.47", + "dicer": "^0.3.0", + "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", + "node-forge": "^0.10.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^4.5.0", + "@google-cloud/storage": "^5.3.0" + } + }, "node_modules/flagged-respawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", @@ -5404,17 +5955,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -5431,7 +5971,21 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, "node_modules/fstream": { "version": "1.0.12", @@ -5470,12 +6024,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "devOptional": true }, "node_modules/gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, "dependencies": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -5491,6 +6046,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -5499,6 +6055,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, "dependencies": { "number-is-nan": "^1.0.0" }, @@ -5510,6 +6067,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5523,6 +6081,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, @@ -5530,6 +6089,22 @@ "node": ">=0.10.0" } }, + "node_modules/gaxios": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz", + "integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==", + "optional": true, + "dependencies": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", @@ -5542,6 +6117,77 @@ "node": ">= 4.0.0" } }, + "node_modules/gcp-metadata": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", + "optional": true, + "dependencies": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gcs-resumable-upload": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.1.4.tgz", + "integrity": "sha512-5dyDfHrrVcIskiw/cPssVD4HRiwoHjhk1Nd6h5W3pQ/qffDvhfy4oNCr1f3ZXFPwTnxkCbibsB+73oOM+NvmJQ==", + "optional": true, + "dependencies": { + "abort-controller": "^3.0.0", + "configstore": "^5.0.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "google-auth-library": "^7.0.0", + "pumpify": "^2.0.0", + "stream-events": "^1.0.4" + }, + "bin": { + "gcs-upload": "build/src/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gcs-resumable-upload/node_modules/duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/gcs-resumable-upload/node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "optional": true, + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "node_modules/gcs-resumable-upload/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -5561,7 +6207,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, + "devOptional": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -5593,7 +6239,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -5626,6 +6271,7 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5645,7 +6291,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5828,6 +6473,25 @@ "node": ">=0.10.0" } }, + "node_modules/glob-watcher/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, "node_modules/glob-watcher/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -5959,7 +6623,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "dev": true, "dependencies": { "ini": "1.3.7" }, @@ -5973,8 +6636,7 @@ "node_modules/global-dirs/node_modules/ini": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", - "dev": true + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" }, "node_modules/global-modules": { "version": "1.0.0", @@ -6070,11 +6732,115 @@ "node": ">= 0.10" } }, + "node_modules/google-auth-library": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.1.0.tgz", + "integrity": "sha512-X+gbkGjnLN3HUZP2W3KBREuA603BXd80ITvL0PeS0QpyDNYz/u0pIZ7aRuGnrSuUc0grk/qxEgtVTFt1ogbP+A==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-auth-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-auth-library/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, + "node_modules/google-gax": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.14.1.tgz", + "integrity": "sha512-I5RDEN7MEptrCxeHX3ht7nKFGfyjgYX4hQKI9eVMBohMzVbFSwWUndo0CcKXu8es7NhB4gt2XYLm1AHkXhtHpA==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "~1.3.0", + "@grpc/proto-loader": "^0.6.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.0.2", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "object-hash": "^2.1.1", + "protobufjs": "^6.10.2", + "retry-request": "^4.0.0" + }, + "bin": { + "compileProtos": "build/tools/compileProtos.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-gax/node_modules/duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/google-gax/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/google-p12-pem": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", + "optional": true, + "dependencies": { + "node-forge": "^0.10.0" + }, + "bin": { + "gp12-pem": "build/src/bin/gp12-pem.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, "dependencies": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", @@ -6096,7 +6862,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -6107,8 +6872,21 @@ "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "node_modules/gtoken": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", + "optional": true, + "dependencies": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, "node_modules/gulp": { "version": "4.0.2", @@ -6441,7 +7219,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, "engines": { "node": ">=4" } @@ -6461,7 +7238,8 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true }, "node_modules/has-value": { "version": "1.0.0", @@ -6530,7 +7308,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, "engines": { "node": ">=8" } @@ -6563,6 +7340,12 @@ "node": ">= 6" } }, + "node_modules/hash-stream-validation": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", + "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", + "optional": true + }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -6619,8 +7402,7 @@ "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "node_modules/http-errors": { "version": "1.7.2", @@ -6642,6 +7424,25 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "node_modules/http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -6667,6 +7468,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "optional": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -6821,8 +7623,7 @@ "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -6844,7 +7645,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, "engines": { "node": ">=4" } @@ -6853,7 +7653,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -6883,6 +7682,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6896,8 +7696,7 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inline-source-map": { "version": "0.6.2", @@ -7132,7 +7931,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7177,7 +7975,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, "dependencies": { "ci-info": "^2.0.0" }, @@ -7186,9 +7983,9 @@ } }, "node_modules/is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -7281,7 +8078,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7302,7 +8098,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -7323,7 +8118,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -7335,7 +8129,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, "dependencies": { "global-dirs": "^2.0.1", "is-path-inside": "^3.0.1" @@ -7372,7 +8165,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true, "engines": { "node": ">=8" } @@ -7381,7 +8173,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -7402,7 +8193,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, "engines": { "node": ">=8" } @@ -7420,7 +8210,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -7466,11 +8255,17 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" } }, + "node_modules/is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", + "optional": true + }, "node_modules/is-string": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", @@ -7520,8 +8315,7 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "node_modules/is-unc-path": { "version": "1.0.0", @@ -7562,8 +8356,7 @@ "node_modules/is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "node_modules/isarray": { "version": "1.0.0", @@ -7591,6 +8384,20 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "node_modules/jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "dependencies": { + "@panva/asn1.js": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0 < 13 || >=13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-base64": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", @@ -7634,11 +8441,19 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, "node_modules/json-parse-better-errors": { "version": "1.0.2", @@ -7737,6 +8552,25 @@ "npm": ">=1.4.28" } }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/jsonwebtoken/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -7767,21 +8601,38 @@ "dev": true }, "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "node_modules/jwks-rsa": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.3.tgz", + "integrity": "sha512-/rkjXRWAp0cS00tunsHResw68P5iTQru8+jHufLNv3JHc4nObFEndfEUSuPugh09N+V9XYxKUqi7QrkmCHSSSg==", "dependencies": { - "jwa": "^1.4.1", + "@types/express-jwt": "0.0.42", + "debug": "^4.1.0", + "jose": "^2.0.5", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.2" + }, + "engines": { + "node": ">=10 < 13 || >=14" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "dependencies": { + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -7794,7 +8645,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, "dependencies": { "json-buffer": "3.0.0" } @@ -7835,7 +8685,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, "dependencies": { "package-json": "^6.3.0" }, @@ -7923,6 +8772,11 @@ "node": ">=0.10.0" } }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "node_modules/lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -7987,6 +8841,17 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -8034,6 +8899,12 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "optional": true + }, "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -8051,7 +8922,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -8066,6 +8936,24 @@ "yallist": "^2.1.2" } }, + "node_modules/lru-memoizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -8452,7 +9340,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -8461,7 +9349,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, "engines": { "node": ">=4" } @@ -8492,41 +9379,7 @@ "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -8597,14 +9450,14 @@ } }, "node_modules/mongodb": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.6.tgz", - "integrity": "sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz", + "integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==", "dependencies": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", - "optional-require": "^1.0.2", + "optional-require": "^1.0.3", "safe-buffer": "^5.1.2" }, "engines": { @@ -8644,14 +9497,14 @@ } }, "node_modules/mongoose": { - "version": "5.12.8", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.8.tgz", - "integrity": "sha512-+6Q8mvTsIHQkXBWmBGnEy93Gm0fjKIwV/AEIT23wXN3O4Pd3L/aZaJWrdOStcuE4b9SqXrs1QBnnR9MNqNZwrw==", + "version": "5.12.12", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.12.tgz", + "integrity": "sha512-n+ZmGApaL5x/r92w6S4pb+c075i+YKzg1F9YWkznSzQMtvetj/2dSjj2cqsITpd6z60k3K7ZaosIl6hzHwUA9g==", "dependencies": { "@types/mongodb": "^3.5.27", "bson": "^1.1.4", "kareem": "2.3.2", - "mongodb": "3.6.6", + "mongodb": "3.6.8", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.8.3", "mquery": "3.2.5", @@ -8826,19 +9679,23 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node_modules/node-addon-api": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", - "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==" - }, "node_modules/node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "optional": true, "engines": { "node": "4.x || >=6.0.0" } }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/node-gyp": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", @@ -8887,9 +9744,9 @@ } }, "node_modules/node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", "dev": true }, "node_modules/node-sass": { @@ -8989,19 +9846,10 @@ "node": ">=0.8.0" } }, - "node_modules/nodemailer": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.1.tgz", - "integrity": "sha512-1xzFN3gqv+/qJ6YRyxBxfTYstLNt0FCtZaFRvf4Sg9wxNGWbwFmGXVpfSi6ThGK6aRxAo+KjHtYSW8NvCsNSAg==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/nodemon": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "dev": true, "hasInstallScript": true, "dependencies": { "chokidar": "^3.2.2", @@ -9030,7 +9878,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -9039,7 +9886,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -9081,16 +9927,14 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true, + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "engines": { "node": ">=8" } @@ -9132,6 +9976,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, "dependencies": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -9143,6 +9988,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -9249,6 +10095,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", @@ -9373,7 +10228,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, + "devOptional": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -9477,7 +10332,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, "engines": { "node": ">=6" } @@ -9486,7 +10340,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, + "devOptional": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -9540,7 +10394,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, "dependencies": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", @@ -9683,6 +10536,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -9772,7 +10626,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -9868,7 +10721,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, "engines": { "node": ">=4" } @@ -10062,6 +10914,32 @@ "node": ">=0.4.0" } }, + "node_modules/protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -10077,8 +10955,7 @@ "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "node_modules/psl": { "version": "1.8.0", @@ -10089,8 +10966,7 @@ "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, "node_modules/public-encrypt": { "version": "4.0.3", @@ -10116,7 +10992,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -10153,7 +11028,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, "dependencies": { "escape-goat": "^2.0.0" }, @@ -10253,7 +11127,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -10268,7 +11141,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10415,7 +11287,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -10540,7 +11411,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, "dependencies": { "rc": "^1.2.8" }, @@ -10552,7 +11422,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, "dependencies": { "rc": "^1.2.8" }, @@ -10709,7 +11578,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -10778,7 +11647,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, "dependencies": { "lowercase-keys": "^1.0.0" } @@ -10805,6 +11673,27 @@ "node": ">=0.12" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.3.tgz", + "integrity": "sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ==", + "optional": true, + "dependencies": { + "debug": "^4.1.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -10819,6 +11708,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -10938,6 +11828,9 @@ "lodash": "^4.0.0", "scss-tokenizer": "^0.2.3", "yargs": "^13.3.2" + }, + "bin": { + "sassgraph": "bin/sassgraph" } }, "node_modules/scss-tokenizer": { @@ -10980,7 +11873,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, "dependencies": { "semver": "^6.3.0" }, @@ -11070,7 +11962,8 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "node_modules/set-value": { "version": "2.0.1", @@ -11241,6 +12134,12 @@ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" }, + "node_modules/snakeize": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", + "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", + "optional": true + }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -11538,6 +12437,11 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, "engines": { "node": ">=0.10.0" } @@ -11689,6 +12593,15 @@ "readable-stream": "^2.0.2" } }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, "node_modules/stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", @@ -11725,7 +12638,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true + "devOptional": true }, "node_modules/stream-splicer": { "version": "2.0.1", @@ -11737,11 +12650,19 @@ "readable-stream": "^2.0.2" } }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, + "devOptional": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -11750,7 +12671,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11764,7 +12684,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, "engines": { "node": ">=8" } @@ -11773,7 +12692,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.0" }, @@ -11811,7 +12729,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "dependencies": { "ansi-regex": "^4.1.0" }, @@ -11867,6 +12784,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "optional": true + }, "node_modules/subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -11880,7 +12803,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -11962,11 +12884,35 @@ "inherits": "2" } }, + "node_modules/teeny-request": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.0.tgz", + "integrity": "sha512-hPfSc05a7Mf3syqVhSkrVMb844sMiP60MrfGMts3ft6V6UlSkEIGQzgwf0dy1KjdE3FV2lJ5s7QCBFcaoQLA6g==", + "optional": true, + "dependencies": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, "engines": { "node": ">=8" }, @@ -12097,7 +13043,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, "engines": { "node": ">=6" } @@ -12121,7 +13066,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -12153,7 +13097,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, "dependencies": { "nopt": "~1.0.10" }, @@ -12165,12 +13108,14 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" } }, "node_modules/tough-cookie": { @@ -12304,7 +13249,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, "dependencies": { "is-typedarray": "^1.0.0" } @@ -12362,7 +13306,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, "dependencies": { "debug": "^2.2.0" } @@ -12371,7 +13314,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -12379,8 +13321,7 @@ "node_modules/undefsafe/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/undertaker": { "version": "1.3.0", @@ -12496,7 +13437,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, "dependencies": { "crypto-random-string": "^2.0.0" }, @@ -12574,7 +13514,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "dev": true, "dependencies": { "boxen": "^4.2.0", "chalk": "^3.0.0", @@ -12601,7 +13540,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -12616,7 +13554,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -12629,7 +13566,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -12641,7 +13577,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -12650,7 +13585,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -12697,7 +13631,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, "dependencies": { "prepend-http": "^2.0.0" }, @@ -12947,6 +13880,27 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -13012,6 +13966,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, "dependencies": { "string-width": "^1.0.2 || 2" } @@ -13020,6 +13975,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, "engines": { "node": ">=4" } @@ -13028,6 +13984,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, "engines": { "node": ">=4" } @@ -13036,6 +13993,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -13048,6 +14006,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, @@ -13059,7 +14018,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, "dependencies": { "string-width": "^4.0.0" }, @@ -13140,7 +14098,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -13152,7 +14109,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, "engines": { "node": ">=8" } @@ -13175,8 +14131,7 @@ "node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "node_modules/yaml": { "version": "1.10.2", @@ -13318,7 +14273,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=10" }, @@ -13344,20 +14299,20 @@ "dev": true }, "@babel/core": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", - "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.2.tgz", + "integrity": "sha512-OgC1mON+l4U4B4wiohJlQNUU3H73mpTyYY3j/c8U9dr9UagGGSm+WFpzjy/YLdoyjiG++c1kIDgxCo/mLwQJeQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", + "@babel/generator": "^7.14.2", "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-module-transforms": "^7.14.2", "@babel/helpers": "^7.14.0", - "@babel/parser": "^7.14.0", + "@babel/parser": "^7.14.2", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0", + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -13367,12 +14322,12 @@ } }, "@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.2.tgz", + "integrity": "sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ==", "dev": true, "requires": { - "@babel/types": "^7.14.1", + "@babel/types": "^7.14.2", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -13409,13 +14364,13 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz", - "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.2.tgz", + "integrity": "sha512-6YctwVsmlkchxfGUogvVrrhzyD3grFJyluj5JgDlQrwfMLJSt5tdAzFZfPf4H2Xoi5YLcQ6BxfJlaOBHuctyIw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", + "@babel/helper-function-name": "^7.14.2", "@babel/helper-member-expression-to-functions": "^7.13.12", "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-replace-supers": "^7.13.12", @@ -13458,14 +14413,14 @@ } }, "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.12.13", "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.2" } }, "@babel/helper-get-function-arity": { @@ -13506,9 +14461,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", - "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz", + "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.13.12", @@ -13517,8 +14472,8 @@ "@babel/helper-split-export-declaration": "^7.12.13", "@babel/helper-validator-identifier": "^7.14.0", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0" + "@babel/traverse": "^7.14.2", + "@babel/types": "^7.14.2" } }, "@babel/helper-optimise-call-expression": { @@ -13633,9 +14588,9 @@ } }, "@babel/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.2.tgz", + "integrity": "sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==", "dev": true }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { @@ -13650,9 +14605,9 @@ } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", - "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz", + "integrity": "sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13681,9 +14636,9 @@ } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", - "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz", + "integrity": "sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13691,19 +14646,19 @@ } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", - "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz", + "integrity": "sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", - "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz", + "integrity": "sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13711,9 +14666,9 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", - "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz", + "integrity": "sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13721,9 +14676,9 @@ } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", - "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz", + "integrity": "sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13731,32 +14686,32 @@ } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", - "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz", + "integrity": "sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", - "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.2.tgz", + "integrity": "sha512-hBIQFxwZi8GIp934+nj5uV31mqclC1aYDhctDu5khTi9PCCUOczyy0b34W0oE9U/eJXiqQaKyVsmjeagOaSlbw==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", + "@babel/compat-data": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" + "@babel/plugin-transform-parameters": "^7.14.2" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", - "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz", + "integrity": "sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13764,9 +14719,9 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", - "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz", + "integrity": "sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0", @@ -13962,25 +14917,25 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz", - "integrity": "sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.2.tgz", + "integrity": "sha512-neZZcP19NugZZqNwMTH+KoBjx5WyvESPSIOQb4JHpfd+zPfqcH65RMu5xJju5+6q/Y2VzYrleQTr+b6METyyxg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-classes": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", - "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.2.tgz", + "integrity": "sha512-7oafAVcucHquA/VZCsXv/gmuiHeYd64UJyyTYU+MPfNu0KeNlxw06IeENBO8bJjXVbolu+j1MM5aKQtH1OMCNg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", + "@babel/helper-function-name": "^7.14.2", "@babel/helper-optimise-call-expression": "^7.12.13", "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.12", "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" } @@ -14070,12 +15025,12 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz", - "integrity": "sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz", + "integrity": "sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-module-transforms": "^7.14.2", "@babel/helper-plugin-utils": "^7.13.0", "babel-plugin-dynamic-import-node": "^2.3.3" } @@ -14144,9 +15099,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", - "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz", + "integrity": "sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.13.0" @@ -14180,9 +15135,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz", - "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.2.tgz", + "integrity": "sha512-LyA2AiPkaYzI7G5e2YI4NCasTfFe7mZvlupNprDOB7CdNUHb2DQC4uV6oeZ0396gOcicUzUCh0MShL6wiUgk+Q==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.13.12", @@ -14259,9 +15214,9 @@ } }, "@babel/preset-env": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.1.tgz", - "integrity": "sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.2.tgz", + "integrity": "sha512-7dD7lVT8GMrE73v4lvDEb85cgcQhdES91BSD7jS/xjC6QY8PnRhux35ac+GCpbiRhp8crexBvZZqnaL6VrY8TQ==", "dev": true, "requires": { "@babel/compat-data": "^7.14.0", @@ -14269,18 +15224,18 @@ "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-validator-option": "^7.12.17", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", + "@babel/plugin-proposal-async-generator-functions": "^7.14.2", "@babel/plugin-proposal-class-properties": "^7.13.0", "@babel/plugin-proposal-class-static-block": "^7.13.11", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-dynamic-import": "^7.14.2", + "@babel/plugin-proposal-export-namespace-from": "^7.14.2", + "@babel/plugin-proposal-json-strings": "^7.14.2", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.2", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2", + "@babel/plugin-proposal-numeric-separator": "^7.14.2", + "@babel/plugin-proposal-object-rest-spread": "^7.14.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.2", + "@babel/plugin-proposal-optional-chaining": "^7.14.2", "@babel/plugin-proposal-private-methods": "^7.13.0", "@babel/plugin-proposal-private-property-in-object": "^7.14.0", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", @@ -14301,8 +15256,8 @@ "@babel/plugin-transform-arrow-functions": "^7.13.0", "@babel/plugin-transform-async-to-generator": "^7.13.0", "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.14.1", - "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-block-scoping": "^7.14.2", + "@babel/plugin-transform-classes": "^7.14.2", "@babel/plugin-transform-computed-properties": "^7.13.0", "@babel/plugin-transform-destructuring": "^7.13.17", "@babel/plugin-transform-dotall-regex": "^7.12.13", @@ -14312,14 +15267,14 @@ "@babel/plugin-transform-function-name": "^7.12.13", "@babel/plugin-transform-literals": "^7.12.13", "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.14.0", + "@babel/plugin-transform-modules-amd": "^7.14.2", "@babel/plugin-transform-modules-commonjs": "^7.14.0", "@babel/plugin-transform-modules-systemjs": "^7.13.8", "@babel/plugin-transform-modules-umd": "^7.14.0", "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", "@babel/plugin-transform-new-target": "^7.12.13", "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-parameters": "^7.14.2", "@babel/plugin-transform-property-literals": "^7.12.13", "@babel/plugin-transform-regenerator": "^7.13.15", "@babel/plugin-transform-reserved-words": "^7.12.13", @@ -14331,7 +15286,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.12.13", "@babel/plugin-transform-unicode-regex": "^7.12.13", "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.14.1", + "@babel/types": "^7.14.2", "babel-plugin-polyfill-corejs2": "^0.2.0", "babel-plugin-polyfill-corejs3": "^0.2.0", "babel-plugin-polyfill-regenerator": "^0.2.0", @@ -14372,93 +15327,363 @@ } }, "@babel/traverse": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", - "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", - "@babel/helper-function-name": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.0", - "@babel/types": "^7.14.0", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" } }, - "@mapbox/node-pre-gyp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", + "@firebase/app-types": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.2.tgz", + "integrity": "sha512-2VXvq/K+n8XMdM4L2xy5bYp2ZXMawJXluUIDzUBvMthVR+lhxK4pfFiqr1mmDbv9ydXvEAuFsD+6DpcZuJcSSw==" + }, + "@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==", + "requires": {} + }, + "@firebase/component": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.0.tgz", + "integrity": "sha512-v18csWtXb0ri+3m7wuGLY/UDgcb89vuMlZGQ//+7jEPLIQeLbylvZhol1uzW9WzoOpxMxOS2W5qyVGX36wZvEA==", "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.1", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.4", - "tar": "^6.1.0" + "@firebase/util": "1.1.0", + "tslib": "^2.1.0" }, "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "@firebase/database": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.2.tgz", + "integrity": "sha512-jMGtl5eBES9k0rOIZd6/EAuVB6m3LzRei1lvEiqWWBje2Xoz//7sjZcxOYtAKCCLldEI1EUrzW8Tv5yEAoPPpg==", + "requires": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.0", + "@firebase/database-types": "0.7.2", + "@firebase/logger": "0.2.6", + "@firebase/util": "1.1.0", + "faye-websocket": "0.11.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "@firebase/database-types": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.2.tgz", + "integrity": "sha512-cdAd/dgwvC0r3oLEDUR+ULs1vBsEvy0b27nlzKhU6LQgm9fCDzgaH9nFGv8x+S9dly4B0egAXkONkVoWcOAisg==", + "requires": { + "@firebase/app-types": "0.6.2" + } + }, + "@firebase/logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", + "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" + }, + "@firebase/util": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.1.0.tgz", + "integrity": "sha512-lfuSASuPKNdfebuFR8rjFamMQUPH9iiZHcKS755Rkm/5gRT0qC7BMhCh3ZkHf7NVbplzIc/GhmX2jM+igDRCag==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, + "@google-cloud/common": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", + "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", + "optional": true, + "requires": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^7.0.2", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, "requires": { - "yallist": "^4.0.0" + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "@google-cloud/firestore": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.12.2.tgz", + "integrity": "sha512-5rurTAJXQ0SANEf8K9eA2JAB5zAh+pu4tGRnkZx5gBWQLZXdBFdtepS+irvKuSXw1KbeAQOuRANSc/nguys6SQ==", + "optional": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^2.12.0", + "protobufjs": "^6.8.6" + } + }, + "@google-cloud/paginator": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", + "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", + "optional": true, + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, + "@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", + "optional": true + }, + "@google-cloud/promisify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", + "optional": true + }, + "@google-cloud/storage": { + "version": "5.8.5", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.8.5.tgz", + "integrity": "sha512-i0gB9CRwQeOBYP7xuvn14M40LhHCwMjceBjxE4CTvsqL519sVY5yVKxLiAedHWGwUZHJNRa7Q2CmNfkdRwVNPg==", + "optional": true, + "requires": { + "@google-cloud/common": "^3.6.0", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.0", + "async-retry": "^1.3.1", + "compressible": "^2.0.12", + "date-and-time": "^1.0.0", + "duplexify": "^4.0.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "gcs-resumable-upload": "^3.1.4", + "get-stream": "^6.0.0", + "hash-stream-validation": "^0.2.2", + "mime": "^2.2.0", + "mime-types": "^2.0.8", + "onetime": "^5.1.0", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "snakeize": "^0.1.0", + "stream-events": "^1.0.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } }, - "nopt": { + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "optional": true + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "optional": true + }, + "pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "optional": true, + "requires": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "@grpc/grpc-js": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz", + "integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==", + "optional": true, + "requires": { + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.2.tgz", + "integrity": "sha512-q2Qle60Ht2OQBCp9S5hv1JbI4uBBq6/mqSevFNK3ZEgRDBCAkWqZPUhD/K9gXOHrHKluliHiVq2L9sw1mVyAIg==", + "optional": true, + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.1.1" + }, + "dependencies": { + "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "optional": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "optional": true, "requires": { - "abbrev": "1" + "color-convert": "^2.0.1" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, "requires": { - "lru-cache": "^6.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "optional": true, "requires": { - "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" + "color-name": "~1.1.4" } }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "optional": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "optional": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "optional": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, + "requires": { + "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-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "optional": true } } }, @@ -14488,21 +15713,103 @@ "fastq": "^1.6.0" } }, + "@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", + "optional": true + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "optional": true + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "optional": true + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", + "optional": true + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", + "optional": true + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", + "optional": true + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", + "optional": true + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", + "optional": true + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "optional": true + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, "requires": { "defer-to-connect": "^1.0.1" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, "@types/bson": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", @@ -14511,6 +15818,63 @@ "@types/node": "*" } }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", + "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-jwt": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", + "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", + "requires": { + "@types/express": "*", + "@types/express-unless": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.20.tgz", + "integrity": "sha512-8qqFN4W53IEWa9bdmuVrUcVkFemQWnt5DKPQ/oa8xKDYgtjCr2OO6NX5TIK49NLFr3mPYU2cLh92DQquC3oWWQ==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/express-unless": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", + "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", + "requires": { + "@types/express": "*" + } + }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", + "optional": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -14518,18 +15882,18 @@ "dev": true }, "@types/mongodb": { - "version": "3.6.12", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", - "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", + "version": "3.6.17", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.17.tgz", + "integrity": "sha512-9hhgvYPdC5iHyyksPcKCu45gfaAIPQHKHGdvNXu4582DmOZX3wrUJIJPT40o4G1oTKPgpMMFqZglOTjhnYoF+A==", "requires": { "@types/bson": "*", "@types/node": "*" } }, "@types/node": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz", - "integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ==" + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", + "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==" }, "@types/parse-json": { "version": "4.0.0", @@ -14537,11 +15901,39 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "optional": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -14585,6 +15977,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, "requires": { "debug": "4" } @@ -14621,7 +16014,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, "requires": { "string-width": "^3.0.0" }, @@ -14629,20 +16021,17 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -14681,8 +16070,7 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "ansi-styles": { "version": "3.2.1", @@ -14703,7 +16091,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -14721,7 +16108,8 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true }, "archy": { "version": "1.0.0", @@ -14733,6 +16121,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -14880,7 +16269,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true + "devOptional": true }, "asn1": { "version": "0.2.4", @@ -14980,6 +16369,15 @@ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", "dev": true }, + "async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "optional": true, + "requires": { + "retry": "0.12.0" + } + }, "async-settle": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", @@ -15142,16 +16540,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bcrypt": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", - "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", - "requires": { - "@mapbox/node-pre-gyp": "^1.0.0", - "node-addon-api": "^3.1.0" - } + "devOptional": true }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -15162,11 +16551,26 @@ "tweetnacl": "^0.14.3" } }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", + "optional": true + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } }, "bl": { "version": "1.2.3", @@ -15239,7 +16643,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, "requires": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", @@ -15255,7 +16658,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -15263,14 +16665,12 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -15280,7 +16680,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -15288,14 +16687,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -15303,8 +16700,7 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, @@ -15321,7 +16717,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -15580,7 +16975,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -15594,8 +16988,7 @@ "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" } } }, @@ -15638,9 +17031,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001223", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", - "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", "dev": true }, "caseless": { @@ -15709,7 +17102,6 @@ "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -15721,16 +17113,10 @@ "readdirp": "~3.5.0" } }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "cipher-base": { "version": "1.0.4", @@ -15825,8 +17211,7 @@ "cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" }, "cli-cursor": { "version": "3.1.0", @@ -15895,7 +17280,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -15920,7 +17304,8 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true }, "collection-map": { "version": "1.0.0", @@ -16016,6 +17401,15 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -16082,7 +17476,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -16101,7 +17494,8 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true }, "constants-browserify": { "version": "1.0.0", @@ -16195,6 +17589,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", @@ -16296,8 +17699,7 @@ "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" }, "currently-unhandled": { "version": "0.4.1", @@ -16342,6 +17744,12 @@ "assert-plus": "^1.0.0" } }, + "date-and-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-1.0.1.tgz", + "integrity": "sha512-7u+uNfnjWkX+YFQfivvW24TjaJG6ahvTrfw1auq7KlC7osuGcZBIWGBvB9UcENjH6JnLVhMqlRripk1dSHjAUA==", + "optional": true + }, "date-fns": { "version": "2.21.3", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.3.tgz", @@ -16372,7 +17780,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -16380,8 +17787,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", @@ -16407,8 +17813,7 @@ "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, "define-properties": { "version": "1.1.3", @@ -16460,7 +17865,8 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true }, "denque": { "version": "1.5.0", @@ -16505,11 +17911,6 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, "detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -16521,6 +17922,14 @@ "minimist": "^1.1.1" } }, + "dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "requires": { + "streamsearch": "0.1.2" + } + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -16568,16 +17977,10 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, "requires": { "is-obj": "^2.0.0" } }, - "dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==" - }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -16590,8 +17993,7 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "duplexify": { "version": "3.7.1", @@ -16681,8 +18083,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "encodeurl": { "version": "1.0.2", @@ -16693,11 +18094,16 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "optional": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -16790,13 +18196,12 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "devOptional": true }, "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" }, "escape-html": { "version": "1.0.3", @@ -16964,6 +18369,12 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true + }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -17239,7 +18650,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "devOptional": true }, "extend-shallow": { "version": "3.0.2", @@ -17326,7 +18737,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "devOptional": true }, "fast-glob": { "version": "3.2.5", @@ -17360,6 +18771,12 @@ "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", "dev": true }, + "fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", + "optional": true + }, "fastq": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", @@ -17369,6 +18786,14 @@ "reusify": "^1.0.4" } }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -17387,11 +18812,17 @@ "flat-cache": "^2.0.1" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -17597,6 +19028,22 @@ } } }, + "firebase-admin": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.9.0.tgz", + "integrity": "sha512-04HT7JAAqcJYty95qf15IBD9CXf+vr7S8zNU6Zt1ayC1J05DLaCsUd19/sCNAjZ614KHexAYUtyLgZoJwu2wOQ==", + "requires": { + "@firebase/database": "^0.10.0", + "@firebase/database-types": "^0.7.2", + "@google-cloud/firestore": "^4.5.0", + "@google-cloud/storage": "^5.3.0", + "@types/node": ">=12.12.47", + "dicer": "^0.3.0", + "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", + "node-forge": "^0.10.0" + } + }, "flagged-respawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", @@ -17703,14 +19150,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, "fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -17724,7 +19163,14 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true }, "fstream": { "version": "1.0.12", @@ -17759,12 +19205,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "devOptional": true }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -17779,12 +19226,14 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -17793,6 +19242,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -17803,12 +19253,26 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, "requires": { "ansi-regex": "^2.0.0" } } } }, + "gaxios": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz", + "integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==", + "optional": true, + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", @@ -17818,6 +19282,67 @@ "globule": "^1.0.0" } }, + "gcp-metadata": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", + "optional": true, + "requires": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + } + }, + "gcs-resumable-upload": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.1.4.tgz", + "integrity": "sha512-5dyDfHrrVcIskiw/cPssVD4HRiwoHjhk1Nd6h5W3pQ/qffDvhfy4oNCr1f3ZXFPwTnxkCbibsB+73oOM+NvmJQ==", + "optional": true, + "requires": { + "abort-controller": "^3.0.0", + "configstore": "^5.0.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "google-auth-library": "^7.0.0", + "pumpify": "^2.0.0", + "stream-events": "^1.0.4" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "optional": true, + "requires": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -17834,7 +19359,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "devOptional": true }, "get-intrinsic": { "version": "1.1.1", @@ -17857,7 +19382,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -17881,6 +19405,7 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -17894,7 +19419,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -18052,6 +19576,17 @@ } } }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -18162,7 +19697,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "dev": true, "requires": { "ini": "1.3.7" }, @@ -18170,8 +19704,7 @@ "ini": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", - "dev": true + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" } } }, @@ -18247,11 +19780,98 @@ "sparkles": "^1.0.0" } }, + "google-auth-library": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.1.0.tgz", + "integrity": "sha512-X+gbkGjnLN3HUZP2W3KBREuA603BXd80ITvL0PeS0QpyDNYz/u0pIZ7aRuGnrSuUc0grk/qxEgtVTFt1ogbP+A==", + "optional": true, + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, + "google-gax": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.14.1.tgz", + "integrity": "sha512-I5RDEN7MEptrCxeHX3ht7nKFGfyjgYX4hQKI9eVMBohMzVbFSwWUndo0CcKXu8es7NhB4gt2XYLm1AHkXhtHpA==", + "optional": true, + "requires": { + "@grpc/grpc-js": "~1.3.0", + "@grpc/proto-loader": "^0.6.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.0.2", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "object-hash": "^2.1.1", + "protobufjs": "^6.10.2", + "retry-request": "^4.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "google-p12-pem": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", + "optional": true, + "requires": { + "node-forge": "^0.10.0" + } + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, "requires": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", @@ -18270,7 +19890,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -18280,8 +19899,18 @@ "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "gtoken": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", + "optional": true, + "requires": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0" + } }, "gulp": { "version": "4.0.2", @@ -18555,8 +20184,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.2", @@ -18567,7 +20195,8 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true }, "has-value": { "version": "1.0.0", @@ -18624,8 +20253,7 @@ "has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" }, "hash-base": { "version": "3.1.0", @@ -18651,6 +20279,12 @@ } } }, + "hash-stream-validation": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", + "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", + "optional": true + }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -18701,8 +20335,7 @@ "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { "version": "1.7.2", @@ -18723,6 +20356,22 @@ } } }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -18744,6 +20393,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "optional": true, "requires": { "agent-base": "6", "debug": "4" @@ -18841,8 +20491,7 @@ "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" }, "import-fresh": { "version": "3.3.0", @@ -18857,14 +20506,12 @@ "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "in-publish": { "version": "2.0.1", @@ -18882,6 +20529,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -18895,8 +20543,7 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inline-source-map": { "version": "0.6.2", @@ -19075,7 +20722,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -19105,15 +20751,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, "requires": { "ci-info": "^2.0.0" } }, "is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "requires": { "has": "^1.0.3" @@ -19184,8 +20829,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { "version": "1.1.0", @@ -19196,8 +20840,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-generator-function": { "version": "1.0.9", @@ -19209,7 +20852,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -19218,7 +20860,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, "requires": { "global-dirs": "^2.0.1", "is-path-inside": "^3.0.1" @@ -19239,14 +20880,12 @@ "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { "version": "1.0.5", @@ -19257,8 +20896,7 @@ "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-path-cwd": { "version": "2.2.0", @@ -19269,8 +20907,7 @@ "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, "is-plain-object": { "version": "5.0.0", @@ -19301,7 +20938,13 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true + "devOptional": true + }, + "is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", + "optional": true }, "is-string": { "version": "1.0.6", @@ -19334,8 +20977,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-unc-path": { "version": "1.0.0", @@ -19367,8 +21009,7 @@ "is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "isarray": { "version": "1.0.0", @@ -19393,6 +21034,14 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "requires": { + "@panva/asn1.js": "^1.0.0" + } + }, "js-base64": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", @@ -19427,11 +21076,19 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, + "requires": { + "bignumber.js": "^9.0.0" + } + }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, "json-parse-better-errors": { "version": "1.0.2", @@ -19511,6 +21168,25 @@ "semver": "^5.6.0" }, "dependencies": { + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -19537,21 +21213,35 @@ "dev": true }, "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "jwks-rsa": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.3.tgz", + "integrity": "sha512-/rkjXRWAp0cS00tunsHResw68P5iTQru8+jHufLNv3JHc4nObFEndfEUSuPugh09N+V9XYxKUqi7QrkmCHSSSg==", "requires": { - "jwa": "^1.4.1", + "@types/express-jwt": "0.0.42", + "debug": "^4.1.0", + "jose": "^2.0.5", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.2" + } + }, + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "requires": { + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -19564,7 +21254,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, "requires": { "json-buffer": "3.0.0" } @@ -19599,7 +21288,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, "requires": { "package-json": "^6.3.0" } @@ -19668,6 +21356,11 @@ } } }, + "limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -19719,6 +21412,17 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "optional": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -19766,6 +21470,12 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "optional": true + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -19779,8 +21489,7 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "lru-cache": { "version": "4.1.5", @@ -19792,6 +21501,26 @@ "yallist": "^2.1.2" } }, + "lru-memoizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + } + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -20100,13 +21829,12 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "devOptional": true }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "minimalistic-assert": { "version": "1.0.1", @@ -20131,39 +21859,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mixin-deep": { "version": "1.3.2", @@ -20219,14 +21915,14 @@ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "mongodb": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.6.tgz", - "integrity": "sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz", + "integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==", "requires": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", - "optional-require": "^1.0.2", + "optional-require": "^1.0.3", "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" }, @@ -20243,14 +21939,14 @@ } }, "mongoose": { - "version": "5.12.8", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.8.tgz", - "integrity": "sha512-+6Q8mvTsIHQkXBWmBGnEy93Gm0fjKIwV/AEIT23wXN3O4Pd3L/aZaJWrdOStcuE4b9SqXrs1QBnnR9MNqNZwrw==", + "version": "5.12.12", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.12.tgz", + "integrity": "sha512-n+ZmGApaL5x/r92w6S4pb+c075i+YKzg1F9YWkznSzQMtvetj/2dSjj2cqsITpd6z60k3K7ZaosIl6hzHwUA9g==", "requires": { "@types/mongodb": "^3.5.27", "bson": "^1.1.4", "kareem": "2.3.2", - "mongodb": "3.6.6", + "mongodb": "3.6.8", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.8.3", "mquery": "3.2.5", @@ -20396,15 +22092,16 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-addon-api": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", - "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==" - }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "optional": true + }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, "node-gyp": { "version": "3.8.0", @@ -20444,9 +22141,9 @@ } }, "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==", "dev": true }, "node-sass": { @@ -20526,16 +22223,10 @@ } } }, - "nodemailer": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.1.tgz", - "integrity": "sha512-1xzFN3gqv+/qJ6YRyxBxfTYstLNt0FCtZaFRvf4Sg9wxNGWbwFmGXVpfSi6ThGK6aRxAo+KjHtYSW8NvCsNSAg==" - }, "nodemon": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz", "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==", - "dev": true, "requires": { "chokidar": "^3.2.2", "debug": "^3.2.6", @@ -20553,7 +22244,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -20561,8 +22251,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -20598,14 +22287,12 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" }, "now-and-later": { "version": "2.0.1", @@ -20637,6 +22324,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -20647,7 +22335,8 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true }, "oauth-sign": { "version": "0.9.0", @@ -20728,6 +22417,12 @@ } } }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "optional": true + }, "object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", @@ -20822,7 +22517,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, + "devOptional": true, "requires": { "mimic-fn": "^2.1.0" } @@ -20901,14 +22596,13 @@ "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, + "devOptional": true, "requires": { "yocto-queue": "^0.1.0" } @@ -20941,7 +22635,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, "requires": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", @@ -21053,7 +22746,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "2.0.1", @@ -21121,8 +22815,7 @@ "picomatch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "dev": true + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" }, "pify": { "version": "3.0.0", @@ -21190,8 +22883,7 @@ "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { "version": "2.1.2", @@ -21324,6 +23016,27 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -21336,8 +23049,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.8.0", @@ -21348,8 +23060,7 @@ "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, "public-encrypt": { "version": "4.0.3", @@ -21377,7 +23088,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -21416,7 +23126,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, "requires": { "escape-goat": "^2.0.0" } @@ -21484,7 +23193,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -21495,8 +23203,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" } } }, @@ -21624,7 +23331,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -21727,7 +23433,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, "requires": { "rc": "^1.2.8" } @@ -21736,7 +23441,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, "requires": { "rc": "^1.2.8" } @@ -21861,7 +23565,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "devOptional": true }, "require-main-filename": { "version": "2.0.0", @@ -21914,7 +23618,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, "requires": { "lowercase-keys": "^1.0.0" } @@ -21935,6 +23638,21 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "optional": true + }, + "retry-request": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.3.tgz", + "integrity": "sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ==", + "optional": true, + "requires": { + "debug": "^4.1.1" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -21945,6 +23663,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -22059,7 +23778,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, "requires": { "semver": "^6.3.0" } @@ -22135,7 +23853,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "set-value": { "version": "2.0.1", @@ -22266,6 +23985,12 @@ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" }, + "snakeize": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", + "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", + "optional": true + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -22651,6 +24376,15 @@ "readable-stream": "^2.0.2" } }, + "stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "requires": { + "stubs": "^3.0.0" + } + }, "stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", @@ -22686,7 +24420,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true + "devOptional": true }, "stream-splicer": { "version": "2.0.1", @@ -22698,11 +24432,16 @@ "readable-stream": "^2.0.2" } }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, + "devOptional": true, "requires": { "safe-buffer": "~5.2.0" } @@ -22711,7 +24450,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -22721,14 +24459,12 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -22759,7 +24495,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -22794,6 +24529,12 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "optional": true + }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -22807,7 +24548,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -22879,11 +24619,31 @@ "inherits": "2" } }, + "teeny-request": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.0.tgz", + "integrity": "sha512-hPfSc05a7Mf3syqVhSkrVMb844sMiP60MrfGMts3ft6V6UlSkEIGQzgwf0dy1KjdE3FV2lJ5s7QCBFcaoQLA6g==", + "optional": true, + "requires": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true + } + } + }, "term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" }, "text-table": { "version": "0.2.0", @@ -22985,8 +24745,7 @@ "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" }, "to-regex": { "version": "3.0.2", @@ -23004,7 +24763,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -23027,7 +24785,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, "requires": { "nopt": "~1.0.10" }, @@ -23036,7 +24793,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, "requires": { "abbrev": "1" } @@ -23149,7 +24905,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -23195,7 +24950,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, "requires": { "debug": "^2.2.0" }, @@ -23204,7 +24958,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -23212,8 +24965,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -23311,7 +25063,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, "requires": { "crypto-random-string": "^2.0.0" } @@ -23371,7 +25122,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "dev": true, "requires": { "boxen": "^4.2.0", "chalk": "^3.0.0", @@ -23392,7 +25142,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -23401,7 +25150,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -23411,7 +25159,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -23419,14 +25166,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -23478,7 +25223,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, "requires": { "prepend-http": "^2.0.0" } @@ -23687,6 +25431,21 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -23740,6 +25499,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, "requires": { "string-width": "^1.0.2 || 2" }, @@ -23747,17 +25507,20 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -23767,6 +25530,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -23777,7 +25541,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, "requires": { "string-width": "^4.0.0" } @@ -23842,7 +25605,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -23853,8 +25615,7 @@ "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, "xtend": { "version": "4.0.2", @@ -23871,8 +25632,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yaml": { "version": "1.10.2", @@ -23988,7 +25748,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "devOptional": true } } } diff --git a/package.json b/package.json index 9cedeadbd..10593e6f0 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "postinstall": "cd functions && npm install", "build": "npx gulp build", - "start:dev": "npm run build && concurrently --kill-others \"npx gulp watch\" \"nodemon ./backend/server.js\"", + "start:dev": "npm run build && concurrently --kill-others \"npx gulp watch\" \"nodemon ./backend/server.js\" \"firebase serve\"", "deploy:live:hosting": "npm run build && firebase deploy -P monkey-type --only hosting", "deploy:live:functions": "npm run build && firebase deploy -P monkey-type --only functions", "deploy:live": "npm run build && firebase deploy -P live" @@ -30,7 +30,6 @@ "gulp-eslint": "^6.0.0", "gulp-sass": "^4.1.0", "husky": "^4.3.0", - "nodemon": "^2.0.7", "prettier": "2.1.2", "pretty-quick": "^3.1.0", "vinyl-buffer": "^1.0.1", @@ -45,16 +44,15 @@ "dependencies": { "@babel/runtime": "^7.12.5", "axios": "^0.21.1", - "bcrypt": "^5.0.1", "chart.js": "^2.9.4", "chartjs-plugin-annotation": "^0.5.7", "chartjs-plugin-trendline": "^0.2.2", - "dotenv": "^9.0.2", + "cors": "^2.8.5", "express": "^4.17.1", + "firebase-admin": "^9.9.0", "howler": "^2.2.1", - "jsonwebtoken": "^8.5.1", - "mongoose": "^5.12.8", - "nodemailer": "^6.6.1", + "mongoose": "^5.12.12", + "nodemon": "^2.0.7", "tinycolor2": "^1.4.2" } } diff --git a/src/js/account-controller.js b/src/js/account-controller.js index 6b4888625..cf8218838 100644 --- a/src/js/account-controller.js +++ b/src/js/account-controller.js @@ -14,42 +14,52 @@ import * as DB from "./db"; import * as TestLogic from "./test-logic"; import * as UI from "./ui"; import axiosInstance from "./axios-instance"; -//var gmailProvider = new firebase.auth.GoogleAuthProvider(); + +var gmailProvider = new firebase.auth.GoogleAuthProvider(); export function signIn() { $(".pageLogin .preloader").removeClass("hidden"); let email = $(".pageLogin .login input")[0].value; let password = $(".pageLogin .login input")[1].value; - axiosInstance - .post("/api/signIn", { - email: email, - password: password, - }) - .then((response) => { - // UI.changePage("test"); - if ($(".pageLogin .login #rememberMe input").prop("checked")) { - // TODO: set user login cookie that persists after session - window.localStorage.setItem("accessToken", response.data.accessToken); - window.localStorage.setItem("refreshToken", response.data.refreshToken); - window.localStorage.setItem("user", JSON.stringify(response.data.user)); - } else { - //set user login cookie to persist only as long as the session lives - window.localStorage.setItem("accessToken", response.data.accessToken); - window.localStorage.setItem("refreshToken", response.data.refreshToken); - window.localStorage.setItem("user", JSON.stringify(response.data.user)); - } - userStateChanged(response.data.user); - }) - .catch((e) => { - console.log("Could not be signed in"); - Notifications.add(e.message, -1); - $(".pageLogin .preloader").addClass("hidden"); - }); + + if ($(".pageLogin .login #rememberMe input").prop("checked")) { + //remember me + firebase + .auth() + .setPersistence(firebase.auth.Auth.Persistence.LOCAL) + .then(function () { + return firebase + .auth() + .signInWithEmailAndPassword(email, password) + .then((e) => { + // UI.changePage("test"); + }) + .catch(function (error) { + Notifications.add(error.message, -1); + $(".pageLogin .preloader").addClass("hidden"); + }); + }); + } else { + //dont remember + firebase + .auth() + .setPersistence(firebase.auth.Auth.Persistence.SESSION) + .then(function () { + return firebase + .auth() + .signInWithEmailAndPassword(email, password) + .then((e) => { + // UI.changePage("test"); + }) + .catch(function (error) { + Notifications.add(error.message, -1); + $(".pageLogin .preloader").addClass("hidden"); + }); + }); + } } export async function signInWithGoogle() { - console.log("Login with google temporarily unavailable"); - /* $(".pageLogin .preloader").removeClass("hidden"); if ($(".pageLogin .login #rememberMe input").prop("checked")) { @@ -81,12 +91,9 @@ export async function signInWithGoogle() { $(".pageLogin .preloader").addClass("hidden"); }); } - */ } export function linkWithGoogle() { - console.log("Link with google temporarily unavailable"); - /* firebase .auth() .currentUser.linkWithPopup(gmailProvider) @@ -96,21 +103,23 @@ export function linkWithGoogle() { .catch(function (error) { console.log(error); }); - */ } export function signOut() { - //don't think I need an axios request here if I'm using jwt - window.localStorage.removeItem("accessToken"); - window.localStorage.removeItem("refreshToken"); - window.localStorage.removeItem("user"); - Notifications.add("Signed out", 0, 2); - AllTimeStats.clear(); - Settings.hideAccountSection(); - AccountButton.update(); - UI.changePage("login"); - DB.setSnapshot(null); - userStateChanged(null); + firebase + .auth() + .signOut() + .then(function () { + Notifications.add("Signed out", 0, 2); + AllTimeStats.clear(); + Settings.hideAccountSection(); + AccountButton.update(); + UI.changePage("login"); + DB.setSnapshot(null); + }) + .catch(function (error) { + Notifications.add(error.message, -1); + }); } function signUp() { @@ -127,65 +136,131 @@ function signUp() { $(".pageLogin .register .button").removeClass("disabled"); return; } - - axiosInstance - .post("/api/signUp", { - name: nname, - email: email, - password: password, - }) - .then((response) => { - let usr = response.data.user; - window.localStorage.setItem("accessToken", response.data.accessToken); - window.localStorage.setItem("refreshToken", response.data.refreshToken); - window.localStorage.setItem("user", JSON.stringify(response.data.user)); - //Cookies.set('refreshToken', response.data.refreshToken); - AllTimeStats.clear(); - Notifications.add("Account created", 1, 3); - $("#menu .icon-button.account .text").text(nname); - $(".pageLogin .preloader").addClass("hidden"); - DB.setSnapshot({ - results: [], - personalBests: {}, - tags: [], - globalStats: { - time: undefined, - started: undefined, - completed: undefined, - }, - }); - if (TestLogic.notSignedInLastResult !== null) { - TestLogic.setNotSignedInUid(usr.uid); - CloudFunctions.testCompleted({ - uid: usr.uid, - obj: TestLogic.notSignedInLastResult, - }); - DB.getSnapshot().results.push(TestLogic.notSignedInLastResult); - } - UI.changePage("account"); - $(".pageLogin .register .button").removeClass("disabled"); - userStateChanged(usr); - }) - .catch((error) => { - //Notifications.add("Account not created. " + error.message, -1); - Notifications.add(error, -1); + axiosInstance.get(`/api/nameCheck/${nname}`).then((d) => { + console.log(d.data); + if (d.data.resultCode === -1) { + Notifications.add("Name unavailable", -1); $(".pageLogin .preloader").addClass("hidden"); $(".pageLogin .register .button").removeClass("disabled"); return; - }); + } else if (d.data.resultCode === -2) { + Notifications.add( + "Name cannot contain special characters or contain more than 14 characters. Can include _ . and -", + -1 + ); + $(".pageLogin .preloader").addClass("hidden"); + $(".pageLogin .register .button").removeClass("disabled"); + return; + } else if (d.data.resultCode === 1) { + firebase + .auth() + .createUserWithEmailAndPassword(email, password) + .then((user) => { + // Account has been created here. + // dontCheckUserName = true; + let usr = user.user; + //maybe there's a better place for the api call + axiosInstance.post("/api/signUp", { + name: nname, + uid: usr.uid, + email: email, + }); + usr + .updateProfile({ + displayName: nname, + }) + .then(async function () { + // Update successful. + await firebase + .firestore() + .collection("users") + .doc(usr.uid) + .set({ name: nname }, { merge: true }); + usr.sendEmailVerification(); + AllTimeStats.clear(); + Notifications.add("Account created", 1, 3); + $("#menu .icon-button.account .text").text(nname); + try { + firebase.analytics().logEvent("accountCreated", usr.uid); + } catch (e) { + console.log("Analytics unavailable"); + } + $(".pageLogin .preloader").addClass("hidden"); + DB.setSnapshot({ + results: [], + personalBests: {}, + tags: [], + globalStats: { + time: undefined, + started: undefined, + completed: undefined, + }, + }); + if (TestLogic.notSignedInLastResult !== null) { + TestLogic.setNotSignedInUid(usr.uid); + CloudFunctions.testCompleted({ + uid: usr.uid, + obj: TestLogic.notSignedInLastResult, + }); + DB.getSnapshot().results.push(TestLogic.notSignedInLastResult); + } + UI.changePage("account"); + usr.sendEmailVerification(); + $(".pageLogin .register .button").removeClass("disabled"); + }) + .catch(function (error) { + // An error happened. + $(".pageLogin .register .button").removeClass("disabled"); + console.error(error); + usr + .delete() + .then(function () { + // User deleted. + Notifications.add( + "Account not created. " + error.message, + -1 + ); + $(".pageLogin .preloader").addClass("hidden"); + }) + .catch(function (error) { + // An error happened. + $(".pageLogin .preloader").addClass("hidden"); + Notifications.add( + "Something went wrong. " + error.message, + -1 + ); + console.error(error); + }); + }); + }) + .catch(function (error) { + // Handle Errors here. + $(".pageLogin .register .button").removeClass("disabled"); + Notifications.add(error.message, -1); + $(".pageLogin .preloader").addClass("hidden"); + }); + } else { + $(".pageLogin .preloader").addClass("hidden"); + Notifications.add( + "Something went wrong when checking name: " + d.data.message, + -1 + ); + } + }); } $(".pageLogin #forgotPasswordButton").click((e) => { let email = prompt("Email address"); if (email) { - axiosInstance - .post("/api/passwordReset", { - email: email, - }) - .then(() => { + firebase + .auth() + .sendPasswordResetEmail(email) + .then(function () { + // Email sent. Notifications.add("Email sent", 1, 2); }) - .catch((error) => { + .catch(function (error) { + // An error happened. Notifications.add(error.message, -1); }); } @@ -212,7 +287,7 @@ $(".signOut").click((e) => { signOut(); }); -export function userStateChanged(user) { +firebase.auth().onAuthStateChanged(function (user) { if (user) { // User is signed in. $(".pageAccount .content p.accountVerificatinNotice").remove(); @@ -224,7 +299,7 @@ export function userStateChanged(user) { AccountButton.update(); AccountButton.loading(true); Account.getDataAndInit(); - // var name = user.name; + // var displayName = user.displayName; // var email = user.email; // var emailVerified = user.emailVerified; // var photoURL = user.photoURL; @@ -236,8 +311,7 @@ export function userStateChanged(user) { // showFavouriteThemesAtTheTop(); CommandlineLists.updateThemeCommands(); - let text = - "Account created on " + user.metadata.creationTime.substring(0, 10); + let text = "Account created on " + user.metadata.creationTime; const date1 = new Date(user.metadata.creationTime); const date2 = new Date(); @@ -275,7 +349,7 @@ export function userStateChanged(user) { ChallengeController.setup(challengeName); }, 1000); } -} +}); $(".pageLogin .register input").keyup((e) => { if ($(".pageLogin .register .button").hasClass("disabled")) return; diff --git a/src/js/account.js b/src/js/account.js index 3da19a866..5abee9ad8 100644 --- a/src/js/account.js +++ b/src/js/account.js @@ -27,7 +27,7 @@ export function getDataAndInit() { if (snap === null) { throw "Missing db snapshot. Client likely could not connect to the backend."; } - let user = DB.currentUser(); // I think that this should be stored in cookie + let user = firebase.auth().currentUser; // I think that this should be stored in cookie if (snap.name === undefined) { //verify username if (Misc.isUsernameValid(user.name)) { diff --git a/src/js/axios-instance.js b/src/js/axios-instance.js index a8ae396b8..a74f34c2b 100644 --- a/src/js/axios-instance.js +++ b/src/js/axios-instance.js @@ -1,14 +1,21 @@ import axios from "axios"; -const axiosInstance = axios.create(); +const axiosInstance = axios.create({ + baseURL: "http://localhost:5005", +}); // Request interceptor for API calls axiosInstance.interceptors.request.use( async (config) => { - const accessToken = window.localStorage.getItem("accessToken"); - if (accessToken) { + let idToken; + if (firebase.auth().currentUser != null) { + idToken = await firebase.auth().currentUser.getIdToken(); + } else { + idToken = null; + } + if (idToken) { config.headers = { - Authorization: `Bearer ${accessToken}`, + Authorization: `Bearer ${idToken}`, Accept: "application/json", "Content-Type": "application/json", }; @@ -25,35 +32,4 @@ axiosInstance.interceptors.request.use( } ); -// Response interceptor for API calls -axiosInstance.interceptors.response.use( - (response) => { - return response; - }, - async function (error) { - const originalRequest = error.config; - if (error.response.status === 401 && !originalRequest._retry) { - originalRequest._retry = true; - const refreshToken = window.localStorage.getItem("refreshToken"); - await axios - .post( - `/api/refreshToken`, - {}, - { headers: { Authorization: `Bearer ${refreshToken}` } } - ) - .then((response) => { - window.localStorage.setItem("accessToken", response.data.accessToken); - axios.defaults.headers.common["Authorization"] = - "Bearer " + response.data.accessToken; - }) - .catch((error) => { - console.log(error); - axios.defaults.headers.common["Authorization"] = "Bearer failed"; - }); - return axiosInstance(originalRequest); - } - return Promise.reject(error); - } -); - export default axiosInstance; diff --git a/src/js/commandline.js b/src/js/commandline.js index cba440836..d78614b74 100644 --- a/src/js/commandline.js +++ b/src/js/commandline.js @@ -4,7 +4,6 @@ import Config, * as UpdateConfig from "./config"; import * as Focus from "./focus"; import * as CommandlineLists from "./commandline-lists"; import * as TestUI from "./test-ui"; -import axiosInstance from "./axios-instance"; let commandLineMouseMode = false; @@ -162,11 +161,13 @@ function trigger(command) { } }); if (!subgroup && !input && !sticky) { - axiosInstance - .post("/api/analytics/usedCommandLine", { command: command }) - .catch(() => { - console.log("Analytics unavailable"); + try { + firebase.analytics().logEvent("usedCommandLine", { + command: command, }); + } catch (e) { + console.log("Analytics unavailable"); + } hide(); } } @@ -322,11 +323,13 @@ $("#commandInput input").keydown((e) => { } } }); - axiosInstance - .post("/api/analytics/usedCommandLine", { command: command }) - .catch(() => { - console.log("Analytics unavailable"); + try { + firebase.analytics().logEvent("usedCommandLine", { + command: command, }); + } catch (e) { + console.log("Analytics unavailable"); + } hide(); } return; diff --git a/src/js/config.js b/src/js/config.js index 34a0bd268..2ef46f554 100644 --- a/src/js/config.js +++ b/src/js/config.js @@ -17,7 +17,6 @@ import * as UI from "./ui"; import * as CommandlineLists from "./commandline-lists"; import * as BackgroundFilter from "./custom-background-filter"; import LayoutList from "./layouts"; -import axiosInstance from "./axios-instance"; export let localStorageConfig = null; export let dbConfigLoaded = false; @@ -485,7 +484,7 @@ export function setPaceCaret(val, nosave) { val = "off"; } if (document.readyState === "complete") { - if (val == "pb" && DB.currentUser() === null) { + if (val == "pb" && firebase.auth().currentUser === null) { Notifications.add("PB pace caret is unavailable without an account", 0); return; } @@ -1244,11 +1243,13 @@ export function setLanguage(language, nosave) { language = "english"; } config.language = language; - axiosInstance - .post("/api/analytics/changedLanguage", { language: language }) - .catch(() => { - console.log("Analytics unavailable"); + try { + firebase.analytics().logEvent("changedLanguage", { + language: language, }); + } catch (e) { + console.log("Analytics unavailable"); + } if (!nosave) saveToLocalStorage(); } @@ -1563,8 +1564,10 @@ export function apply(configObj) { try { setEnableAds(configObj.enableAds, true); let addemo = false; - //if the app is not running on production, play advertisement demo - if (window.location.hostname === "localhost") { + if ( + firebase.app().options.projectId === "monkey-type-dev-67af4" || + window.location.hostname === "localhost" + ) { addemo = true; } diff --git a/src/js/db.js b/src/js/db.js index d61a5220c..132a0512d 100644 --- a/src/js/db.js +++ b/src/js/db.js @@ -27,19 +27,9 @@ export function setSnapshot(newSnapshot) { dbSnapshot = newSnapshot; } -export function currentUser() { - const token = window.localStorage.getItem("accessToken"); - if (token) { - const user = JSON.parse(window.localStorage.getItem("user")); - return user; - } else { - return null; - } -} - export async function initSnapshot() { //send api request with token that returns tags, presets, and data needed for snap - if (currentUser() == null) return false; + if (firebase.auth().currentUser == null) return false; await axiosInstance .get("/api/fetchSnapshot") .then((response) => { @@ -53,7 +43,7 @@ export async function initSnapshot() { } export async function getUserResults() { - let user = currentUser(); + let user = firebase.auth().currentUser; if (user == null) return false; if (dbSnapshot === null) return false; if (dbSnapshot.results !== undefined) { @@ -418,7 +408,7 @@ export function updateLbMemory(mode, mode2, type, value) { } export async function saveConfig(config) { - if (currentUser() !== null) { + if (firebase.auth().currentUser !== null) { AccountButton.loading(true); axiosInstance .post("/api/saveConfig", { diff --git a/src/js/elements/account-button.js b/src/js/elements/account-button.js index c54eb74de..c7eef4379 100644 --- a/src/js/elements/account-button.js +++ b/src/js/elements/account-button.js @@ -1,5 +1,4 @@ import * as UI from "./ui"; -import * as DB from "./db"; export function loading(truefalse) { if (truefalse) { @@ -14,7 +13,7 @@ export function loading(truefalse) { } export function update() { - if (DB.currentUser() != null) { + if (firebase.auth().currentUser != null) { UI.swapElements( $("#menu .icon-button.login"), $("#menu .icon-button.account"), diff --git a/src/js/elements/leaderboards.js b/src/js/elements/leaderboards.js index 52f40b3ed..7e320c8eb 100644 --- a/src/js/elements/leaderboards.js +++ b/src/js/elements/leaderboards.js @@ -1,4 +1,3 @@ -import * as CloudFunctions from "./cloud-functions"; import * as Loader from "./loader"; import * as Notifications from "./notifications"; import * as DB from "./db"; @@ -82,7 +81,8 @@ function update() { dailyData.board.forEach((entry) => { if (entry.hidden) return; let meClassString = ""; - if (entry.name == DB.currentUser().name) { + //hacky way to get username because auth().currentUser.name isn't working after mongo switch + if (DB.getSnapshot() && entry.name == DB.getSnapshot().name) { meClassString = ' class="me"'; $("#leaderboardsWrapper table.daily tfoot").html(` @@ -165,7 +165,7 @@ function update() { globalData.board.forEach((entry) => { if (entry.hidden) return; let meClassString = ""; - if (entry.name == DB.currentUser().name) { + if (DB.getSnapshot() && entry.name == DB.getSnapshot().name) { meClassString = ' class="me"'; $("#leaderboardsWrapper table.global tfoot").html(` diff --git a/src/js/misc.js b/src/js/misc.js index e91ffe02c..291826076 100644 --- a/src/js/misc.js +++ b/src/js/misc.js @@ -1,10 +1,9 @@ import * as Loader from "./loader"; -import * as DB from "./db"; import axiosInstance from "./axios-instance"; export function getuid() { console.error("Only share this uid with Miodec and nobody else!"); - console.log(DB.currentUser().uid); + console.log(firebase.auth().currentUser.uid); console.error("Only share this uid with Miodec and nobody else!"); } @@ -315,7 +314,7 @@ export function migrateFromCookies() { export function sendVerificationEmail() { Loader.show(); - let cu = DB.currentUser(); + let cu = firebase.auth().currentUser; axiosInstance .post("/api/sendEmailVerification", {}) .then(() => { diff --git a/src/js/popups/result-tags-popup.js b/src/js/popups/result-tags-popup.js index e77bacd35..facaf6099 100644 --- a/src/js/popups/result-tags-popup.js +++ b/src/js/popups/result-tags-popup.js @@ -86,7 +86,7 @@ $("#resultEditTagsPanel .confirmButton").click((e) => { Loader.show(); hide(); CloudFunctions.updateResultTags({ - uid: DB.currentUser().uid, + uid: firebase.auth().currentUser.uid, tags: newtags, resultid: resultid, }).then((r) => { diff --git a/src/js/ready.js b/src/js/ready.js index 19e510cfa..c1c9ca1b2 100644 --- a/src/js/ready.js +++ b/src/js/ready.js @@ -7,9 +7,7 @@ import * as RouteController from "./route-controller"; import * as UI from "./ui"; import * as SignOutButton from "./sign-out-button"; import * as AccountController from "./account-controller"; -import * as DB from "./db"; -console.log("redy loaded"); ManualRestart.set(); Misc.migrateFromCookies(); UpdateConfig.loadFromLocalStorage(); @@ -61,6 +59,5 @@ $(document).ready(() => { } }); Settings.settingsFillPromise.then(Settings.update); - let user = DB.currentUser(); - if (user) AccountController.userStateChanged(user); + let user = firebase.auth().currentUser; }); diff --git a/src/js/route-controller.js b/src/js/route-controller.js index 7b7ad8898..49beeb03d 100644 --- a/src/js/route-controller.js +++ b/src/js/route-controller.js @@ -1,6 +1,5 @@ import * as Funbox from "./funbox"; import * as UI from "./ui"; -import * as DB from "./db"; let mappedRoutes = { "/": "pageTest", @@ -36,7 +35,7 @@ $(window).on("popstate", (e) => { // show about UI.changePage("about"); } else if (state == "account" || state == "login") { - if (DB.currentUser()) { + if (firebase.auth().currentUser) { UI.changePage("account"); } else { UI.changePage("login"); diff --git a/src/js/settings.js b/src/js/settings.js index 50ad233f0..55cc64b9b 100644 --- a/src/js/settings.js +++ b/src/js/settings.js @@ -422,7 +422,7 @@ function showActiveTags() { export function updateDiscordSection() { //no code and no discord - if (DB.currentUser() == null) { + if (firebase.auth().currentUser == null) { $(".pageSettings .section.discordIntegration").addClass("hidden"); } else { if (DB.getSnapshot() == null) return; @@ -453,7 +453,7 @@ function setActiveFunboxButton() { } function refreshTagsSettingsSection() { - if (DB.currentUser() !== null && DB.getSnapshot() !== null) { + if (firebase.auth().currentUser !== null && DB.getSnapshot() !== null) { let tagsEl = $(".pageSettings .section.tags .tagsList").empty(); DB.getSnapshot().tags.forEach((tag) => { let tagPbString = "No PB found"; @@ -480,7 +480,7 @@ function refreshTagsSettingsSection() { } function refreshPresetsSettingsSection() { - if (DB.currentUser() !== null && DB.getSnapshot() !== null) { + if (firebase.auth().currentUser !== null && DB.getSnapshot() !== null) { let presetsEl = $(".pageSettings .section.presets .presetsList").empty(); DB.getSnapshot().presets.forEach((preset) => { presetsEl.append(` @@ -649,7 +649,7 @@ $( ).click((e) => { Loader.show(); CloudFunctions.generatePairingCode({ - uid: DB.currentUser().uid, + uid: firebase.auth().currentUser.uid, }) .then((ret) => { Loader.hide(); @@ -675,7 +675,7 @@ $(".pageSettings .section.discordIntegration #unlinkDiscordButton").click( if (confirm("Are you sure?")) { Loader.show(); CloudFunctions.unlinkDiscord({ - uid: DB.currentUser().uid, + uid: firebase.auth().currentUser.uid, }).then((ret) => { Loader.hide(); console.log(ret); diff --git a/src/js/simple-popups.js b/src/js/simple-popups.js index 1d159ecb1..929fa6525 100644 --- a/src/js/simple-popups.js +++ b/src/js/simple-popups.js @@ -153,7 +153,7 @@ list.updateEmail = new SimplePopup( try { Loader.show(); CloudFunctions.updateEmail({ - uid: DB.currentUser().uid, + uid: firebase.auth().currentUser.uid, previousEmail: previousEmail, newEmail: newEmail, }).then((data) => { @@ -190,7 +190,7 @@ list.clearTagPb = new SimplePopup( let tagid = eval("this.parameters[0]"); Loader.show(); CloudFunctions.clearTagPb({ - uid: DB.currentUser().uid, + uid: firebase.auth().currentUser.uid, tagid: tagid, }) .then((res) => { diff --git a/src/js/test/test-leaderboards.js b/src/js/test/test-leaderboards.js index 112d5446d..f92ba8874 100644 --- a/src/js/test/test-leaderboards.js +++ b/src/js/test/test-leaderboards.js @@ -1,4 +1,3 @@ -import * as CloudFunctions from "./cloud-functions"; import * as DB from "./db"; import * as Notifications from "./notifications"; import Config from "./config"; @@ -115,7 +114,7 @@ export function show(data, mode2) { string = globalLbString + "
" + dailyLbString; // CloudFunctions.saveLbMemory({ - // uid: DB.currentUser().uid, + // uid: firebase.auth().currentUser.uid, // obj: DB.getSnapshot().lbMemory, // }).then((d) => { // if (d.data.returnCode === 1) { diff --git a/src/js/test/test-logic.js b/src/js/test/test-logic.js index 1dab93422..366a026df 100644 --- a/src/js/test/test-logic.js +++ b/src/js/test/test-logic.js @@ -316,10 +316,10 @@ export function startTest() { UpdateConfig.setChangedBeforeDb(true); } try { - if (DB.currentUser() != null) { - axiosInstance.post("/api/analytics/testStarted"); + if (firebase.auth().currentUser != null) { + firebase.analytics().logEvent("testStarted"); } else { - axiosInstance.post("/api/analytics/testStartedNoLogin"); + firebase.analytics().logEvent("testStartedNoLogin"); } } catch (e) { console.log("Analytics unavailable"); @@ -1404,8 +1404,8 @@ export function finish(difficultyFailed = false) { stats.acc > 50 && stats.acc <= 100 ) { - if (DB.currentUser() != null) { - completedEvent.uid = DB.currentUser().uid; + if (firebase.auth().currentUser != null) { + completedEvent.uid = firebase.auth().currentUser.uid; //check local pb AccountButton.loading(true); let dontShowCrown = false; @@ -1638,13 +1638,13 @@ export function finish(difficultyFailed = false) { } } - axiosInstance - .post("/api/analytics/testCompleted", { - completedEvent: completedEvent, - }) - .catch(() => { - console.log("Analytics unavailable"); - }); + try { + firebase + .analytics() + .logEvent("testCompleted", completedEvent); + } catch (e) { + console.log("Analytics unavailable"); + } if (e.data.resultCode === 2) { //new pb @@ -1679,29 +1679,25 @@ export function finish(difficultyFailed = false) { }); }); } else { - axiosInstance - .post("/api/analytics/testCompletedNoLogin", { - completedEvent: completedEvent, - }) - .catch((e) => { - console.log("Analytics unavailable"); - }); + try { + firebase.analytics().logEvent("testCompletedNoLogin", completedEvent); + } catch (e) { + console.log("Analytics unavailable"); + } notSignedInLastResult = completedEvent; } } else { Notifications.add("Test invalid", 0); TestStats.setInvalid(); - axiosInstance - .post("/api/analytics/testCompletedInvalid", { - completedEvent: completedEvent, - }) - .catch((e) => { - console.log("Analytics unavailable"); - }); + try { + firebase.analytics().logEvent("testCompletedInvalid", completedEvent); + } catch (e) { + console.log("Analytics unavailable"); + } } } - if (DB.currentUser() != null) { + if (firebase.auth().currentUser != null) { $("#result .loginTip").addClass("hidden"); } else { $("#result .stats .leaderboards").addClass("hidden"); diff --git a/src/js/test/test-ui.js b/src/js/test/test-ui.js index a02d4700f..ba22f5e10 100644 --- a/src/js/test/test-ui.js +++ b/src/js/test/test-ui.js @@ -192,7 +192,7 @@ export function screenshot() { $(".pageTest .ssWatermark").addClass("hidden"); $(".pageTest .buttons").removeClass("hidden"); if (revealReplay) $("#resultReplay").removeClass("hidden"); - if (DB.currentUser() == null) + if (firebase.auth().currentUser == null) $(".pageTest .loginTip").removeClass("hidden"); } diff --git a/src/js/theme-controller.js b/src/js/theme-controller.js index 41d44cf22..5d727580f 100644 --- a/src/js/theme-controller.js +++ b/src/js/theme-controller.js @@ -96,13 +96,13 @@ export function apply(themeName) { }); } - axiosInstance - .post("/api/analytics/changedTheme", { + try { + firebase.analytics().logEvent("changedTheme", { theme: themeName, - }) - .catch((e) => { - console.log("Analytics unavailable"); }); + } catch (e) { + console.log("Analytics unavailable"); + } setTimeout(() => { $(".keymap-key").attr("style", ""); ChartController.updateAllChartColors(); diff --git a/src/js/ui.js b/src/js/ui.js index 7438a9187..ee7ba3474 100644 --- a/src/js/ui.js +++ b/src/js/ui.js @@ -14,7 +14,6 @@ import * as Settings from "./settings"; import * as Account from "./account"; import * as Leaderboards from "./leaderboards"; import * as Funbox from "./funbox"; -import * as DB from "./db"; export let pageTransition = false; @@ -164,8 +163,10 @@ export function changePage(page) { TestConfig.hide(); SignOutButton.hide(); } else if (page == "account") { - if (!DB.currentUser()) { - console.log(`current user is ${DB.currentUser()}, going back to login`); + if (!firebase.auth().currentUser) { + console.log( + `current user is ${firebase.auth().currentUser}, going back to login` + ); changePage("login"); } else { setPageTransition(true); @@ -188,7 +189,7 @@ export function changePage(page) { TestConfig.hide(); } } else if (page == "login") { - if (DB.currentUser() != null) { + if (firebase.auth().currentUser != null) { changePage("account"); } else { setPageTransition(true); diff --git a/static/index.html b/static/index.html index 4395428fd..280fea4e7 100644 --- a/static/index.html +++ b/static/index.html @@ -4258,7 +4258,18 @@ + + + + + + + + + + diff --git a/static/quotes/english.json b/static/quotes/english.json index 1004f81b0..ae950b272 100644 --- a/static/quotes/english.json +++ b/static/quotes/english.json @@ -32896,6 +32896,12 @@ "source": "Steins;Gate", "length": 247, "id": 5538 + }, + { + "text": "Any fool can write code that a computer can understand. Good programmers write code that humans can understand.", + "source": "Martin Fowler", + "length": 111, + "id": 5539 } ] } diff --git a/static/webfonts/fa-brands-400.eot b/static/webfonts/fa-brands-400.eot index a1bc094ab14d8c7d84d8c59aa511de9e69440d0a..55ce7fd7be46eff0181894dbca2eea6ec470e1c9 100644 GIT binary patch delta 54779 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 delta 39534 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 Im);BhA2#KKP5=M^